@shapeshift-labs/frontier-lang-compiler 0.2.86 → 0.2.88
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-patch-bundle-overlaps.d.ts +112 -0
- package/dist/declarations/semantic-patch-bundle.d.ts +31 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/internal/index-impl/semanticPatchBundleOverlaps.js +173 -0
- package/dist/internal/index-impl/semanticPatchBundleRecords.js +58 -7
- package/package.json +1 -1
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { SemanticPatchBundleRecord } from './semantic-patch-bundle.js';
|
|
2
|
+
|
|
3
|
+
export type SemanticPatchBundleOverlapKind =
|
|
4
|
+
| 'operation-content'
|
|
5
|
+
| 'edit-content'
|
|
6
|
+
| 'semantic-edit-key'
|
|
7
|
+
| 'semantic-identity'
|
|
8
|
+
| 'source-identity'
|
|
9
|
+
| 'region'
|
|
10
|
+
| 'conflict-key'
|
|
11
|
+
| 'source-path'
|
|
12
|
+
| string;
|
|
13
|
+
|
|
14
|
+
export type SemanticPatchBundleOverlapStatus =
|
|
15
|
+
| 'duplicate'
|
|
16
|
+
| 'semantic-overlap'
|
|
17
|
+
| 'source-overlap'
|
|
18
|
+
| 'independent'
|
|
19
|
+
| string;
|
|
20
|
+
|
|
21
|
+
export interface SemanticPatchBundleOverlapShared {
|
|
22
|
+
readonly operationContentHashes: readonly string[];
|
|
23
|
+
readonly editContentHashes: readonly string[];
|
|
24
|
+
readonly semanticEditKeys: readonly string[];
|
|
25
|
+
readonly semanticIdentityHashes: readonly string[];
|
|
26
|
+
readonly sourceIdentityHashes: readonly string[];
|
|
27
|
+
readonly regionKeys: readonly string[];
|
|
28
|
+
readonly conflictKeys: readonly string[];
|
|
29
|
+
readonly sourcePaths: readonly string[];
|
|
30
|
+
readonly baseHashes: readonly string[];
|
|
31
|
+
readonly targetHashes: readonly string[];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface SemanticPatchBundleOverlapAdmission {
|
|
35
|
+
readonly status: SemanticPatchBundleOverlapStatus;
|
|
36
|
+
readonly reviewRequired: boolean;
|
|
37
|
+
readonly autoMergeClaim: false;
|
|
38
|
+
readonly reasonCodes: readonly string[];
|
|
39
|
+
readonly sharedKeyCount: number;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface SemanticPatchBundleOverlapRecord {
|
|
43
|
+
readonly kind: 'frontier.lang.semanticPatchBundleOverlapRecord';
|
|
44
|
+
readonly version: 1;
|
|
45
|
+
readonly schema: 'frontier.lang.semanticPatchBundleOverlapRecord.v1';
|
|
46
|
+
readonly id: string;
|
|
47
|
+
readonly leftBundleId: string;
|
|
48
|
+
readonly rightBundleId: string;
|
|
49
|
+
readonly overlapKinds: readonly SemanticPatchBundleOverlapKind[];
|
|
50
|
+
readonly shared: SemanticPatchBundleOverlapShared;
|
|
51
|
+
readonly admission: SemanticPatchBundleOverlapAdmission;
|
|
52
|
+
readonly score: number;
|
|
53
|
+
readonly summary: {
|
|
54
|
+
readonly sharedKeys: number;
|
|
55
|
+
readonly duplicateSignals: number;
|
|
56
|
+
readonly semanticSignals: number;
|
|
57
|
+
readonly sourceSignals: number;
|
|
58
|
+
readonly baseHashMismatch: boolean;
|
|
59
|
+
readonly targetHashMismatch: boolean;
|
|
60
|
+
};
|
|
61
|
+
readonly metadata?: Record<string, unknown>;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface CompareSemanticPatchBundleRecordsOptions {
|
|
65
|
+
readonly id?: string;
|
|
66
|
+
readonly includeSourcePaths?: boolean;
|
|
67
|
+
readonly reviewIndependent?: boolean;
|
|
68
|
+
readonly metadata?: Record<string, unknown>;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface SemanticPatchBundleOverlapQuery {
|
|
72
|
+
readonly includeIndependent?: boolean;
|
|
73
|
+
readonly includeSourcePaths?: boolean;
|
|
74
|
+
readonly reviewIndependent?: boolean;
|
|
75
|
+
readonly metadata?: Record<string, unknown>;
|
|
76
|
+
readonly id?: string | readonly string[];
|
|
77
|
+
readonly ids?: readonly string[];
|
|
78
|
+
readonly bundleId?: string | readonly string[];
|
|
79
|
+
readonly bundleIds?: readonly string[];
|
|
80
|
+
readonly status?: SemanticPatchBundleOverlapStatus | readonly string[];
|
|
81
|
+
readonly statuses?: readonly string[];
|
|
82
|
+
readonly admissionStatus?: SemanticPatchBundleOverlapStatus | readonly string[];
|
|
83
|
+
readonly admissionStatuses?: readonly string[];
|
|
84
|
+
readonly overlapKind?: SemanticPatchBundleOverlapKind | readonly string[];
|
|
85
|
+
readonly overlapKinds?: readonly string[];
|
|
86
|
+
readonly reasonCode?: string | readonly string[];
|
|
87
|
+
readonly reasonCodes?: readonly string[];
|
|
88
|
+
readonly sourcePath?: string | readonly string[];
|
|
89
|
+
readonly sourcePaths?: readonly string[];
|
|
90
|
+
readonly conflictKey?: string | readonly string[];
|
|
91
|
+
readonly conflictKeys?: readonly string[];
|
|
92
|
+
readonly semanticEditKey?: string | readonly string[];
|
|
93
|
+
readonly semanticEditKeys?: readonly string[];
|
|
94
|
+
readonly operationContentHash?: string | readonly string[];
|
|
95
|
+
readonly operationContentHashes?: readonly string[];
|
|
96
|
+
readonly editContentHash?: string | readonly string[];
|
|
97
|
+
readonly editContentHashes?: readonly string[];
|
|
98
|
+
readonly reviewRequired?: boolean;
|
|
99
|
+
readonly minScore?: number;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export declare const SemanticPatchBundleOverlapKinds: readonly SemanticPatchBundleOverlapKind[];
|
|
103
|
+
export declare const SemanticPatchBundleOverlapStatuses: readonly SemanticPatchBundleOverlapStatus[];
|
|
104
|
+
export declare function compareSemanticPatchBundleRecords(
|
|
105
|
+
left?: SemanticPatchBundleRecord | Record<string, unknown>,
|
|
106
|
+
right?: SemanticPatchBundleRecord | Record<string, unknown>,
|
|
107
|
+
options?: CompareSemanticPatchBundleRecordsOptions
|
|
108
|
+
): SemanticPatchBundleOverlapRecord;
|
|
109
|
+
export declare function querySemanticPatchBundleOverlaps(
|
|
110
|
+
records: SemanticPatchBundleRecord | readonly SemanticPatchBundleRecord[],
|
|
111
|
+
query?: SemanticPatchBundleOverlapQuery
|
|
112
|
+
): readonly SemanticPatchBundleOverlapRecord[];
|
|
@@ -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[];
|
package/dist/index.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ export * from './declarations/semantic-edit-script.js';
|
|
|
20
20
|
export * from './declarations/semantic-lineage.js';
|
|
21
21
|
export * from './declarations/semantic-history.js';
|
|
22
22
|
export * from './declarations/semantic-patch-bundle.js';
|
|
23
|
+
export * from './declarations/semantic-patch-bundle-overlaps.js';
|
|
23
24
|
export * from './declarations/bidirectional-target-change.js';
|
|
24
25
|
export * from './declarations/semantic-impact.js';
|
|
25
26
|
export * from './declarations/semantic-sidecar.js';
|
package/dist/index.js
CHANGED
|
@@ -67,6 +67,7 @@ export { projectNativeImportToSource } from './internal/index-impl/projectNative
|
|
|
67
67
|
export { queryNativeParserFeatureMatrix } from './internal/index-impl/queryNativeParserFeatureMatrix.js';
|
|
68
68
|
export { queryProjectionReadinessMatrix } from './internal/index-impl/queryProjectionReadinessMatrix.js';
|
|
69
69
|
export { createSemanticPatchBundleRecord, querySemanticPatchBundleRecords, SemanticPatchBundleAdmissionStatuses } from './internal/index-impl/semanticPatchBundleRecords.js';
|
|
70
|
+
export { compareSemanticPatchBundleRecords, querySemanticPatchBundleOverlaps, SemanticPatchBundleOverlapKinds, SemanticPatchBundleOverlapStatuses } from './internal/index-impl/semanticPatchBundleOverlaps.js';
|
|
70
71
|
export { createSemanticMergeCandidateAdmissionRecord, decorateSemanticMergeCandidateForAdmission, querySemanticMergeCandidateAdmissionOverlaps, SemanticMergeCandidateProjectionRisks, semanticMergeCandidateReadinessSortKey, sortSemanticMergeCandidateAdmissionRecords } from './internal/index-impl/semanticMergeCandidateRecords.js';
|
|
71
72
|
export { querySemanticMergeConflictClasses, SemanticMergeConflictClasses, semanticMergeConflictRiskScore, sortSemanticMergeCandidatesByConflictRisk, summarizeSemanticMergeConflicts } from './internal/index-impl/semanticMergeConflicts.js';
|
|
72
73
|
export { createSemanticEditScript, SemanticEditScriptAdmissionStatuses } from './internal/index-impl/semanticEditScripts.js';
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import{idFragment,uniqueStrings as uniqueRawStrings}from'../../native-import-utils.js';
|
|
2
|
+
|
|
3
|
+
export const SemanticPatchBundleOverlapKinds=Object.freeze([
|
|
4
|
+
'operation-content',
|
|
5
|
+
'edit-content',
|
|
6
|
+
'semantic-edit-key',
|
|
7
|
+
'semantic-identity',
|
|
8
|
+
'source-identity',
|
|
9
|
+
'region',
|
|
10
|
+
'conflict-key',
|
|
11
|
+
'source-path'
|
|
12
|
+
]);
|
|
13
|
+
|
|
14
|
+
export const SemanticPatchBundleOverlapStatuses=Object.freeze([
|
|
15
|
+
'duplicate',
|
|
16
|
+
'semantic-overlap',
|
|
17
|
+
'source-overlap',
|
|
18
|
+
'independent'
|
|
19
|
+
]);
|
|
20
|
+
|
|
21
|
+
const KIND_FIELDS=Object.freeze({
|
|
22
|
+
'operation-content':'operationContentHashes',
|
|
23
|
+
'edit-content':'editContentHashes',
|
|
24
|
+
'semantic-edit-key':'semanticEditKeys',
|
|
25
|
+
'semantic-identity':'semanticIdentityHashes',
|
|
26
|
+
'source-identity':'sourceIdentityHashes',
|
|
27
|
+
region:'regionKeys',
|
|
28
|
+
'conflict-key':'conflictKeys',
|
|
29
|
+
'source-path':'sourcePaths'
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
export function compareSemanticPatchBundleRecords(left={},right={},options={}){
|
|
33
|
+
const leftIndex=bundleIndex(left);
|
|
34
|
+
const rightIndex=bundleIndex(right);
|
|
35
|
+
const shared=sharedIndex(leftIndex,rightIndex,options);
|
|
36
|
+
const overlapKinds=SemanticPatchBundleOverlapKinds
|
|
37
|
+
.filter((kind)=>shared[KIND_FIELDS[kind]]?.length);
|
|
38
|
+
const admission=overlapAdmission(shared,{leftIndex,rightIndex,options});
|
|
39
|
+
return{
|
|
40
|
+
kind:'frontier.lang.semanticPatchBundleOverlapRecord',
|
|
41
|
+
version:1,
|
|
42
|
+
schema:'frontier.lang.semanticPatchBundleOverlapRecord.v1',
|
|
43
|
+
id:options.id??`semantic_patch_bundle_overlap_${idFragment(left?.id??'left')}_${idFragment(right?.id??'right')}`,
|
|
44
|
+
leftBundleId:String(left?.id??'left'),
|
|
45
|
+
rightBundleId:String(right?.id??'right'),
|
|
46
|
+
overlapKinds,
|
|
47
|
+
shared,
|
|
48
|
+
admission,
|
|
49
|
+
score:overlapScore(admission.status,shared,admission.reasonCodes),
|
|
50
|
+
summary:{
|
|
51
|
+
sharedKeys:countShared(shared),
|
|
52
|
+
duplicateSignals:shared.operationContentHashes.length+shared.editContentHashes.length,
|
|
53
|
+
semanticSignals:shared.semanticEditKeys.length+shared.semanticIdentityHashes.length+shared.sourceIdentityHashes.length,
|
|
54
|
+
sourceSignals:shared.regionKeys.length+shared.conflictKeys.length+shared.sourcePaths.length,
|
|
55
|
+
baseHashMismatch:admission.reasonCodes.includes('base-hash-mismatch'),
|
|
56
|
+
targetHashMismatch:admission.reasonCodes.includes('target-hash-mismatch')
|
|
57
|
+
},
|
|
58
|
+
metadata:compactRecord(options.metadata)
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function querySemanticPatchBundleOverlaps(records,query={}){
|
|
63
|
+
const list=array(records).filter(Boolean);
|
|
64
|
+
const result=[];
|
|
65
|
+
const compareOptions={
|
|
66
|
+
includeSourcePaths:query.includeSourcePaths,
|
|
67
|
+
reviewIndependent:query.reviewIndependent,
|
|
68
|
+
metadata:query.metadata
|
|
69
|
+
};
|
|
70
|
+
for(let leftIndex=0;leftIndex<list.length;leftIndex+=1){
|
|
71
|
+
for(let rightIndex=leftIndex+1;rightIndex<list.length;rightIndex+=1){
|
|
72
|
+
const overlap=compareSemanticPatchBundleRecords(list[leftIndex],list[rightIndex],compareOptions);
|
|
73
|
+
if(matchesOverlap(overlap,query))result.push(overlap);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return result.sort((left,right)=>right.score-left.score||left.leftBundleId.localeCompare(right.leftBundleId)
|
|
77
|
+
||left.rightBundleId.localeCompare(right.rightBundleId));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function sharedIndex(left,right,options){
|
|
81
|
+
return{
|
|
82
|
+
operationContentHashes:intersect(left.operationContentHashes,right.operationContentHashes),
|
|
83
|
+
editContentHashes:intersect(left.editContentHashes,right.editContentHashes),
|
|
84
|
+
semanticEditKeys:intersect(left.semanticEditKeys,right.semanticEditKeys),
|
|
85
|
+
semanticIdentityHashes:intersect(left.semanticIdentityHashes,right.semanticIdentityHashes),
|
|
86
|
+
sourceIdentityHashes:intersect(left.sourceIdentityHashes,right.sourceIdentityHashes),
|
|
87
|
+
regionKeys:intersect(left.regionKeys,right.regionKeys),
|
|
88
|
+
conflictKeys:intersect(left.conflictKeys,right.conflictKeys),
|
|
89
|
+
sourcePaths:options.includeSourcePaths===false?[]:intersect(left.sourcePaths,right.sourcePaths),
|
|
90
|
+
baseHashes:intersect(left.baseHashes,right.baseHashes),
|
|
91
|
+
targetHashes:intersect(left.targetHashes,right.targetHashes)
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function overlapAdmission(shared,{leftIndex,rightIndex,options}){
|
|
96
|
+
const duplicate=shared.operationContentHashes.length||shared.editContentHashes.length;
|
|
97
|
+
const semantic=shared.semanticEditKeys.length||shared.semanticIdentityHashes.length||shared.sourceIdentityHashes.length;
|
|
98
|
+
const source=shared.regionKeys.length||shared.conflictKeys.length||shared.sourcePaths.length;
|
|
99
|
+
const status=duplicate?'duplicate':semantic?'semantic-overlap':source?'source-overlap':'independent';
|
|
100
|
+
const reasonCodes=uniqueStrings([
|
|
101
|
+
shared.operationContentHashes.length?'same-operation-content':undefined,
|
|
102
|
+
shared.editContentHashes.length?'same-edit-content':undefined,
|
|
103
|
+
shared.semanticEditKeys.length?'same-semantic-edit-key':undefined,
|
|
104
|
+
shared.semanticIdentityHashes.length?'same-semantic-identity':undefined,
|
|
105
|
+
shared.sourceIdentityHashes.length?'same-source-identity':undefined,
|
|
106
|
+
shared.regionKeys.length?'same-region-key':undefined,
|
|
107
|
+
shared.conflictKeys.length?'same-conflict-key':undefined,
|
|
108
|
+
shared.sourcePaths.length?'same-source-path':undefined,
|
|
109
|
+
status!=='independent'&&disjointNonEmpty(leftIndex.baseHashes,rightIndex.baseHashes)?'base-hash-mismatch':undefined,
|
|
110
|
+
status!=='independent'&&disjointNonEmpty(leftIndex.targetHashes,rightIndex.targetHashes)?'target-hash-mismatch':undefined
|
|
111
|
+
]);
|
|
112
|
+
return{
|
|
113
|
+
status,
|
|
114
|
+
reviewRequired:options.reviewIndependent?true:status!=='independent',
|
|
115
|
+
autoMergeClaim:false,
|
|
116
|
+
reasonCodes,
|
|
117
|
+
sharedKeyCount:countShared(shared)
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function bundleIndex(record){
|
|
122
|
+
const index=record?.index??{};
|
|
123
|
+
return{
|
|
124
|
+
baseHashes:uniqueStrings([record?.baseHash,...strings(index.baseHashes)]),
|
|
125
|
+
targetHashes:uniqueStrings([record?.targetHash,...strings(index.targetHashes)]),
|
|
126
|
+
sourcePaths:uniqueStrings([record?.sourcePath,...strings(index.sourcePaths)]),
|
|
127
|
+
regionKeys:uniqueStrings(index.regionKeys),
|
|
128
|
+
conflictKeys:uniqueStrings(index.conflictKeys),
|
|
129
|
+
semanticEditKeys:uniqueStrings(index.semanticEditKeys),
|
|
130
|
+
semanticIdentityHashes:uniqueStrings(index.semanticIdentityHashes),
|
|
131
|
+
sourceIdentityHashes:uniqueStrings(index.sourceIdentityHashes),
|
|
132
|
+
operationContentHashes:uniqueStrings(index.operationContentHashes),
|
|
133
|
+
editContentHashes:uniqueStrings(index.editContentHashes)
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function matchesOverlap(overlap,query){
|
|
138
|
+
const statusFilters=queryValues(query.status,query.statuses,query.admissionStatus,query.admissionStatuses);
|
|
139
|
+
const includeIndependent=query.includeIndependent===true||statusFilters.includes('independent');
|
|
140
|
+
if(!includeIndependent&&overlap.admission.status==='independent')return false;
|
|
141
|
+
return matchAny(queryValues(query.id,query.ids),[overlap.id])
|
|
142
|
+
&&matchAny(queryValues(query.bundleId,query.bundleIds),[overlap.leftBundleId,overlap.rightBundleId])
|
|
143
|
+
&&matchAny(statusFilters,[overlap.admission.status])
|
|
144
|
+
&&matchAny(queryValues(query.overlapKind,query.overlapKinds),overlap.overlapKinds)
|
|
145
|
+
&&matchAny(queryValues(query.reasonCode,query.reasonCodes),overlap.admission.reasonCodes)
|
|
146
|
+
&&matchAny(queryValues(query.sourcePath,query.sourcePaths),overlap.shared.sourcePaths)
|
|
147
|
+
&&matchAny(queryValues(query.conflictKey,query.conflictKeys),overlap.shared.conflictKeys)
|
|
148
|
+
&&matchAny(queryValues(query.semanticEditKey,query.semanticEditKeys),overlap.shared.semanticEditKeys)
|
|
149
|
+
&&matchAny(queryValues(query.operationContentHash,query.operationContentHashes),overlap.shared.operationContentHashes)
|
|
150
|
+
&&matchAny(queryValues(query.editContentHash,query.editContentHashes),overlap.shared.editContentHashes)
|
|
151
|
+
&&(query.reviewRequired===undefined||overlap.admission.reviewRequired===query.reviewRequired)
|
|
152
|
+
&&(query.minScore===undefined||overlap.score>=Number(query.minScore));
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function overlapScore(status,shared,reasonCodes){
|
|
156
|
+
const base=status==='duplicate'?100:status==='semantic-overlap'?75:status==='source-overlap'?35:0;
|
|
157
|
+
const sharedBonus=Math.min(20,countShared(shared));
|
|
158
|
+
const stalePenalty=reasonCodes.includes('base-hash-mismatch')||reasonCodes.includes('target-hash-mismatch')?15:0;
|
|
159
|
+
return Math.max(0,base+sharedBonus-stalePenalty);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function countShared(shared){
|
|
163
|
+
return Object.values(shared).reduce((total,values)=>total+(Array.isArray(values)?values.length:0),0);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function intersect(left,right){const rightSet=new Set(right??[]);return uniqueStrings((left??[]).filter((value)=>rightSet.has(value)));}
|
|
167
|
+
function disjointNonEmpty(left,right){return Boolean(left?.length&&right?.length&&intersect(left,right).length===0);}
|
|
168
|
+
function queryValues(...values){return uniqueStrings(values.flatMap((value)=>strings(value)));}
|
|
169
|
+
function matchAny(filters,values){if(filters.length===0)return true;const valueSet=new Set(strings(values));return filters.some((filter)=>valueSet.has(filter));}
|
|
170
|
+
function array(value){if(value===undefined||value===null)return[];return Array.isArray(value)?value:[value];}
|
|
171
|
+
function strings(value){return array(value).map((entry)=>String(entry??'')).filter(Boolean);}
|
|
172
|
+
function uniqueStrings(values){return uniqueRawStrings((values??[]).filter((entry)=>entry!==undefined&&entry!==null&&String(entry)!==''));}
|
|
173
|
+
function compactRecord(value){return Object.fromEntries(Object.entries(value??{}).filter(([,entry])=>entry!==undefined&&(!Array.isArray(entry)||entry.length>0)));}
|
|
@@ -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