@shapeshift-labs/frontier-lang-compiler 0.2.99 → 0.2.100

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 (27) hide show
  1. package/dist/declarations/semantic-edit-bundle.d.ts +13 -1
  2. package/dist/declarations/semantic-edit-script.d.ts +34 -37
  3. package/dist/declarations/semantic-lineage.d.ts +63 -34
  4. package/dist/declarations/semantic-patch-bundle.d.ts +13 -0
  5. package/dist/internal/index-impl/declarationRecord.js +2 -2
  6. package/dist/internal/index-impl/inferSemanticLineageEvents.js +8 -0
  7. package/dist/internal/index-impl/projectSemanticEditScriptToSource.js +56 -64
  8. package/dist/internal/index-impl/replaySemanticEditProjection.js +54 -22
  9. package/dist/internal/index-impl/semanticEditBundleAdmission.js +95 -12
  10. package/dist/internal/index-impl/semanticEditBundleIndex.js +16 -10
  11. package/dist/internal/index-impl/semanticEditSourceRanges.js +204 -0
  12. package/dist/internal/index-impl/semanticHistoryLineageResolution.js +35 -1
  13. package/dist/internal/index-impl/semanticIndexFromNativeDeclarations.js +2 -2
  14. package/dist/internal/index-impl/semanticLineageInferenceMatching.js +150 -13
  15. package/dist/internal/index-impl/semanticLineageResolutionRecords.js +28 -1
  16. package/dist/internal/index-impl/semanticPatchBundleAdmission.js +122 -20
  17. package/dist/internal/index-impl/semanticPatchBundleLineageLinks.js +199 -0
  18. package/dist/internal/index-impl/semanticPatchBundleOverlaps.js +6 -2
  19. package/dist/internal/index-impl/semanticPatchBundleRecords.js +28 -104
  20. package/dist/internal/index-impl/semanticPatchBundleSourceRecords.js +127 -0
  21. package/dist/internal/index-impl/sourceTextForSpan.js +4 -9
  22. package/dist/lightweight-dependency-relations.js +113 -7
  23. package/dist/native-import-utils.js +15 -1
  24. package/dist/native-region-scanner-js-helpers.js +61 -17
  25. package/dist/native-region-scanner-js.js +12 -4
  26. package/dist/semantic-import-regions.js +3 -3
  27. package/package.json +1 -1
@@ -0,0 +1,199 @@
1
+ import { uniqueStrings } from '../../native-import-utils.js';
2
+
3
+ export function lineageLinkInputs(source, options, changedRegions, targetPortability) {
4
+ return [
5
+ ...array(options.lineageResolutionLinks ?? options.semanticLineageResolutionLinks),
6
+ ...array(options.lineageResolutions ?? options.semanticLineageResolutions),
7
+ ...array(source.lineageResolutionLinks ?? source.semanticLineageResolutionLinks),
8
+ ...array(source.lineageResolutions ?? source.semanticLineageResolutions),
9
+ ...array(source.metadata?.semanticLineageResolutionLinks),
10
+ ...array(source.metadata?.semanticHistoryLineageResolution),
11
+ ...array(source.metadata?.semanticLineageResolution),
12
+ ...array(source.metadata?.targetPortability?.lineageResolutionLinks),
13
+ ...array(targetPortability?.lineageResolutionLinks),
14
+ ...array(targetPortability?.lineageResolutions),
15
+ ...changedRegions.flatMap((region) => lineageLinksFromRegion(region))
16
+ ];
17
+ }
18
+
19
+ export function normalizeLineageResolutionLinks(entries) {
20
+ const seen = new Set();
21
+ const result = [];
22
+ for (const entry of lineageResolutionEntries(entries)) {
23
+ const currentAnchors = array(entry.currentAnchors);
24
+ const summary = entry.summary ?? {};
25
+ const anchorSummary = entry.anchorSummary ?? {};
26
+ const ids = uniqueStrings([
27
+ entry.id,
28
+ entry.resolutionId,
29
+ entry.lineageResolutionId,
30
+ ...strings(entry.lineageResolutionIds),
31
+ ...strings(entry.semanticLineageResolutionIds),
32
+ ...strings(summary.lineageResolutionIds)
33
+ ]);
34
+ const link = compactRecord({
35
+ id: firstString(entry.id, entry.resolutionId, entry.lineageResolutionId, ids[0]),
36
+ lineageResolutionIds: ids,
37
+ status: entry.status,
38
+ readiness: entry.readiness ?? entry.admission?.readiness,
39
+ action: entry.action ?? entry.admission?.action,
40
+ anchorKeys: uniqueStrings([
41
+ entry.anchorKey,
42
+ entry.query?.anchorKey,
43
+ entry.startAnchor?.key,
44
+ ...strings(entry.anchorKeys),
45
+ ...strings(anchorSummary.activeAnchorKeys),
46
+ ...strings(anchorSummary.candidateAnchorKeys),
47
+ ...strings(anchorSummary.blockedAnchorKeys),
48
+ ...strings(summary.activeAnchorKeys),
49
+ ...strings(summary.candidateAnchorKeys),
50
+ ...strings(summary.blockedAnchorKeys),
51
+ ...currentAnchors.map((anchor) => anchor.key)
52
+ ]),
53
+ sourcePaths: uniqueStrings([
54
+ entry.sourcePath,
55
+ entry.query?.sourcePath,
56
+ entry.startAnchor?.sourcePath,
57
+ ...strings(entry.sourcePaths),
58
+ ...strings(entry.lineageSourcePaths),
59
+ ...strings(summary.sourcePaths),
60
+ ...currentAnchors.flatMap((anchor) => [anchor.sourcePath, ...strings(anchor.lineageSourcePaths)])
61
+ ]),
62
+ evidenceIds: uniqueStrings([
63
+ ...strings(entry.evidenceIds),
64
+ ...strings(entry.lineageEvidenceIds),
65
+ ...strings(summary.evidenceIds),
66
+ ...currentAnchors.flatMap((anchor) => strings(anchor.evidenceIds))
67
+ ]),
68
+ proofIds: uniqueStrings([
69
+ ...strings(entry.proofIds),
70
+ ...strings(entry.lineageProofIds),
71
+ ...strings(summary.proofIds),
72
+ ...currentAnchors.flatMap((anchor) => strings(anchor.proofIds))
73
+ ]),
74
+ lineageEventIds: uniqueStrings([
75
+ ...strings(entry.lineageEventIds),
76
+ ...strings(entry.traversedEventIds),
77
+ ...strings(summary.lineageEventIds),
78
+ ...strings(summary.traversedEventIds),
79
+ ...currentAnchors.flatMap((anchor) => strings(anchor.lineageEventIds))
80
+ ]),
81
+ terminalEventIds: uniqueStrings([
82
+ ...strings(entry.terminalEventIds),
83
+ ...strings(summary.terminalEventIds),
84
+ ...currentAnchors.flatMap((anchor) => strings(anchor.terminalLineageEventIds))
85
+ ]),
86
+ crdtOperationIds: uniqueStrings([
87
+ ...strings(entry.crdtOperationIds),
88
+ ...strings(summary.crdtOperationIds),
89
+ ...currentAnchors.flatMap((anchor) => strings(anchor.crdtOperationIds))
90
+ ]),
91
+ crdtHeads: uniqueStrings([
92
+ ...strings(entry.crdtHeads),
93
+ ...strings(summary.crdtHeads),
94
+ ...currentAnchors.flatMap((anchor) => strings(anchor.crdtHeads))
95
+ ]),
96
+ reasonCodes: uniqueStrings([
97
+ ...strings(entry.reasonCodes),
98
+ ...strings(entry.lineageReasonCodes),
99
+ ...strings(summary.reasonCodes),
100
+ ...currentAnchors.flatMap((anchor) => strings(anchor.lineageReasonCodes))
101
+ ])
102
+ });
103
+ const key = firstString(link.id, ...strings(link.lineageResolutionIds), ...strings(link.lineageEventIds), ...strings(link.evidenceIds), ...strings(link.sourcePaths));
104
+ if (!key || seen.has(key)) continue;
105
+ seen.add(key);
106
+ result.push(link);
107
+ }
108
+ return result;
109
+ }
110
+
111
+ export function semanticLineageLinkIndex(links = [], changedRegions = [], targetPortability, admission) {
112
+ const records = normalizeLineageResolutionLinks([
113
+ ...array(links),
114
+ ...array(targetPortability?.lineageResolutionLinks),
115
+ ...array(targetPortability?.lineageResolutions),
116
+ ...array(admission?.metadata?.semanticLineageResolutionLinks),
117
+ ...array(changedRegions).flatMap((region) => lineageLinksFromRegion(region))
118
+ ]);
119
+ return {
120
+ lineageResolutionIds: uniqueStrings(records.flatMap((record) => [record.id, ...strings(record.lineageResolutionIds)])),
121
+ lineageEventIds: uniqueStrings(records.flatMap((record) => record.lineageEventIds)),
122
+ sourcePaths: uniqueStrings(records.flatMap((record) => record.sourcePaths)),
123
+ evidenceIds: uniqueStrings(records.flatMap((record) => record.evidenceIds)),
124
+ proofIds: uniqueStrings(records.flatMap((record) => record.proofIds)),
125
+ reasonCodes: uniqueStrings(records.flatMap((record) => record.reasonCodes)),
126
+ terminalEventIds: uniqueStrings(records.flatMap((record) => record.terminalEventIds)),
127
+ crdtOperationIds: uniqueStrings(records.flatMap((record) => record.crdtOperationIds)),
128
+ crdtHeads: uniqueStrings(records.flatMap((record) => record.crdtHeads))
129
+ };
130
+ }
131
+
132
+ export function linkAdmissionLineage(admission, lineageLinks) {
133
+ if (lineageLinks.length === 0) return admission;
134
+ const lineageIndex = semanticLineageLinkIndex(lineageLinks);
135
+ return {
136
+ ...admission,
137
+ evidenceIds: uniqueStrings([...strings(admission.evidenceIds), ...lineageIndex.evidenceIds]),
138
+ reasonCodes: uniqueStrings([...strings(admission.reasonCodes), 'semantic-lineage-resolution-linked', ...lineageIndex.reasonCodes]),
139
+ metadata: compactRecord({
140
+ ...(admission.metadata ?? {}),
141
+ semanticLineageResolutionLinks: lineageLinks
142
+ })
143
+ };
144
+ }
145
+
146
+ function lineageLinksFromRegion(region = {}) {
147
+ const metadata = region.metadata ?? {};
148
+ const bidirectional = metadata.bidirectionalTargetChange ?? {};
149
+ const history = metadata.semanticHistoryLineageResolution ?? {};
150
+ const lineage = metadata.semanticLineageResolution ?? {};
151
+ return [
152
+ ...array(region.lineageResolutionLinks),
153
+ ...array(region.lineageResolutions),
154
+ compactRecord({
155
+ lineageResolutionIds: region.lineageResolutionIds,
156
+ lineageEventIds: region.lineageEventIds,
157
+ sourcePaths: region.lineageSourcePaths,
158
+ evidenceIds: region.lineageEvidenceIds,
159
+ proofIds: region.lineageProofIds,
160
+ reasonCodes: region.lineageReasonCodes
161
+ }),
162
+ bidirectional,
163
+ history,
164
+ lineage,
165
+ ...array(bidirectional.lineageResolutionLinks),
166
+ ...array(history.lineageResolutionLinks),
167
+ ...array(lineage.lineageResolutionLinks)
168
+ ].filter((entry) => Object.keys(entry ?? {}).length > 0);
169
+ }
170
+
171
+ function lineageResolutionEntries(entries) {
172
+ const result = [];
173
+ for (const entry of array(entries).filter(Boolean)) {
174
+ result.push(entry);
175
+ result.push(...array(entry.resolutions));
176
+ result.push(...array(entry.lineageResolutions));
177
+ result.push(...array(entry.semanticLineageResolutions));
178
+ result.push(...array(entry.lineageResolutionLinks));
179
+ result.push(...array(entry.semanticLineageResolutionLinks));
180
+ }
181
+ return result;
182
+ }
183
+
184
+ function array(value) {
185
+ if (value === undefined || value === null) return [];
186
+ return Array.isArray(value) ? value : [value];
187
+ }
188
+
189
+ function strings(value) {
190
+ return array(value).map((entry) => String(entry ?? '')).filter(Boolean);
191
+ }
192
+
193
+ function firstString(...values) {
194
+ return values.map((value) => value === undefined || value === null ? '' : String(value)).find(Boolean);
195
+ }
196
+
197
+ function compactRecord(value) {
198
+ return Object.fromEntries(Object.entries(value ?? {}).filter(([, entry]) => entry !== undefined && (!Array.isArray(entry) || entry.length > 0)));
199
+ }
@@ -113,8 +113,12 @@ function sharedIndex(left,right,options){
113
113
  }
114
114
 
115
115
  function overlapAdmission(shared,{leftIndex,rightIndex,options}){
116
- const duplicate=shared.operationContentHashes.length||shared.editContentHashes.length||shared.semanticTransformContentHashes.length||shared.semanticEditReplayIds.length||shared.semanticEditReplayOutputHashes.length;
117
- const semantic=shared.semanticEditKeys.length||shared.semanticIdentityHashes.length||shared.sourceIdentityHashes.length||shared.semanticTransformIdentityHashes.length||shared.projectionIdentityHashes.length;
116
+ const hashMismatch=disjointNonEmpty(leftIndex.baseHashes,rightIndex.baseHashes)||disjointNonEmpty(leftIndex.targetHashes,rightIndex.targetHashes);
117
+ const sourceRelated=shared.sourcePaths.length||shared.regionKeys.length||shared.conflictKeys.length||shared.sourceIdentityHashes.length;
118
+ const editContent=shared.operationContentHashes.length||shared.editContentHashes.length||shared.semanticEditReplayOutputHashes.length;
119
+ const transformContent=shared.semanticTransformContentHashes.length&&shared.projectionIdentityHashes.length;
120
+ const duplicate=(transformContent||shared.semanticEditReplayIds.length||(editContent&&sourceRelated))&&!hashMismatch;
121
+ const semantic=editContent||shared.semanticEditKeys.length||shared.semanticIdentityHashes.length||shared.sourceIdentityHashes.length||shared.semanticTransformIdentityHashes.length||shared.projectionIdentityHashes.length;
118
122
  const source=shared.regionKeys.length||shared.conflictKeys.length||shared.sourcePaths.length||shared.semanticEditReplayCurrentHashes.length;
119
123
  const status=duplicate?'duplicate':semantic?'semantic-overlap':source?'source-overlap':'independent';
120
124
  const reasonCodes=uniqueStrings([
@@ -2,6 +2,8 @@ import{idFragment,normalizeSemanticMergeReadiness,uniqueStrings}from'../../nativ
2
2
  import{createSemanticEditBundleAdmission}from'./semanticEditBundleAdmission.js';
3
3
  import{createSemanticPatchBundleAdmission}from'./semanticPatchBundleAdmission.js';
4
4
  import{semanticEditRecordIndex,semanticEditSummary}from'./semanticEditBundleIndex.js';
5
+ import{lineageLinkInputs,linkAdmissionLineage,normalizeLineageResolutionLinks,semanticLineageLinkIndex}from'./semanticPatchBundleLineageLinks.js';
6
+ import{normalizeRegions,normalizeSourceMapLinks,normalizeSources,sourceRef}from'./semanticPatchBundleSourceRecords.js';
5
7
  import{normalizeSemanticTransformIdentityRecords,semanticTransformInputs,semanticTransformRecordIndex,semanticTransformSummary}from'./semanticTransformIdentityRecords.js';
6
8
 
7
9
  export const SemanticPatchBundleAdmissionStatuses=Object.freeze(['proposed','queued','admitted','needs-review','blocked','rejected']);
@@ -13,8 +15,10 @@ export function createSemanticPatchBundleRecord(input={},options={}){
13
15
  const semanticEditScripts=array(options.semanticEditScripts??source.semanticEditScripts??source.semanticEditScript);
14
16
  const semanticEditProjections=array(options.semanticEditProjections??source.semanticEditProjections??source.semanticEditProjection);
15
17
  const semanticEditReplays=array(options.semanticEditReplays??source.semanticEditReplays??source.semanticEditReplay);
18
+ const evidenceRecords=[...array(options.evidence??source.evidence),...array(patch?.evidence),...array(mergeCandidate?.evidence),...semanticEditScripts.flatMap((script)=>array(script.evidence))];
16
19
  const editAdmission=createSemanticEditBundleAdmission({
17
20
  semanticEditScripts,semanticEditProjections,semanticEditReplays,
21
+ evidence:evidenceRecords,
18
22
  ...(source.metadata?.semanticEditAdmission??{}),
19
23
  ...(source.semanticEditAdmission??{}),
20
24
  ...(options.semanticEditAdmission??{})
@@ -35,15 +39,16 @@ export function createSemanticPatchBundleRecord(input={},options={}){
35
39
  sourceRef(source.before,'before',source.beforeHash),
36
40
  sourceRef(source.after,'after',source.afterHash)
37
41
  ],source);
38
- const evidenceRecords=[...array(options.evidence??source.evidence),...array(patch?.evidence),...array(mergeCandidate?.evidence),...semanticEditScripts.flatMap((script)=>array(script.evidence))];
39
42
  const patchId=firstString(options.patchId,source.patchId,patch?.id,mergeCandidate?.patchId);
40
43
  const mergeCandidateId=firstString(options.mergeCandidateId,source.mergeCandidateId,mergeCandidate?.id);
41
44
  const baseHash=firstString(options.baseHash,source.baseHash,source.beforeHash,patch?.baseHash,mergeCandidate?.baseHash,...sources.map((item)=>item.baseHash));
42
45
  const targetHash=firstString(options.targetHash,source.targetHash,source.afterHash,patch?.targetHash,mergeCandidate?.targetHash,...sources.map((item)=>item.targetHash));
43
46
  const readiness=normalizeSemanticMergeReadiness(firstString(options.readiness,source.readiness,source.admission?.readiness,mergeCandidate?.readiness))
44
47
  ?? firstString(options.readiness,source.readiness,source.admission?.readiness,mergeCandidate?.readiness,'needs-review');
45
- const evidenceIds=uniqueStrings([...strings(options.evidenceIds),...strings(source.evidenceIds),...evidenceRecords.map((record)=>record?.id),...strings(mergeCandidate?.evidenceIds)]);
46
- const proofIds=uniqueStrings([...strings(options.proofIds),...strings(source.proofIds),...evidenceRecords.filter((record)=>record?.kind==='proof').map((record)=>record.id),...strings(mergeCandidate?.proofIds)]);
48
+ const lineageLinks=normalizeLineageResolutionLinks(lineageLinkInputs(source,options,changedRegions,targetPortability));
49
+ const lineageIndex=semanticLineageLinkIndex(lineageLinks,changedRegions,targetPortability);
50
+ const evidenceIds=uniqueStrings([...strings(options.evidenceIds),...strings(source.evidenceIds),...evidenceRecords.map((record)=>record?.id),...strings(mergeCandidate?.evidenceIds),...lineageIndex.evidenceIds]);
51
+ const proofIds=uniqueStrings([...strings(options.proofIds),...strings(source.proofIds),...evidenceRecords.filter((record)=>record?.kind==='proof').map((record)=>record.id),...strings(mergeCandidate?.proofIds),...lineageIndex.proofIds]);
47
52
  const historyIds=uniqueStrings([...strings(options.historyIds),...strings(options.historyId),...strings(source.historyIds),...strings(source.historyId)]);
48
53
  const semanticOperationIds=uniqueStrings([...strings(options.semanticOperationIds),...strings(options.semanticOperationId),...strings(source.semanticOperationIds),...strings(source.semanticOperationId),...strings(patch?.semanticOperationIds),...strings(mergeCandidate?.semanticOperationIds),...editIndex.semanticEditOperationIds]);
49
54
  const conflictKeys=uniqueStrings([
@@ -53,12 +58,12 @@ export function createSemanticPatchBundleRecord(input={},options={}){
53
58
  ...changedRegions.flatMap((region)=>[region.conflictKey,...array(region.admission?.conflictKeys)]),
54
59
  ...(source.metadata?.semanticMergeConflictSummary?.conflictKeys??[])
55
60
  ]);
56
- const admission=createSemanticPatchBundleAdmission(options.admission??source.admission,{readiness,conflictKeys,source,mergeCandidate,semanticTransformIndex,semanticTransformIdentities,semanticEditAdmission:editAdmission});
61
+ const admission=linkAdmissionLineage(createSemanticPatchBundleAdmission(options.admission??source.admission,{readiness,conflictKeys,source,mergeCandidate,evidenceRecords,semanticTransformIndex,semanticTransformIdentities,semanticEditAdmission:editAdmission}),lineageLinks);
57
62
  const id=options.id??(source.kind==='frontier.lang.semanticPatchBundleRecord'?source.id:undefined)
58
63
  ??`semantic_patch_bundle_${idFragment(firstString(source.id,patchId,mergeCandidateId,source.sourcePath,source.language,'record'))}`;
59
64
  const language=options.language??source.language??mergeCandidate?.language??sources.find((item)=>item.language)?.language;
60
65
  const sourcePath=options.sourcePath??source.sourcePath??mergeCandidate?.sourcePath??sources.find((item)=>item.sourcePath)?.sourcePath;
61
- const index=recordIndex({baseHash,targetHash,sources,changedRegions,sourceMapLinks,evidenceIds,proofIds,historyIds,semanticOperationIds,patchId,mergeCandidateId,admission,semanticEditAdmission:editAdmission,semanticEditIndex:editIndex,semanticTransformIndex,targetPortability});
66
+ const index=recordIndex({baseHash,targetHash,sources,changedRegions,sourceMapLinks,evidenceIds,proofIds,historyIds,semanticOperationIds,patchId,mergeCandidateId,admission,semanticEditAdmission:editAdmission,semanticEditIndex:editIndex,semanticTransformIndex,targetPortability,lineageLinks});
62
67
  return{
63
68
  kind:'frontier.lang.semanticPatchBundleRecord',
64
69
  version:1,
@@ -95,6 +100,7 @@ export function createSemanticPatchBundleRecord(input={},options={}){
95
100
  semanticEditAdmission:editAdmission,
96
101
  semanticTransformSummary:semanticTransformSummary(semanticTransformIndex),
97
102
  targetPortability,
103
+ semanticLineageResolutionLinks:lineageLinks,
98
104
  ...options.metadata
99
105
  })
100
106
  };
@@ -104,118 +110,30 @@ export function querySemanticPatchBundleRecords(records,query={}){
104
110
  return array(records).filter(Boolean).filter((record)=>matchesRecord(record,query)).sort((left,right)=>String(left.id).localeCompare(String(right.id)));
105
111
  }
106
112
 
107
- function normalizeSources(entries,context){
108
- return entries.filter(Boolean).map((entry,index)=>compactRecord({
109
- id:entry.id??entry.sourceId,
110
- side:entry.side,
111
- importId:entry.importId??entry.importResultId,
112
- language:entry.language??context.language,
113
- sourcePath:entry.sourcePath??context.sourcePath,
114
- sourceHash:entry.sourceHash??entry.hash,
115
- baseHash:entry.baseHash??entry.beforeHash??context.baseHash??context.beforeHash,
116
- targetHash:entry.targetHash??entry.afterHash??context.targetHash??context.afterHash,
117
- nativeSourceId:entry.nativeSourceId,
118
- nativeAstId:entry.nativeAstId,
119
- semanticIndexId:entry.semanticIndexId,
120
- universalAstId:entry.universalAstId,
121
- sourceMapIds:uniqueStrings(entry.sourceMapIds),
122
- ordinal:index
123
- })).filter((entry)=>entry.importId||entry.sourcePath||entry.sourceHash||entry.baseHash||entry.targetHash);
124
- }
125
-
126
- function sourceRef(importResult,side,sourceHash){
127
- if(!importResult)return undefined;
128
- return compactRecord({
129
- id:`${side}_${importResult.id??idFragment(importResult.sourcePath??'source')}`,side,importId:importResult.id,
130
- language:importResult.language,
131
- sourcePath:importResult.sourcePath,
132
- sourceHash:sourceHash??importResult.nativeSource?.sourceHash??importResult.nativeAst?.sourceHash??importResult.sourceHash,
133
- nativeSourceId:importResult.nativeSource?.id,
134
- nativeAstId:importResult.nativeAst?.id,
135
- semanticIndexId:importResult.semanticIndex?.id,
136
- universalAstId:importResult.universalAst?.id,
137
- sourceMapIds:uniqueStrings((importResult.sourceMaps??[]).map((map)=>map.id))
138
- });
139
- }
140
-
141
- function normalizeRegions(regions,context){
142
- return regions.filter(Boolean).map((region,index)=>{
143
- const projection=region.metadata?.changedRegionProjection??region.projection;
144
- const projected=projection?.region??{};
145
- const key=firstString(region.key,region.ownershipKey,projected.key,region.conflictKey,region.id);
146
- const conflictKey=firstString(region.conflictKey,projection?.conflictKey,key);
147
- const links=array(projection?.sourceMapLinks??region.sourceMapLinks);
148
- return compactRecord({
149
- id:region.id??projected.id??`changed_region_${index+1}`,
150
- key,
151
- conflictKey,
152
- changeKind:region.changeKind??projection?.changeKind,
153
- regionKind:region.regionKind??region.ownershipRegionKind??projected.kind,
154
- granularity:region.granularity??projected.granularity,
155
- precision:region.precision??projected.precision,
156
- language:region.language??projection?.language??context.language,
157
- sourcePath:region.sourcePath??projection?.sourcePath??context.sourcePath,
158
- sourceHash:region.sourceHash??projection?.after?.sourceHash??projection?.before?.sourceHash,
159
- symbolId:region.symbolId??projected.symbolId,
160
- symbolName:region.symbolName??region.name??projected.symbolName,
161
- symbolKind:region.symbolKind??projected.symbolKind,
162
- sourceSpan:region.sourceSpan??projected.sourceSpan,
163
- sourceMapLinkIds:uniqueStrings([...strings(region.sourceMapLinkIds),...links.map((link)=>link.id)]),
164
- sourceMapIds:uniqueStrings([...strings(region.sourceMapIds),...links.map((link)=>link.sourceMapId)]),
165
- sourceMapMappingIds:uniqueStrings([...strings(region.sourceMapMappingIds),...links.map((link)=>link.sourceMapMappingId)]),
166
- admission:compactRecord({
167
- readiness:projection?.admission?.readiness??region.admission?.readiness,
168
- action:projection?.admission?.action??region.admission?.action,
169
- reasonCodes:uniqueStrings([...strings(region.admission?.reasonCodes),...strings(projection?.admission?.reasons)]),
170
- conflictKeys:uniqueStrings([...strings(region.admission?.conflictKeys),...strings(projection?.admission?.conflictKeys)])
171
- }),
172
- metadata:region.metadata
173
- });
174
- });
175
- }
176
-
177
- function normalizeSourceMapLinks(links){
178
- const seen=new Set();
179
- const result=[];
180
- for(const link of links.filter(Boolean)){
181
- const id=link.id??`source_map_link_${result.length+1}`;
182
- if(seen.has(id))continue;
183
- seen.add(id);
184
- result.push(compactRecord({
185
- id,side:link.side,sourceMapId:link.sourceMapId,sourceMapMappingId:link.sourceMapMappingId,
186
- sourcePath:link.sourcePath,sourceHash:link.sourceHash,targetPath:link.targetPath,targetHash:link.targetHash,
187
- semanticSymbolId:link.semanticSymbolId,
188
- semanticOccurrenceId:link.semanticOccurrenceId,
189
- semanticNodeId:link.semanticNodeId,
190
- nativeSourceId:link.nativeSourceId,
191
- nativeAstNodeId:link.nativeAstNodeId,
192
- precision:link.precision,
193
- sourceSpan:link.sourceSpan,
194
- generatedSpan:link.generatedSpan,
195
- regionKey:link.ownershipRegionKey,
196
- regionKind:link.ownershipRegionKind
197
- }));
198
- }
199
- return result;
200
- }
201
-
202
113
  function recordIndex(parts){
203
114
  const editIndex=parts.semanticEditIndex??semanticEditRecordIndex([],[],[],parts);
204
115
  const editAdmission=parts.semanticEditAdmission??{};
205
116
  const semanticTransformIndex=parts.semanticTransformIndex??semanticTransformRecordIndex([],parts);
117
+ const lineageIndex=semanticLineageLinkIndex(parts.lineageLinks,parts.changedRegions,parts.targetPortability,parts.admission);
206
118
  return{
207
119
  baseHashes:uniqueStrings([parts.baseHash,...parts.sources.map((item)=>item.baseHash)]),
208
120
  targetHashes:uniqueStrings([parts.targetHash,...parts.sources.map((item)=>item.targetHash)]),
209
121
  sourceHashes:uniqueStrings(parts.sources.map((item)=>item.sourceHash)),
210
- sourcePaths:uniqueStrings([...parts.sources.map((item)=>item.sourcePath),...strings(editAdmission.sourcePaths),...editIndex.projectedSourcePaths,...semanticTransformIndex.transformSourcePaths,...semanticTransformIndex.transformTargetPaths]),
122
+ sourcePaths:uniqueStrings([...parts.sources.map((item)=>item.sourcePath),...strings(editAdmission.sourcePaths),...editIndex.projectedSourcePaths,...semanticTransformIndex.transformSourcePaths,...semanticTransformIndex.transformTargetPaths,...lineageIndex.sourcePaths]),
211
123
  regionKeys:uniqueStrings([...parts.changedRegions.map((region)=>region.key),...editIndex.anchorKeys]),
212
124
  regionKinds:uniqueStrings(parts.changedRegions.map((region)=>region.regionKind)),
213
125
  conflictKeys:uniqueStrings([...parts.changedRegions.flatMap((region)=>[region.conflictKey,...array(region.admission?.conflictKeys)]),...editIndex.conflictKeys]),
214
126
  sourceMapIds:uniqueStrings([...parts.sourceMapLinks.map((link)=>link.sourceMapId),...parts.changedRegions.flatMap((region)=>region.sourceMapIds??[])]),
215
127
  sourceMapMappingIds:uniqueStrings([...parts.sourceMapLinks.map((link)=>link.sourceMapMappingId),...parts.changedRegions.flatMap((region)=>region.sourceMapMappingIds??[])]),
216
128
  sourceMapLinkIds:uniqueStrings(parts.sourceMapLinks.map((link)=>link.id)),
217
- evidenceIds:parts.evidenceIds,
218
- proofIds:parts.proofIds,
129
+ evidenceIds:uniqueStrings([...parts.evidenceIds,...lineageIndex.evidenceIds]),
130
+ proofIds:uniqueStrings([...parts.proofIds,...lineageIndex.proofIds]),
131
+ lineageResolutionIds:lineageIndex.lineageResolutionIds,
132
+ lineageEventIds:lineageIndex.lineageEventIds,
133
+ lineageSourcePaths:lineageIndex.sourcePaths,
134
+ lineageEvidenceIds:lineageIndex.evidenceIds,
135
+ lineageProofIds:lineageIndex.proofIds,
136
+ lineageReasonCodes:lineageIndex.reasonCodes,
219
137
  historyIds:parts.historyIds,
220
138
  semanticOperationIds:uniqueStrings(parts.semanticOperationIds),
221
139
  semanticEditScriptIds:editIndex.semanticEditScriptIds,
@@ -255,7 +173,7 @@ function recordIndex(parts){
255
173
  }
256
174
 
257
175
  function matchesRecord(record,query){
258
- const index=record.index??recordIndex({...record,baseHash:record.baseHash,targetHash:record.targetHash,sources:record.sources??[],changedRegions:record.changedRegions??[],sourceMapLinks:record.sourceMapLinks??[],evidenceIds:record.evidenceIds??[],proofIds:record.proofIds??[],historyIds:record.historyIds??[],semanticOperationIds:record.semanticOperationIds??[],patchId:record.patchId,mergeCandidateId:record.mergeCandidateId,admission:record.admission??{},semanticEditAdmission:record.admission?.semanticEditAdmission??record.metadata?.semanticEditAdmission,targetPortability:record.metadata?.targetPortability});
176
+ const index=record.index??recordIndex({...record,baseHash:record.baseHash,targetHash:record.targetHash,sources:record.sources??[],changedRegions:record.changedRegions??[],sourceMapLinks:record.sourceMapLinks??[],evidenceIds:record.evidenceIds??[],proofIds:record.proofIds??[],historyIds:record.historyIds??[],semanticOperationIds:record.semanticOperationIds??[],patchId:record.patchId,mergeCandidateId:record.mergeCandidateId,admission:record.admission??{},semanticEditAdmission:record.admission?.semanticEditAdmission??record.metadata?.semanticEditAdmission,targetPortability:record.metadata?.targetPortability,lineageLinks:normalizeLineageResolutionLinks([...array(record.metadata?.semanticLineageResolutionLinks),...array(record.admission?.metadata?.semanticLineageResolutionLinks)])});
259
177
  return matchAny(queryValues(query.id,query.ids),[record.id])
260
178
  &&matchAny(queryValues(query.patchId,query.patchIds),index.patchIds)
261
179
  &&matchAny(queryValues(query.mergeCandidateId,query.mergeCandidateIds),index.mergeCandidateIds)
@@ -271,6 +189,12 @@ function matchesRecord(record,query){
271
189
  &&matchAny(queryValues(query.sourceMapLinkId,query.sourceMapLinkIds),index.sourceMapLinkIds)
272
190
  &&matchAny(queryValues(query.evidenceId,query.evidenceIds),index.evidenceIds)
273
191
  &&matchAny(queryValues(query.proofId,query.proofIds),index.proofIds)
192
+ &&matchAny(queryValues(query.lineageResolutionId,query.lineageResolutionIds,query.semanticLineageResolutionId,query.semanticLineageResolutionIds),index.lineageResolutionIds)
193
+ &&matchAny(queryValues(query.lineageEventId,query.lineageEventIds),index.lineageEventIds)
194
+ &&matchAny(queryValues(query.lineageSourcePath,query.lineageSourcePaths),index.lineageSourcePaths)
195
+ &&matchAny(queryValues(query.lineageEvidenceId,query.lineageEvidenceIds),index.lineageEvidenceIds)
196
+ &&matchAny(queryValues(query.lineageProofId,query.lineageProofIds),index.lineageProofIds)
197
+ &&matchAny(queryValues(query.lineageReasonCode,query.lineageReasonCodes),index.lineageReasonCodes)
274
198
  &&matchAny(queryValues(query.historyId,query.historyIds),index.historyIds)
275
199
  &&matchAny(queryValues(query.semanticOperationId,query.semanticOperationIds),index.semanticOperationIds)
276
200
  &&matchAny(queryValues(query.semanticEditScriptId,query.semanticEditScriptIds),index.semanticEditScriptIds)
@@ -0,0 +1,127 @@
1
+ import { idFragment, uniqueStrings } from '../../native-import-utils.js';
2
+
3
+ export function normalizeSources(entries, context) {
4
+ return entries.filter(Boolean).map((entry, index) => compactRecord({
5
+ id: entry.id ?? entry.sourceId,
6
+ side: entry.side,
7
+ importId: entry.importId ?? entry.importResultId,
8
+ language: entry.language ?? context.language,
9
+ sourcePath: entry.sourcePath ?? context.sourcePath,
10
+ sourceHash: entry.sourceHash ?? entry.hash,
11
+ baseHash: entry.baseHash ?? entry.beforeHash ?? context.baseHash ?? context.beforeHash,
12
+ targetHash: entry.targetHash ?? entry.afterHash ?? context.targetHash ?? context.afterHash,
13
+ nativeSourceId: entry.nativeSourceId,
14
+ nativeAstId: entry.nativeAstId,
15
+ semanticIndexId: entry.semanticIndexId,
16
+ universalAstId: entry.universalAstId,
17
+ sourceMapIds: uniqueStrings(entry.sourceMapIds),
18
+ ordinal: index
19
+ })).filter((entry) => entry.importId || entry.sourcePath || entry.sourceHash || entry.baseHash || entry.targetHash);
20
+ }
21
+
22
+ export function sourceRef(importResult, side, sourceHash) {
23
+ if (!importResult) return undefined;
24
+ return compactRecord({
25
+ id: `${side}_${importResult.id ?? idFragment(importResult.sourcePath ?? 'source')}`,
26
+ side,
27
+ importId: importResult.id,
28
+ language: importResult.language,
29
+ sourcePath: importResult.sourcePath,
30
+ sourceHash: sourceHash ?? importResult.nativeSource?.sourceHash ?? importResult.nativeAst?.sourceHash ?? importResult.sourceHash,
31
+ nativeSourceId: importResult.nativeSource?.id,
32
+ nativeAstId: importResult.nativeAst?.id,
33
+ semanticIndexId: importResult.semanticIndex?.id,
34
+ universalAstId: importResult.universalAst?.id,
35
+ sourceMapIds: uniqueStrings((importResult.sourceMaps ?? []).map((map) => map.id))
36
+ });
37
+ }
38
+
39
+ export function normalizeRegions(regions, context) {
40
+ return regions.filter(Boolean).map((region, index) => {
41
+ const projection = region.metadata?.changedRegionProjection ?? region.projection;
42
+ const projected = projection?.region ?? {};
43
+ const key = firstString(region.key, region.ownershipKey, projected.key, region.conflictKey, region.id);
44
+ const conflictKey = firstString(region.conflictKey, projection?.conflictKey, key);
45
+ const links = array(projection?.sourceMapLinks ?? region.sourceMapLinks);
46
+ return compactRecord({
47
+ id: region.id ?? projected.id ?? `changed_region_${index + 1}`,
48
+ key,
49
+ conflictKey,
50
+ changeKind: region.changeKind ?? projection?.changeKind,
51
+ regionKind: region.regionKind ?? region.ownershipRegionKind ?? projected.kind,
52
+ granularity: region.granularity ?? projected.granularity,
53
+ precision: region.precision ?? projected.precision,
54
+ language: region.language ?? projection?.language ?? context.language,
55
+ sourcePath: region.sourcePath ?? projection?.sourcePath ?? context.sourcePath,
56
+ sourceHash: region.sourceHash ?? projection?.after?.sourceHash ?? projection?.before?.sourceHash,
57
+ symbolId: region.symbolId ?? projected.symbolId,
58
+ symbolName: region.symbolName ?? region.name ?? projected.symbolName,
59
+ symbolKind: region.symbolKind ?? projected.symbolKind,
60
+ sourceSpan: region.sourceSpan ?? projected.sourceSpan,
61
+ sourceMapLinkIds: uniqueStrings([...strings(region.sourceMapLinkIds), ...links.map((link) => link.id)]),
62
+ sourceMapIds: uniqueStrings([...strings(region.sourceMapIds), ...links.map((link) => link.sourceMapId)]),
63
+ sourceMapMappingIds: uniqueStrings([...strings(region.sourceMapMappingIds), ...links.map((link) => link.sourceMapMappingId)]),
64
+ lineageResolutionIds: uniqueStrings([...strings(region.lineageResolutionIds), ...strings(projection?.lineageResolutionIds), ...strings(region.metadata?.bidirectionalTargetChange?.lineageResolutionIds), ...strings(region.metadata?.semanticHistoryLineageResolution?.lineageResolutionIds), region.metadata?.semanticHistoryLineageResolution?.id]),
65
+ lineageEventIds: uniqueStrings([...strings(region.lineageEventIds), ...strings(projection?.lineageEventIds), ...strings(region.metadata?.semanticHistoryLineageResolution?.lineageEventIds)]),
66
+ lineageSourcePaths: uniqueStrings([...strings(region.lineageSourcePaths), ...strings(projection?.lineageSourcePaths), ...strings(region.metadata?.semanticHistoryLineageResolution?.sourcePaths)]),
67
+ lineageEvidenceIds: uniqueStrings([...strings(region.lineageEvidenceIds), ...strings(projection?.lineageEvidenceIds), ...strings(region.metadata?.semanticHistoryLineageResolution?.evidenceIds)]),
68
+ lineageProofIds: uniqueStrings([...strings(region.lineageProofIds), ...strings(projection?.lineageProofIds), ...strings(region.metadata?.semanticHistoryLineageResolution?.proofIds)]),
69
+ lineageReasonCodes: uniqueStrings([...strings(region.lineageReasonCodes), ...strings(projection?.lineageReasonCodes), ...strings(region.metadata?.semanticHistoryLineageResolution?.reasonCodes)]),
70
+ admission: compactRecord({
71
+ readiness: projection?.admission?.readiness ?? region.admission?.readiness,
72
+ action: projection?.admission?.action ?? region.admission?.action,
73
+ reasonCodes: uniqueStrings([...strings(region.admission?.reasonCodes), ...strings(projection?.admission?.reasons)]),
74
+ conflictKeys: uniqueStrings([...strings(region.admission?.conflictKeys), ...strings(projection?.admission?.conflictKeys)])
75
+ }),
76
+ metadata: region.metadata
77
+ });
78
+ });
79
+ }
80
+
81
+ export function normalizeSourceMapLinks(links) {
82
+ const seen = new Set();
83
+ const result = [];
84
+ for (const link of links.filter(Boolean)) {
85
+ const id = link.id ?? `source_map_link_${result.length + 1}`;
86
+ if (seen.has(id)) continue;
87
+ seen.add(id);
88
+ result.push(compactRecord({
89
+ id,
90
+ side: link.side,
91
+ sourceMapId: link.sourceMapId,
92
+ sourceMapMappingId: link.sourceMapMappingId,
93
+ sourcePath: link.sourcePath,
94
+ sourceHash: link.sourceHash,
95
+ targetPath: link.targetPath,
96
+ targetHash: link.targetHash,
97
+ semanticSymbolId: link.semanticSymbolId,
98
+ semanticOccurrenceId: link.semanticOccurrenceId,
99
+ semanticNodeId: link.semanticNodeId,
100
+ nativeSourceId: link.nativeSourceId,
101
+ nativeAstNodeId: link.nativeAstNodeId,
102
+ precision: link.precision,
103
+ sourceSpan: link.sourceSpan,
104
+ generatedSpan: link.generatedSpan,
105
+ regionKey: link.ownershipRegionKey,
106
+ regionKind: link.ownershipRegionKind
107
+ }));
108
+ }
109
+ return result;
110
+ }
111
+
112
+ function array(value) {
113
+ if (value === undefined || value === null) return [];
114
+ return Array.isArray(value) ? value : [value];
115
+ }
116
+
117
+ function strings(value) {
118
+ return array(value).map((entry) => String(entry ?? '')).filter(Boolean);
119
+ }
120
+
121
+ function firstString(...values) {
122
+ return values.map((value) => value === undefined || value === null ? '' : String(value)).find(Boolean);
123
+ }
124
+
125
+ function compactRecord(value) {
126
+ return Object.fromEntries(Object.entries(value ?? {}).filter(([, entry]) => entry !== undefined && (!Array.isArray(entry) || entry.length > 0)));
127
+ }
@@ -1,12 +1,7 @@
1
+ import { spanOffsets } from './semanticEditSourceRanges.js';
2
+
1
3
  export function sourceTextForSpan(sourceText, span) {
2
4
  if (typeof sourceText !== 'string' || !span) return undefined;
3
- if (typeof span.start === 'number' && typeof span.end === 'number' && span.end >= span.start) {
4
- return sourceText.slice(span.start, span.end);
5
- }
6
- if (typeof span.startLine === 'number') {
7
- const lines = sourceText.split(/\r?\n/);
8
- const endLine = typeof span.endLine === 'number' && span.endLine >= span.startLine ? span.endLine : span.startLine;
9
- return lines.slice(span.startLine - 1, endLine).join('\n');
10
- }
11
- return undefined;
5
+ const range = spanOffsets(sourceText, span);
6
+ return range ? sourceText.slice(range.start, range.end) : undefined;
12
7
  }