@shapeshift-labs/frontier-lang-compiler 0.2.89 → 0.2.91
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.d.ts +25 -0
- package/dist/declarations/semantic-transform-identity.d.ts +11 -0
- package/dist/index.js +1 -1
- package/dist/internal/index-impl/semanticPatchBundleAdmission.js +97 -0
- package/dist/internal/index-impl/semanticPatchBundleRecords.js +6 -19
- package/dist/internal/index-impl/semanticTransformIdentityRecords.js +62 -2
- package/package.json +1 -1
|
@@ -81,6 +81,8 @@ export interface SemanticPatchBundleAdmission {
|
|
|
81
81
|
readonly readiness: SemanticMergeReadiness | string;
|
|
82
82
|
readonly reviewRequired: boolean;
|
|
83
83
|
readonly autoMergeClaim: false;
|
|
84
|
+
readonly autoApplyCandidate?: boolean;
|
|
85
|
+
readonly transformAdmission?: SemanticPatchBundleTransformAdmission;
|
|
84
86
|
readonly reasonCodes?: readonly string[];
|
|
85
87
|
readonly conflictKeys?: readonly string[];
|
|
86
88
|
readonly admittedAt?: number | string;
|
|
@@ -89,6 +91,23 @@ export interface SemanticPatchBundleAdmission {
|
|
|
89
91
|
readonly metadata?: Record<string, unknown>;
|
|
90
92
|
}
|
|
91
93
|
|
|
94
|
+
export interface SemanticPatchBundleTransformAdmission {
|
|
95
|
+
readonly status: 'none' | 'ready' | 'needs-review' | 'blocked' | string;
|
|
96
|
+
readonly action: 'none' | 'admit' | 'review' | 'block' | string;
|
|
97
|
+
readonly readiness: SemanticMergeReadiness | string;
|
|
98
|
+
readonly crossLanguage?: boolean;
|
|
99
|
+
readonly reasonCodes?: readonly string[];
|
|
100
|
+
readonly transformIds?: readonly string[];
|
|
101
|
+
readonly transformKeys?: readonly string[];
|
|
102
|
+
readonly contentHashes?: readonly string[];
|
|
103
|
+
readonly projectionIdentityHashes?: readonly string[];
|
|
104
|
+
readonly sourceLanguages?: readonly string[];
|
|
105
|
+
readonly targetLanguages?: readonly string[];
|
|
106
|
+
readonly sourcePaths?: readonly string[];
|
|
107
|
+
readonly targetPaths?: readonly string[];
|
|
108
|
+
readonly evidenceIds?: readonly string[];
|
|
109
|
+
}
|
|
110
|
+
|
|
92
111
|
export interface SemanticPatchBundleRecordIndex {
|
|
93
112
|
readonly baseHashes: readonly string[];
|
|
94
113
|
readonly targetHashes: readonly string[];
|
|
@@ -116,6 +135,8 @@ export interface SemanticPatchBundleRecordIndex {
|
|
|
116
135
|
readonly semanticTransformIdentityHashes: readonly string[];
|
|
117
136
|
readonly semanticTransformContentHashes: readonly string[];
|
|
118
137
|
readonly projectionIdentityHashes: readonly string[];
|
|
138
|
+
readonly semanticTransformReadinesses: readonly string[];
|
|
139
|
+
readonly semanticTransformEvidenceIds: readonly string[];
|
|
119
140
|
readonly transformSourceLanguages: readonly string[];
|
|
120
141
|
readonly transformTargetLanguages: readonly string[];
|
|
121
142
|
readonly transformSourcePaths: readonly string[];
|
|
@@ -263,6 +284,10 @@ export interface SemanticPatchBundleRecordQuery {
|
|
|
263
284
|
readonly semanticTransformContentHashes?: readonly string[];
|
|
264
285
|
readonly projectionIdentityHash?: string | readonly string[];
|
|
265
286
|
readonly projectionIdentityHashes?: readonly string[];
|
|
287
|
+
readonly semanticTransformReadiness?: string | readonly string[];
|
|
288
|
+
readonly semanticTransformReadinesses?: readonly string[];
|
|
289
|
+
readonly semanticTransformEvidenceId?: string | readonly string[];
|
|
290
|
+
readonly semanticTransformEvidenceIds?: readonly string[];
|
|
266
291
|
readonly transformSourceLanguage?: string | readonly string[];
|
|
267
292
|
readonly transformSourceLanguages?: readonly string[];
|
|
268
293
|
readonly transformTargetLanguage?: string | readonly string[];
|
|
@@ -44,6 +44,13 @@ export interface CreateSemanticTransformIdentityRecordOptions extends Partial<Se
|
|
|
44
44
|
readonly operationId?: string;
|
|
45
45
|
}
|
|
46
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
|
+
|
|
47
54
|
export type CreateSemanticTransformIdentityRecordInput =
|
|
48
55
|
| Partial<SemanticTransformIdentityRecord>
|
|
49
56
|
| Record<string, unknown>;
|
|
@@ -55,3 +62,7 @@ export declare function createSemanticTransformIdentityRecord(
|
|
|
55
62
|
export declare function semanticTransformIdentityFields(
|
|
56
63
|
record?: SemanticTransformIdentityRecord | Record<string, unknown>
|
|
57
64
|
): SemanticTransformIdentityRecord;
|
|
65
|
+
export declare function deriveSemanticTransformIdentityRecords(
|
|
66
|
+
input?: DeriveSemanticTransformIdentityRecordsOptions | Record<string, unknown>,
|
|
67
|
+
options?: DeriveSemanticTransformIdentityRecordsOptions
|
|
68
|
+
): readonly SemanticTransformIdentityRecord[];
|
package/dist/index.js
CHANGED
|
@@ -68,7 +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, semanticTransformIdentityFields } from './internal/index-impl/semanticTransformIdentityRecords.js';
|
|
71
|
+
export { createSemanticTransformIdentityRecord, deriveSemanticTransformIdentityRecords, semanticTransformIdentityFields } from './internal/index-impl/semanticTransformIdentityRecords.js';
|
|
72
72
|
export { createSemanticMergeCandidateAdmissionRecord, decorateSemanticMergeCandidateForAdmission, querySemanticMergeCandidateAdmissionOverlaps, SemanticMergeCandidateProjectionRisks, semanticMergeCandidateReadinessSortKey, sortSemanticMergeCandidateAdmissionRecords } from './internal/index-impl/semanticMergeCandidateRecords.js';
|
|
73
73
|
export { querySemanticMergeConflictClasses, SemanticMergeConflictClasses, semanticMergeConflictRiskScore, sortSemanticMergeCandidatesByConflictRisk, summarizeSemanticMergeConflicts } from './internal/index-impl/semanticMergeConflicts.js';
|
|
74
74
|
export { createSemanticEditScript, SemanticEditScriptAdmissionStatuses } from './internal/index-impl/semanticEditScripts.js';
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { normalizeSemanticMergeReadiness, uniqueStrings } from '../../native-import-utils.js';
|
|
2
|
+
|
|
3
|
+
export function createSemanticPatchBundleAdmission(input = {}, context = {}) {
|
|
4
|
+
const transformAdmission = semanticTransformAdmission(context);
|
|
5
|
+
const fallbackReadiness = transformAdmission.readiness === 'ready' ? 'ready' : context.readiness;
|
|
6
|
+
const readiness = normalizeSemanticMergeReadiness(input.readiness ?? fallbackReadiness) ?? input.readiness ?? fallbackReadiness;
|
|
7
|
+
const status = input.status ?? admissionStatusForReadiness(readiness, transformAdmission);
|
|
8
|
+
const autoApplyCandidate = input.autoApplyCandidate ?? (status === 'admitted' && transformAdmission.action === 'admit');
|
|
9
|
+
return compactRecord({
|
|
10
|
+
status,
|
|
11
|
+
readiness,
|
|
12
|
+
reviewRequired: input.reviewRequired ?? status !== 'admitted',
|
|
13
|
+
autoMergeClaim: false,
|
|
14
|
+
autoApplyCandidate,
|
|
15
|
+
transformAdmission,
|
|
16
|
+
reasonCodes: uniqueStrings([
|
|
17
|
+
...strings(input.reasonCodes),
|
|
18
|
+
...strings(context.source?.reasons),
|
|
19
|
+
...strings(context.mergeCandidate?.reasons),
|
|
20
|
+
...transformAdmission.reasonCodes
|
|
21
|
+
]),
|
|
22
|
+
conflictKeys: uniqueStrings([...strings(input.conflictKeys), ...context.conflictKeys]),
|
|
23
|
+
admittedAt: input.admittedAt,
|
|
24
|
+
reviewerId: input.reviewerId,
|
|
25
|
+
evidenceIds: uniqueStrings([...strings(input.evidenceIds), ...strings(transformAdmission.evidenceIds)]),
|
|
26
|
+
metadata: input.metadata
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function semanticTransformAdmission(context) {
|
|
31
|
+
const records = array(context.semanticTransformIdentities);
|
|
32
|
+
const index = context.semanticTransformIndex ?? {};
|
|
33
|
+
if (!records.length && !strings(index.semanticTransformIds).length) {
|
|
34
|
+
return { status: 'none', action: 'none', readiness: 'needs-review', reasonCodes: [] };
|
|
35
|
+
}
|
|
36
|
+
const readinesses = uniqueStrings([...strings(index.semanticTransformReadinesses), ...records.map((record) => record.readiness)]);
|
|
37
|
+
const normalizedReadinesses = uniqueStrings(readinesses.map(transformReadiness).filter(Boolean));
|
|
38
|
+
const blocked = normalizedReadinesses.includes('blocked');
|
|
39
|
+
const complete = strings(index.semanticTransformContentHashes).length > 0 &&
|
|
40
|
+
strings(index.projectionIdentityHashes).length > 0 &&
|
|
41
|
+
strings(index.transformSourceLanguages).length > 0 &&
|
|
42
|
+
strings(index.transformTargetLanguages).length > 0 &&
|
|
43
|
+
strings(index.transformSourcePaths).length > 0 &&
|
|
44
|
+
strings(index.transformTargetPaths).length > 0;
|
|
45
|
+
const ready = !blocked && complete && (normalizedReadinesses.length === 0 || normalizedReadinesses.every((entry) => entry === 'ready'));
|
|
46
|
+
const status = blocked ? 'blocked' : ready ? 'ready' : 'needs-review';
|
|
47
|
+
return compactRecord({
|
|
48
|
+
status,
|
|
49
|
+
action: blocked ? 'block' : ready ? 'admit' : 'review',
|
|
50
|
+
readiness: blocked ? 'blocked' : ready ? 'ready' : 'needs-review',
|
|
51
|
+
crossLanguage: hasCrossLanguageTransform(index),
|
|
52
|
+
reasonCodes: transformReasonCodes({ blocked, complete, ready, readinesses, index }),
|
|
53
|
+
transformIds: strings(index.semanticTransformIds),
|
|
54
|
+
transformKeys: strings(index.semanticTransformKeys),
|
|
55
|
+
contentHashes: strings(index.semanticTransformContentHashes),
|
|
56
|
+
projectionIdentityHashes: strings(index.projectionIdentityHashes),
|
|
57
|
+
sourceLanguages: strings(index.transformSourceLanguages),
|
|
58
|
+
targetLanguages: strings(index.transformTargetLanguages),
|
|
59
|
+
sourcePaths: strings(index.transformSourcePaths),
|
|
60
|
+
targetPaths: strings(index.transformTargetPaths),
|
|
61
|
+
evidenceIds: strings(index.semanticTransformEvidenceIds)
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function transformReasonCodes(input) {
|
|
66
|
+
return uniqueStrings([
|
|
67
|
+
input.blocked ? 'transform-readiness-blocked' : undefined,
|
|
68
|
+
!input.complete ? 'transform-evidence-incomplete' : undefined,
|
|
69
|
+
input.ready ? 'transform-auto-apply-candidate' : undefined,
|
|
70
|
+
...input.readinesses.map((readiness) => `transform-readiness:${readiness}`)
|
|
71
|
+
]);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function transformReadiness(value) {
|
|
75
|
+
const normalized = normalizeSemanticMergeReadiness(value);
|
|
76
|
+
if (normalized) return normalized === 'ready-with-losses' ? 'needs-review' : normalized;
|
|
77
|
+
const status = String(value ?? '').toLowerCase();
|
|
78
|
+
if (['auto-merge-candidate', 'portable', 'projected', 'applied'].includes(status)) return 'ready';
|
|
79
|
+
if (['conflict', 'blocked', 'stale', 'rejected'].includes(status)) return 'blocked';
|
|
80
|
+
if (['needs-port', 'review', 'needs-review', 'candidate'].includes(status)) return 'needs-review';
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function admissionStatusForReadiness(readiness, transformAdmission) {
|
|
85
|
+
if (readiness === 'blocked') return 'blocked';
|
|
86
|
+
if (transformAdmission.action === 'admit' && readiness === 'ready') return 'admitted';
|
|
87
|
+
return readiness === 'needs-review' ? 'needs-review' : 'proposed';
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function hasCrossLanguageTransform(index) {
|
|
91
|
+
const source = new Set(strings(index.transformSourceLanguages));
|
|
92
|
+
return strings(index.transformTargetLanguages).some((target) => !source.has(target));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function array(value) { if (value === undefined || value === null) return []; return Array.isArray(value) ? value : [value]; }
|
|
96
|
+
function strings(value) { return array(value).map((entry) => String(entry ?? '')).filter(Boolean); }
|
|
97
|
+
function compactRecord(value) { return Object.fromEntries(Object.entries(value ?? {}).filter(([, entry]) => entry !== undefined && (!Array.isArray(entry) || entry.length > 0))); }
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import{idFragment,normalizeSemanticMergeReadiness,uniqueStrings}from'../../native-import-utils.js';
|
|
2
|
+
import{createSemanticPatchBundleAdmission}from'./semanticPatchBundleAdmission.js';
|
|
2
3
|
import{normalizeSemanticTransformIdentityRecords,semanticTransformInputs,semanticTransformRecordIndex,semanticTransformSummary}from'./semanticTransformIdentityRecords.js';
|
|
3
4
|
|
|
4
5
|
export const SemanticPatchBundleAdmissionStatuses=Object.freeze(['proposed','queued','admitted','needs-review','blocked','rejected']);
|
|
@@ -42,7 +43,7 @@ export function createSemanticPatchBundleRecord(input={},options={}){
|
|
|
42
43
|
...changedRegions.flatMap((region)=>[region.conflictKey,...array(region.admission?.conflictKeys)]),
|
|
43
44
|
...(source.metadata?.semanticMergeConflictSummary?.conflictKeys??[])
|
|
44
45
|
]);
|
|
45
|
-
const admission=
|
|
46
|
+
const admission=createSemanticPatchBundleAdmission(options.admission??source.admission,{readiness,conflictKeys,source,mergeCandidate,semanticTransformIndex,semanticTransformIdentities});
|
|
46
47
|
const id=options.id??(source.kind==='frontier.lang.semanticPatchBundleRecord'?source.id:undefined)
|
|
47
48
|
??`semantic_patch_bundle_${idFragment(firstString(source.id,patchId,mergeCandidateId,source.sourcePath,source.language,'record'))}`;
|
|
48
49
|
const language=options.language??source.language??mergeCandidate?.language??sources.find((item)=>item.language)?.language;
|
|
@@ -184,23 +185,6 @@ function normalizeSourceMapLinks(links){
|
|
|
184
185
|
return result;
|
|
185
186
|
}
|
|
186
187
|
|
|
187
|
-
function normalizeAdmission(input={},context){
|
|
188
|
-
const readiness=normalizeSemanticMergeReadiness(input.readiness??context.readiness)??input.readiness??context.readiness;
|
|
189
|
-
const status=input.status??admissionStatusForReadiness(readiness);
|
|
190
|
-
return compactRecord({
|
|
191
|
-
status,
|
|
192
|
-
readiness,
|
|
193
|
-
reviewRequired:input.reviewRequired??status!=='admitted',
|
|
194
|
-
autoMergeClaim:false,
|
|
195
|
-
reasonCodes:uniqueStrings([...strings(input.reasonCodes),...strings(context.source.reasons),...strings(context.mergeCandidate?.reasons)]),
|
|
196
|
-
conflictKeys:uniqueStrings([...strings(input.conflictKeys),...context.conflictKeys]),
|
|
197
|
-
admittedAt:input.admittedAt,
|
|
198
|
-
reviewerId:input.reviewerId,
|
|
199
|
-
evidenceIds:uniqueStrings(input.evidenceIds),
|
|
200
|
-
metadata:input.metadata
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
|
|
204
188
|
function recordIndex(parts){
|
|
205
189
|
const semanticEditIndex=parts.semanticEditIndex??semanticEditRecordIndex([],[]);
|
|
206
190
|
const semanticTransformIndex=parts.semanticTransformIndex??semanticTransformRecordIndex([],parts);
|
|
@@ -231,6 +215,8 @@ function recordIndex(parts){
|
|
|
231
215
|
semanticTransformIdentityHashes:semanticTransformIndex.semanticTransformIdentityHashes,
|
|
232
216
|
semanticTransformContentHashes:semanticTransformIndex.semanticTransformContentHashes,
|
|
233
217
|
projectionIdentityHashes:semanticTransformIndex.projectionIdentityHashes,
|
|
218
|
+
semanticTransformReadinesses:semanticTransformIndex.semanticTransformReadinesses,
|
|
219
|
+
semanticTransformEvidenceIds:semanticTransformIndex.semanticTransformEvidenceIds,
|
|
234
220
|
transformSourceLanguages:semanticTransformIndex.transformSourceLanguages,
|
|
235
221
|
transformTargetLanguages:semanticTransformIndex.transformTargetLanguages,
|
|
236
222
|
transformSourcePaths:semanticTransformIndex.transformSourcePaths,
|
|
@@ -273,6 +259,8 @@ function matchesRecord(record,query){
|
|
|
273
259
|
&&matchAny(queryValues(query.semanticTransformIdentityHash,query.semanticTransformIdentityHashes),index.semanticTransformIdentityHashes)
|
|
274
260
|
&&matchAny(queryValues(query.semanticTransformContentHash,query.semanticTransformContentHashes),index.semanticTransformContentHashes)
|
|
275
261
|
&&matchAny(queryValues(query.projectionIdentityHash,query.projectionIdentityHashes),index.projectionIdentityHashes)
|
|
262
|
+
&&matchAny(queryValues(query.semanticTransformReadiness,query.semanticTransformReadinesses),index.semanticTransformReadinesses)
|
|
263
|
+
&&matchAny(queryValues(query.semanticTransformEvidenceId,query.semanticTransformEvidenceIds),index.semanticTransformEvidenceIds)
|
|
276
264
|
&&matchAny(queryValues(query.transformSourceLanguage,query.transformSourceLanguages),index.transformSourceLanguages)
|
|
277
265
|
&&matchAny(queryValues(query.transformTargetLanguage,query.transformTargetLanguages),index.transformTargetLanguages)
|
|
278
266
|
&&matchAny(queryValues(query.transformSourcePath,query.transformSourcePaths),index.transformSourcePaths)
|
|
@@ -281,7 +269,6 @@ function matchesRecord(record,query){
|
|
|
281
269
|
&&matchAny(queryValues(query.admissionStatus,query.admissionStatuses),index.admissionStatuses);
|
|
282
270
|
}
|
|
283
271
|
|
|
284
|
-
function admissionStatusForReadiness(readiness){return readiness==='blocked'?'blocked':readiness==='needs-review'?'needs-review':'proposed';}
|
|
285
272
|
function semanticEditRecordIndex(scripts,projections,source={}){
|
|
286
273
|
const operations=scripts.flatMap((script)=>array(script.operations));
|
|
287
274
|
const edits=projections.flatMap((projection)=>array(projection.edits));
|
|
@@ -72,17 +72,30 @@ export function semanticTransformIdentityFields(record = {}) {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
export function normalizeSemanticTransformIdentityRecords(records, context = {}) {
|
|
75
|
-
return array(records).filter(Boolean).map((record) => createSemanticTransformIdentityRecord(record, context));
|
|
75
|
+
return uniqueRecords(array(records).filter(Boolean).map((record) => createSemanticTransformIdentityRecord(record, context)));
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
export function semanticTransformInputs(source = {}, options = {}) {
|
|
79
|
+
const projections = [
|
|
80
|
+
...array(options.semanticEditProjections ?? options.semanticEditProjection),
|
|
81
|
+
...array(source.semanticEditProjections ?? source.semanticEditProjection)
|
|
82
|
+
];
|
|
79
83
|
return [
|
|
80
84
|
...array(options.semanticTransformIdentities ?? options.semanticTransformIdentity),
|
|
81
85
|
...array(source.semanticTransformIdentities ?? source.semanticTransformIdentity ?? source.semanticTransforms),
|
|
82
|
-
...array(source.index?.semanticTransformIdentities)
|
|
86
|
+
...array(source.index?.semanticTransformIdentities),
|
|
87
|
+
...deriveSemanticTransformIdentityRecords({ semanticEditProjections: projections }, { ...source, ...options })
|
|
83
88
|
];
|
|
84
89
|
}
|
|
85
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
|
+
|
|
86
99
|
export function semanticTransformRecordIndex(records, source = {}) {
|
|
87
100
|
const index = source.index ?? {};
|
|
88
101
|
return {
|
|
@@ -91,6 +104,8 @@ export function semanticTransformRecordIndex(records, source = {}) {
|
|
|
91
104
|
semanticTransformIdentityHashes: uniqueStrings([...strings(source.semanticTransformIdentityHashes), ...strings(index.semanticTransformIdentityHashes), ...records.map((record) => record.transformIdentityHash)]),
|
|
92
105
|
semanticTransformContentHashes: uniqueStrings([...strings(source.semanticTransformContentHashes), ...strings(index.semanticTransformContentHashes), ...records.map((record) => record.transformContentHash)]),
|
|
93
106
|
projectionIdentityHashes: uniqueStrings([...strings(source.projectionIdentityHashes), ...strings(index.projectionIdentityHashes), ...records.map((record) => record.projectionIdentityHash)]),
|
|
107
|
+
semanticTransformReadinesses: uniqueStrings([...strings(source.semanticTransformReadinesses), ...strings(index.semanticTransformReadinesses), ...records.map((record) => record.readiness)]),
|
|
108
|
+
semanticTransformEvidenceIds: uniqueStrings([...strings(source.semanticTransformEvidenceIds), ...strings(index.semanticTransformEvidenceIds), ...records.flatMap((record) => record.evidenceIds)]),
|
|
94
109
|
transformSourceLanguages: uniqueStrings([...strings(source.transformSourceLanguages), ...strings(index.transformSourceLanguages), ...records.map((record) => record.sourceLanguage)]),
|
|
95
110
|
transformTargetLanguages: uniqueStrings([...strings(source.transformTargetLanguages), ...strings(index.transformTargetLanguages), ...records.map((record) => record.targetLanguage)]),
|
|
96
111
|
transformSourcePaths: uniqueStrings([...strings(source.transformSourcePaths), ...strings(index.transformSourcePaths), ...records.map((record) => record.sourcePath)]),
|
|
@@ -106,6 +121,8 @@ export function semanticTransformSummary(index) {
|
|
|
106
121
|
identityHashes: index.semanticTransformIdentityHashes,
|
|
107
122
|
contentHashes: index.semanticTransformContentHashes,
|
|
108
123
|
projectionIdentityHashes: index.projectionIdentityHashes,
|
|
124
|
+
readinesses: index.semanticTransformReadinesses,
|
|
125
|
+
evidenceIds: index.semanticTransformEvidenceIds,
|
|
109
126
|
sourceLanguages: index.transformSourceLanguages,
|
|
110
127
|
targetLanguages: index.transformTargetLanguages,
|
|
111
128
|
targetPaths: index.transformTargetPaths
|
|
@@ -120,6 +137,49 @@ function semanticTransformKey(record) {
|
|
|
120
137
|
return ['semantic-transform', route, scope].filter(Boolean).join(':');
|
|
121
138
|
}
|
|
122
139
|
|
|
140
|
+
function semanticEditProjectionInputs(input) {
|
|
141
|
+
if (input.kind === 'frontier.lang.semanticEditProjection') return [input];
|
|
142
|
+
return [
|
|
143
|
+
...array(input.semanticEditProjections ?? input.semanticEditProjection),
|
|
144
|
+
...array(input.projections ?? input.projection)
|
|
145
|
+
].filter((entry) => entry && typeof entry === 'object');
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function transformRecordForProjectionEdit(edit, projection, input, options, projectionIndex, editIndex) {
|
|
149
|
+
const sourceLanguage = firstString(edit.sourceLanguage, edit.language, input.sourceLanguage, options.sourceLanguage, projection.sourceLanguage, projection.language);
|
|
150
|
+
const targetLanguage = firstString(edit.targetLanguage, edit.projectedLanguage, input.targetLanguage, options.targetLanguage, projection.targetLanguage, projection.projectedLanguage, projection.language);
|
|
151
|
+
const sourcePath = firstString(edit.originalSourcePath, edit.sourcePath, input.sourcePath, options.sourcePath, projection.sourcePath);
|
|
152
|
+
const targetPath = firstString(edit.targetPath, edit.targetSourcePath, input.targetPath, options.targetPath, projection.targetPath, projection.projectedSourcePath, projection.sourcePath);
|
|
153
|
+
const transformId = [projection.id, edit.operationId, projectionIndex, editIndex].filter((entry) => entry !== undefined && entry !== null).join(':');
|
|
154
|
+
return createSemanticTransformIdentityRecord(edit, {
|
|
155
|
+
id: `semantic_transform_${idFragment(transformId)}`,
|
|
156
|
+
sourceLanguage,
|
|
157
|
+
targetLanguage,
|
|
158
|
+
sourcePath,
|
|
159
|
+
targetPath,
|
|
160
|
+
baseHash: firstString(edit.baseHash, projection.baseHash, input.baseHash, options.baseHash),
|
|
161
|
+
targetHash: firstString(edit.targetHash, projection.projectedHash, projection.targetHash, input.targetHash, options.targetHash),
|
|
162
|
+
readiness: firstString(edit.readiness, projection.admission?.status, projection.status),
|
|
163
|
+
evidenceIds: uniqueStrings([...strings(input.evidenceIds), ...strings(options.evidenceIds), ...strings(projection.evidenceIds), ...strings(edit.evidenceIds)]),
|
|
164
|
+
metadata: compactRecord({
|
|
165
|
+
sourceProjectionId: projection.id,
|
|
166
|
+
sourceProjectionEditOperationId: edit.operationId
|
|
167
|
+
})
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function uniqueRecords(records) {
|
|
172
|
+
const seen = new Set();
|
|
173
|
+
const result = [];
|
|
174
|
+
for (const record of records) {
|
|
175
|
+
const key = firstString(record.id, record.transformContentHash, record.projectionIdentityHash, record.transformIdentityHash);
|
|
176
|
+
if (!key || seen.has(key)) continue;
|
|
177
|
+
seen.add(key);
|
|
178
|
+
result.push(record);
|
|
179
|
+
}
|
|
180
|
+
return result;
|
|
181
|
+
}
|
|
182
|
+
|
|
123
183
|
function array(value) { if (value === undefined || value === null) return []; return Array.isArray(value) ? value : [value]; }
|
|
124
184
|
function strings(value) { return array(value).map((entry) => String(entry ?? '')).filter(Boolean); }
|
|
125
185
|
function firstString(...values) { return values.map((value) => value === undefined || value === null ? '' : String(value)).find(Boolean); }
|
package/package.json
CHANGED