@shapeshift-labs/frontier-lang-compiler 0.2.109 → 0.2.111

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.
@@ -7,6 +7,7 @@ import type {
7
7
  JsTsSafeMergeSummary
8
8
  } from './js-ts-safe-merge.js';
9
9
  import type { JsTsSafeMemberMergePolicy, JsTsSafeMemberMergePolicyRegion } from './js-ts-safe-member-merge.js';
10
+ import type { NativeProjectImportResult, NativeProjectSymbolGraphSummary } from './native-project.js';
10
11
 
11
12
  export type JsTsProjectSafeMergeStatus = 'merged' | 'blocked';
12
13
  export type JsTsProjectSafeMergeFileStatus = 'merged' | 'blocked';
@@ -53,6 +54,7 @@ export interface JsTsProjectSafeMergeInput {
53
54
  readonly headFiles?: JsTsProjectSafeMergeFileMap;
54
55
  readonly allowFileAdditions?: boolean;
55
56
  readonly allowFileDeletes?: boolean;
57
+ readonly includeOutputProjectSymbolGraph?: boolean;
56
58
  readonly workerChangeSetId?: string;
57
59
  readonly headChangeSetId?: string;
58
60
  readonly policy?: JsTsSafeMemberMergePolicy | readonly JsTsSafeMemberMergePolicyRegion[];
@@ -112,6 +114,8 @@ export interface JsTsProjectSafeMergeResult {
112
114
  readonly status: JsTsProjectSafeMergeStatus;
113
115
  readonly files: readonly JsTsProjectSafeMergeFileResult[];
114
116
  readonly outputFiles: readonly JsTsProjectSafeMergeOutputFile[];
117
+ readonly outputProjectImport?: NativeProjectImportResult;
118
+ readonly outputProjectSymbolGraph?: NativeProjectSymbolGraphSummary;
115
119
  readonly conflicts: readonly JsTsSafeMergeConflict[];
116
120
  readonly admission: JsTsProjectSafeMergeAdmission;
117
121
  readonly summary: {
@@ -78,7 +78,6 @@ export interface ImportNativeProjectOptions {
78
78
  }
79
79
 
80
80
  export type NativeProjectSymbolGraphRemainingField =
81
- | 'moduleEdges[].resolvedTargetSymbolId'
82
81
  | 'moduleEdges[].resolutionKind'
83
82
  | 'moduleEdges[].packageName'
84
83
  | 'moduleEdges[].packageExportCondition'
@@ -112,6 +111,7 @@ export interface NativeProjectSymbolGraphModuleEdgeRecord {
112
111
  readonly moduleSpecifier?: string;
113
112
  readonly resolvedModulePath?: string;
114
113
  readonly targetDocumentId?: string;
114
+ readonly resolvedTargetSymbolId?: string;
115
115
  readonly resolutionKind?: 'relative-source' | 'relative-missing' | string;
116
116
  readonly importKind?: string;
117
117
  readonly exportKind?: string;
@@ -1,6 +1,6 @@
1
1
  import{idFragment,uniqueByEvidenceId,uniqueByLossId,uniqueStrings}from'../../native-import-utils.js';import{createDocument,createPatch,createUniversalAstEnvelope}from'@shapeshift-labs/frontier-lang-kernel';
2
2
  import{createNativeImportResultContract}from'./createNativeImportResultContract.js';import{createProjectImportAdmissionRecord}from'./createProjectImportAdmissionRecord.js';import{mergeSemanticIndexes}from'./mergeSemanticIndexes.js';import{summarizeNativeImportLosses}from'./summarizeNativeImportLosses.js';import{summarizeProjectSourcePreservation}from'./summarizeProjectSourcePreservation.js';
3
- import{resolveRelativeProjectModule}from'./projectSymbolGraphModuleResolution.js';
3
+ import{createProjectModuleSymbolResolver,resolveRelativeProjectModule}from'./projectSymbolGraphModuleResolution.js';
4
4
  export function createNativeProjectImportResult(input, imports) {
5
5
  const idPart = idFragment(input.id ?? input.projectRoot ?? 'native_project');
6
6
  const nodes = {};
@@ -141,7 +141,6 @@ export function createNativeProjectImportResult(input, imports) {
141
141
  }
142
142
 
143
143
  const PROJECT_SYMBOL_GRAPH_REMAINING_FIELDS = Object.freeze([
144
- 'moduleEdges[].resolvedTargetSymbolId',
145
144
  'moduleEdges[].resolutionKind',
146
145
  'moduleEdges[].packageName',
147
146
  'moduleEdges[].packageExportCondition',
@@ -158,16 +157,17 @@ function createProjectSymbolGraphSummary(semanticIndex, imports, input) {
158
157
  const symbolsById = new Map((semanticIndex?.symbols ?? []).map((symbol) => [symbol.id, symbol]));
159
158
  const documentsById = new Map(documents.map((document) => [document.id, document]));
160
159
  const documentsByPath = new Map(documents.filter((document) => document.path).map((document) => [document.path, document]));
160
+ const resolveTargetSymbolId = createProjectModuleSymbolResolver(semanticIndex?.symbols ?? [], documents);
161
161
  const facts = semanticIndex?.facts ?? [];
162
162
  const moduleEdgeFacts = facts.filter((fact) => fact.predicate === 'moduleEdge');
163
163
  const moduleEdgeByRelation = new Map(moduleEdgeFacts.map((fact) => [fact.subjectId, fact]));
164
164
  const relations = semanticIndex?.relations ?? [];
165
165
  const importEdges = relations
166
166
  .filter((relation) => relation.predicate === 'imports')
167
- .map((relation) => moduleEdgeRecord(relation, moduleEdgeByRelation, symbolsById, documentsById, documentsByPath));
167
+ .map((relation) => moduleEdgeRecord(relation, moduleEdgeByRelation, symbolsById, documentsById, documentsByPath, resolveTargetSymbolId));
168
168
  const exportEdges = relations
169
169
  .filter((relation) => relation.predicate === 'exports')
170
- .map((relation) => moduleEdgeRecord(relation, moduleEdgeByRelation, symbolsById, documentsById, documentsByPath));
170
+ .map((relation) => moduleEdgeRecord(relation, moduleEdgeByRelation, symbolsById, documentsById, documentsByPath, resolveTargetSymbolId));
171
171
  const reExportIdentities = uniqueRecords([
172
172
  ...facts
173
173
  .filter((fact) => fact.predicate === 'reExportIdentity' && fact.value)
@@ -213,7 +213,7 @@ function createProjectSymbolGraphSummary(semanticIndex, imports, input) {
213
213
  };
214
214
  }
215
215
 
216
- function moduleEdgeRecord(relation, moduleEdgeByRelation, symbolsById, documentsById, documentsByPath) {
216
+ function moduleEdgeRecord(relation, moduleEdgeByRelation, symbolsById, documentsById, documentsByPath, resolveTargetSymbolId) {
217
217
  const fact = moduleEdgeByRelation.get(relation.id);
218
218
  const value = objectValue(fact?.value);
219
219
  const metadata = objectValue(relation.metadata);
@@ -226,10 +226,13 @@ function moduleEdgeRecord(relation, moduleEdgeByRelation, symbolsById, documents
226
226
  value.moduleSpecifier,
227
227
  metadata.moduleSpecifier,
228
228
  symbolMetadata.moduleSpecifier,
229
+ symbolMetadata.importPath,
230
+ symbolMetadata.exportPath,
231
+ symbolMetadata.source,
229
232
  symbol?.kind === 'module' ? symbol.name : undefined
230
233
  );
231
234
  const resolution = resolveRelativeProjectModule(document?.path, moduleSpecifier, documentsByPath);
232
- return compactRecord({
235
+ const record = {
233
236
  id: relation.id,
234
237
  sourceDocumentId: relation.sourceId,
235
238
  targetSymbolId: relation.targetId,
@@ -241,17 +244,18 @@ function moduleEdgeRecord(relation, moduleEdgeByRelation, symbolsById, documents
241
244
  resolvedModulePath: resolution?.path,
242
245
  targetDocumentId: resolution?.documentId,
243
246
  resolutionKind: resolution?.kind,
244
- importKind: firstString(moduleEdge.importKind, value.importKind),
245
- exportKind: firstString(moduleEdge.exportKind, value.exportKind),
246
- importedName: firstString(moduleEdge.importedName, value.importedName),
247
- exportedName: firstString(moduleEdge.exportedName, value.exportedName),
248
- localName: firstString(moduleEdge.localName, value.localName),
249
- namespace: firstString(moduleEdge.namespace, value.namespace),
247
+ importKind: firstString(moduleEdge.importKind, value.importKind, symbolMetadata.importKind),
248
+ exportKind: firstString(moduleEdge.exportKind, value.exportKind, symbolMetadata.exportKind),
249
+ importedName: firstString(moduleEdge.importedName, value.importedName, symbolMetadata.importedName),
250
+ exportedName: firstString(moduleEdge.exportedName, value.exportedName, symbolMetadata.exportedName),
251
+ localName: firstString(moduleEdge.localName, value.localName, symbolMetadata.localName),
252
+ namespace: firstString(moduleEdge.namespace, value.namespace, symbolMetadata.namespace),
250
253
  isTypeOnly: firstBoolean(moduleEdge.isTypeOnly, value.isTypeOnly),
251
254
  isReExport: firstBoolean(moduleEdge.isReExport, value.isReExport) ?? (relation.predicate === 'exports' && Boolean(moduleSpecifier)),
252
255
  publicContract: firstBoolean(moduleEdge.publicContract, value.publicContract, metadata.publicContract),
253
256
  evidenceIds: uniqueStrings([...(relation.evidenceIds ?? []), ...(fact?.evidenceIds ?? [])])
254
- });
257
+ };
258
+ return compactRecord({ ...record, resolvedTargetSymbolId: resolveTargetSymbolId(record) });
255
259
  }
256
260
 
257
261
  function fileHashRecord(document) {
@@ -10,6 +10,23 @@ export function resolveRelativeProjectModule(sourcePath, moduleSpecifier, docume
10
10
  };
11
11
  }
12
12
 
13
+ export function createProjectModuleSymbolResolver(symbols, documents) {
14
+ const documentsByPath = new Map(documents.filter((document) => document.path).map((document) => [document.path, document]));
15
+ const exportedByDocumentAndName = new Map();
16
+ for (const symbol of symbols ?? []) {
17
+ if (symbol?.kind !== 'export' || !symbol.name) continue;
18
+ const document = documentsByPath.get(symbol.definitionSpan?.path);
19
+ if (!document) continue;
20
+ exportedByDocumentAndName.set(symbolKey(document.id, symbol.name), symbol);
21
+ }
22
+ return function resolveProjectModuleSymbol(edge) {
23
+ if (!edge?.targetDocumentId) return undefined;
24
+ const targetName = targetExportName(edge);
25
+ if (!targetName) return undefined;
26
+ return exportedByDocumentAndName.get(symbolKey(edge.targetDocumentId, targetName))?.id;
27
+ };
28
+ }
29
+
13
30
  function moduleTargetDocument(path, documentsByPath) {
14
31
  for (const candidate of modulePathCandidates(path)) {
15
32
  const document = documentsByPath.get(candidate);
@@ -22,6 +39,16 @@ function modulePathCandidates(path) {
22
39
  return [path, `${path}.js`, `${path}.ts`, `${path}.tsx`, `${path}.jsx`, `${path}/index.js`, `${path}/index.ts`];
23
40
  }
24
41
 
42
+ function targetExportName(edge) {
43
+ const name = edge.importedName ?? edge.localName ?? edge.exportedName;
44
+ if (!name || name === '*') return undefined;
45
+ return String(name);
46
+ }
47
+
48
+ function symbolKey(documentId, name) {
49
+ return `${documentId}\u0000${name}`;
50
+ }
51
+
25
52
  function normalizeProjectPath(path) {
26
53
  const parts = [];
27
54
  for (const part of String(path).split('/')) {
@@ -0,0 +1,35 @@
1
+ import { idFragment } from './native-import-utils.js';
2
+ import { createNativeProjectImportResult } from './internal/index-impl/createNativeProjectImportResult.js';
3
+ import { importNativeSource } from './internal/index-impl/importNativeSource.js';
4
+
5
+ function createJsTsProjectSafeMergeGraphArtifacts(input, outputFiles, mergeId) {
6
+ const sources = outputFiles.map((file) => ({
7
+ id: `${mergeId}_output_${idFragment(file.sourcePath)}`,
8
+ language: file.language ?? input.language ?? languageForPath(file.sourcePath),
9
+ sourcePath: file.sourcePath,
10
+ sourceText: file.sourceText,
11
+ metadata: { semanticImportExpected: true, projectSafeMergeOutput: true }
12
+ }));
13
+ const imports = sources.map((source) => importNativeSource(source));
14
+ const projectImport = createNativeProjectImportResult({
15
+ id: `${mergeId}_output_project_import`,
16
+ projectRoot: input.projectRoot,
17
+ sources,
18
+ metadata: {
19
+ projectSafeMergeId: mergeId,
20
+ outputProjectSymbolGraph: true
21
+ }
22
+ }, imports);
23
+ return {
24
+ projectImport,
25
+ projectSymbolGraph: projectImport.projectSymbolGraph
26
+ };
27
+ }
28
+
29
+ function languageForPath(sourcePath) {
30
+ const path = String(sourcePath ?? '').toLowerCase();
31
+ if (path.endsWith('.js') || path.endsWith('.jsx') || path.endsWith('.mjs') || path.endsWith('.cjs')) return 'javascript';
32
+ return 'typescript';
33
+ }
34
+
35
+ export { createJsTsProjectSafeMergeGraphArtifacts };
@@ -1,6 +1,7 @@
1
1
  import { hashSemanticValue } from '@shapeshift-labs/frontier-lang-kernel';
2
2
  import { safeMergeJsTsSource } from './js-ts-safe-merge-composed.js';
3
3
  import { compactRecord } from './js-ts-safe-merge-context.js';
4
+ import { createJsTsProjectSafeMergeGraphArtifacts } from './js-ts-safe-project-merge-graph.js';
4
5
 
5
6
  function safeMergeJsTsProject(input = {}) {
6
7
  const id = String(input.id ?? 'js_ts_project_safe_merge');
@@ -18,6 +19,9 @@ function safeMergeJsTsProject(input = {}) {
18
19
  operation: file.operation
19
20
  }));
20
21
  const reasonCodes = uniqueStrings(blockedFiles.flatMap((file) => file.admission.reasonCodes));
22
+ const graphArtifacts = status === 'merged' && input.includeOutputProjectSymbolGraph
23
+ ? createJsTsProjectSafeMergeGraphArtifacts(input, outputFiles, id)
24
+ : undefined;
21
25
  const core = {
22
26
  kind: 'frontier.lang.jsTsProjectSafeMerge',
23
27
  version: 1,
@@ -26,6 +30,8 @@ function safeMergeJsTsProject(input = {}) {
26
30
  status,
27
31
  files: fileResults,
28
32
  outputFiles,
33
+ outputProjectImport: graphArtifacts?.projectImport,
34
+ outputProjectSymbolGraph: graphArtifacts?.projectSymbolGraph,
29
35
  conflicts: fileResults.flatMap((file) => file.conflicts),
30
36
  admission: {
31
37
  status: status === 'merged' ? 'auto-merge-candidate' : 'blocked',
@@ -43,6 +49,7 @@ function safeMergeJsTsProject(input = {}) {
43
49
  headChangeSetId: input.headChangeSetId,
44
50
  projectRoot: input.projectRoot,
45
51
  filesInput: Array.isArray(input.files) ? 'records' : 'maps',
52
+ outputProjectSymbolGraph: Boolean(graphArtifacts?.projectSymbolGraph),
46
53
  autoMergeClaim: false,
47
54
  semanticEquivalenceClaim: false
48
55
  })
@@ -71,6 +71,8 @@ function nativeImportBindingDeclaration(input, lineNumber, importPath, binding,
71
71
  },
72
72
  metadata: {
73
73
  scan: 'lightweight-import-binding',
74
+ importPath: String(importPath),
75
+ moduleSpecifier: String(importPath),
74
76
  localName,
75
77
  importedName,
76
78
  importKind,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shapeshift-labs/frontier-lang-compiler",
3
- "version": "0.2.109",
3
+ "version": "0.2.111",
4
4
  "description": "Compiler facade for Frontier Lang source documents and language projection adapters.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",