@shapeshift-labs/frontier-lang-compiler 0.2.88 → 0.2.90

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.
@@ -6,6 +6,9 @@ export type SemanticPatchBundleOverlapKind =
6
6
  | 'semantic-edit-key'
7
7
  | 'semantic-identity'
8
8
  | 'source-identity'
9
+ | 'transform-content'
10
+ | 'semantic-transform'
11
+ | 'projection-identity'
9
12
  | 'region'
10
13
  | 'conflict-key'
11
14
  | 'source-path'
@@ -24,6 +27,9 @@ export interface SemanticPatchBundleOverlapShared {
24
27
  readonly semanticEditKeys: readonly string[];
25
28
  readonly semanticIdentityHashes: readonly string[];
26
29
  readonly sourceIdentityHashes: readonly string[];
30
+ readonly semanticTransformContentHashes: readonly string[];
31
+ readonly semanticTransformIdentityHashes: readonly string[];
32
+ readonly projectionIdentityHashes: readonly string[];
27
33
  readonly regionKeys: readonly string[];
28
34
  readonly conflictKeys: readonly string[];
29
35
  readonly sourcePaths: readonly string[];
@@ -91,6 +97,12 @@ export interface SemanticPatchBundleOverlapQuery {
91
97
  readonly conflictKeys?: readonly string[];
92
98
  readonly semanticEditKey?: string | readonly string[];
93
99
  readonly semanticEditKeys?: readonly string[];
100
+ readonly semanticTransformIdentityHash?: string | readonly string[];
101
+ readonly semanticTransformIdentityHashes?: readonly string[];
102
+ readonly semanticTransformContentHash?: string | readonly string[];
103
+ readonly semanticTransformContentHashes?: readonly string[];
104
+ readonly projectionIdentityHash?: string | readonly string[];
105
+ readonly projectionIdentityHashes?: readonly string[];
94
106
  readonly operationContentHash?: string | readonly string[];
95
107
  readonly operationContentHashes?: readonly string[];
96
108
  readonly editContentHash?: string | readonly string[];
@@ -8,6 +8,7 @@ import type {
8
8
  } from '@shapeshift-labs/frontier-lang-kernel';
9
9
  import type { NativeSourceChangeKind, NativeSourceChangeSet } from './native-diff.js';
10
10
  import type { SemanticEditProjection, SemanticEditScript } from './semantic-edit-script.js';
11
+ import type { SemanticTransformIdentityRecord } from './semantic-transform-identity.js';
11
12
 
12
13
  export type SemanticPatchBundleAdmissionStatus = 'proposed' | 'queued' | 'admitted' | 'needs-review' | 'blocked' | 'rejected' | string;
13
14
 
@@ -110,6 +111,15 @@ export interface SemanticPatchBundleRecordIndex {
110
111
  readonly sourceIdentityHashes: readonly string[];
111
112
  readonly operationContentHashes: readonly string[];
112
113
  readonly editContentHashes: readonly string[];
114
+ readonly semanticTransformIds: readonly string[];
115
+ readonly semanticTransformKeys: readonly string[];
116
+ readonly semanticTransformIdentityHashes: readonly string[];
117
+ readonly semanticTransformContentHashes: readonly string[];
118
+ readonly projectionIdentityHashes: readonly string[];
119
+ readonly transformSourceLanguages: readonly string[];
120
+ readonly transformTargetLanguages: readonly string[];
121
+ readonly transformSourcePaths: readonly string[];
122
+ readonly transformTargetPaths: readonly string[];
113
123
  readonly patchIds: readonly string[];
114
124
  readonly mergeCandidateIds: readonly string[];
115
125
  readonly readinesses: readonly string[];
@@ -137,6 +147,7 @@ export interface SemanticPatchBundleRecord {
137
147
  readonly semanticOperationIds: readonly string[];
138
148
  readonly semanticEditScriptIds: readonly string[];
139
149
  readonly semanticEditProjectionIds: readonly string[];
150
+ readonly semanticTransformIdentityIds: readonly string[];
140
151
  readonly admission: SemanticPatchBundleAdmission;
141
152
  readonly index: SemanticPatchBundleRecordIndex;
142
153
  readonly summary: {
@@ -149,6 +160,7 @@ export interface SemanticPatchBundleRecord {
149
160
  readonly semanticEditScripts: number;
150
161
  readonly semanticEditProjections: number;
151
162
  readonly semanticEditProjectionEdits: number;
163
+ readonly semanticTransformIdentities: number;
152
164
  readonly reviewRequired: boolean;
153
165
  readonly autoMergeClaim: false;
154
166
  };
@@ -181,6 +193,10 @@ export interface CreateSemanticPatchBundleRecordOptions {
181
193
  readonly semanticEditScripts?: readonly SemanticEditScript[] | SemanticEditScript;
182
194
  readonly semanticEditProjection?: SemanticEditProjection;
183
195
  readonly semanticEditProjections?: readonly SemanticEditProjection[] | SemanticEditProjection;
196
+ readonly semanticTransformIdentity?: SemanticTransformIdentityRecord | Record<string, unknown>;
197
+ readonly semanticTransformIdentities?: readonly (SemanticTransformIdentityRecord | Record<string, unknown>)[];
198
+ readonly sourceLanguage?: FrontierSourceLanguage | string;
199
+ readonly targetLanguage?: FrontierSourceLanguage | string;
184
200
  readonly conflictKeys?: readonly string[] | string;
185
201
  readonly admission?: Partial<SemanticPatchBundleAdmission>;
186
202
  readonly metadata?: Record<string, unknown>;
@@ -237,6 +253,24 @@ export interface SemanticPatchBundleRecordQuery {
237
253
  readonly operationContentHashes?: readonly string[];
238
254
  readonly editContentHash?: string | readonly string[];
239
255
  readonly editContentHashes?: readonly string[];
256
+ readonly semanticTransformId?: string | readonly string[];
257
+ readonly semanticTransformIds?: readonly string[];
258
+ readonly semanticTransformKey?: string | readonly string[];
259
+ readonly semanticTransformKeys?: readonly string[];
260
+ readonly semanticTransformIdentityHash?: string | readonly string[];
261
+ readonly semanticTransformIdentityHashes?: readonly string[];
262
+ readonly semanticTransformContentHash?: string | readonly string[];
263
+ readonly semanticTransformContentHashes?: readonly string[];
264
+ readonly projectionIdentityHash?: string | readonly string[];
265
+ readonly projectionIdentityHashes?: readonly string[];
266
+ readonly transformSourceLanguage?: string | readonly string[];
267
+ readonly transformSourceLanguages?: readonly string[];
268
+ readonly transformTargetLanguage?: string | readonly string[];
269
+ readonly transformTargetLanguages?: readonly string[];
270
+ readonly transformSourcePath?: string | readonly string[];
271
+ readonly transformSourcePaths?: readonly string[];
272
+ readonly transformTargetPath?: string | readonly string[];
273
+ readonly transformTargetPaths?: readonly string[];
240
274
  readonly readiness?: SemanticMergeReadiness | string | readonly string[];
241
275
  readonly readinesses?: readonly string[];
242
276
  readonly admissionStatus?: SemanticPatchBundleAdmissionStatus | readonly string[];
@@ -0,0 +1,68 @@
1
+ import type { FrontierSourceLanguage } from '@shapeshift-labs/frontier-lang-kernel';
2
+
3
+ export interface SemanticTransformIdentityRecord {
4
+ readonly kind: 'frontier.lang.semanticTransformIdentityRecord';
5
+ readonly version: 1;
6
+ readonly schema: 'frontier.lang.semanticTransformIdentityRecord.v1';
7
+ readonly id: string;
8
+ readonly sourceLanguage?: FrontierSourceLanguage | string;
9
+ readonly targetLanguage?: FrontierSourceLanguage | string;
10
+ readonly sourcePath?: string;
11
+ readonly targetPath?: string;
12
+ readonly baseHash?: string;
13
+ readonly targetHash?: string;
14
+ readonly semanticKey?: string;
15
+ readonly transformKey?: string;
16
+ readonly semanticIdentityHash?: string;
17
+ readonly sourceIdentityHash?: string;
18
+ readonly operationContentHash?: string;
19
+ readonly editContentHash?: string;
20
+ readonly transformIdentityHash?: string;
21
+ readonly projectionIdentityHash?: string;
22
+ readonly transformContentHash?: string;
23
+ readonly readiness?: string;
24
+ readonly confidence?: number;
25
+ readonly evidenceIds?: readonly string[];
26
+ readonly metadata?: {
27
+ readonly autoMergeClaim: false;
28
+ readonly semanticEquivalenceClaim: false;
29
+ readonly sourceTransformId?: string;
30
+ readonly [key: string]: unknown;
31
+ };
32
+ }
33
+
34
+ export interface CreateSemanticTransformIdentityRecordOptions extends Partial<SemanticTransformIdentityRecord> {
35
+ readonly language?: FrontierSourceLanguage | string;
36
+ readonly projectedLanguage?: FrontierSourceLanguage | string;
37
+ readonly originalSourcePath?: string;
38
+ readonly targetSourcePath?: string;
39
+ readonly projectedSourcePath?: string;
40
+ readonly symbolName?: string;
41
+ readonly symbolKind?: string;
42
+ readonly anchorKey?: string;
43
+ readonly regionId?: string;
44
+ readonly operationId?: string;
45
+ }
46
+
47
+ export interface DeriveSemanticTransformIdentityRecordsOptions extends CreateSemanticTransformIdentityRecordOptions {
48
+ readonly semanticEditProjection?: unknown;
49
+ readonly semanticEditProjections?: readonly unknown[] | unknown;
50
+ readonly projection?: unknown;
51
+ readonly projections?: readonly unknown[] | unknown;
52
+ }
53
+
54
+ export type CreateSemanticTransformIdentityRecordInput =
55
+ | Partial<SemanticTransformIdentityRecord>
56
+ | Record<string, unknown>;
57
+
58
+ export declare function createSemanticTransformIdentityRecord(
59
+ input?: CreateSemanticTransformIdentityRecordInput,
60
+ options?: CreateSemanticTransformIdentityRecordOptions
61
+ ): SemanticTransformIdentityRecord;
62
+ export declare function semanticTransformIdentityFields(
63
+ record?: SemanticTransformIdentityRecord | Record<string, unknown>
64
+ ): SemanticTransformIdentityRecord;
65
+ export declare function deriveSemanticTransformIdentityRecords(
66
+ input?: DeriveSemanticTransformIdentityRecordsOptions | Record<string, unknown>,
67
+ options?: DeriveSemanticTransformIdentityRecordsOptions
68
+ ): readonly SemanticTransformIdentityRecord[];
package/dist/index.d.ts CHANGED
@@ -21,6 +21,7 @@ export * from './declarations/semantic-lineage.js';
21
21
  export * from './declarations/semantic-history.js';
22
22
  export * from './declarations/semantic-patch-bundle.js';
23
23
  export * from './declarations/semantic-patch-bundle-overlaps.js';
24
+ export * from './declarations/semantic-transform-identity.js';
24
25
  export * from './declarations/bidirectional-target-change.js';
25
26
  export * from './declarations/semantic-impact.js';
26
27
  export * from './declarations/semantic-sidecar.js';
package/dist/index.js CHANGED
@@ -68,6 +68,7 @@ export { queryNativeParserFeatureMatrix } from './internal/index-impl/queryNativ
68
68
  export { queryProjectionReadinessMatrix } from './internal/index-impl/queryProjectionReadinessMatrix.js';
69
69
  export { createSemanticPatchBundleRecord, querySemanticPatchBundleRecords, SemanticPatchBundleAdmissionStatuses } from './internal/index-impl/semanticPatchBundleRecords.js';
70
70
  export { compareSemanticPatchBundleRecords, querySemanticPatchBundleOverlaps, SemanticPatchBundleOverlapKinds, SemanticPatchBundleOverlapStatuses } from './internal/index-impl/semanticPatchBundleOverlaps.js';
71
+ export { createSemanticTransformIdentityRecord, deriveSemanticTransformIdentityRecords, semanticTransformIdentityFields } from './internal/index-impl/semanticTransformIdentityRecords.js';
71
72
  export { createSemanticMergeCandidateAdmissionRecord, decorateSemanticMergeCandidateForAdmission, querySemanticMergeCandidateAdmissionOverlaps, SemanticMergeCandidateProjectionRisks, semanticMergeCandidateReadinessSortKey, sortSemanticMergeCandidateAdmissionRecords } from './internal/index-impl/semanticMergeCandidateRecords.js';
72
73
  export { querySemanticMergeConflictClasses, SemanticMergeConflictClasses, semanticMergeConflictRiskScore, sortSemanticMergeCandidatesByConflictRisk, summarizeSemanticMergeConflicts } from './internal/index-impl/semanticMergeConflicts.js';
73
74
  export { createSemanticEditScript, SemanticEditScriptAdmissionStatuses } from './internal/index-impl/semanticEditScripts.js';
@@ -6,6 +6,9 @@ export const SemanticPatchBundleOverlapKinds=Object.freeze([
6
6
  'semantic-edit-key',
7
7
  'semantic-identity',
8
8
  'source-identity',
9
+ 'transform-content',
10
+ 'semantic-transform',
11
+ 'projection-identity',
9
12
  'region',
10
13
  'conflict-key',
11
14
  'source-path'
@@ -24,6 +27,9 @@ const KIND_FIELDS=Object.freeze({
24
27
  'semantic-edit-key':'semanticEditKeys',
25
28
  'semantic-identity':'semanticIdentityHashes',
26
29
  'source-identity':'sourceIdentityHashes',
30
+ 'transform-content':'semanticTransformContentHashes',
31
+ 'semantic-transform':'semanticTransformIdentityHashes',
32
+ 'projection-identity':'projectionIdentityHashes',
27
33
  region:'regionKeys',
28
34
  'conflict-key':'conflictKeys',
29
35
  'source-path':'sourcePaths'
@@ -49,8 +55,8 @@ export function compareSemanticPatchBundleRecords(left={},right={},options={}){
49
55
  score:overlapScore(admission.status,shared,admission.reasonCodes),
50
56
  summary:{
51
57
  sharedKeys:countShared(shared),
52
- duplicateSignals:shared.operationContentHashes.length+shared.editContentHashes.length,
53
- semanticSignals:shared.semanticEditKeys.length+shared.semanticIdentityHashes.length+shared.sourceIdentityHashes.length,
58
+ duplicateSignals:shared.operationContentHashes.length+shared.editContentHashes.length+shared.semanticTransformContentHashes.length,
59
+ semanticSignals:shared.semanticEditKeys.length+shared.semanticIdentityHashes.length+shared.sourceIdentityHashes.length+shared.semanticTransformIdentityHashes.length+shared.projectionIdentityHashes.length,
54
60
  sourceSignals:shared.regionKeys.length+shared.conflictKeys.length+shared.sourcePaths.length,
55
61
  baseHashMismatch:admission.reasonCodes.includes('base-hash-mismatch'),
56
62
  targetHashMismatch:admission.reasonCodes.includes('target-hash-mismatch')
@@ -84,6 +90,9 @@ function sharedIndex(left,right,options){
84
90
  semanticEditKeys:intersect(left.semanticEditKeys,right.semanticEditKeys),
85
91
  semanticIdentityHashes:intersect(left.semanticIdentityHashes,right.semanticIdentityHashes),
86
92
  sourceIdentityHashes:intersect(left.sourceIdentityHashes,right.sourceIdentityHashes),
93
+ semanticTransformContentHashes:intersect(left.semanticTransformContentHashes,right.semanticTransformContentHashes),
94
+ semanticTransformIdentityHashes:intersect(left.semanticTransformIdentityHashes,right.semanticTransformIdentityHashes),
95
+ projectionIdentityHashes:intersect(left.projectionIdentityHashes,right.projectionIdentityHashes),
87
96
  regionKeys:intersect(left.regionKeys,right.regionKeys),
88
97
  conflictKeys:intersect(left.conflictKeys,right.conflictKeys),
89
98
  sourcePaths:options.includeSourcePaths===false?[]:intersect(left.sourcePaths,right.sourcePaths),
@@ -93,16 +102,19 @@ function sharedIndex(left,right,options){
93
102
  }
94
103
 
95
104
  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;
105
+ const duplicate=shared.operationContentHashes.length||shared.editContentHashes.length||shared.semanticTransformContentHashes.length;
106
+ const semantic=shared.semanticEditKeys.length||shared.semanticIdentityHashes.length||shared.sourceIdentityHashes.length||shared.semanticTransformIdentityHashes.length||shared.projectionIdentityHashes.length;
98
107
  const source=shared.regionKeys.length||shared.conflictKeys.length||shared.sourcePaths.length;
99
108
  const status=duplicate?'duplicate':semantic?'semantic-overlap':source?'source-overlap':'independent';
100
109
  const reasonCodes=uniqueStrings([
101
110
  shared.operationContentHashes.length?'same-operation-content':undefined,
102
111
  shared.editContentHashes.length?'same-edit-content':undefined,
112
+ shared.semanticTransformContentHashes.length?'same-transform-content':undefined,
103
113
  shared.semanticEditKeys.length?'same-semantic-edit-key':undefined,
104
114
  shared.semanticIdentityHashes.length?'same-semantic-identity':undefined,
105
115
  shared.sourceIdentityHashes.length?'same-source-identity':undefined,
116
+ shared.semanticTransformIdentityHashes.length?'same-semantic-transform':undefined,
117
+ shared.projectionIdentityHashes.length?'same-projection-identity':undefined,
106
118
  shared.regionKeys.length?'same-region-key':undefined,
107
119
  shared.conflictKeys.length?'same-conflict-key':undefined,
108
120
  shared.sourcePaths.length?'same-source-path':undefined,
@@ -129,6 +141,9 @@ function bundleIndex(record){
129
141
  semanticEditKeys:uniqueStrings(index.semanticEditKeys),
130
142
  semanticIdentityHashes:uniqueStrings(index.semanticIdentityHashes),
131
143
  sourceIdentityHashes:uniqueStrings(index.sourceIdentityHashes),
144
+ semanticTransformContentHashes:uniqueStrings(index.semanticTransformContentHashes),
145
+ semanticTransformIdentityHashes:uniqueStrings(index.semanticTransformIdentityHashes),
146
+ projectionIdentityHashes:uniqueStrings(index.projectionIdentityHashes),
132
147
  operationContentHashes:uniqueStrings(index.operationContentHashes),
133
148
  editContentHashes:uniqueStrings(index.editContentHashes)
134
149
  };
@@ -146,6 +161,9 @@ function matchesOverlap(overlap,query){
146
161
  &&matchAny(queryValues(query.sourcePath,query.sourcePaths),overlap.shared.sourcePaths)
147
162
  &&matchAny(queryValues(query.conflictKey,query.conflictKeys),overlap.shared.conflictKeys)
148
163
  &&matchAny(queryValues(query.semanticEditKey,query.semanticEditKeys),overlap.shared.semanticEditKeys)
164
+ &&matchAny(queryValues(query.semanticTransformIdentityHash,query.semanticTransformIdentityHashes),overlap.shared.semanticTransformIdentityHashes)
165
+ &&matchAny(queryValues(query.semanticTransformContentHash,query.semanticTransformContentHashes),overlap.shared.semanticTransformContentHashes)
166
+ &&matchAny(queryValues(query.projectionIdentityHash,query.projectionIdentityHashes),overlap.shared.projectionIdentityHashes)
149
167
  &&matchAny(queryValues(query.operationContentHash,query.operationContentHashes),overlap.shared.operationContentHashes)
150
168
  &&matchAny(queryValues(query.editContentHash,query.editContentHashes),overlap.shared.editContentHashes)
151
169
  &&(query.reviewRequired===undefined||overlap.admission.reviewRequired===query.reviewRequired)
@@ -1,4 +1,5 @@
1
1
  import{idFragment,normalizeSemanticMergeReadiness,uniqueStrings}from'../../native-import-utils.js';
2
+ import{normalizeSemanticTransformIdentityRecords,semanticTransformInputs,semanticTransformRecordIndex,semanticTransformSummary}from'./semanticTransformIdentityRecords.js';
2
3
 
3
4
  export const SemanticPatchBundleAdmissionStatuses=Object.freeze(['proposed','queued','admitted','needs-review','blocked','rejected']);
4
5
 
@@ -9,6 +10,9 @@ export function createSemanticPatchBundleRecord(input={},options={}){
9
10
  const semanticEditScripts=array(options.semanticEditScripts??source.semanticEditScripts??source.semanticEditScript);
10
11
  const semanticEditProjections=array(options.semanticEditProjections??source.semanticEditProjections??source.semanticEditProjection);
11
12
  const semanticEditIndex=semanticEditRecordIndex(semanticEditScripts,semanticEditProjections,source);
13
+ const transformContext={sourceLanguage:options.sourceLanguage??source.sourceLanguage??source.language,targetLanguage:options.targetLanguage??source.targetLanguage};
14
+ const semanticTransformIdentities=normalizeSemanticTransformIdentityRecords(semanticTransformInputs(source,options),transformContext);
15
+ const semanticTransformIndex=semanticTransformRecordIndex(semanticTransformIdentities,source);
12
16
  const regionInputs=array(options.changedRegions??source.changedRegions??source.regions);
13
17
  const sourceMapLinks=normalizeSourceMapLinks([
14
18
  ...array(options.sourceMapLinks??source.sourceMapLinks),
@@ -43,7 +47,7 @@ export function createSemanticPatchBundleRecord(input={},options={}){
43
47
  ??`semantic_patch_bundle_${idFragment(firstString(source.id,patchId,mergeCandidateId,source.sourcePath,source.language,'record'))}`;
44
48
  const language=options.language??source.language??mergeCandidate?.language??sources.find((item)=>item.language)?.language;
45
49
  const sourcePath=options.sourcePath??source.sourcePath??mergeCandidate?.sourcePath??sources.find((item)=>item.sourcePath)?.sourcePath;
46
- const index=recordIndex({baseHash,targetHash,sources,changedRegions,sourceMapLinks,evidenceIds,proofIds,historyIds,semanticOperationIds,patchId,mergeCandidateId,admission,semanticEditIndex});
50
+ const index=recordIndex({baseHash,targetHash,sources,changedRegions,sourceMapLinks,evidenceIds,proofIds,historyIds,semanticOperationIds,patchId,mergeCandidateId,admission,semanticEditIndex,semanticTransformIndex});
47
51
  return{
48
52
  kind:'frontier.lang.semanticPatchBundleRecord',
49
53
  version:1,
@@ -65,9 +69,10 @@ export function createSemanticPatchBundleRecord(input={},options={}){
65
69
  semanticOperationIds,
66
70
  semanticEditScriptIds:semanticEditIndex.semanticEditScriptIds,
67
71
  semanticEditProjectionIds:semanticEditIndex.semanticEditProjectionIds,
72
+ semanticTransformIdentityIds:semanticTransformIndex.semanticTransformIds,
68
73
  admission,
69
74
  index,
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},
75
+ 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,semanticTransformIdentities:semanticTransformIdentities.length,reviewRequired:admission.reviewRequired,autoMergeClaim:admission.autoMergeClaim},
71
76
  metadata:compactRecord({
72
77
  sourceChangeSetId:source.kind==='frontier.lang.nativeSourceChangeSet'?source.id:undefined,
73
78
  patchRisk:patch?.risk,
@@ -75,6 +80,7 @@ export function createSemanticPatchBundleRecord(input={},options={}){
75
80
  changedRegionProjectionSummary:source.metadata?.changedRegionProjectionSummary,
76
81
  semanticMergeConflictSummary:source.metadata?.semanticMergeConflictSummary,
77
82
  semanticEditSummary:semanticEditSummary(semanticEditIndex),
83
+ semanticTransformSummary:semanticTransformSummary(semanticTransformIndex),
78
84
  ...options.metadata
79
85
  })
80
86
  };
@@ -197,11 +203,12 @@ function normalizeAdmission(input={},context){
197
203
 
198
204
  function recordIndex(parts){
199
205
  const semanticEditIndex=parts.semanticEditIndex??semanticEditRecordIndex([],[]);
206
+ const semanticTransformIndex=parts.semanticTransformIndex??semanticTransformRecordIndex([],parts);
200
207
  return{
201
208
  baseHashes:uniqueStrings([parts.baseHash,...parts.sources.map((item)=>item.baseHash)]),
202
209
  targetHashes:uniqueStrings([parts.targetHash,...parts.sources.map((item)=>item.targetHash)]),
203
210
  sourceHashes:uniqueStrings(parts.sources.map((item)=>item.sourceHash)),
204
- sourcePaths:uniqueStrings([...parts.sources.map((item)=>item.sourcePath),...semanticEditIndex.projectedSourcePaths]),
211
+ sourcePaths:uniqueStrings([...parts.sources.map((item)=>item.sourcePath),...semanticEditIndex.projectedSourcePaths,...semanticTransformIndex.transformSourcePaths,...semanticTransformIndex.transformTargetPaths]),
205
212
  regionKeys:uniqueStrings([...parts.changedRegions.map((region)=>region.key),...semanticEditIndex.anchorKeys]),
206
213
  regionKinds:uniqueStrings(parts.changedRegions.map((region)=>region.regionKind)),
207
214
  conflictKeys:uniqueStrings([...parts.changedRegions.flatMap((region)=>[region.conflictKey,...array(region.admission?.conflictKeys)]),...semanticEditIndex.conflictKeys]),
@@ -219,6 +226,15 @@ function recordIndex(parts){
219
226
  sourceIdentityHashes:semanticEditIndex.sourceIdentityHashes,
220
227
  operationContentHashes:semanticEditIndex.operationContentHashes,
221
228
  editContentHashes:semanticEditIndex.editContentHashes,
229
+ semanticTransformIds:semanticTransformIndex.semanticTransformIds,
230
+ semanticTransformKeys:semanticTransformIndex.semanticTransformKeys,
231
+ semanticTransformIdentityHashes:semanticTransformIndex.semanticTransformIdentityHashes,
232
+ semanticTransformContentHashes:semanticTransformIndex.semanticTransformContentHashes,
233
+ projectionIdentityHashes:semanticTransformIndex.projectionIdentityHashes,
234
+ transformSourceLanguages:semanticTransformIndex.transformSourceLanguages,
235
+ transformTargetLanguages:semanticTransformIndex.transformTargetLanguages,
236
+ transformSourcePaths:semanticTransformIndex.transformSourcePaths,
237
+ transformTargetPaths:semanticTransformIndex.transformTargetPaths,
222
238
  patchIds:uniqueStrings([parts.patchId]),
223
239
  mergeCandidateIds:uniqueStrings([parts.mergeCandidateId]),
224
240
  readinesses:uniqueStrings([parts.admission.readiness,...parts.changedRegions.map((region)=>region.admission?.readiness)]),
@@ -252,6 +268,15 @@ function matchesRecord(record,query){
252
268
  &&matchAny(queryValues(query.sourceIdentityHash,query.sourceIdentityHashes),index.sourceIdentityHashes)
253
269
  &&matchAny(queryValues(query.operationContentHash,query.operationContentHashes),index.operationContentHashes)
254
270
  &&matchAny(queryValues(query.editContentHash,query.editContentHashes),index.editContentHashes)
271
+ &&matchAny(queryValues(query.semanticTransformId,query.semanticTransformIds),index.semanticTransformIds)
272
+ &&matchAny(queryValues(query.semanticTransformKey,query.semanticTransformKeys),index.semanticTransformKeys)
273
+ &&matchAny(queryValues(query.semanticTransformIdentityHash,query.semanticTransformIdentityHashes),index.semanticTransformIdentityHashes)
274
+ &&matchAny(queryValues(query.semanticTransformContentHash,query.semanticTransformContentHashes),index.semanticTransformContentHashes)
275
+ &&matchAny(queryValues(query.projectionIdentityHash,query.projectionIdentityHashes),index.projectionIdentityHashes)
276
+ &&matchAny(queryValues(query.transformSourceLanguage,query.transformSourceLanguages),index.transformSourceLanguages)
277
+ &&matchAny(queryValues(query.transformTargetLanguage,query.transformTargetLanguages),index.transformTargetLanguages)
278
+ &&matchAny(queryValues(query.transformSourcePath,query.transformSourcePaths),index.transformSourcePaths)
279
+ &&matchAny(queryValues(query.transformTargetPath,query.transformTargetPaths),index.transformTargetPaths)
255
280
  &&matchAny(queryValues(query.readiness,query.readinesses),index.readinesses)
256
281
  &&matchAny(queryValues(query.admissionStatus,query.admissionStatuses),index.admissionStatuses);
257
282
  }
@@ -0,0 +1,183 @@
1
+ import { hashSemanticValue } from '@shapeshift-labs/frontier-lang-kernel';
2
+ import { idFragment, uniqueStrings as uniqueRawStrings } from '../../native-import-utils.js';
3
+ import { semanticEditIdentityFields } from './semanticEditIdentityRecords.js';
4
+
5
+ export function createSemanticTransformIdentityRecord(input = {}, options = {}) {
6
+ const source = input?.transform ?? input;
7
+ const merged = { ...source, ...options };
8
+ const editIdentity = semanticEditIdentityFields(merged);
9
+ const semanticKey = firstString(merged.semanticKey, editIdentity.semanticKey);
10
+ const transformKey = firstString(merged.transformKey, semanticTransformKey({ ...merged, semanticKey }));
11
+ const sourceLanguage = firstString(merged.sourceLanguage, merged.language);
12
+ const targetLanguage = firstString(merged.targetLanguage, merged.projectedLanguage);
13
+ const sourcePath = firstString(merged.sourcePath, merged.originalSourcePath);
14
+ const targetPath = firstString(merged.targetPath, merged.targetSourcePath, merged.projectedSourcePath);
15
+ const semanticIdentityHash = firstString(merged.semanticIdentityHash, editIdentity.semanticIdentityHash);
16
+ const sourceIdentityHash = firstString(merged.sourceIdentityHash, editIdentity.sourceIdentityHash);
17
+ const transformIdentityHash = firstString(merged.transformIdentityHash, hashSemanticValue(compactRecord({
18
+ transformKey,
19
+ semanticIdentityHash,
20
+ sourceLanguage,
21
+ targetLanguage
22
+ })));
23
+ const projectionIdentityHash = firstString(merged.projectionIdentityHash, hashSemanticValue(compactRecord({
24
+ transformIdentityHash,
25
+ sourceIdentityHash,
26
+ sourcePath,
27
+ targetPath
28
+ })));
29
+ const operationContentHash = firstString(merged.operationContentHash);
30
+ const editContentHash = firstString(merged.editContentHash);
31
+ const transformContentHash = firstString(
32
+ merged.transformContentHash,
33
+ operationContentHash || editContentHash ? hashSemanticValue(compactRecord({ transformIdentityHash, operationContentHash, editContentHash })) : undefined
34
+ );
35
+ const id = merged.id && source.kind === 'frontier.lang.semanticTransformIdentityRecord'
36
+ ? merged.id
37
+ : firstString(merged.id, `semantic_transform_${idFragment(firstString(transformKey, semanticKey, sourcePath, targetPath, 'record'))}`);
38
+ return compactRecord({
39
+ kind: 'frontier.lang.semanticTransformIdentityRecord',
40
+ version: 1,
41
+ schema: 'frontier.lang.semanticTransformIdentityRecord.v1',
42
+ id,
43
+ sourceLanguage,
44
+ targetLanguage,
45
+ sourcePath,
46
+ targetPath,
47
+ baseHash: firstString(merged.baseHash),
48
+ targetHash: firstString(merged.targetHash, merged.projectedHash),
49
+ semanticKey,
50
+ transformKey,
51
+ semanticIdentityHash,
52
+ sourceIdentityHash,
53
+ operationContentHash,
54
+ editContentHash,
55
+ transformIdentityHash,
56
+ projectionIdentityHash,
57
+ transformContentHash,
58
+ readiness: firstString(merged.readiness),
59
+ confidence: typeof merged.confidence === 'number' ? merged.confidence : undefined,
60
+ evidenceIds: uniqueStrings(merged.evidenceIds),
61
+ metadata: compactRecord({
62
+ autoMergeClaim: false,
63
+ semanticEquivalenceClaim: false,
64
+ sourceTransformId: source.kind === 'frontier.lang.semanticTransformIdentityRecord' ? source.id : undefined,
65
+ ...merged.metadata
66
+ })
67
+ });
68
+ }
69
+
70
+ export function semanticTransformIdentityFields(record = {}) {
71
+ return createSemanticTransformIdentityRecord(record);
72
+ }
73
+
74
+ export function normalizeSemanticTransformIdentityRecords(records, context = {}) {
75
+ return uniqueRecords(array(records).filter(Boolean).map((record) => createSemanticTransformIdentityRecord(record, context)));
76
+ }
77
+
78
+ export function semanticTransformInputs(source = {}, options = {}) {
79
+ const projections = [
80
+ ...array(options.semanticEditProjections ?? options.semanticEditProjection),
81
+ ...array(source.semanticEditProjections ?? source.semanticEditProjection)
82
+ ];
83
+ return [
84
+ ...array(options.semanticTransformIdentities ?? options.semanticTransformIdentity),
85
+ ...array(source.semanticTransformIdentities ?? source.semanticTransformIdentity ?? source.semanticTransforms),
86
+ ...array(source.index?.semanticTransformIdentities),
87
+ ...deriveSemanticTransformIdentityRecords({ semanticEditProjections: projections }, { ...source, ...options })
88
+ ];
89
+ }
90
+
91
+ export function deriveSemanticTransformIdentityRecords(input = {}, options = {}) {
92
+ const projections = semanticEditProjectionInputs(input);
93
+ return uniqueRecords(projections.flatMap((projection, projectionIndex) => {
94
+ const edits = array(projection.edits).filter((edit) => edit && typeof edit === 'object');
95
+ return edits.map((edit, editIndex) => transformRecordForProjectionEdit(edit, projection, input, options, projectionIndex, editIndex));
96
+ }));
97
+ }
98
+
99
+ export function semanticTransformRecordIndex(records, source = {}) {
100
+ const index = source.index ?? {};
101
+ return {
102
+ semanticTransformIds: uniqueStrings([...strings(source.semanticTransformIds), ...strings(index.semanticTransformIds), ...records.map((record) => record.id)]),
103
+ semanticTransformKeys: uniqueStrings([...strings(source.semanticTransformKeys), ...strings(index.semanticTransformKeys), ...records.map((record) => record.transformKey)]),
104
+ semanticTransformIdentityHashes: uniqueStrings([...strings(source.semanticTransformIdentityHashes), ...strings(index.semanticTransformIdentityHashes), ...records.map((record) => record.transformIdentityHash)]),
105
+ semanticTransformContentHashes: uniqueStrings([...strings(source.semanticTransformContentHashes), ...strings(index.semanticTransformContentHashes), ...records.map((record) => record.transformContentHash)]),
106
+ projectionIdentityHashes: uniqueStrings([...strings(source.projectionIdentityHashes), ...strings(index.projectionIdentityHashes), ...records.map((record) => record.projectionIdentityHash)]),
107
+ transformSourceLanguages: uniqueStrings([...strings(source.transformSourceLanguages), ...strings(index.transformSourceLanguages), ...records.map((record) => record.sourceLanguage)]),
108
+ transformTargetLanguages: uniqueStrings([...strings(source.transformTargetLanguages), ...strings(index.transformTargetLanguages), ...records.map((record) => record.targetLanguage)]),
109
+ transformSourcePaths: uniqueStrings([...strings(source.transformSourcePaths), ...strings(index.transformSourcePaths), ...records.map((record) => record.sourcePath)]),
110
+ transformTargetPaths: uniqueStrings([...strings(source.transformTargetPaths), ...strings(index.transformTargetPaths), ...records.map((record) => record.targetPath)])
111
+ };
112
+ }
113
+
114
+ export function semanticTransformSummary(index) {
115
+ if (!index.semanticTransformIds.length && !index.semanticTransformKeys.length) return undefined;
116
+ return compactRecord({
117
+ ids: index.semanticTransformIds,
118
+ keys: index.semanticTransformKeys,
119
+ identityHashes: index.semanticTransformIdentityHashes,
120
+ contentHashes: index.semanticTransformContentHashes,
121
+ projectionIdentityHashes: index.projectionIdentityHashes,
122
+ sourceLanguages: index.transformSourceLanguages,
123
+ targetLanguages: index.transformTargetLanguages,
124
+ targetPaths: index.transformTargetPaths
125
+ });
126
+ }
127
+
128
+ function semanticTransformKey(record) {
129
+ const scope = record.semanticKey ?? (record.symbolName
130
+ ? `${record.symbolKind ?? 'symbol'}:${record.symbolName}`
131
+ : record.anchorKey ?? record.regionId ?? record.operationId ?? record.id);
132
+ const route = [record.sourceLanguage ?? record.language, record.targetLanguage ?? record.projectedLanguage].filter(Boolean).join('->');
133
+ return ['semantic-transform', route, scope].filter(Boolean).join(':');
134
+ }
135
+
136
+ function semanticEditProjectionInputs(input) {
137
+ if (input.kind === 'frontier.lang.semanticEditProjection') return [input];
138
+ return [
139
+ ...array(input.semanticEditProjections ?? input.semanticEditProjection),
140
+ ...array(input.projections ?? input.projection)
141
+ ].filter((entry) => entry && typeof entry === 'object');
142
+ }
143
+
144
+ function transformRecordForProjectionEdit(edit, projection, input, options, projectionIndex, editIndex) {
145
+ const sourceLanguage = firstString(edit.sourceLanguage, edit.language, input.sourceLanguage, options.sourceLanguage, projection.sourceLanguage, projection.language);
146
+ const targetLanguage = firstString(edit.targetLanguage, edit.projectedLanguage, input.targetLanguage, options.targetLanguage, projection.targetLanguage, projection.projectedLanguage, projection.language);
147
+ const sourcePath = firstString(edit.originalSourcePath, edit.sourcePath, input.sourcePath, options.sourcePath, projection.sourcePath);
148
+ const targetPath = firstString(edit.targetPath, edit.targetSourcePath, input.targetPath, options.targetPath, projection.targetPath, projection.projectedSourcePath, projection.sourcePath);
149
+ const transformId = [projection.id, edit.operationId, projectionIndex, editIndex].filter((entry) => entry !== undefined && entry !== null).join(':');
150
+ return createSemanticTransformIdentityRecord(edit, {
151
+ id: `semantic_transform_${idFragment(transformId)}`,
152
+ sourceLanguage,
153
+ targetLanguage,
154
+ sourcePath,
155
+ targetPath,
156
+ baseHash: firstString(edit.baseHash, projection.baseHash, input.baseHash, options.baseHash),
157
+ targetHash: firstString(edit.targetHash, projection.projectedHash, projection.targetHash, input.targetHash, options.targetHash),
158
+ readiness: firstString(edit.readiness, projection.admission?.status, projection.status),
159
+ evidenceIds: uniqueStrings([...strings(input.evidenceIds), ...strings(options.evidenceIds), ...strings(projection.evidenceIds), ...strings(edit.evidenceIds)]),
160
+ metadata: compactRecord({
161
+ sourceProjectionId: projection.id,
162
+ sourceProjectionEditOperationId: edit.operationId
163
+ })
164
+ });
165
+ }
166
+
167
+ function uniqueRecords(records) {
168
+ const seen = new Set();
169
+ const result = [];
170
+ for (const record of records) {
171
+ const key = firstString(record.id, record.transformContentHash, record.projectionIdentityHash, record.transformIdentityHash);
172
+ if (!key || seen.has(key)) continue;
173
+ seen.add(key);
174
+ result.push(record);
175
+ }
176
+ return result;
177
+ }
178
+
179
+ function array(value) { if (value === undefined || value === null) return []; return Array.isArray(value) ? value : [value]; }
180
+ function strings(value) { return array(value).map((entry) => String(entry ?? '')).filter(Boolean); }
181
+ function firstString(...values) { return values.map((value) => value === undefined || value === null ? '' : String(value)).find(Boolean); }
182
+ function uniqueStrings(values) { return uniqueRawStrings((values ?? []).filter((entry) => entry !== undefined && entry !== null && String(entry) !== '')); }
183
+ function compactRecord(value) { return Object.fromEntries(Object.entries(value ?? {}).filter(([, entry]) => entry !== undefined && (!Array.isArray(entry) || entry.length > 0))); }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shapeshift-labs/frontier-lang-compiler",
3
- "version": "0.2.88",
3
+ "version": "0.2.90",
4
4
  "description": "Compiler facade for Frontier Lang source documents and language projection adapters.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",