@shapeshift-labs/frontier-lang-compiler 0.2.73 → 0.2.75
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/README.md +32 -0
- package/bench/native-transform-suite.mjs +37 -0
- package/bench/smoke.mjs +4 -0
- package/dist/declarations/semantic-lineage.d.ts +48 -0
- package/dist/index.js +1 -0
- package/dist/internal/index-impl/semanticLineageResolutionRecords.js +195 -0
- package/dist/language-adapter-package-rows.js +5 -5
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -418,6 +418,38 @@ console.log(querySemanticHistoryRecordOverlaps([left, right])[0].conflict); // t
|
|
|
418
418
|
|
|
419
419
|
The record stores base/target hashes, source and import IDs, ownership-region keys, semantic candidate IDs and conflict keys, evidence/proof IDs, reviewer and admission status, plus replay links. Overlap queries compare those compact indexes directly, so centralized and distributed swarms can find shared regions, stale-base conflicts, and replay targets without loading source text.
|
|
420
420
|
|
|
421
|
+
Resolve old semantic anchors through move/rename/split/delete lineage before a coordinator decides whether a worker bundle still touches the current code shape:
|
|
422
|
+
|
|
423
|
+
```js
|
|
424
|
+
import {
|
|
425
|
+
createSemanticLineageEvent,
|
|
426
|
+
createSemanticLineageMap,
|
|
427
|
+
resolveSemanticLineage
|
|
428
|
+
} from '@shapeshift-labs/frontier-lang-compiler';
|
|
429
|
+
|
|
430
|
+
const lineage = createSemanticLineageMap([
|
|
431
|
+
createSemanticLineageEvent({
|
|
432
|
+
eventKind: 'moved',
|
|
433
|
+
from: { key: 'source#src/runtime.ts#function#step' },
|
|
434
|
+
to: { key: 'source#src/runtime-core.ts#function#step' },
|
|
435
|
+
evidenceIds: ['evidence_source_scan']
|
|
436
|
+
}),
|
|
437
|
+
createSemanticLineageEvent({
|
|
438
|
+
eventKind: 'renamed',
|
|
439
|
+
from: { key: 'source#src/runtime-core.ts#function#step' },
|
|
440
|
+
to: { key: 'source#src/runtime-core.ts#function#advance' }
|
|
441
|
+
})
|
|
442
|
+
]);
|
|
443
|
+
|
|
444
|
+
const resolution = resolveSemanticLineage(lineage, 'source#src/runtime.ts#function#step');
|
|
445
|
+
|
|
446
|
+
console.log(resolution.status); // "resolved"
|
|
447
|
+
console.log(resolution.currentAnchors[0].key); // current semantic anchor
|
|
448
|
+
console.log(resolution.traversedEventIds); // compact history path
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
Resolver output is merge-admission evidence: it helps a swarm compare old worker bundles against current semantic anchors after code moved, split, or was deleted. It is not proof that the projected code is correct or semantically equivalent; admission still needs tests, source evidence, review status, and conflict scoring.
|
|
452
|
+
|
|
421
453
|
Extract a surgical semantic slice when a worker only needs one symbol, region, native AST node, or source path:
|
|
422
454
|
|
|
423
455
|
```js
|
|
@@ -2,12 +2,15 @@ import { performance } from 'node:perf_hooks';
|
|
|
2
2
|
import {
|
|
3
3
|
compileNativeSource,
|
|
4
4
|
createNativeSourcePreservation,
|
|
5
|
+
createSemanticLineageEvent,
|
|
6
|
+
createSemanticLineageMap,
|
|
5
7
|
createSemanticImportSidecar,
|
|
6
8
|
createSemanticSlice,
|
|
7
9
|
createSemanticSliceAdmissionRecord,
|
|
8
10
|
createUniversalConversionArtifacts,
|
|
9
11
|
createUniversalConversionPlan,
|
|
10
12
|
projectNativeImportToSource,
|
|
13
|
+
resolveSemanticLineageBatch,
|
|
11
14
|
summarizeNativeImportFeatureEvidence,
|
|
12
15
|
testSemanticSlice
|
|
13
16
|
} from '../dist/index.js';
|
|
@@ -59,6 +62,36 @@ export function measureNativeTransformations(nativeImportResults) {
|
|
|
59
62
|
const conversionArtifacts = createUniversalConversionArtifacts(conversionPlan);
|
|
60
63
|
const conversionArtifactsDurationMs = performance.now() - conversionArtifactsStart;
|
|
61
64
|
|
|
65
|
+
const lineageResolutionStart = performance.now();
|
|
66
|
+
const lineageEvents = [];
|
|
67
|
+
const lineageQueries = [];
|
|
68
|
+
for (let index = 0; index < 100; index += 1) {
|
|
69
|
+
const fromKey = `bench#lineage#${index}#0`;
|
|
70
|
+
const midKey = `bench#lineage#${index}#1`;
|
|
71
|
+
const targetKey = `bench#lineage#${index}#2`;
|
|
72
|
+
lineageQueries.push(fromKey);
|
|
73
|
+
lineageEvents.push(createSemanticLineageEvent({
|
|
74
|
+
id: `bench_lineage_${index}_move`,
|
|
75
|
+
createdAt: index * 2,
|
|
76
|
+
eventKind: 'moved',
|
|
77
|
+
from: { key: fromKey, sourcePath: `src/${index}.ts` },
|
|
78
|
+
to: { key: midKey, sourcePath: `src/runtime/${index}.ts` },
|
|
79
|
+
confidence: 0.96
|
|
80
|
+
}));
|
|
81
|
+
lineageEvents.push(createSemanticLineageEvent({
|
|
82
|
+
id: `bench_lineage_${index}_rename`,
|
|
83
|
+
createdAt: index * 2 + 1,
|
|
84
|
+
eventKind: index % 10 === 0 ? 'split' : 'renamed',
|
|
85
|
+
from: { key: midKey, sourcePath: `src/runtime/${index}.ts` },
|
|
86
|
+
to: index % 10 === 0
|
|
87
|
+
? [{ key: `${targetKey}:a` }, { key: `${targetKey}:b` }]
|
|
88
|
+
: { key: targetKey, sourcePath: `src/runtime/${index}.ts` },
|
|
89
|
+
confidence: 0.91
|
|
90
|
+
}));
|
|
91
|
+
}
|
|
92
|
+
const lineageResolutions = resolveSemanticLineageBatch(createSemanticLineageMap(lineageEvents), lineageQueries);
|
|
93
|
+
const lineageResolutionDurationMs = performance.now() - lineageResolutionStart;
|
|
94
|
+
|
|
62
95
|
const featureEvidenceStart = performance.now();
|
|
63
96
|
const featureEvidenceSummaries = nativeImportResults.map((imported) => summarizeNativeImportFeatureEvidence(imported.losses, {
|
|
64
97
|
evidence: imported.evidence
|
|
@@ -112,6 +145,10 @@ export function measureNativeTransformations(nativeImportResults) {
|
|
|
112
145
|
conversionArtifactAdmissionEvidenceIds: conversionArtifacts.summary.evidenceIds,
|
|
113
146
|
conversionArtifactAdmissionProofIds: conversionArtifacts.summary.proofIds,
|
|
114
147
|
conversionArtifactsDurationMs,
|
|
148
|
+
lineageResolutionEvents: lineageEvents.length,
|
|
149
|
+
lineageResolutions: lineageResolutions.length,
|
|
150
|
+
lineageResolutionAmbiguous: lineageResolutions.filter((result) => result.status === 'ambiguous').length,
|
|
151
|
+
lineageResolutionDurationMs,
|
|
115
152
|
featureEvidencePolicyMatches,
|
|
116
153
|
featureEvidenceDurationMs,
|
|
117
154
|
nativeProjections: nativeProjections.length,
|
package/bench/smoke.mjs
CHANGED
|
@@ -82,6 +82,10 @@ console.log(JSON.stringify({
|
|
|
82
82
|
conversionArtifactAdmissionEvidenceIds: transformMetrics.conversionArtifactAdmissionEvidenceIds,
|
|
83
83
|
conversionArtifactAdmissionProofIds: transformMetrics.conversionArtifactAdmissionProofIds,
|
|
84
84
|
conversionArtifactsDurationMs: Number(transformMetrics.conversionArtifactsDurationMs.toFixed(2)),
|
|
85
|
+
lineageResolutionEvents: transformMetrics.lineageResolutionEvents,
|
|
86
|
+
lineageResolutions: transformMetrics.lineageResolutions,
|
|
87
|
+
lineageResolutionAmbiguous: transformMetrics.lineageResolutionAmbiguous,
|
|
88
|
+
lineageResolutionDurationMs: Number(transformMetrics.lineageResolutionDurationMs.toFixed(2)),
|
|
85
89
|
featureEvidencePolicyMatches: transformMetrics.featureEvidencePolicyMatches,
|
|
86
90
|
featureEvidenceDurationMs: Number(transformMetrics.featureEvidenceDurationMs.toFixed(2)),
|
|
87
91
|
nativeProjections: transformMetrics.nativeProjections,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { FrontierSourceLanguage, SourceSpan } from '@shapeshift-labs/frontier-lang-kernel';
|
|
2
2
|
|
|
3
3
|
export type SemanticLineageEventKind = 'unchanged' | 'moved' | 'renamed' | 'split' | 'merged' | 'deleted' | 'recreated' | 'unknown' | string;
|
|
4
|
+
export type SemanticLineageResolutionStatus = 'unchanged' | 'resolved' | 'ambiguous' | 'deleted' | 'recreated' | 'cycle' | 'max-depth' | 'not-found' | string;
|
|
4
5
|
|
|
5
6
|
export interface SemanticAnchor {
|
|
6
7
|
readonly id?: string;
|
|
@@ -126,6 +127,50 @@ export interface SemanticLineageMap {
|
|
|
126
127
|
};
|
|
127
128
|
}
|
|
128
129
|
|
|
130
|
+
export interface SemanticLineageResolutionQuery {
|
|
131
|
+
readonly id?: string;
|
|
132
|
+
readonly anchor?: SemanticAnchor | string;
|
|
133
|
+
readonly anchorKey?: string;
|
|
134
|
+
readonly key?: string;
|
|
135
|
+
readonly sourcePath?: string;
|
|
136
|
+
readonly sourceHash?: string;
|
|
137
|
+
readonly symbolId?: string;
|
|
138
|
+
readonly symbolName?: string;
|
|
139
|
+
readonly maxDepth?: number;
|
|
140
|
+
readonly generatedAt?: number | string;
|
|
141
|
+
readonly metadata?: Record<string, unknown>;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export interface SemanticLineageResolution {
|
|
145
|
+
readonly kind: 'frontier.lang.semanticLineageResolution';
|
|
146
|
+
readonly version: 1;
|
|
147
|
+
readonly id: string;
|
|
148
|
+
readonly stableId: string;
|
|
149
|
+
readonly hash: string;
|
|
150
|
+
readonly generatedAt: number | string;
|
|
151
|
+
readonly query: {
|
|
152
|
+
readonly anchorKey?: string;
|
|
153
|
+
readonly anchorId?: string;
|
|
154
|
+
readonly sourcePath?: string;
|
|
155
|
+
readonly symbolName?: string;
|
|
156
|
+
readonly maxDepth?: number;
|
|
157
|
+
};
|
|
158
|
+
readonly startAnchor?: SemanticAnchor;
|
|
159
|
+
readonly currentAnchors: readonly SemanticAnchor[];
|
|
160
|
+
readonly traversedEventIds: readonly string[];
|
|
161
|
+
readonly terminalEventIds: readonly string[];
|
|
162
|
+
readonly status: SemanticLineageResolutionStatus;
|
|
163
|
+
readonly confidence?: number;
|
|
164
|
+
readonly conflictKeys: readonly string[];
|
|
165
|
+
readonly evidenceIds: readonly string[];
|
|
166
|
+
readonly proofIds: readonly string[];
|
|
167
|
+
readonly crdtOperationIds: readonly string[];
|
|
168
|
+
readonly crdtHeads: readonly string[];
|
|
169
|
+
readonly lineageEventKinds: readonly SemanticLineageEventKind[];
|
|
170
|
+
readonly reasonCodes: readonly string[];
|
|
171
|
+
readonly metadata?: Record<string, unknown>;
|
|
172
|
+
}
|
|
173
|
+
|
|
129
174
|
export interface SemanticLineageQuery {
|
|
130
175
|
readonly eventKind?: SemanticLineageEventKind | readonly string[];
|
|
131
176
|
readonly anchorKey?: string | readonly string[];
|
|
@@ -139,7 +184,10 @@ export interface SemanticLineageQuery {
|
|
|
139
184
|
}
|
|
140
185
|
|
|
141
186
|
export declare const SemanticLineageEventKinds: readonly SemanticLineageEventKind[];
|
|
187
|
+
export declare const SemanticLineageResolutionStatuses: readonly SemanticLineageResolutionStatus[];
|
|
142
188
|
export declare function createSemanticAnchor(input?: SemanticAnchor | string, defaults?: Partial<SemanticAnchor>): SemanticAnchor | undefined;
|
|
143
189
|
export declare function createSemanticLineageEvent(input?: CreateSemanticLineageEventInput, options?: { readonly id?: string; readonly createdAt?: number | string; readonly actor?: SemanticLineageActor | string; readonly actorId?: string; readonly actorRole?: string }): SemanticLineageEvent;
|
|
144
190
|
export declare function createSemanticLineageMap(events?: readonly (SemanticLineageEvent | CreateSemanticLineageEventInput)[], options?: { readonly id?: string; readonly generatedAt?: number | string }): SemanticLineageMap;
|
|
145
191
|
export declare function querySemanticLineageEvents(events: SemanticLineageEvent | readonly SemanticLineageEvent[], query?: SemanticLineageQuery): readonly SemanticLineageEvent[];
|
|
192
|
+
export declare function resolveSemanticLineage(eventsOrMap?: SemanticLineageMap | readonly (SemanticLineageEvent | CreateSemanticLineageEventInput)[], query?: SemanticLineageResolutionQuery | SemanticAnchor | string, options?: { readonly id?: string; readonly generatedAt?: number | string; readonly maxDepth?: number; readonly metadata?: Record<string, unknown> }): SemanticLineageResolution;
|
|
193
|
+
export declare function resolveSemanticLineageBatch(eventsOrMap?: SemanticLineageMap | readonly (SemanticLineageEvent | CreateSemanticLineageEventInput)[], queries?: readonly (SemanticLineageResolutionQuery | SemanticAnchor | string)[], options?: { readonly generatedAt?: number | string; readonly maxDepth?: number; readonly metadata?: Record<string, unknown> }): readonly SemanticLineageResolution[];
|
package/dist/index.js
CHANGED
|
@@ -69,6 +69,7 @@ export { createSemanticMergeCandidateAdmissionRecord, decorateSemanticMergeCandi
|
|
|
69
69
|
export { querySemanticMergeConflictClasses, SemanticMergeConflictClasses, semanticMergeConflictRiskScore, sortSemanticMergeCandidatesByConflictRisk, summarizeSemanticMergeConflicts } from './internal/index-impl/semanticMergeConflicts.js';
|
|
70
70
|
export { queryUniversalConversionPlan } from './internal/index-impl/queryUniversalConversionPlan.js';
|
|
71
71
|
export { createSemanticAnchor, createSemanticLineageEvent, createSemanticLineageMap, querySemanticLineageEvents, SemanticLineageEventKinds } from './internal/index-impl/semanticLineageRecords.js';
|
|
72
|
+
export { resolveSemanticLineage, resolveSemanticLineageBatch, SemanticLineageResolutionStatuses } from './internal/index-impl/semanticLineageResolutionRecords.js';
|
|
72
73
|
export { createSemanticHistoryRecord, querySemanticHistoryRecordOverlaps, SemanticHistoryAdmissionStatuses, SemanticHistoryConflictReasons, SemanticHistoryOverlapKinds, SemanticHistoryReviewerStatuses, semanticHistoryRecordsConflict, semanticHistoryRecordsOverlap } from './internal/index-impl/semanticHistoryRecords.js';
|
|
73
74
|
export { readSemanticSliceJson } from './internal/index-impl/readSemanticSliceJson.js';
|
|
74
75
|
export { readUniversalAstJson } from './internal/index-impl/readUniversalAstJson.js';
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { hashSemanticValue } from '@shapeshift-labs/frontier-lang-kernel';
|
|
2
|
+
import { idFragment, uniqueStrings as uniqueRawStrings } from '../../native-import-utils.js';
|
|
3
|
+
import { createSemanticAnchor, createSemanticLineageEvent } from './semanticLineageRecords.js';
|
|
4
|
+
|
|
5
|
+
export const SemanticLineageResolutionStatuses = Object.freeze(['unchanged', 'resolved', 'ambiguous', 'deleted', 'recreated', 'cycle', 'max-depth', 'not-found']);
|
|
6
|
+
|
|
7
|
+
export function resolveSemanticLineage(eventsOrMap = [], query = {}, options = {}) {
|
|
8
|
+
const events = lineageEventsFrom(eventsOrMap);
|
|
9
|
+
const resolutionQuery = normalizeResolutionQuery(query);
|
|
10
|
+
const start = createSemanticAnchor(resolutionQuery.anchor ?? resolutionQuery.anchorKey ?? resolutionQuery.key ?? resolutionQuery, resolutionQuery);
|
|
11
|
+
const maxDepth = positiveInteger(resolutionQuery.maxDepth ?? options.maxDepth, 64);
|
|
12
|
+
const byFromKey = new Map();
|
|
13
|
+
const byFromId = new Map();
|
|
14
|
+
for (const event of events.slice().sort(compareLineageEvents)) {
|
|
15
|
+
indexLineageEvent(byFromKey, event.from?.key, event);
|
|
16
|
+
indexLineageEvent(byFromId, event.from?.id, event);
|
|
17
|
+
}
|
|
18
|
+
const state = createResolutionState(start);
|
|
19
|
+
const visitedEvents = new Set();
|
|
20
|
+
const visitedStates = new Set([anchorStateKey(state.current)]);
|
|
21
|
+
for (let depth = 0; depth < maxDepth; depth += 1) {
|
|
22
|
+
const nextEvents = nextLineageEvents(state.current, byFromKey, byFromId).filter((event) => !visitedEvents.has(event.id));
|
|
23
|
+
if (nextEvents.length === 0) break;
|
|
24
|
+
for (const event of nextEvents) applyLineageEvent(state, event, visitedEvents);
|
|
25
|
+
const key = anchorStateKey(state.current);
|
|
26
|
+
if (visitedStates.has(key) && key) {
|
|
27
|
+
state.cycle = true;
|
|
28
|
+
state.status = 'cycle';
|
|
29
|
+
state.reasonCodes.push('lineage-cycle');
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
visitedStates.add(key);
|
|
33
|
+
}
|
|
34
|
+
if (resolutionHitMaxDepth(state, maxDepth, byFromKey, byFromId, visitedEvents)) {
|
|
35
|
+
state.maxDepthHit = true;
|
|
36
|
+
state.status = 'max-depth';
|
|
37
|
+
state.reasonCodes.push('max-depth');
|
|
38
|
+
}
|
|
39
|
+
if (!state.cycle && !state.maxDepthHit) state.status = classifyResolutionStatus(state);
|
|
40
|
+
return buildResolutionRecord(state, start, maxDepth, resolutionQuery, options);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function resolveSemanticLineageBatch(eventsOrMap = [], queries = [], options = {}) {
|
|
44
|
+
return array(queries).map((query) => resolveSemanticLineage(eventsOrMap, query, options));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function createResolutionState(start) {
|
|
48
|
+
return {
|
|
49
|
+
current: start ? [start] : [],
|
|
50
|
+
traversed: [],
|
|
51
|
+
terminal: [],
|
|
52
|
+
conflictKeys: [],
|
|
53
|
+
evidenceIds: [],
|
|
54
|
+
proofIds: [],
|
|
55
|
+
operationIds: [],
|
|
56
|
+
heads: [],
|
|
57
|
+
eventKinds: [],
|
|
58
|
+
reasonCodes: [],
|
|
59
|
+
confidence: start ? 1 : undefined,
|
|
60
|
+
status: start ? 'unchanged' : 'not-found',
|
|
61
|
+
cycle: false,
|
|
62
|
+
maxDepthHit: false
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function buildResolutionRecord(state, start, maxDepth, query, options) {
|
|
67
|
+
const core = {
|
|
68
|
+
kind: 'frontier.lang.semanticLineageResolution',
|
|
69
|
+
version: 1,
|
|
70
|
+
query: compactRecord({ anchorKey: start?.key, anchorId: start?.id, sourcePath: start?.sourcePath, symbolName: start?.symbolName, maxDepth }),
|
|
71
|
+
startAnchor: start,
|
|
72
|
+
currentAnchors: uniqueAnchors(state.current),
|
|
73
|
+
traversedEventIds: uniqueStrings(state.traversed),
|
|
74
|
+
terminalEventIds: uniqueStrings(state.terminal),
|
|
75
|
+
status: state.status,
|
|
76
|
+
confidence: clampConfidence(state.confidence),
|
|
77
|
+
conflictKeys: uniqueStrings(state.conflictKeys),
|
|
78
|
+
evidenceIds: uniqueStrings(state.evidenceIds),
|
|
79
|
+
proofIds: uniqueStrings(state.proofIds),
|
|
80
|
+
crdtOperationIds: uniqueStrings(state.operationIds),
|
|
81
|
+
crdtHeads: uniqueStrings(state.heads),
|
|
82
|
+
lineageEventKinds: uniqueStrings(state.eventKinds),
|
|
83
|
+
reasonCodes: uniqueStrings(state.reasonCodes),
|
|
84
|
+
metadata: compactRecord(options.metadata ?? query.metadata)
|
|
85
|
+
};
|
|
86
|
+
const hash = hashSemanticValue(core);
|
|
87
|
+
return {
|
|
88
|
+
...core,
|
|
89
|
+
id: options.id ?? query.id ?? `semantic_lineage_resolution_${idFragment(firstString(start?.key, start?.id, hash))}`,
|
|
90
|
+
stableId: `semantic_lineage_resolution_${idFragment(hash)}`,
|
|
91
|
+
hash,
|
|
92
|
+
generatedAt: options.generatedAt ?? query.generatedAt ?? Date.now()
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function applyLineageEvent(state, event, visitedEvents) {
|
|
97
|
+
visitedEvents.add(event.id);
|
|
98
|
+
state.traversed.push(event.id);
|
|
99
|
+
state.conflictKeys.push(...(event.conflictKeys ?? []));
|
|
100
|
+
state.evidenceIds.push(...(event.evidenceIds ?? []));
|
|
101
|
+
state.proofIds.push(...(event.proofIds ?? []));
|
|
102
|
+
state.operationIds.push(event.crdt?.operationId);
|
|
103
|
+
state.heads.push(...(event.crdt?.heads ?? []));
|
|
104
|
+
state.eventKinds.push(event.eventKind);
|
|
105
|
+
if (event.confidence !== undefined) state.confidence = state.confidence === undefined ? event.confidence : Math.min(state.confidence, event.confidence);
|
|
106
|
+
const matched = state.current.filter((anchor) => anchorsMatch(anchor, event.from));
|
|
107
|
+
const unmatched = state.current.filter((anchor) => !anchorsMatch(anchor, event.from));
|
|
108
|
+
if (event.eventKind === 'deleted' || event.to.length === 0) {
|
|
109
|
+
state.current = unmatched;
|
|
110
|
+
state.terminal.push(event.id);
|
|
111
|
+
state.reasonCodes.push(event.eventKind === 'deleted' ? 'anchor-deleted' : 'lineage-event-without-target-anchor');
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
state.current = uniqueAnchors([...unmatched, ...event.to]);
|
|
115
|
+
if (matched.length === 0) state.reasonCodes.push('lineage-event-applied-by-index');
|
|
116
|
+
if (event.eventKind === 'split' || event.to.length > 1) state.reasonCodes.push('anchor-split');
|
|
117
|
+
if (event.eventKind === 'merged') state.reasonCodes.push('anchor-merged');
|
|
118
|
+
if (event.eventKind === 'recreated') state.reasonCodes.push('anchor-recreated');
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function lineageEventsFrom(value) {
|
|
122
|
+
const source = value?.kind === 'frontier.lang.semanticLineageMap' ? value.events : value;
|
|
123
|
+
return array(source).map((event) => event?.kind === 'frontier.lang.semanticLineageEvent' ? event : createSemanticLineageEvent(event)).filter(Boolean);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function resolutionHitMaxDepth(state, maxDepth, byFromKey, byFromId, visitedEvents) {
|
|
127
|
+
return !state.cycle && state.traversed.length >= maxDepth && nextLineageEvents(state.current, byFromKey, byFromId).some((event) => !visitedEvents.has(event.id));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function nextLineageEvents(anchors, byFromKey, byFromId) {
|
|
131
|
+
const records = [];
|
|
132
|
+
for (const anchor of anchors) {
|
|
133
|
+
for (const event of byFromKey.get(String(anchor.key ?? '')) ?? []) records.push(event);
|
|
134
|
+
for (const event of byFromId.get(String(anchor.id ?? '')) ?? []) records.push(event);
|
|
135
|
+
}
|
|
136
|
+
return uniqueEvents(records).sort(compareLineageEvents);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function classifyResolutionStatus(state) {
|
|
140
|
+
if (state.current.length === 0 && state.traversed.length > 0) return 'deleted';
|
|
141
|
+
if (state.eventKinds.includes('recreated')) return 'recreated';
|
|
142
|
+
if (state.current.length > 1 || state.eventKinds.includes('split') || state.eventKinds.includes('merged')) return 'ambiguous';
|
|
143
|
+
if (state.traversed.length > 0) return 'resolved';
|
|
144
|
+
return 'unchanged';
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function indexLineageEvent(index, key, event) {
|
|
148
|
+
if (!key) return;
|
|
149
|
+
const value = String(key);
|
|
150
|
+
if (!index.has(value)) index.set(value, []);
|
|
151
|
+
index.get(value).push(event);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function normalizeResolutionQuery(query) { return typeof query === 'string' ? { anchorKey: query } : query ?? {}; }
|
|
155
|
+
function anchorsMatch(left, right) { return Boolean(left && right && ((left.key && left.key === right.key) || (left.id && left.id === right.id))); }
|
|
156
|
+
function anchorStateKey(anchors) { return uniqueStrings(anchors.map((anchor) => anchor.key ?? anchor.id)).sort().join('|'); }
|
|
157
|
+
function compareLineageEvents(left, right) { return compareCreatedAt(left.createdAt, right.createdAt) || String(left.id).localeCompare(String(right.id)); }
|
|
158
|
+
function compareCreatedAt(left, right) {
|
|
159
|
+
const leftNumber = Number(left);
|
|
160
|
+
const rightNumber = Number(right);
|
|
161
|
+
if (Number.isFinite(leftNumber) && Number.isFinite(rightNumber) && leftNumber !== rightNumber) return leftNumber - rightNumber;
|
|
162
|
+
return String(left ?? '').localeCompare(String(right ?? ''));
|
|
163
|
+
}
|
|
164
|
+
function uniqueAnchors(anchors) {
|
|
165
|
+
const seen = new Set();
|
|
166
|
+
return anchors.filter(Boolean).filter((anchor) => {
|
|
167
|
+
const key = anchor.key ?? anchor.id;
|
|
168
|
+
if (!key || seen.has(key)) return false;
|
|
169
|
+
seen.add(key);
|
|
170
|
+
return true;
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
function uniqueEvents(events) {
|
|
174
|
+
const seen = new Set();
|
|
175
|
+
return events.filter((event) => {
|
|
176
|
+
if (!event?.id || seen.has(event.id)) return false;
|
|
177
|
+
seen.add(event.id);
|
|
178
|
+
return true;
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
function positiveInteger(value, fallback) {
|
|
182
|
+
const number = Number(value);
|
|
183
|
+
return Number.isFinite(number) && number > 0 ? Math.floor(number) : fallback;
|
|
184
|
+
}
|
|
185
|
+
function clampConfidence(value) {
|
|
186
|
+
if (value === undefined || value === null || value === '') return undefined;
|
|
187
|
+
const number = Number(value);
|
|
188
|
+
if (!Number.isFinite(number)) return undefined;
|
|
189
|
+
return Math.max(0, Math.min(1, number));
|
|
190
|
+
}
|
|
191
|
+
function array(value) { return value === undefined || value === null ? [] : Array.isArray(value) ? value : [value]; }
|
|
192
|
+
function strings(value) { return array(value).map((entry) => String(entry ?? '')).filter(Boolean); }
|
|
193
|
+
function uniqueStrings(values) { return uniqueRawStrings(strings(values)); }
|
|
194
|
+
function firstString(...values) { return values.map((value) => value === undefined || value === null ? '' : String(value)).find(Boolean); }
|
|
195
|
+
function compactRecord(value) { return Object.fromEntries(Object.entries(value ?? {}).filter(([, entry]) => entry !== undefined && (!Array.isArray(entry) || entry.length > 0))); }
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
const packageRows = [
|
|
2
|
-
row('@shapeshift-labs/frontier-lang-typescript', '0.3.
|
|
3
|
-
row('@shapeshift-labs/frontier-lang-javascript', '0.2.
|
|
4
|
-
row('@shapeshift-labs/frontier-lang-rust', '0.2.
|
|
5
|
-
row('@shapeshift-labs/frontier-lang-python', '0.2.
|
|
6
|
-
row('@shapeshift-labs/frontier-lang-c', '0.2.
|
|
2
|
+
row('@shapeshift-labs/frontier-lang-typescript', '0.3.9', 'typescript', 'typescript-compiler-api', { target: 'typescript' }),
|
|
3
|
+
row('@shapeshift-labs/frontier-lang-javascript', '0.2.9', 'javascript', 'estree', { target: 'javascript', formats: ['estree', 'babel'] }),
|
|
4
|
+
row('@shapeshift-labs/frontier-lang-rust', '0.2.9', 'rust', 'rust-syn', { target: 'rust', proofKeys: ['parserAst', 'sourceMap', 'semanticSidecar', 'macroExpansionEvidence'] }),
|
|
5
|
+
row('@shapeshift-labs/frontier-lang-python', '0.2.9', 'python', 'python-ast', { target: 'python', formats: ['python-ast', 'libcst'] }),
|
|
6
|
+
row('@shapeshift-labs/frontier-lang-c', '0.2.9', 'c', 'clang-ast-json', { target: 'c', proofKeys: ['parserAst', 'sourceMap', 'semanticSidecar', 'compileCommandsHash', 'preprocessorRecordsHash'] }),
|
|
7
7
|
platform('@shapeshift-labs/frontier-lang-java', '0.1.8', 'java', 'java-ast', ['semanticdb', 'lsp']),
|
|
8
8
|
platform('@shapeshift-labs/frontier-lang-kotlin', '0.1.8', 'kotlin', 'kotlin-psi', ['semanticdb', 'lsp']),
|
|
9
9
|
platform('@shapeshift-labs/frontier-lang-swift', '0.1.8', 'swift', 'swift-syntax', ['sourcekit-lsp', 'lsp']),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shapeshift-labs/frontier-lang-compiler",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.75",
|
|
4
4
|
"description": "Compiler facade for Frontier Lang source documents and language projection adapters.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -61,14 +61,14 @@
|
|
|
61
61
|
"access": "public"
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"@shapeshift-labs/frontier-lang-c": "0.2.
|
|
65
|
-
"@shapeshift-labs/frontier-lang-checker": "0.3.
|
|
66
|
-
"@shapeshift-labs/frontier-lang-javascript": "0.2.
|
|
64
|
+
"@shapeshift-labs/frontier-lang-c": "0.2.9",
|
|
65
|
+
"@shapeshift-labs/frontier-lang-checker": "0.3.8",
|
|
66
|
+
"@shapeshift-labs/frontier-lang-javascript": "0.2.9",
|
|
67
67
|
"@shapeshift-labs/frontier-lang-kernel": "0.3.12",
|
|
68
|
-
"@shapeshift-labs/frontier-lang-parser": "0.3.
|
|
69
|
-
"@shapeshift-labs/frontier-lang-python": "0.2.
|
|
70
|
-
"@shapeshift-labs/frontier-lang-rust": "0.2.
|
|
71
|
-
"@shapeshift-labs/frontier-lang-typescript": "0.3.
|
|
68
|
+
"@shapeshift-labs/frontier-lang-parser": "0.3.8",
|
|
69
|
+
"@shapeshift-labs/frontier-lang-python": "0.2.9",
|
|
70
|
+
"@shapeshift-labs/frontier-lang-rust": "0.2.9",
|
|
71
|
+
"@shapeshift-labs/frontier-lang-typescript": "0.3.9"
|
|
72
72
|
},
|
|
73
73
|
"devDependencies": {
|
|
74
74
|
"typescript": "^5.9.3"
|