@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.
- package/dist/declarations/semantic-edit-bundle.d.ts +13 -1
- package/dist/declarations/semantic-edit-script.d.ts +34 -37
- package/dist/declarations/semantic-lineage.d.ts +63 -34
- package/dist/declarations/semantic-patch-bundle.d.ts +13 -0
- package/dist/internal/index-impl/declarationRecord.js +2 -2
- package/dist/internal/index-impl/inferSemanticLineageEvents.js +8 -0
- package/dist/internal/index-impl/projectSemanticEditScriptToSource.js +56 -64
- package/dist/internal/index-impl/replaySemanticEditProjection.js +54 -22
- package/dist/internal/index-impl/semanticEditBundleAdmission.js +95 -12
- package/dist/internal/index-impl/semanticEditBundleIndex.js +16 -10
- package/dist/internal/index-impl/semanticEditSourceRanges.js +204 -0
- package/dist/internal/index-impl/semanticHistoryLineageResolution.js +35 -1
- package/dist/internal/index-impl/semanticIndexFromNativeDeclarations.js +2 -2
- package/dist/internal/index-impl/semanticLineageInferenceMatching.js +150 -13
- package/dist/internal/index-impl/semanticLineageResolutionRecords.js +28 -1
- package/dist/internal/index-impl/semanticPatchBundleAdmission.js +122 -20
- package/dist/internal/index-impl/semanticPatchBundleLineageLinks.js +199 -0
- package/dist/internal/index-impl/semanticPatchBundleOverlaps.js +6 -2
- package/dist/internal/index-impl/semanticPatchBundleRecords.js +28 -104
- package/dist/internal/index-impl/semanticPatchBundleSourceRecords.js +127 -0
- package/dist/internal/index-impl/sourceTextForSpan.js +4 -9
- package/dist/lightweight-dependency-relations.js +113 -7
- package/dist/native-import-utils.js +15 -1
- package/dist/native-region-scanner-js-helpers.js +61 -17
- package/dist/native-region-scanner-js.js +12 -4
- package/dist/semantic-import-regions.js +3 -3
- 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
|
|
117
|
-
const
|
|
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
|
|
46
|
-
const
|
|
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
|
-
|
|
4
|
-
|
|
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
|
}
|