@lmzhen/dsh-evolution-core 0.19.0 → 0.19.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.
package/lib/index.js CHANGED
@@ -6100,8 +6100,27 @@ function newRunRegistry(options) {
6100
6100
  };
6101
6101
  let converged = 0;
6102
6102
  let liveElsewhere = 0;
6103
+ let healed = 0;
6103
6104
  for (const record of parsed.records) {
6104
- if (records.some((item) => item.id === record.id)) continue;
6105
+ const knownIndex = records.findIndex((item) => item.id === record.id);
6106
+ if (knownIndex >= 0) {
6107
+ const known = records[knownIndex];
6108
+ if (!controllers.has(record.id) && !TERMINAL.has(known.state)) {
6109
+ if (TERMINAL.has(record.state)) {
6110
+ records[knownIndex] = record;
6111
+ healed++;
6112
+ } else if (record.pid === void 0 || !isProcessAlive(record.pid)) {
6113
+ records[knownIndex] = {
6114
+ ...record,
6115
+ state: "failed",
6116
+ endedAt: now(),
6117
+ failure: "no live owner process — the run was interrupted before it settled (orphan)"
6118
+ };
6119
+ converged++;
6120
+ }
6121
+ }
6122
+ continue;
6123
+ }
6105
6124
  if (record.state !== "running") {
6106
6125
  records.push(record);
6107
6126
  continue;
@@ -6119,18 +6138,19 @@ function newRunRegistry(options) {
6119
6138
  failure: "no live owner process — the run was interrupted before it settled (orphan)"
6120
6139
  });
6121
6140
  }
6122
- if (converged > 0) await persist();
6141
+ if (converged > 0 || healed > 0) await persist();
6123
6142
  const notes = [
6124
6143
  parsed.note,
6125
6144
  converged > 0 ? `${converged} run(s) with no live owner were recorded as failed(orphan)` : void 0,
6126
- liveElsewhere > 0 ? `${liveElsewhere} run(s) are in flight in another process sharing this home` : void 0
6145
+ liveElsewhere > 0 ? `${liveElsewhere} run(s) are in flight in another process sharing this home` : void 0,
6146
+ healed > 0 ? `${healed} run(s) settled by their owner were re-read from the index` : void 0
6127
6147
  ].filter((note) => note !== void 0);
6128
6148
  return {
6129
6149
  ok: true,
6130
6150
  ...notes.length > 0 ? { note: notes.join("; ") } : {}
6131
6151
  };
6132
6152
  },
6133
- begin(kind) {
6153
+ async begin(kind) {
6134
6154
  const id = randomUUID();
6135
6155
  const startedAt = now();
6136
6156
  const controller = new AbortController();
@@ -6142,7 +6162,7 @@ function newRunRegistry(options) {
6142
6162
  startedAt,
6143
6163
  pid: process.pid
6144
6164
  });
6145
- persist();
6165
+ await persist();
6146
6166
  return {
6147
6167
  id,
6148
6168
  kind,
@@ -65,13 +65,23 @@ export interface RunOutcome {
65
65
  }
66
66
  /** The registry surface the commands row drives. */
67
67
  export interface RunRegistry {
68
- /** Converge the persisted index once at mount; see the module doc. */
68
+ /**
69
+ * Converge the persisted index; the commands row calls it before answering any read
70
+ * (0.19.1: it also re-reads a terminal state written by the run's OWNER — see the
71
+ * implementation note below).
72
+ */
69
73
  load(): Promise<{
70
74
  ok: boolean;
71
75
  note?: string;
72
76
  }>;
73
- /** Register a new run, arm its cancellation, and return its handle. */
74
- begin(kind: RunKind): RunHandle;
77
+ /**
78
+ * Register a new run, arm its cancellation, and return its handle.
79
+ *
80
+ * Resolves only once the row is in the shared index (0.19.1, review P2): the detached
81
+ * lifetime starts when the caller answers "started", so a plane that reads that answer
82
+ * must find the run. The cost is one local index write on the ack path (milliseconds).
83
+ */
84
+ begin(kind: RunKind): Promise<RunHandle>;
75
85
  /** Record a run's terminal state (first writer wins). */
76
86
  settle(id: string, outcome: RunOutcome): Promise<void>;
77
87
  /** The live run, when there is one (one kind today — see the implementation note). */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lmzhen/dsh-evolution-core",
3
3
  "description": "Shared stores, prompts, signals and lifecycle logic for the dsh-evolution plugin family (community build)",
4
- "version": "0.19.0",
4
+ "version": "0.19.1",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },