pm-csv 2026.10.5 → 2026.10.14
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/CHANGELOG.md +10 -0
- package/README.md +35 -16
- package/dist/atomic-update.d.ts +42 -0
- package/dist/atomic-update.d.ts.map +1 -0
- package/dist/atomic-update.js +182 -0
- package/dist/atomic-update.js.map +1 -0
- package/dist/index.d.ts +7 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +83 -42
- package/dist/index.js.map +1 -1
- package/docs/atomic-compensation.md +76 -0
- package/manifest.json +1 -1
- package/package.json +12 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2026.10.12 - 2026-10-12
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Capture prior field values in the transaction record so a failed update can be truly compensated ([pm-csv-71zg](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/features/pm-csv-71zg.toon))
|
|
8
|
+
|
|
9
|
+
### Other
|
|
10
|
+
|
|
11
|
+
- Certify self-syncing toolchain upgrades and validated CSV closure ([pm-csv-hzn7](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/chores/pm-csv-hzn7.toon))
|
|
12
|
+
|
|
3
13
|
## 2026.10.5 - 2026-10-05
|
|
4
14
|
|
|
5
15
|
### Other
|
package/README.md
CHANGED
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
CSV importer and exporter for [pm-cli](https://github.com/unbraind/pm-cli).
|
|
4
4
|
|
|
5
|
-
Import pm items from a CSV file, export them back out, or wire up a programmatic `csv-import` importer
|
|
5
|
+
Import pm items from a CSV file, export them back out, or wire up a programmatic `csv-import` importer.
|
|
6
6
|
|
|
7
|
-
The extension requires pm CLI
|
|
8
|
-
|
|
7
|
+
The extension requires the pm CLI compatibility floor declared in
|
|
8
|
+
`package.json` and `manifest.json`. Development and release gates use the exact
|
|
9
|
+
pm CLI/SDK, pm-ops and pm-changelog versions in `package.json`, verified against
|
|
10
|
+
`package-lock.json` and installed package metadata so host behavior stays reproducible.
|
|
9
11
|
|
|
10
12
|
---
|
|
11
13
|
|
|
@@ -63,7 +65,7 @@ pm csv import tasks.csv --atomic # writer-locked, crash-recoverable import
|
|
|
63
65
|
| `--priority <n>` | integer | — | Import **only** rows whose integer priority equals this value |
|
|
64
66
|
| `--strict` | boolean | false | Abort before writing if validation finds missing titles, unknown statuses, invalid/out-of-range priorities, or duplicate mapped columns |
|
|
65
67
|
| `--dry-run` | boolean | false | Preview what would be imported without writing any data |
|
|
66
|
-
| `--atomic` | boolean | false | Use one writer-locked, crash-recoverable transaction. On failure, attempt best-effort create compensation; pre-existing
|
|
68
|
+
| `--atomic` | boolean | false | Use one writer-locked, crash-recoverable transaction. On failure, attempt best-effort create compensation; pre-existing updates restore captured prior values unless a conflict prevents safe compensation. Inspect and reconcile any marked orphan before retrying. Incompatible with `--stream` |
|
|
67
69
|
|
|
68
70
|
#### Strict import gate
|
|
69
71
|
|
|
@@ -88,8 +90,20 @@ workspace writer lock and recorded in a crash-recoverable journal.
|
|
|
88
90
|
reason `atomic csv import rolled back`, rolls back the transaction journal,
|
|
89
91
|
and exits non-zero with a reconciliation warning. A failed close deliberately
|
|
90
92
|
retains both transaction markers so an operator can inspect and reconcile the
|
|
91
|
-
open orphan by transaction id before retrying.
|
|
92
|
-
|
|
93
|
+
open orphan by transaction id before retrying. Before each update, a version 2
|
|
94
|
+
compensation record stores the complete prior item document and verified
|
|
95
|
+
history boundary. On failure, an append-only restore recovers prior values,
|
|
96
|
+
including absent versus empty metadata, tags, dependencies, body, and lifecycle
|
|
97
|
+
side effects. A second guarded phase preserves stored empty fields that the
|
|
98
|
+
SDK canonicalizes away; its completion receipt makes that phase resumable.
|
|
99
|
+
Only `updated_at` advances to record the compensation. See
|
|
100
|
+
[the compensation design and validation](docs/atomic-compensation.md).
|
|
101
|
+
- **Concurrent writer safety:** compensation checks the history boundary and
|
|
102
|
+
current state while holding the SDK item lock. Any intervening mutation
|
|
103
|
+
outside this batch refuses restoration, including edits to unrelated fields.
|
|
104
|
+
The journal remains compensating with its prior values intact; inspect and
|
|
105
|
+
reconcile the conflict before retrying. The workspace transaction lock
|
|
106
|
+
serializes atomic imports; ordinary item writers use their item locks.
|
|
93
107
|
- **Crash-recoverable / resumable:** the transaction id is stable and derivable
|
|
94
108
|
from the resolved file path and parsed content fingerprint, so re-running the
|
|
95
109
|
same unchanged `--atomic` import resumes from the durable journal while edited
|
|
@@ -97,8 +111,10 @@ workspace writer lock and recorded in a crash-recoverable journal.
|
|
|
97
111
|
Resume/compensation matching is **per-row-precise**: every item this
|
|
98
112
|
transaction writes is stamped with a per-row ownership marker
|
|
99
113
|
`csv-txrow:<transactionId>#<rowIndex>` (plus a batch-level
|
|
100
|
-
`csv-tx:<transactionId>` marker for scanning)
|
|
101
|
-
|
|
114
|
+
`csv-tx:<transactionId>` marker for scanning). Creates resume from these
|
|
115
|
+
markers; updates also inspect immutable history. Versioned journal step ids
|
|
116
|
+
preserve the original operation and update target even if another writer
|
|
117
|
+
removes the CSV tags. This means a
|
|
102
118
|
CSV with **duplicate titles or duplicate keys** is handled correctly — a row
|
|
103
119
|
is only skipped when its exact rowIndex was already applied, never because a
|
|
104
120
|
same-titled/same-keyed sibling happens to match.
|
|
@@ -114,13 +130,16 @@ workspace writer lock and recorded in a crash-recoverable journal.
|
|
|
114
130
|
- **Incompatible with `--stream`:** an unbounded stream cannot be committed as
|
|
115
131
|
one bounded transaction, so `--atomic --stream` fails fast with a usage
|
|
116
132
|
error.
|
|
117
|
-
- **
|
|
133
|
+
- **Create compensation uses `close`, not `delete`**, to avoid the known history-
|
|
118
134
|
resurrection issue, so compensated items remain in the tracker as closed
|
|
119
|
-
items rather than being erased.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
135
|
+
items rather than being erased. Update compensation restores the pre-update
|
|
136
|
+
document through the SDK mutation primitive, retaining immutable history.
|
|
137
|
+
Versioned step ids refuse legacy in-flight journals before mutation instead
|
|
138
|
+
of guessing missing prior values. Replaying a restore after a crash is a
|
|
139
|
+
no-op, and reverse-order compensation supports multiple rows for one item.
|
|
140
|
+
A terminal row interrupted between update and close is compensated on restart
|
|
141
|
+
before a fresh attempt; it is never treated as a completed row.
|
|
142
|
+
A failed compensation reports remaining work for operator reconciliation.
|
|
124
143
|
|
|
125
144
|
```bash
|
|
126
145
|
pm csv import tasks.csv --atomic # resumes an unchanged interrupted import
|
|
@@ -375,7 +394,7 @@ npm install
|
|
|
375
394
|
npm run build # runs tsc → dist/
|
|
376
395
|
```
|
|
377
396
|
|
|
378
|
-
TypeScript
|
|
397
|
+
TypeScript version pinned in `package.json`, ES2022 target, NodeNext module resolution, strict mode. The runtime dependency is `@toon-format/toon`.
|
|
379
398
|
|
|
380
399
|
---
|
|
381
400
|
|
|
@@ -404,7 +423,7 @@ This package is release-ready for GitHub, npm, and Bun-compatible installs. CI r
|
|
|
404
423
|
This repo tracks its project management in `.agents/pm/` and ships a committed `.gitattributes`
|
|
405
424
|
that maps those tracker artifacts to pm-cli's field-aware Git merge drivers, so concurrent-branch
|
|
406
425
|
tracker edits merge cleanly instead of hard-conflicting. The driver **definitions** live in
|
|
407
|
-
per-clone Git config; `npm install` / `npm ci` wires them automatically via the `prepare` script, `scripts/prepare-merge-driver.ts`:
|
|
426
|
+
per-clone Git config; `npm install` / `npm ci` wires them automatically via the `prepare` script, `scripts/prepare-merge-driver.ts`: a launcher delegating to the installed pm-ops public installer entry. Tests verify the installer behavior rather than comparing version-specific template bytes. It runs pm-ops's installer, which calls `pm merge install` when the `pm` CLI is on `PATH` and skips with a notice when it is not. A production install of a clone (`npm ci --omit=dev`) has no `pm-ops`, so the launcher skips with one notice, while a stale or broken `pm-ops` fails the install. Registry installs of this package never run `prepare`. Being Node-based, it behaves identically on POSIX shells and Windows `cmd.exe`. To (re)run manually: `npm run merge:install`.
|
|
408
427
|
|
|
409
428
|
After merging a branch that touched `.agents/pm/`, reconcile any residual history-hash drift with
|
|
410
429
|
**`pm merge reconcile`** (pm-cli ≥ 2026.7.22): preview with `pm merge reconcile --dry-run`, apply with
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { ItemDocument, WorkspaceTransactionStepInspection, WorkspaceTransactionJsonValue } from "@unbrained/pm-cli/sdk";
|
|
2
|
+
/** Version of CSV prior-document compensation; also bound into every step id. */
|
|
3
|
+
export declare const UPDATE_COMPENSATION_VERSION = 2;
|
|
4
|
+
/** Read authoritative item state, including absent fields and every collection. */
|
|
5
|
+
export declare function readUpdateSnapshot(pmRoot: string, id: string): Promise<{
|
|
6
|
+
raw: string;
|
|
7
|
+
document: ItemDocument;
|
|
8
|
+
located: import("@unbrained/pm-cli/sdk").LocatedItem;
|
|
9
|
+
}>;
|
|
10
|
+
/** Read canonical field values without discarding the stored snapshot API. */
|
|
11
|
+
export declare function readUpdateDocument(pmRoot: string, id: string): Promise<ItemDocument>;
|
|
12
|
+
/**
|
|
13
|
+
* Inspect update ownership in immutable history as well as legacy row tags.
|
|
14
|
+
* A terminal row interrupted between update and close refuses forward replay;
|
|
15
|
+
* the coordinator then compensates using the already saved original values.
|
|
16
|
+
* Completed restores stay pending even when an older scan still saw tags.
|
|
17
|
+
*/
|
|
18
|
+
export declare function inspectUpdate(pmRoot: string, id: string, marker: string, terminal: boolean): Promise<WorkspaceTransactionStepInspection>;
|
|
19
|
+
/**
|
|
20
|
+
* Capture the entire prior document and its verified history boundary under the
|
|
21
|
+
* item lock. The coordinator persists this versioned data before apply starts.
|
|
22
|
+
* A full document includes lifecycle side effects and dependency collections,
|
|
23
|
+
* and JSON preserves absent properties separately from empty strings/lists.
|
|
24
|
+
*/
|
|
25
|
+
export declare function captureUpdateCompensation(pmRoot: string, id: string, marker: string, author: string): Promise<WorkspaceTransactionJsonValue>;
|
|
26
|
+
/** Durable compensation boundaries available to diagnostics and crash tests. */
|
|
27
|
+
export type CompensationPhase = "canonical_restored" | "representation_written" | "compensation_recorded";
|
|
28
|
+
/**
|
|
29
|
+
* Restore the captured document through an append-only SDK mutation. History
|
|
30
|
+
* verification and writer detection occur INSIDE the item lock, so another
|
|
31
|
+
* agent cannot write between the guard and restoration. Refuse any intervening
|
|
32
|
+
* history outside this batch, including edits to unrelated fields. A durable
|
|
33
|
+
* compensation message makes a crash after restoration safe to replay.
|
|
34
|
+
*/
|
|
35
|
+
export declare function compensateUpdate(pmRoot: string, id: string, marker: string, author: string, data: WorkspaceTransactionJsonValue | undefined, onPhase?: (phase: CompensationPhase) => void | Promise<void>): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Re-encode original physical fields without canonicalizing empty values. Only
|
|
38
|
+
* the audited mutation timestamp changes. JSON Markdown inputs migrate to the
|
|
39
|
+
* SDK's normal TOON output, preserving metadata values and body content.
|
|
40
|
+
*/
|
|
41
|
+
export declare function priorRepresentation(raw: string, format: "toon" | "json_markdown", updatedAt: string): string;
|
|
42
|
+
//# sourceMappingURL=atomic-update.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atomic-update.d.ts","sourceRoot":"","sources":["../atomic-update.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,kCAAkC,EAAE,6BAA6B,EAAE,MAAM,uBAAuB,CAAC;AAI7H,iFAAiF;AACjF,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAE7C,mFAAmF;AACnF,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;;;;GAMlE;AAED,8EAA8E;AAC9E,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAE1F;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAC5D,OAAO,CAAC,kCAAkC,CAAC,CAY7C;AAOD;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GACzD,OAAO,CAAC,6BAA6B,CAAC,CAgBxC;AAED,gFAAgF;AAChF,MAAM,MAAM,iBAAiB,GAAG,oBAAoB,GAAG,wBAAwB,GAAG,uBAAuB,CAAC;AAiB1G;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAC1D,IAAI,EAAE,6BAA6B,GAAG,SAAS,EAC/C,OAAO,GAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAY,GACrE,OAAO,CAAC,IAAI,CAAC,CAmEf;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,eAAe,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAW5G"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { acquireLock, appendHistoryEntry, createHistoryEntry, getHistoryPath, nowIso, parseItemDocument, splitFrontMatter, writeFileAtomic, locateItem, mutateItem, readHistoryEntries, readLocatedItem, readSettings, resolveItemTypeRegistry, verifyHistoryEntries, } from "@unbrained/pm-cli/sdk";
|
|
2
|
+
import { decode, encode } from "@toon-format/toon";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
/** Version of CSV prior-document compensation; also bound into every step id. */
|
|
5
|
+
export const UPDATE_COMPENSATION_VERSION = 2;
|
|
6
|
+
/** Read authoritative item state, including absent fields and every collection. */
|
|
7
|
+
export async function readUpdateSnapshot(pmRoot, id) {
|
|
8
|
+
const settings = await readSettings(pmRoot);
|
|
9
|
+
const registry = resolveItemTypeRegistry(settings);
|
|
10
|
+
const located = await locateItem(pmRoot, id, settings.id_prefix, settings.item_format, registry.type_to_folder);
|
|
11
|
+
if (!located)
|
|
12
|
+
throw new Error(`Atomic update item ${id} is missing; reconcile before retrying.`);
|
|
13
|
+
return { ...(await readLocatedItem(located, { schema: settings.schema })), located };
|
|
14
|
+
}
|
|
15
|
+
/** Read canonical field values without discarding the stored snapshot API. */
|
|
16
|
+
export async function readUpdateDocument(pmRoot, id) {
|
|
17
|
+
return (await readUpdateSnapshot(pmRoot, id)).document;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Inspect update ownership in immutable history as well as legacy row tags.
|
|
21
|
+
* A terminal row interrupted between update and close refuses forward replay;
|
|
22
|
+
* the coordinator then compensates using the already saved original values.
|
|
23
|
+
* Completed restores stay pending even when an older scan still saw tags.
|
|
24
|
+
*/
|
|
25
|
+
export async function inspectUpdate(pmRoot, id, marker, terminal) {
|
|
26
|
+
const document = await readUpdateDocument(pmRoot, id);
|
|
27
|
+
const history = await readHistoryEntries(getHistoryPath(pmRoot, id), id);
|
|
28
|
+
const lastOwn = [...history].reverse().find(entry => entry.message === `${marker}:apply`
|
|
29
|
+
|| entry.message === `${marker}:close` || entry.message === `${marker}:restore` || entry.message === `${marker}:compensate`);
|
|
30
|
+
if (lastOwn?.message === `${marker}:compensate`)
|
|
31
|
+
return { state: "pending" };
|
|
32
|
+
const applied = Boolean(lastOwn) || Boolean(document.metadata.tags?.includes(marker));
|
|
33
|
+
if (applied && terminal && lastOwn?.message === `${marker}:apply`
|
|
34
|
+
&& document.metadata.status !== "closed" && document.metadata.status !== "canceled") {
|
|
35
|
+
throw new Error(`Atomic update item ${id} has an incomplete terminal transition; compensation required.`);
|
|
36
|
+
}
|
|
37
|
+
return applied ? { state: "applied", result: id } : { state: "pending" };
|
|
38
|
+
}
|
|
39
|
+
/** Hash journal-safe data for immutable history-boundary comparison. */
|
|
40
|
+
function journalHash(value) {
|
|
41
|
+
return createHash("sha256").update(JSON.stringify(value)).digest("hex");
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Capture the entire prior document and its verified history boundary under the
|
|
45
|
+
* item lock. The coordinator persists this versioned data before apply starts.
|
|
46
|
+
* A full document includes lifecycle side effects and dependency collections,
|
|
47
|
+
* and JSON preserves absent properties separately from empty strings/lists.
|
|
48
|
+
*/
|
|
49
|
+
export async function captureUpdateCompensation(pmRoot, id, marker, author) {
|
|
50
|
+
const settings = await readSettings(pmRoot);
|
|
51
|
+
const release = await acquireLock(pmRoot, id, settings.locks.ttl_seconds, author, false, false, settings.locks.wait_ms);
|
|
52
|
+
try {
|
|
53
|
+
const { document, raw, located } = await readUpdateSnapshot(pmRoot, id);
|
|
54
|
+
const history = await readHistoryEntries(getHistoryPath(pmRoot, id), id);
|
|
55
|
+
if (!verifyHistoryEntries(history, document).ok) {
|
|
56
|
+
throw new Error(`Atomic update item ${id} has unverified history; reconcile before retrying.`);
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
version: UPDATE_COMPENSATION_VERSION, id, marker,
|
|
60
|
+
prior: JSON.stringify(document), raw, format: located.item_format, historyLength: history.length, historyHash: journalHash(history),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
await release();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Parse a journalled prior document read back from disk. Anything other than
|
|
69
|
+
* an object with an object `metadata` field (invalid JSON, null, arrays,
|
|
70
|
+
* scalars) is refused with the same reconcile message as other journal damage.
|
|
71
|
+
*/
|
|
72
|
+
function parsePriorDocument(raw, id) {
|
|
73
|
+
let parsed;
|
|
74
|
+
try {
|
|
75
|
+
parsed = JSON.parse(raw);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
parsed = undefined;
|
|
79
|
+
}
|
|
80
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed) || !("metadata" in parsed)
|
|
81
|
+
|| parsed.metadata === null || typeof parsed.metadata !== "object" || Array.isArray(parsed.metadata)) {
|
|
82
|
+
throw new Error(`Atomic update item ${id} has missing or incompatible prior values; reconcile before retrying.`);
|
|
83
|
+
}
|
|
84
|
+
return parsed;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Restore the captured document through an append-only SDK mutation. History
|
|
88
|
+
* verification and writer detection occur INSIDE the item lock, so another
|
|
89
|
+
* agent cannot write between the guard and restoration. Refuse any intervening
|
|
90
|
+
* history outside this batch, including edits to unrelated fields. A durable
|
|
91
|
+
* compensation message makes a crash after restoration safe to replay.
|
|
92
|
+
*/
|
|
93
|
+
export async function compensateUpdate(pmRoot, id, marker, author, data, onPhase = () => { }) {
|
|
94
|
+
if (!data || typeof data !== "object" || Array.isArray(data)
|
|
95
|
+
|| data.version !== UPDATE_COMPENSATION_VERSION || data.id !== id || data.marker !== marker
|
|
96
|
+
|| typeof data.raw !== "string" || !["toon", "json_markdown"].includes(String(data.format))
|
|
97
|
+
|| typeof data.prior !== "string" || typeof data.historyLength !== "number" || typeof data.historyHash !== "string") {
|
|
98
|
+
throw new Error(`Atomic update item ${id} has missing or incompatible prior values; reconcile before retrying.`);
|
|
99
|
+
}
|
|
100
|
+
const prior = parsePriorDocument(data.prior, id);
|
|
101
|
+
const historyLength = data.historyLength;
|
|
102
|
+
const historyHash = data.historyHash;
|
|
103
|
+
const batchPrefix = `${marker.slice(0, marker.lastIndexOf("#"))}#`;
|
|
104
|
+
const compensationMessage = `${marker}:compensate`;
|
|
105
|
+
const restoreMessage = `${marker}:restore`;
|
|
106
|
+
let completed = false;
|
|
107
|
+
const settings = await readSettings(pmRoot);
|
|
108
|
+
await mutateItem({
|
|
109
|
+
pmRoot, settings, id, op: "restore", author, message: restoreMessage,
|
|
110
|
+
skipNoop: true,
|
|
111
|
+
async mutate(document) {
|
|
112
|
+
const history = await readHistoryEntries(getHistoryPath(pmRoot, id), id);
|
|
113
|
+
if (!verifyHistoryEntries(history, document).ok
|
|
114
|
+
|| journalHash(history.slice(0, historyLength)) !== historyHash
|
|
115
|
+
|| !verifyHistoryEntries(history.slice(0, historyLength), prior).ok) {
|
|
116
|
+
throw new Error(`Atomic update item ${id} has changed history or state; refusing compensation.`);
|
|
117
|
+
}
|
|
118
|
+
const subsequent = history.slice(historyLength);
|
|
119
|
+
if (subsequent.some(entry => entry.message === compensationMessage)) {
|
|
120
|
+
completed = true;
|
|
121
|
+
return { changedFields: [] };
|
|
122
|
+
}
|
|
123
|
+
// Reverse-order restores of later rows in this same batch are safe. Any
|
|
124
|
+
// other author's mutation remains a conflict, even if its value is equal.
|
|
125
|
+
if (subsequent.some(entry => !entry.message?.startsWith(batchPrefix)
|
|
126
|
+
|| !/^\d+:(apply|close|restore|compensate)$/.test(entry.message.slice(batchPrefix.length)))) {
|
|
127
|
+
throw new Error(`Atomic update item ${id} has a concurrent writer; refusing compensation.`);
|
|
128
|
+
}
|
|
129
|
+
if (subsequent.some(entry => entry.message === restoreMessage))
|
|
130
|
+
return { changedFields: [] };
|
|
131
|
+
const changedFields = [...new Set([...Object.keys(document.metadata), ...Object.keys(prior.metadata), "body"])];
|
|
132
|
+
document.metadata = structuredClone(prior.metadata);
|
|
133
|
+
document.body = prior.body;
|
|
134
|
+
return { changedFields };
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
if (completed)
|
|
138
|
+
return;
|
|
139
|
+
await onPhase("canonical_restored");
|
|
140
|
+
// The SDK canonicalizes empty metadata to absent values. Preserve the raw
|
|
141
|
+
// prior representation in a second, guarded, resumable phase. It has exactly
|
|
142
|
+
// the same canonical hash as the SDK restore, so the derived index is valid.
|
|
143
|
+
const release = await acquireLock(pmRoot, id, settings.locks.ttl_seconds, author, false, false, settings.locks.wait_ms);
|
|
144
|
+
try {
|
|
145
|
+
const current = await readUpdateSnapshot(pmRoot, id);
|
|
146
|
+
const history = await readHistoryEntries(getHistoryPath(pmRoot, id), id);
|
|
147
|
+
const contents = priorRepresentation(data.raw, data.format, current.document.metadata.updated_at);
|
|
148
|
+
const represented = parseItemDocument(contents, { format: "toon", schema: settings.schema });
|
|
149
|
+
if (history.at(-1)?.message !== restoreMessage || !verifyHistoryEntries(history, current.document).ok
|
|
150
|
+
|| !verifyHistoryEntries(history, represented).ok) {
|
|
151
|
+
throw new Error(`Atomic update item ${id} changed during representation restoration; refusing compensation.`);
|
|
152
|
+
}
|
|
153
|
+
await writeFileAtomic(current.located.itemPath, contents);
|
|
154
|
+
await onPhase("representation_written");
|
|
155
|
+
await appendHistoryEntry(getHistoryPath(pmRoot, id), createHistoryEntry({
|
|
156
|
+
nowIso: nowIso(), author, op: "restore", before: current.document, after: represented, message: compensationMessage,
|
|
157
|
+
}));
|
|
158
|
+
await onPhase("compensation_recorded");
|
|
159
|
+
}
|
|
160
|
+
finally {
|
|
161
|
+
await release();
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Re-encode original physical fields without canonicalizing empty values. Only
|
|
166
|
+
* the audited mutation timestamp changes. JSON Markdown inputs migrate to the
|
|
167
|
+
* SDK's normal TOON output, preserving metadata values and body content.
|
|
168
|
+
*/
|
|
169
|
+
export function priorRepresentation(raw, format, updatedAt) {
|
|
170
|
+
let record;
|
|
171
|
+
if (format === "toon") {
|
|
172
|
+
record = decode(raw);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
const { frontMatter, body } = splitFrontMatter(raw);
|
|
176
|
+
record = { ...JSON.parse(frontMatter), body };
|
|
177
|
+
}
|
|
178
|
+
const metadata = Object.hasOwn(record, "front_matter") ? record.front_matter : record;
|
|
179
|
+
metadata.updated_at = updatedAt;
|
|
180
|
+
return `${encode(record)}\n`;
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=atomic-update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atomic-update.js","sourceRoot":"","sources":["../atomic-update.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,kBAAkB,EAC7K,eAAe,EAAE,YAAY,EAAE,uBAAuB,EAAE,oBAAoB,GAC7E,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,iFAAiF;AACjF,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC;AAE7C,mFAAmF;AACnF,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAc,EAAE,EAAU;IACjE,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,EAAE,EAAE,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;IAChH,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,EAAE,yCAAyC,CAAC,CAAC;IACjG,OAAO,EAAE,GAAG,CAAC,MAAM,eAAe,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;AACvF,CAAC;AAED,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAc,EAAE,EAAU;IACjE,OAAO,CAAC,MAAM,kBAAkB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;AACzD,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAc,EAAE,EAAU,EAAE,MAAc,EAAE,QAAiB;IAE7D,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,cAAc,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IACzE,MAAM,OAAO,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,KAAK,GAAG,MAAM,QAAQ;WACnF,KAAK,CAAC,OAAO,KAAK,GAAG,MAAM,QAAQ,IAAI,KAAK,CAAC,OAAO,KAAK,GAAG,MAAM,UAAU,IAAI,KAAK,CAAC,OAAO,KAAK,GAAG,MAAM,aAAa,CAAC,CAAC;IAC/H,IAAI,OAAO,EAAE,OAAO,KAAK,GAAG,MAAM,aAAa;QAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IAC7E,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IACtF,IAAI,OAAO,IAAI,QAAQ,IAAI,OAAO,EAAE,OAAO,KAAK,GAAG,MAAM,QAAQ;WAC1D,QAAQ,CAAC,QAAQ,CAAC,MAAM,KAAK,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QACxF,MAAM,IAAI,KAAK,CAAC,sBAAsB,EAAE,gEAAgE,CAAC,CAAC;IAC5G,CAAC;IACD,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AAC3E,CAAC;AAED,wEAAwE;AACxE,SAAS,WAAW,CAAC,KAAc;IACjC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC1E,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,MAAc,EAAE,EAAU,EAAE,MAAc,EAAE,MAAc;IAE1D,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACxH,IAAI,CAAC;QACH,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,MAAM,kBAAkB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACxE,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,cAAc,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACzE,IAAI,CAAC,oBAAoB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC;YAChD,MAAM,IAAI,KAAK,CAAC,sBAAsB,EAAE,qDAAqD,CAAC,CAAC;QACjG,CAAC;QACD,OAAO;YACL,OAAO,EAAE,2BAA2B,EAAE,EAAE,EAAE,MAAM;YAChD,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,WAAW,EAAE,aAAa,EAAE,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC;SACpI,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,EAAE,CAAC;IAClB,CAAC;AACH,CAAC;AAKD;;;;GAIG;AACH,SAAS,kBAAkB,CAAC,GAAW,EAAE,EAAU;IACjD,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,MAAM,GAAG,SAAS,CAAC;IAAC,CAAC;IAC/D,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,IAAI,MAAM,CAAC;WAC9F,MAAM,CAAC,QAAQ,KAAK,IAAI,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzG,MAAM,IAAI,KAAK,CAAC,sBAAsB,EAAE,uEAAuE,CAAC,CAAC;IACnH,CAAC;IACD,OAAO,MAAsB,CAAC;AAChC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAc,EAAE,EAAU,EAAE,MAAc,EAAE,MAAc,EAC1D,IAA+C,EAC/C,OAAO,GAAuD,GAAG,EAAE,GAAE,CAAC;IAEtE,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;WACrD,IAAI,CAAC,OAAO,KAAK,2BAA2B,IAAI,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM;WACxF,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;WACxF,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,aAAa,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;QACxH,MAAM,IAAI,KAAK,CAAC,sBAAsB,EAAE,uEAAuE,CAAC,CAAC;IACnH,CAAC;IACD,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACjD,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;IACzC,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;IACrC,MAAM,WAAW,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC;IACnE,MAAM,mBAAmB,GAAG,GAAG,MAAM,aAAa,CAAC;IACnD,MAAM,cAAc,GAAG,GAAG,MAAM,UAAU,CAAC;IAC3C,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,UAAU,CAAC;QACf,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc;QACpE,QAAQ,EAAE,IAAI;QACd,KAAK,CAAC,MAAM,CAAC,QAAQ;YACnB,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,cAAc,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YACzE,IAAI,CAAC,oBAAoB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,EAAE;mBACxC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,KAAK,WAAW;mBAC5D,CAAC,oBAAoB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;gBACxE,MAAM,IAAI,KAAK,CAAC,sBAAsB,EAAE,uDAAuD,CAAC,CAAC;YACnG,CAAC;YACD,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YAChD,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,KAAK,mBAAmB,CAAC,EAAE,CAAC;gBACpE,SAAS,GAAG,IAAI,CAAC;gBACjB,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC;YAC/B,CAAC;YACD,wEAAwE;YACxE,0EAA0E;YAC1E,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,UAAU,CAAC,WAAW,CAAC;mBAC7D,CAAC,wCAAwC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChG,MAAM,IAAI,KAAK,CAAC,sBAAsB,EAAE,kDAAkD,CAAC,CAAC;YAC9F,CAAC;YACD,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,KAAK,cAAc,CAAC;gBAAE,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC;YAC7F,MAAM,aAAa,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;YAChH,QAAQ,CAAC,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YACpD,QAAQ,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;YAC3B,OAAO,EAAE,aAAa,EAAE,CAAC;QAC3B,CAAC;KACF,CAAC,CAAC;IACH,IAAI,SAAS;QAAE,OAAO;IACtB,MAAM,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACpC,0EAA0E;IAC1E,6EAA6E;IAC7E,6EAA6E;IAC7E,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACxH,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACrD,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,cAAc,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACzE,MAAM,QAAQ,GAAG,mBAAmB,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAkC,EAAE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC9H,MAAM,WAAW,GAAG,iBAAiB,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7F,IAAI,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,KAAK,cAAc,IAAI,CAAC,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE;eAC9F,CAAC,oBAAoB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,EAAE,CAAC;YACtD,MAAM,IAAI,KAAK,CAAC,sBAAsB,EAAE,oEAAoE,CAAC,CAAC;QAChH,CAAC;QACD,MAAM,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC1D,MAAM,OAAO,CAAC,wBAAwB,CAAC,CAAC;QACxC,MAAM,kBAAkB,CAAC,cAAc,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,kBAAkB,CAAC;YACtE,MAAM,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,mBAAmB;SACpH,CAAC,CAAC,CAAC;QACJ,MAAM,OAAO,CAAC,uBAAuB,CAAC,CAAC;IACzC,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,EAAE,CAAC;IAClB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAW,EAAE,MAAgC,EAAE,SAAiB;IAClG,IAAI,MAA+B,CAAC;IACpC,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,MAAM,GAAG,MAAM,CAAC,GAAG,CAA4B,CAAC;IAClD,CAAC;SAAM,CAAC;QACN,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;QACpD,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAA4B,EAAE,IAAI,EAAE,CAAC;IAC3E,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,YAAuC,CAAC,CAAC,CAAC,MAAM,CAAC;IACjH,QAAQ,CAAC,UAAU,GAAG,SAAS,CAAC;IAChC,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;AAC/B,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -286,8 +286,9 @@ interface CsvImportOptions {
|
|
|
286
286
|
/**
|
|
287
287
|
* Import under one workspace writer-locked, crash-recoverable transaction
|
|
288
288
|
* (pm-cli >= 2026.7.19 `commitWorkspaceTransaction`). On failure the
|
|
289
|
-
* coordinator attempts reverse-order
|
|
290
|
-
*
|
|
289
|
+
* coordinator attempts reverse-order compensation: creates are closed on a
|
|
290
|
+
* best-effort basis and updates restore their captured prior state unless
|
|
291
|
+
* another writer intervened. An interrupted
|
|
291
292
|
* run resumes from the durable journal, while a failed compensation remains
|
|
292
293
|
* transaction-marked so an operator can inspect and reconcile it before a
|
|
293
294
|
* retry. Incompatible with `--stream` (an unbounded stream cannot be one
|
|
@@ -406,13 +407,15 @@ export declare function atomicTransactionId(filePath: string, opts?: {
|
|
|
406
407
|
* `inspect()` uses to detect rows already applied by a prior (interrupted) run:
|
|
407
408
|
* - byRowIndex: rowIndex -> item id
|
|
408
409
|
*
|
|
409
|
-
*
|
|
410
|
+
* For creates, the per-row marker is the source of truth for resume: it makes
|
|
410
411
|
* matching per-row-precise, so a CSV with duplicate titles or duplicate keys
|
|
411
412
|
* can never trick inspect() into skipping the wrong row. The batch-level
|
|
412
413
|
* `csv-tx:<transactionId>` marker is also stamped (handy for scanning) but is
|
|
413
414
|
* NOT used for matching. Only items carrying a per-row marker for THIS
|
|
414
415
|
* transaction are included, so pre-existing items this transaction never
|
|
415
|
-
* touched are never mistaken for already-applied steps.
|
|
416
|
+
* touched are never mistaken for already-applied steps. Updates additionally
|
|
417
|
+
* inspect immutable history and bind their targets through journal step ids,
|
|
418
|
+
* so removing mutable tags cannot retarget an interrupted update.
|
|
416
419
|
*
|
|
417
420
|
* Presence of the row marker — NOT item status — is the applied signal. A row
|
|
418
421
|
* whose CSV `status` is `closed`/`canceled` is legitimately imported as a
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAmB,MAAM,iCAAiC,CAAC;AAGrF,OAAO,EAAa,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
|