@shapeshift-labs/frontier-lang-compiler 0.2.85 → 0.2.87
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-script.d.ts +10 -0
- package/dist/declarations/semantic-patch-bundle.d.ts +31 -0
- package/dist/internal/index-impl/projectSemanticEditScriptToSource.js +23 -3
- package/dist/internal/index-impl/semanticEditScriptClassification.js +21 -6
- package/dist/internal/index-impl/semanticEditScripts.js +8 -2
- package/dist/internal/index-impl/semanticPatchBundleRecords.js +58 -7
- package/package.json +1 -1
|
@@ -66,6 +66,9 @@ export interface SemanticEditScriptOperation {
|
|
|
66
66
|
readonly reanchor?: {
|
|
67
67
|
readonly fromAnchorKey?: string;
|
|
68
68
|
readonly toAnchorKey?: string;
|
|
69
|
+
readonly toSourcePath?: string;
|
|
70
|
+
readonly toSymbolName?: string;
|
|
71
|
+
readonly toSymbolKind?: string;
|
|
69
72
|
readonly lineageStatus?: string;
|
|
70
73
|
readonly traversedEventIds?: readonly string[];
|
|
71
74
|
};
|
|
@@ -138,6 +141,11 @@ export interface SemanticEditProjectionEdit {
|
|
|
138
141
|
readonly regionId?: string;
|
|
139
142
|
readonly regionKind?: string;
|
|
140
143
|
readonly sourcePath?: string;
|
|
144
|
+
readonly originalSourcePath?: string;
|
|
145
|
+
readonly targetAnchorKey?: string;
|
|
146
|
+
readonly targetSourcePath?: string;
|
|
147
|
+
readonly targetSymbolName?: string;
|
|
148
|
+
readonly targetSymbolKind?: string;
|
|
141
149
|
readonly symbolId?: string;
|
|
142
150
|
readonly symbolName?: string;
|
|
143
151
|
readonly symbolKind?: string;
|
|
@@ -188,6 +196,7 @@ export interface ProjectSemanticEditScriptToSourceOptions {
|
|
|
188
196
|
readonly script: SemanticEditScript;
|
|
189
197
|
readonly workerSourceText: string;
|
|
190
198
|
readonly headSourceText: string;
|
|
199
|
+
readonly headSourcePath?: string;
|
|
191
200
|
readonly metadata?: Record<string, unknown>;
|
|
192
201
|
}
|
|
193
202
|
|
|
@@ -207,6 +216,7 @@ export interface CreateSemanticEditScriptOptions {
|
|
|
207
216
|
readonly workerSourceText?: string;
|
|
208
217
|
readonly afterSourceText?: string;
|
|
209
218
|
readonly headSourceText?: string;
|
|
219
|
+
readonly headSourcePath?: string;
|
|
210
220
|
readonly currentSourceText?: string;
|
|
211
221
|
readonly baseSourceHash?: string;
|
|
212
222
|
readonly workerSourceHash?: string;
|
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
SourceSpan
|
|
8
8
|
} from '@shapeshift-labs/frontier-lang-kernel';
|
|
9
9
|
import type { NativeSourceChangeKind, NativeSourceChangeSet } from './native-diff.js';
|
|
10
|
+
import type { SemanticEditProjection, SemanticEditScript } from './semantic-edit-script.js';
|
|
10
11
|
|
|
11
12
|
export type SemanticPatchBundleAdmissionStatus = 'proposed' | 'queued' | 'admitted' | 'needs-review' | 'blocked' | 'rejected' | string;
|
|
12
13
|
|
|
@@ -102,6 +103,13 @@ export interface SemanticPatchBundleRecordIndex {
|
|
|
102
103
|
readonly proofIds: readonly string[];
|
|
103
104
|
readonly historyIds: readonly string[];
|
|
104
105
|
readonly semanticOperationIds: readonly string[];
|
|
106
|
+
readonly semanticEditScriptIds: readonly string[];
|
|
107
|
+
readonly semanticEditProjectionIds: readonly string[];
|
|
108
|
+
readonly semanticEditKeys: readonly string[];
|
|
109
|
+
readonly semanticIdentityHashes: readonly string[];
|
|
110
|
+
readonly sourceIdentityHashes: readonly string[];
|
|
111
|
+
readonly operationContentHashes: readonly string[];
|
|
112
|
+
readonly editContentHashes: readonly string[];
|
|
105
113
|
readonly patchIds: readonly string[];
|
|
106
114
|
readonly mergeCandidateIds: readonly string[];
|
|
107
115
|
readonly readinesses: readonly string[];
|
|
@@ -127,6 +135,8 @@ export interface SemanticPatchBundleRecord {
|
|
|
127
135
|
readonly proofIds: readonly string[];
|
|
128
136
|
readonly historyIds: readonly string[];
|
|
129
137
|
readonly semanticOperationIds: readonly string[];
|
|
138
|
+
readonly semanticEditScriptIds: readonly string[];
|
|
139
|
+
readonly semanticEditProjectionIds: readonly string[];
|
|
130
140
|
readonly admission: SemanticPatchBundleAdmission;
|
|
131
141
|
readonly index: SemanticPatchBundleRecordIndex;
|
|
132
142
|
readonly summary: {
|
|
@@ -136,6 +146,9 @@ export interface SemanticPatchBundleRecord {
|
|
|
136
146
|
readonly proofIds: number;
|
|
137
147
|
readonly historyIds: number;
|
|
138
148
|
readonly semanticOperations: number;
|
|
149
|
+
readonly semanticEditScripts: number;
|
|
150
|
+
readonly semanticEditProjections: number;
|
|
151
|
+
readonly semanticEditProjectionEdits: number;
|
|
139
152
|
readonly reviewRequired: boolean;
|
|
140
153
|
readonly autoMergeClaim: false;
|
|
141
154
|
};
|
|
@@ -164,6 +177,10 @@ export interface CreateSemanticPatchBundleRecordOptions {
|
|
|
164
177
|
readonly historyIds?: readonly string[] | string;
|
|
165
178
|
readonly semanticOperationId?: string;
|
|
166
179
|
readonly semanticOperationIds?: readonly string[] | string;
|
|
180
|
+
readonly semanticEditScript?: SemanticEditScript;
|
|
181
|
+
readonly semanticEditScripts?: readonly SemanticEditScript[] | SemanticEditScript;
|
|
182
|
+
readonly semanticEditProjection?: SemanticEditProjection;
|
|
183
|
+
readonly semanticEditProjections?: readonly SemanticEditProjection[] | SemanticEditProjection;
|
|
167
184
|
readonly conflictKeys?: readonly string[] | string;
|
|
168
185
|
readonly admission?: Partial<SemanticPatchBundleAdmission>;
|
|
169
186
|
readonly metadata?: Record<string, unknown>;
|
|
@@ -206,6 +223,20 @@ export interface SemanticPatchBundleRecordQuery {
|
|
|
206
223
|
readonly historyIds?: readonly string[];
|
|
207
224
|
readonly semanticOperationId?: string | readonly string[];
|
|
208
225
|
readonly semanticOperationIds?: readonly string[];
|
|
226
|
+
readonly semanticEditScriptId?: string | readonly string[];
|
|
227
|
+
readonly semanticEditScriptIds?: readonly string[];
|
|
228
|
+
readonly semanticEditProjectionId?: string | readonly string[];
|
|
229
|
+
readonly semanticEditProjectionIds?: readonly string[];
|
|
230
|
+
readonly semanticEditKey?: string | readonly string[];
|
|
231
|
+
readonly semanticEditKeys?: readonly string[];
|
|
232
|
+
readonly semanticIdentityHash?: string | readonly string[];
|
|
233
|
+
readonly semanticIdentityHashes?: readonly string[];
|
|
234
|
+
readonly sourceIdentityHash?: string | readonly string[];
|
|
235
|
+
readonly sourceIdentityHashes?: readonly string[];
|
|
236
|
+
readonly operationContentHash?: string | readonly string[];
|
|
237
|
+
readonly operationContentHashes?: readonly string[];
|
|
238
|
+
readonly editContentHash?: string | readonly string[];
|
|
239
|
+
readonly editContentHashes?: readonly string[];
|
|
209
240
|
readonly readiness?: SemanticMergeReadiness | string | readonly string[];
|
|
210
241
|
readonly readinesses?: readonly string[];
|
|
211
242
|
readonly admissionStatus?: SemanticPatchBundleAdmissionStatus | readonly string[];
|
|
@@ -25,7 +25,7 @@ export function projectSemanticEditScriptToSource(input = {}) {
|
|
|
25
25
|
id: input.id ?? `semantic_edit_projection_${idFragment(script.id ?? script.hash ?? 'script')}`,
|
|
26
26
|
scriptId: script.id,
|
|
27
27
|
status: blocked ? 'blocked' : 'projected',
|
|
28
|
-
sourcePath: script
|
|
28
|
+
sourcePath: input.headSourcePath ?? projectedSourcePath(script, edits),
|
|
29
29
|
language: script.language,
|
|
30
30
|
baseHash: script.baseHash,
|
|
31
31
|
workerHash: script.workerHash,
|
|
@@ -54,8 +54,9 @@ export function projectSemanticEditScriptToSource(input = {}) {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
function sourceEditForOperation(operation, workerSourceText, headSourceText) {
|
|
57
|
+
const identity = projectionIdentity(operation);
|
|
57
58
|
if (operation.status === 'already-applied') {
|
|
58
|
-
return { ok: true, value: { ...
|
|
59
|
+
return { ok: true, value: { ...identity, operationId: operation.id, start: 0, end: 0, replacement: '', current: '', alreadyApplied: true } };
|
|
59
60
|
}
|
|
60
61
|
if (operation.status !== 'portable') return { ok: false, reasonCodes: [`operation-not-portable:${operation.id}`] };
|
|
61
62
|
const workerOffsets = spanOffsets(workerSourceText, operation.spans?.worker);
|
|
@@ -78,7 +79,7 @@ function sourceEditForOperation(operation, workerSourceText, headSourceText) {
|
|
|
78
79
|
ok: true,
|
|
79
80
|
value: {
|
|
80
81
|
operationId: operation.id,
|
|
81
|
-
...
|
|
82
|
+
...identity,
|
|
82
83
|
start: headOffsets.start,
|
|
83
84
|
end: headOffsets.end,
|
|
84
85
|
workerStart: workerOffsets.start,
|
|
@@ -89,6 +90,11 @@ function sourceEditForOperation(operation, workerSourceText, headSourceText) {
|
|
|
89
90
|
};
|
|
90
91
|
}
|
|
91
92
|
|
|
93
|
+
function projectionIdentity(operation) {
|
|
94
|
+
const identity = semanticEditIdentity(operation);
|
|
95
|
+
return { ...identity, sourcePath: operation.reanchor?.toSourcePath ?? identity.sourcePath };
|
|
96
|
+
}
|
|
97
|
+
|
|
92
98
|
function projectionEditRecord(edit) {
|
|
93
99
|
const deletedTextHash = hashSemanticValue(edit.current);
|
|
94
100
|
const replacementTextHash = hashSemanticValue(edit.replacement);
|
|
@@ -103,6 +109,11 @@ function projectionEditRecord(edit) {
|
|
|
103
109
|
regionId: edit.regionId,
|
|
104
110
|
regionKind: edit.regionKind,
|
|
105
111
|
sourcePath: edit.sourcePath,
|
|
112
|
+
originalSourcePath: edit.originalSourcePath,
|
|
113
|
+
targetAnchorKey: edit.targetAnchorKey,
|
|
114
|
+
targetSourcePath: edit.targetSourcePath,
|
|
115
|
+
targetSymbolName: edit.targetSymbolName,
|
|
116
|
+
targetSymbolKind: edit.targetSymbolKind,
|
|
106
117
|
symbolId: edit.symbolId,
|
|
107
118
|
symbolName: edit.symbolName,
|
|
108
119
|
symbolKind: edit.symbolKind,
|
|
@@ -136,6 +147,11 @@ function semanticEditIdentity(operation) {
|
|
|
136
147
|
regionId: anchor.regionId,
|
|
137
148
|
regionKind: anchor.regionKind,
|
|
138
149
|
sourcePath: anchor.sourcePath,
|
|
150
|
+
originalSourcePath: operation.reanchor?.toSourcePath ? anchor.sourcePath : undefined,
|
|
151
|
+
targetAnchorKey: operation.reanchor?.toAnchorKey,
|
|
152
|
+
targetSourcePath: operation.reanchor?.toSourcePath,
|
|
153
|
+
targetSymbolName: operation.reanchor?.toSymbolName,
|
|
154
|
+
targetSymbolKind: operation.reanchor?.toSymbolKind,
|
|
139
155
|
symbolId: anchor.symbolId,
|
|
140
156
|
symbolName: anchor.symbolName,
|
|
141
157
|
symbolKind: anchor.symbolKind,
|
|
@@ -152,6 +168,10 @@ function applySourceEdits(sourceText, edits) {
|
|
|
152
168
|
.reduce((text, edit) => text.slice(0, edit.start) + edit.replacement + text.slice(edit.end), sourceText);
|
|
153
169
|
}
|
|
154
170
|
|
|
171
|
+
function projectedSourcePath(script, edits) {
|
|
172
|
+
return edits.map((edit) => edit.sourcePath).find(Boolean) ?? script.sourcePath;
|
|
173
|
+
}
|
|
174
|
+
|
|
155
175
|
function spanOffsets(sourceText, span) {
|
|
156
176
|
if (typeof sourceText !== 'string' || !span) return undefined;
|
|
157
177
|
if (typeof span.start === 'number' && typeof span.end === 'number' && span.end >= span.start) return { start: span.start, end: span.end };
|
|
@@ -92,12 +92,15 @@ function classifyMissingHeadAnchor(input) {
|
|
|
92
92
|
? resolveSemanticLineage(input.context.headLineage.lineageMap, { anchorKey: input.anchorKey })
|
|
93
93
|
: undefined;
|
|
94
94
|
if (resolved?.status === 'resolved' && resolved.currentAnchors.length === 1) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
const target = resolved.currentAnchors[0];
|
|
96
|
+
const reanchor = reanchorRecord(input.anchorKey, target, resolved);
|
|
97
|
+
if (target.bodyHash && input.baseSymbol?.spanHash && target.bodyHash === input.baseSymbol.spanHash) {
|
|
98
|
+
return editStatus('portable', 'ready', 0.86, ['anchor-reanchored-head-matches-base'], reanchor, resolved.evidenceIds);
|
|
99
|
+
}
|
|
100
|
+
if (target.bodyHash && input.workerSymbol?.spanHash && target.bodyHash === input.workerSymbol.spanHash) {
|
|
101
|
+
return editStatus('already-applied', 'ready', 0.87, ['anchor-reanchored-head-matches-worker'], reanchor, resolved.evidenceIds);
|
|
102
|
+
}
|
|
103
|
+
return editStatus('needs-port', 'needs-review', 0.72, ['anchor-moved-or-renamed'], reanchor, resolved.evidenceIds);
|
|
101
104
|
}
|
|
102
105
|
if (resolved?.status === 'ambiguous') {
|
|
103
106
|
return editStatus('blocked', 'blocked', 0.1, ['anchor-lineage-ambiguous'], { fromAnchorKey: input.anchorKey, lineageStatus: resolved.status }, resolved.evidenceIds);
|
|
@@ -112,6 +115,18 @@ function editStatus(status, readiness, confidence, reasonCodes, reanchor, eviden
|
|
|
112
115
|
return { status, readiness, confidence, reasonCodes, reanchor, evidenceIds };
|
|
113
116
|
}
|
|
114
117
|
|
|
118
|
+
function reanchorRecord(fromAnchorKey, target, resolved) {
|
|
119
|
+
return {
|
|
120
|
+
fromAnchorKey,
|
|
121
|
+
toAnchorKey: target.key,
|
|
122
|
+
toSourcePath: target.sourcePath,
|
|
123
|
+
toSymbolName: target.symbolName,
|
|
124
|
+
toSymbolKind: target.kind,
|
|
125
|
+
lineageStatus: resolved.status,
|
|
126
|
+
traversedEventIds: resolved.traversedEventIds
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
115
130
|
function admissionStatus(summary) {
|
|
116
131
|
if (summary.operations === 0) return 'evidence-only';
|
|
117
132
|
if (summary.blocked > 0) return 'blocked';
|
|
@@ -132,8 +132,9 @@ function semanticEditOperation(region, index, context, input) {
|
|
|
132
132
|
const anchorKey = region.key ?? region.conflictKey ?? region.id;
|
|
133
133
|
const baseSymbol = context.baseSymbols.get(anchorKey);
|
|
134
134
|
const workerSymbol = context.workerSymbols.get(anchorKey);
|
|
135
|
-
const
|
|
136
|
-
const classification = classifySemanticEdit({ region, anchorKey, baseSymbol, workerSymbol, headSymbol, context });
|
|
135
|
+
const directHeadSymbol = context.headSymbols.get(anchorKey);
|
|
136
|
+
const classification = classifySemanticEdit({ region, anchorKey, baseSymbol, workerSymbol, headSymbol: directHeadSymbol, context });
|
|
137
|
+
const headSymbol = directHeadSymbol ?? reanchoredHeadSymbol(context, classification);
|
|
137
138
|
const kind = semanticEditOperationKind(region);
|
|
138
139
|
const baseText = spanText(context.base, baseSymbol?.sourceSpan ?? region.metadata?.changedRegionProjection?.before?.sourceSpan ?? region.sourceSpan);
|
|
139
140
|
const workerText = spanText(context.worker, workerSymbol?.sourceSpan ?? region.metadata?.changedRegionProjection?.after?.sourceSpan ?? region.sourceSpan);
|
|
@@ -192,6 +193,11 @@ function semanticEditOperation(region, index, context, input) {
|
|
|
192
193
|
});
|
|
193
194
|
}
|
|
194
195
|
|
|
196
|
+
function reanchoredHeadSymbol(context, classification) {
|
|
197
|
+
const targetKey = classification.reanchor?.toAnchorKey;
|
|
198
|
+
return targetKey ? context.headSymbols.get(targetKey) : undefined;
|
|
199
|
+
}
|
|
200
|
+
|
|
195
201
|
function semanticEditIdentityRecord(input) {
|
|
196
202
|
return {
|
|
197
203
|
kind: input.kind,
|
|
@@ -6,6 +6,9 @@ export function createSemanticPatchBundleRecord(input={},options={}){
|
|
|
6
6
|
const source=input?.changeSet??input;
|
|
7
7
|
const patch=options.patch??source.patch??source.semanticPatch??source.patchBundle;
|
|
8
8
|
const mergeCandidate=options.mergeCandidate??source.mergeCandidate??source.candidate;
|
|
9
|
+
const semanticEditScripts=array(options.semanticEditScripts??source.semanticEditScripts??source.semanticEditScript);
|
|
10
|
+
const semanticEditProjections=array(options.semanticEditProjections??source.semanticEditProjections??source.semanticEditProjection);
|
|
11
|
+
const semanticEditIndex=semanticEditRecordIndex(semanticEditScripts,semanticEditProjections,source);
|
|
9
12
|
const regionInputs=array(options.changedRegions??source.changedRegions??source.regions);
|
|
10
13
|
const sourceMapLinks=normalizeSourceMapLinks([
|
|
11
14
|
...array(options.sourceMapLinks??source.sourceMapLinks),
|
|
@@ -17,7 +20,7 @@ export function createSemanticPatchBundleRecord(input={},options={}){
|
|
|
17
20
|
sourceRef(source.before,'before',source.beforeHash),
|
|
18
21
|
sourceRef(source.after,'after',source.afterHash)
|
|
19
22
|
],source);
|
|
20
|
-
const evidenceRecords=[...array(options.evidence??source.evidence),...array(patch?.evidence),...array(mergeCandidate?.evidence)];
|
|
23
|
+
const evidenceRecords=[...array(options.evidence??source.evidence),...array(patch?.evidence),...array(mergeCandidate?.evidence),...semanticEditScripts.flatMap((script)=>array(script.evidence))];
|
|
21
24
|
const patchId=firstString(options.patchId,source.patchId,patch?.id,mergeCandidate?.patchId);
|
|
22
25
|
const mergeCandidateId=firstString(options.mergeCandidateId,source.mergeCandidateId,mergeCandidate?.id);
|
|
23
26
|
const baseHash=firstString(options.baseHash,source.baseHash,source.beforeHash,patch?.baseHash,mergeCandidate?.baseHash,...sources.map((item)=>item.baseHash));
|
|
@@ -27,7 +30,7 @@ export function createSemanticPatchBundleRecord(input={},options={}){
|
|
|
27
30
|
const evidenceIds=uniqueStrings([...strings(options.evidenceIds),...strings(source.evidenceIds),...evidenceRecords.map((record)=>record?.id),...strings(mergeCandidate?.evidenceIds)]);
|
|
28
31
|
const proofIds=uniqueStrings([...strings(options.proofIds),...strings(source.proofIds),...evidenceRecords.filter((record)=>record?.kind==='proof').map((record)=>record.id),...strings(mergeCandidate?.proofIds)]);
|
|
29
32
|
const historyIds=uniqueStrings([...strings(options.historyIds),...strings(options.historyId),...strings(source.historyIds),...strings(source.historyId)]);
|
|
30
|
-
const semanticOperationIds=uniqueStrings([...strings(options.semanticOperationIds),...strings(options.semanticOperationId),...strings(source.semanticOperationIds),...strings(source.semanticOperationId),...strings(patch?.semanticOperationIds),...strings(mergeCandidate?.semanticOperationIds)]);
|
|
33
|
+
const semanticOperationIds=uniqueStrings([...strings(options.semanticOperationIds),...strings(options.semanticOperationId),...strings(source.semanticOperationIds),...strings(source.semanticOperationId),...strings(patch?.semanticOperationIds),...strings(mergeCandidate?.semanticOperationIds),...semanticEditIndex.semanticEditOperationIds]);
|
|
31
34
|
const conflictKeys=uniqueStrings([
|
|
32
35
|
...strings(options.conflictKeys),
|
|
33
36
|
...strings(source.conflictKeys),
|
|
@@ -40,7 +43,7 @@ export function createSemanticPatchBundleRecord(input={},options={}){
|
|
|
40
43
|
??`semantic_patch_bundle_${idFragment(firstString(source.id,patchId,mergeCandidateId,source.sourcePath,source.language,'record'))}`;
|
|
41
44
|
const language=options.language??source.language??mergeCandidate?.language??sources.find((item)=>item.language)?.language;
|
|
42
45
|
const sourcePath=options.sourcePath??source.sourcePath??mergeCandidate?.sourcePath??sources.find((item)=>item.sourcePath)?.sourcePath;
|
|
43
|
-
const index=recordIndex({baseHash,targetHash,sources,changedRegions,sourceMapLinks,evidenceIds,proofIds,historyIds,semanticOperationIds,patchId,mergeCandidateId,admission});
|
|
46
|
+
const index=recordIndex({baseHash,targetHash,sources,changedRegions,sourceMapLinks,evidenceIds,proofIds,historyIds,semanticOperationIds,patchId,mergeCandidateId,admission,semanticEditIndex});
|
|
44
47
|
return{
|
|
45
48
|
kind:'frontier.lang.semanticPatchBundleRecord',
|
|
46
49
|
version:1,
|
|
@@ -60,15 +63,18 @@ export function createSemanticPatchBundleRecord(input={},options={}){
|
|
|
60
63
|
proofIds,
|
|
61
64
|
historyIds,
|
|
62
65
|
semanticOperationIds,
|
|
66
|
+
semanticEditScriptIds:semanticEditIndex.semanticEditScriptIds,
|
|
67
|
+
semanticEditProjectionIds:semanticEditIndex.semanticEditProjectionIds,
|
|
63
68
|
admission,
|
|
64
69
|
index,
|
|
65
|
-
summary:{changedRegions:changedRegions.length,sourceMapLinks:sourceMapLinks.length,evidenceIds:evidenceIds.length,proofIds:proofIds.length,historyIds:historyIds.length,semanticOperations:semanticOperationIds.length,reviewRequired:admission.reviewRequired,autoMergeClaim:admission.autoMergeClaim},
|
|
70
|
+
summary:{changedRegions:changedRegions.length,sourceMapLinks:sourceMapLinks.length,evidenceIds:evidenceIds.length,proofIds:proofIds.length,historyIds:historyIds.length,semanticOperations:semanticOperationIds.length,semanticEditScripts:semanticEditScripts.length,semanticEditProjections:semanticEditProjections.length,semanticEditProjectionEdits:semanticEditIndex.semanticEditProjectionEditCount,reviewRequired:admission.reviewRequired,autoMergeClaim:admission.autoMergeClaim},
|
|
66
71
|
metadata:compactRecord({
|
|
67
72
|
sourceChangeSetId:source.kind==='frontier.lang.nativeSourceChangeSet'?source.id:undefined,
|
|
68
73
|
patchRisk:patch?.risk,
|
|
69
74
|
nativeChangeSummary:source.summary,
|
|
70
75
|
changedRegionProjectionSummary:source.metadata?.changedRegionProjectionSummary,
|
|
71
76
|
semanticMergeConflictSummary:source.metadata?.semanticMergeConflictSummary,
|
|
77
|
+
semanticEditSummary:semanticEditSummary(semanticEditIndex),
|
|
72
78
|
...options.metadata
|
|
73
79
|
})
|
|
74
80
|
};
|
|
@@ -190,14 +196,15 @@ function normalizeAdmission(input={},context){
|
|
|
190
196
|
}
|
|
191
197
|
|
|
192
198
|
function recordIndex(parts){
|
|
199
|
+
const semanticEditIndex=parts.semanticEditIndex??semanticEditRecordIndex([],[]);
|
|
193
200
|
return{
|
|
194
201
|
baseHashes:uniqueStrings([parts.baseHash,...parts.sources.map((item)=>item.baseHash)]),
|
|
195
202
|
targetHashes:uniqueStrings([parts.targetHash,...parts.sources.map((item)=>item.targetHash)]),
|
|
196
203
|
sourceHashes:uniqueStrings(parts.sources.map((item)=>item.sourceHash)),
|
|
197
|
-
sourcePaths:uniqueStrings(parts.sources.map((item)=>item.sourcePath)),
|
|
198
|
-
regionKeys:uniqueStrings(parts.changedRegions.map((region)=>region.key)),
|
|
204
|
+
sourcePaths:uniqueStrings([...parts.sources.map((item)=>item.sourcePath),...semanticEditIndex.projectedSourcePaths]),
|
|
205
|
+
regionKeys:uniqueStrings([...parts.changedRegions.map((region)=>region.key),...semanticEditIndex.anchorKeys]),
|
|
199
206
|
regionKinds:uniqueStrings(parts.changedRegions.map((region)=>region.regionKind)),
|
|
200
|
-
conflictKeys:uniqueStrings(parts.changedRegions.flatMap((region)=>[region.conflictKey,...array(region.admission?.conflictKeys)])),
|
|
207
|
+
conflictKeys:uniqueStrings([...parts.changedRegions.flatMap((region)=>[region.conflictKey,...array(region.admission?.conflictKeys)]),...semanticEditIndex.conflictKeys]),
|
|
201
208
|
sourceMapIds:uniqueStrings([...parts.sourceMapLinks.map((link)=>link.sourceMapId),...parts.changedRegions.flatMap((region)=>region.sourceMapIds??[])]),
|
|
202
209
|
sourceMapMappingIds:uniqueStrings([...parts.sourceMapLinks.map((link)=>link.sourceMapMappingId),...parts.changedRegions.flatMap((region)=>region.sourceMapMappingIds??[])]),
|
|
203
210
|
sourceMapLinkIds:uniqueStrings(parts.sourceMapLinks.map((link)=>link.id)),
|
|
@@ -205,6 +212,13 @@ function recordIndex(parts){
|
|
|
205
212
|
proofIds:parts.proofIds,
|
|
206
213
|
historyIds:parts.historyIds,
|
|
207
214
|
semanticOperationIds:uniqueStrings(parts.semanticOperationIds),
|
|
215
|
+
semanticEditScriptIds:semanticEditIndex.semanticEditScriptIds,
|
|
216
|
+
semanticEditProjectionIds:semanticEditIndex.semanticEditProjectionIds,
|
|
217
|
+
semanticEditKeys:semanticEditIndex.semanticEditKeys,
|
|
218
|
+
semanticIdentityHashes:semanticEditIndex.semanticIdentityHashes,
|
|
219
|
+
sourceIdentityHashes:semanticEditIndex.sourceIdentityHashes,
|
|
220
|
+
operationContentHashes:semanticEditIndex.operationContentHashes,
|
|
221
|
+
editContentHashes:semanticEditIndex.editContentHashes,
|
|
208
222
|
patchIds:uniqueStrings([parts.patchId]),
|
|
209
223
|
mergeCandidateIds:uniqueStrings([parts.mergeCandidateId]),
|
|
210
224
|
readinesses:uniqueStrings([parts.admission.readiness,...parts.changedRegions.map((region)=>region.admission?.readiness)]),
|
|
@@ -231,11 +245,48 @@ function matchesRecord(record,query){
|
|
|
231
245
|
&&matchAny(queryValues(query.proofId,query.proofIds),index.proofIds)
|
|
232
246
|
&&matchAny(queryValues(query.historyId,query.historyIds),index.historyIds)
|
|
233
247
|
&&matchAny(queryValues(query.semanticOperationId,query.semanticOperationIds),index.semanticOperationIds)
|
|
248
|
+
&&matchAny(queryValues(query.semanticEditScriptId,query.semanticEditScriptIds),index.semanticEditScriptIds)
|
|
249
|
+
&&matchAny(queryValues(query.semanticEditProjectionId,query.semanticEditProjectionIds),index.semanticEditProjectionIds)
|
|
250
|
+
&&matchAny(queryValues(query.semanticEditKey,query.semanticEditKeys),index.semanticEditKeys)
|
|
251
|
+
&&matchAny(queryValues(query.semanticIdentityHash,query.semanticIdentityHashes),index.semanticIdentityHashes)
|
|
252
|
+
&&matchAny(queryValues(query.sourceIdentityHash,query.sourceIdentityHashes),index.sourceIdentityHashes)
|
|
253
|
+
&&matchAny(queryValues(query.operationContentHash,query.operationContentHashes),index.operationContentHashes)
|
|
254
|
+
&&matchAny(queryValues(query.editContentHash,query.editContentHashes),index.editContentHashes)
|
|
234
255
|
&&matchAny(queryValues(query.readiness,query.readinesses),index.readinesses)
|
|
235
256
|
&&matchAny(queryValues(query.admissionStatus,query.admissionStatuses),index.admissionStatuses);
|
|
236
257
|
}
|
|
237
258
|
|
|
238
259
|
function admissionStatusForReadiness(readiness){return readiness==='blocked'?'blocked':readiness==='needs-review'?'needs-review':'proposed';}
|
|
260
|
+
function semanticEditRecordIndex(scripts,projections,source={}){
|
|
261
|
+
const operations=scripts.flatMap((script)=>array(script.operations));
|
|
262
|
+
const edits=projections.flatMap((projection)=>array(projection.edits));
|
|
263
|
+
const index=source.index??{};
|
|
264
|
+
return{
|
|
265
|
+
semanticEditScriptIds:uniqueStrings([...strings(source.semanticEditScriptIds),...strings(source.semanticEditScriptId),...strings(index.semanticEditScriptIds),...scripts.map((script)=>script.id)]),
|
|
266
|
+
semanticEditProjectionIds:uniqueStrings([...strings(source.semanticEditProjectionIds),...strings(source.semanticEditProjectionId),...strings(index.semanticEditProjectionIds),...projections.map((projection)=>projection.id)]),
|
|
267
|
+
semanticEditOperationIds:uniqueStrings([...strings(source.semanticOperationIds),...strings(index.semanticOperationIds),...operations.map((operation)=>operation.id)]),
|
|
268
|
+
semanticEditProjectionEditCount:edits.length,
|
|
269
|
+
semanticEditKeys:uniqueStrings([...strings(source.semanticEditKeys),...strings(index.semanticEditKeys),...operations.map((operation)=>operation.semanticKey),...edits.map((edit)=>edit.semanticKey)]),
|
|
270
|
+
semanticIdentityHashes:uniqueStrings([...strings(source.semanticIdentityHashes),...strings(index.semanticIdentityHashes),...operations.map((operation)=>operation.semanticIdentityHash),...edits.map((edit)=>edit.semanticIdentityHash)]),
|
|
271
|
+
sourceIdentityHashes:uniqueStrings([...strings(source.sourceIdentityHashes),...strings(index.sourceIdentityHashes),...operations.map((operation)=>operation.sourceIdentityHash),...edits.map((edit)=>edit.sourceIdentityHash)]),
|
|
272
|
+
operationContentHashes:uniqueStrings([...strings(source.operationContentHashes),...strings(index.operationContentHashes),...operations.map((operation)=>operation.operationContentHash),...edits.map((edit)=>edit.operationContentHash)]),
|
|
273
|
+
editContentHashes:uniqueStrings([...strings(source.editContentHashes),...strings(index.editContentHashes),...edits.map((edit)=>edit.editContentHash)]),
|
|
274
|
+
anchorKeys:uniqueStrings([...operations.map((operation)=>operation.anchor?.key),...edits.map((edit)=>edit.anchorKey)]),
|
|
275
|
+
conflictKeys:uniqueStrings([...operations.map((operation)=>operation.anchor?.conflictKey),...edits.map((edit)=>edit.conflictKey)]),
|
|
276
|
+
projectedSourcePaths:uniqueStrings([...projections.map((projection)=>projection.sourcePath),...edits.flatMap((edit)=>[edit.sourcePath,edit.targetSourcePath])])
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
function semanticEditSummary(index){
|
|
280
|
+
if(!index.semanticEditScriptIds.length&&!index.semanticEditProjectionIds.length)return undefined;
|
|
281
|
+
return compactRecord({
|
|
282
|
+
scriptIds:index.semanticEditScriptIds,
|
|
283
|
+
projectionIds:index.semanticEditProjectionIds,
|
|
284
|
+
semanticEditKeys:index.semanticEditKeys,
|
|
285
|
+
operationContentHashes:index.operationContentHashes,
|
|
286
|
+
editContentHashes:index.editContentHashes,
|
|
287
|
+
projectedSourcePaths:index.projectedSourcePaths
|
|
288
|
+
});
|
|
289
|
+
}
|
|
239
290
|
function queryValues(...values){return uniqueStrings(values.flatMap((value)=>strings(value)));}
|
|
240
291
|
function matchAny(filters,values){if(filters.length===0)return true;const valueSet=new Set(strings(values));return filters.some((filter)=>valueSet.has(filter));}
|
|
241
292
|
function array(value){if(value===undefined||value===null)return[];return Array.isArray(value)?value:[value];}
|
package/package.json
CHANGED