@aburi/diff 0.3.0 → 0.4.0

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/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { CallEdge, SerializeOptions } from "@aburi/core";
1
+ import { CallEdge, IntegrityViolation, SerializeOptions } from "@aburi/core";
2
2
  import { Component, ComponentDiff, Dependency, DependencyDiff, DependencyEndpoint, DependencyUnknown, DiffResult, IR, IRRef, MatchRationale, NotComparedFile, RelativePath, Signature, SkipReason, SliceRecord, Summary, Symbol, SymbolChange, SymbolDelta, SymbolId } from "@aburi/types";
3
3
 
4
4
  //#region src/components.d.ts
@@ -8,12 +8,18 @@ import { Component, ComponentDiff, Dependency, DependencyDiff, DependencyEndpoin
8
8
  * reaching this export directly owns the obligation, because the lookup map here is
9
9
  * last-write-wins and a repeat is lost rather than reported.
10
10
  *
11
- * Component identity is `id`; when a Component is present in both
12
- * base and head with the same id, the three delta booleans describe which axes actually
13
- * moved (roots reshuffle, public API globs, or framework hint list). `modified` deltas
14
- * are intentionally absent from this diff (diff-algorithm.md §5.2.3): fields are reported as before/after
15
- * pairs via the `changed[]` entries so consumers can render them without stringifying
16
- * arrays.
11
+ * Component identity is `id`; when a Component is present in both base and head with the same
12
+ * id, *any* field that differs makes it `changed` — the whole object is compared, not the three
13
+ * axes the delta names. Those two questions were conflated once: a rename, an added language or
14
+ * an edited description left the diff reporting `componentsChanged: 0` and an empty `changed[]`,
15
+ * so the projection layer had no before/after pair to render. The delta booleans stay exactly
16
+ * what they were — a summary of the three axes a reviewer scans for architectural movement — and
17
+ * a `changed[]` entry with all three `false` is a well-formed answer meaning "something else
18
+ * about this component moved", not a bug.
19
+ *
20
+ * `modified` deltas are intentionally absent from this diff (diff-algorithm.md §5.2.3): fields
21
+ * are reported as before/after pairs via the `changed[]` entries so consumers can render them
22
+ * without stringifying arrays.
17
23
  */
18
24
  declare function diffComponents(base: readonly Component[], head: readonly Component[]): ComponentDiff;
19
25
  /**
@@ -295,16 +301,23 @@ declare function buildDiff(input: DiffInput): DiffResult & {
295
301
  declare function writeCanonicalDiff(diff: DiffResult, options?: SerializeOptions): string;
296
302
  //#endregion
297
303
  //#region src/errors.d.ts
298
- /**
299
- * Coded error class for every @aburi/diff failure. Consumers branch on `code` without
300
- * parsing message text. Codes are stable and additions are non-breaking; renames are not.
301
- */
302
304
  type DiffErrorCode = /** `base.$schema` and `head.$schema` disagree; a diff across schema versions cannot be trusted (§9.1). */"schema-mismatch" /** `config.diff.lineFuzz` was outside the documented [0, 10] range (diff-algorithm.md §5.2.1). */ | "invalid-line-fuzz"
303
305
  /**
304
- * `baseIR` or `headIR` failed the top-level shape check that `buildDiff` enforces
305
- * before touching any Symbol. Missing / non-array `symbols`, `components`,
306
- * `dependencies`, or an absent `$schema` — anything that would otherwise crash with a
307
- * cryptic `TypeError: undefined is not iterable` deep in a matching stage.
306
+ * `baseIR` or `headIR` is not a Document of the shape `aburi.ir.v1` requires. `buildDiff`
307
+ * establishes that before touching any Symbol, by running invariant #20
308
+ * (`checkDocumentShape`): every field the schema requires, at every depth, named by the
309
+ * record it sits in and the field inside it — so a missing `stats` or `workspace`, a
310
+ * `symbols[3]` with no `fingerprint`, and a `stats.effectPropagation` with no `sccCount`
311
+ * all raise this. Anything here would otherwise crash during classification or the delta
312
+ * with a `TypeError` naming neither the record nor the field.
313
+ *
314
+ * A non-empty `$schema` is raised under this code too. That one is `buildDiff`'s own
315
+ * requirement rather than the schema's — two Documents that both say `""` agree with each
316
+ * other, so `schema-mismatch` would never fire on the pair.
317
+ *
318
+ * Not the semantic invariants: those are statements about a Document whose answer the diff
319
+ * does not depend on, and refusing an unsorted `symbols[]` would withhold a diff the
320
+ * matcher can produce.
308
321
  */
309
322
  | "ir-shape-invalid"
310
323
  /**
@@ -327,10 +340,20 @@ interface DiffErrorDetail {
327
340
  code: DiffErrorCode;
328
341
  /** Offending value (schema id, fuzz value, etc.) when applicable. */
329
342
  value?: string;
343
+ /**
344
+ * Populated only for `ir-shape-invalid`, one entry per breach of invariant #20.
345
+ *
346
+ * The message quotes the first and counts the rest, which is enough to start on and not
347
+ * enough to finish: a caller fixing a hand-assembled Document needs the others without
348
+ * running the diff again per field. `CoreErrorDetail.violations` carries the same array
349
+ * for the same reason, and the two are the same `IntegrityViolation` type.
350
+ */
351
+ violations?: readonly IntegrityViolation[];
330
352
  }
331
353
  declare class DiffError extends Error {
332
354
  readonly code: DiffErrorCode;
333
355
  readonly value: string | undefined;
356
+ readonly violations: readonly IntegrityViolation[] | undefined;
334
357
  constructor(message: string, detail: DiffErrorDetail, options?: {
335
358
  cause?: unknown;
336
359
  });
@@ -525,5 +548,4 @@ declare function classifyStatus(base: Symbol, head: Symbol): SymbolStatus;
525
548
  type DropDirection = "to-dropped" | "to-kept";
526
549
  declare function dropDirection(head: Symbol): DropDirection;
527
550
  //#endregion
528
- export { DEFAULT_LINE_FUZZ, type DeltaOptions, type DependencySideView, DiffError, type DiffErrorCode, type DiffErrorDetail, type DiffInput, type DropDirection, type GitRenameMap, MAX_LINE_FUZZ, MIN_LINE_FUZZ, type SliceInput, type SliceRecordViolation, type SliceViolationKind, type SymbolPair, type SymbolStatus, assertSliceRecordInvariant, buildDiff, classifyStatus, computeSlices, computeSymbolDelta, dependencySideView, diffComponents, diffDependencies, dropDirection, jaccard, jaccardTokens, lastSegment, matchStageDroppedWeak, matchStageGitRename, matchStageId, matchStageLogicFingerprint, matchStageNameSignature, memberSimilarity, nameSimilarity, ownersAreCompatible, signatureSimilarity, sliceAnchor, sliceRecordViolation, tokenizeName, writeCanonicalDiff };
529
- //# sourceMappingURL=index.d.mts.map
551
+ export { DEFAULT_LINE_FUZZ, type DeltaOptions, type DependencySideView, DiffError, type DiffErrorCode, type DiffErrorDetail, type DiffInput, type DropDirection, type GitRenameMap, MAX_LINE_FUZZ, MIN_LINE_FUZZ, type SliceInput, type SliceRecordViolation, type SliceViolationKind, type SymbolPair, type SymbolStatus, assertSliceRecordInvariant, buildDiff, classifyStatus, computeSlices, computeSymbolDelta, dependencySideView, diffComponents, diffDependencies, dropDirection, jaccard, jaccardTokens, lastSegment, matchStageDroppedWeak, matchStageGitRename, matchStageId, matchStageLogicFingerprint, matchStageNameSignature, memberSimilarity, nameSimilarity, ownersAreCompatible, signatureSimilarity, sliceAnchor, sliceRecordViolation, tokenizeName, writeCanonicalDiff };