mikser-io 9.50.0 → 9.50.1

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/package.json +1 -1
  2. package/src/changeset.js +45 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mikser-io",
3
- "version": "9.50.0",
3
+ "version": "9.50.1",
4
4
  "description": "<p align=\"center\"> <img src=\"mikser-lockup-stacked.svg\" alt=\"mikser\" width=\"198\" /> </p>",
5
5
  "main": "index.js",
6
6
  "exports": {
package/src/changeset.js CHANGED
@@ -61,7 +61,13 @@ registerSchema('change_sets', `
61
61
  -- permanent failure and a pending commit look identical, and both
62
62
  -- read as a null commit forever.
63
63
  commit_error TEXT,
64
- commit_attempts INTEGER NOT NULL DEFAULT 0
64
+ commit_attempts INTEGER NOT NULL DEFAULT 0,
65
+ -- How the set finished. A claimed set had exactly two exits,
66
+ -- committed or failed, and a set whose changes cancel out qualifies
67
+ -- for neither: there is genuinely nothing to write, which is not an
68
+ -- error. Without a third outcome it was re-claimed every pass forever
69
+ -- and reported a null commit that looked like a fault.
70
+ outcome TEXT
65
71
  );
66
72
  CREATE INDEX IF NOT EXISTS idx_mikser_change_sets_created
67
73
  ON mikser_change_sets (created_at DESC);
@@ -222,6 +228,7 @@ function rowsToSets(handle, rows) {
222
228
  recordedAs: row.recorded_as ?? null,
223
229
  commitError: row.commit_error ?? null,
224
230
  commitAttempts: row.commit_attempts ?? 0,
231
+ outcome: row.outcome ?? null,
225
232
  paths: paths.map(p => p.path),
226
233
  deletions: paths.filter(p => p.operation === 'delete').map(p => p.path),
227
234
  }
@@ -241,6 +248,7 @@ function memorySets(filter = () => true) {
241
248
  recordedAs: set.recordedAs ?? null,
242
249
  commitError: set.commitError ?? null,
243
250
  commitAttempts: set.commitAttempts ?? 0,
251
+ outcome: set.outcome ?? null,
244
252
  paths: [...set.paths.keys()],
245
253
  deletions: [...set.paths.entries()].filter(([, op]) => op === 'delete').map(([p]) => p),
246
254
  }))
@@ -375,13 +383,20 @@ export function markChangeSetsRecorded(ids = [], recordedAs = null) {
375
383
  const at = Date.now()
376
384
  for (const id of ids) {
377
385
  const set = memory.get(id)
378
- if (set) { set.recordedAt = at; set.recordedAs = recordedAs; set.commitError = null }
386
+ if (set) {
387
+ set.recordedAt = at
388
+ set.recordedAs = recordedAs
389
+ set.commitError = null
390
+ set.outcome = 'committed'
391
+ }
379
392
  }
380
393
  const handle = db()
381
394
  if (!handle) return
382
395
  try {
383
396
  const stmt = handle.prepare(
384
- 'UPDATE mikser_change_sets SET recorded_at = ?, recorded_as = ?, commit_error = NULL WHERE id = ?')
397
+ `UPDATE mikser_change_sets
398
+ SET recorded_at = ?, recorded_as = ?, commit_error = NULL, outcome = 'committed'
399
+ WHERE id = ?`)
385
400
  for (const id of ids) stmt.run(at, recordedAs, id)
386
401
  } catch { /* memory still holds it */ }
387
402
  }
@@ -416,6 +431,33 @@ export function markChangeSetFailed(id, error) {
416
431
  }
417
432
  }
418
433
 
434
+ // Finish a set that produced no commit, because there was nothing to write.
435
+ //
436
+ // The third outcome. A set whose adds and removals cancel out — an undo of a
437
+ // create, a probe that added and then deleted its own files — leaves an empty
438
+ // diff, and git correctly makes no commit for it. It is not pending and it did
439
+ // not fail: it is DONE, and saying so is what stops it being re-claimed every
440
+ // pass forever while a column of nulls suggests a broken pipeline.
441
+ //
442
+ // `outcome` keeps the distinction that matters to undo: reverting a set that
443
+ // never produced a commit is not the same operation as reverting one that did.
444
+ export function markChangeSetSettled(id, outcome = 'empty') {
445
+ const at = Date.now()
446
+ const set = memory.get(id)
447
+ if (set) { set.recordedAt = at; set.recordedAs = null; set.outcome = outcome }
448
+ const handle = db()
449
+ if (!handle) return
450
+ try {
451
+ handle.prepare(`
452
+ UPDATE mikser_change_sets
453
+ SET recorded_at = COALESCE(recorded_at, ?), outcome = COALESCE(outcome, ?)
454
+ WHERE id = ?
455
+ `).run(at, outcome, id)
456
+ } catch (err) {
457
+ reportChangeSetFailure(err)
458
+ }
459
+ }
460
+
419
461
  export function forgetAllChangeSets() {
420
462
  memory.clear()
421
463
  const handle = db()