@volter/supercode-orchestrator 0.4.96 → 0.4.97

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.
Files changed (2) hide show
  1. package/board/ztrack.mjs +14 -8
  2. package/package.json +1 -1
package/board/ztrack.mjs CHANGED
@@ -109,6 +109,7 @@ class ZtrackBoard {
109
109
 
110
110
  transaction(fn) {
111
111
  if (this.cachedReader) this.invalidate();
112
+ this.readOnly(()=>{ if(this.runtime.prepare('PRAGMA journal_mode').get().journal_mode!=='wal')this.runtime.exec('PRAGMA journal_mode=WAL'); });
112
113
  for (;;) {
113
114
  try { this.runtime.exec('BEGIN'); }
114
115
  catch (error) { if (!/busy|locked/i.test(error.message)) throw error; continue; }
@@ -126,12 +127,12 @@ class ZtrackBoard {
126
127
  const result = fn(this.db);
127
128
  const changes = this.rows.changes(this.mem, { all: !this.rows.normalized() });
128
129
  const canonical = (row, omitted) => row && Object.fromEntries(Object.entries(row).filter(([key])=>!omitted.has(key)));
129
- const cardDirty = this.seed || changes.some(({source})=>{
130
+ const documentChanges = changes.filter(({source})=>{
130
131
  if(source.name==='tasks')return JSON.stringify(canonical(source.row,new Set([...RUNTIME,'status'])))!==JSON.stringify(canonical(this.rows.cachedTasks[JSON.parse(source.key)[0]],new Set([...RUNTIME,'status'])));
131
132
  if(source.name==='supercode_cards')return JSON.stringify(canonical(source.row,new Set(['since','after_fired','next_run_at'])))!==JSON.stringify(canonical(this.rows.cachedCards[JSON.parse(source.key)[0]],new Set(['since','after_fired','next_run_at'])));
132
- return source.name==='task_links';
133
+ return false;
133
134
  });
134
- const documents = cardDirty ? this.documents() : {open:this.text, archived:this.archiveText};
135
+ const documents = this.seed || documentChanges.length ? this.documents(this.seed ? null : documentChanges) : {open:this.text, archived:this.archiveText};
135
136
  const files = [{ path: this.path, before: hash(this.text), base: this.text, text: documents.open }, { path: this.archive, before: hash(this.archiveText), base: this.archiveText, text: documents.archived }];
136
137
  const snapshot = this.snapshot(documents);
137
138
  this.computing = false;
@@ -284,12 +285,13 @@ class ZtrackBoard {
284
285
  this.rows.watch(this.mem);
285
286
  this.mem.exec('DELETE FROM tasks; DELETE FROM supercode_cards; DELETE FROM task_links');
286
287
  this.errors.clear(); this.preserve.clear();
287
- const records = [];
288
+ const records = []; this.documentRecords=new Map();
288
289
  for (const [text,path] of [[this.text,this.path],[this.archiveText,this.archive]]) {
289
290
  const result = this.codec.inspectBoardDocument(text,path);
290
291
  const kept = new Set(result.errors.map(e=>e.id));
291
292
  for(const error of result.errors)this.errors.set(nativeId(error.id),error.reason);
292
293
  for(const record of result.records) {
294
+ this.documentRecords.set(nativeId(record.id),{record,path});
293
295
  try { records.push(this.preset.KanbanRootSchema.parse(this.preset.parseKanban([record])).issues[0]); }
294
296
  catch(error) { this.errors.set(nativeId(record.id),error.message); kept.add(record.id); }
295
297
  }
@@ -389,10 +391,11 @@ class ZtrackBoard {
389
391
  committer() {
390
392
  return 'document-editor';
391
393
  }
392
- documents() {
393
- const rows = this.mem.prepare('SELECT * FROM tasks ORDER BY created_at, id').all();
394
+ documents(changes=null) {
395
+ const allRows = this.mem.prepare('SELECT * FROM tasks ORDER BY created_at, id').all();
394
396
  const states = new Map(this.mem.prepare('SELECT * FROM supercode_cards').all().map((c) => [c.task_id, c]));
395
- const byId = new Map(rows.map((r) => [r.id, r]));
397
+ const affected=changes?new Set(changes.map(({source})=>{const id=JSON.parse(source.key)[0];return states.get(id)?.subtask_of??this.rows.cachedCards[id]?.subtask_of??id;})):null;
398
+ const rows=affected?allRows.filter(row=>affected.has(states.get(row.id)?.subtask_of??row.id)):allRows;
396
399
  const cards = new Map();
397
400
  for (const row of rows.filter((r) => !states.get(r.id)?.subtask_of && !this.errors.has(r.id))) {
398
401
  const c = states.get(row.id) ?? {};
@@ -429,12 +432,15 @@ class ZtrackBoard {
429
432
  blockedBy: json(c.blocked_by, []).map((b) => ({ issue: b.id })) });
430
433
  }
431
434
  const open = [], archived = [];
435
+ if(affected)for(const [id,{record,path}] of this.documentRecords??[])if(!affected.has(id)&&!this.errors.has(id))(path===this.path?open:archived).push(record);
432
436
  for (const [id, card] of cards) {
433
437
  const serialized = this.preset.serializeKanbanCard(card);
434
438
  const record = { id: card.id, title: card.title, status: card.status, ...(card.assignee ? { assignee: card.assignee } : {}), body: serialized.body };
435
439
  (states.get(id)?.archived || ['done', 'cancelled'].includes(card.status) ? archived : open).push(record);
436
440
  }
437
- return { open: this.codec.renderBoardDocument(this.text, open, this.path, [...(this.preserve.get(this.path)??[])]), archived: this.codec.renderBoardDocument(this.archiveText, archived, this.archive, [...(this.preserve.get(this.archive)??[])]) };
441
+ const original=this.documentRecords;
442
+ const changedPath=path=>!affected||[...affected].some(id=>original?.get(id)?.path===path||cards.has(id)&&((states.get(id)?.archived||['done','cancelled'].includes(cards.get(id).status))?this.archive:this.path)===path);
443
+ return { open: !changedPath(this.path)?this.text:this.codec.renderBoardDocument(this.text, open, this.path, [...(this.preserve.get(this.path)??[])]), archived: !changedPath(this.archive)?this.archiveText:this.codec.renderBoardDocument(this.archiveText, archived, this.archive, [...(this.preserve.get(this.archive)??[])]) };
438
444
  }
439
445
  snapshot(documents) {
440
446
  return { documentHashes:{open:hash(documents.open),archived:hash(documents.archived)}, errors:[...this.errors], fingerprints: this.fingerprints(), taskIds: Object.fromEntries([...this.taskKeys].map(([id, key]) => [key, id])) };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/supercode-orchestrator",
3
- "version": "0.4.96",
3
+ "version": "0.4.97",
4
4
  "type": "module",
5
5
  "description": "The orchestrator runtime over the Volter Harness ontology: one typed operational model whose folder is its serialization, read and written through the harness orchestration doors (docs/ORCHESTRATOR-IR.md)",
6
6
  "exports": {