@shapeshift-labs/frontier-lang-compiler 0.2.9 → 0.2.11

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 CHANGED
@@ -50,6 +50,8 @@ console.log(summary.categories);
50
50
  console.log(readiness.readiness);
51
51
  ```
52
52
 
53
+ The loss taxonomy separates broad scanner limits from specific round-trip risks such as conditional compilation, reflection, overload/type-inference gaps, comments/trivia preservation, source-map approximation, parser diagnostics, and target projection loss. These records are evidence labels for merge admission; they are not claims that the lightweight scanner expanded macros, evaluated inactive branches, resolved overloads, or ran a type checker.
54
+
53
55
  Ask the compiler what is actually covered before sending native imports into a merge queue:
54
56
 
55
57
  ```js
@@ -71,6 +73,28 @@ console.log(python.imports.readiness); // scanner imports are intentionally revi
71
73
  console.log(python.parserAdapters); // host-owned exact parsers such as LibCST can be injected
72
74
  ```
73
75
 
76
+ Preserve exact native source text, token/trivia hashes, comments, whitespace, and source directives as evidence. This does not claim full semantic understanding; it keeps round-trip material available while exact parser adapters catch up:
77
+
78
+ ```js
79
+ import {
80
+ createNativeSourcePreservation,
81
+ importNativeSource
82
+ } from '@shapeshift-labs/frontier-lang-compiler';
83
+
84
+ const sourceText = '// kept\nexport function step(frame) { return frame + 1; }\n';
85
+ const preservation = createNativeSourcePreservation({
86
+ language: 'javascript',
87
+ sourcePath: 'src/runtime.js',
88
+ sourceText
89
+ });
90
+ const imported = importNativeSource({ language: 'javascript', sourcePath: 'src/runtime.js', sourceText });
91
+
92
+ console.log(preservation.summary.comments); // comments and whitespace are tracked
93
+ console.log(imported.metadata.sourcePreservation.sourceHash);
94
+ ```
95
+
96
+ When `sourceText` is present, hashes are computed from the actual text. Caller-provided hashes are recorded as declared metadata and cannot make stale text project as exact source. Use `includeTokens`, `includeTrivia`, `includeDirectives`, and `max*` options to keep preservation records compact for large files.
97
+
74
98
  Create a compact semantic sidecar for swarm merge admission. This is the artifact a coordinator can index instead of reading a worker directory by hand:
75
99
 
76
100
  ```js
@@ -96,7 +120,7 @@ console.log(sidecar.ownershipRegions[0].key); // source#src/runtime.ts#class#Run
96
120
  console.log(sidecar.patchHints[0].supportedOperations); // source-region patch operations
97
121
  ```
98
122
 
99
- Project a native import back to source. Exact source is preserved only when the supplied text matches the import hash; otherwise the compiler emits declaration stubs with review-required loss evidence:
123
+ Project a native import back to source. Exact source is preserved when the import carries matching source-preservation evidence or when supplied text matches the import hash; otherwise the compiler emits declaration stubs with review-required loss evidence:
100
124
 
101
125
  ```js
102
126
  import {
@@ -111,7 +135,7 @@ const imported = importNativeSource({
111
135
  sourceText
112
136
  });
113
137
 
114
- const projection = projectNativeImportToSource(imported, { sourceText });
138
+ const projection = projectNativeImportToSource(imported);
115
139
 
116
140
  console.log(projection.mode); // "preserved-source"
117
141
  console.log(projection.readiness.readiness); // "ready"
@@ -146,6 +170,9 @@ const project = await importNativeProject({
146
170
 
147
171
  console.log(imported.universalAst.sourceMaps.length);
148
172
  console.log(project.semanticIndex.symbols.length);
173
+ console.log(imported.adapter.coverage.exactness);
174
+ console.log(imported.adapter.coverage.semanticCoverage.level);
175
+ console.log(project.metadata.sourcePreservationSummary.total);
149
176
  ```
150
177
 
151
178
  The built-in adapter factories are dependency-light wrappers for caller-owned parsers or ASTs:
@@ -155,6 +182,8 @@ The built-in adapter factories are dependency-light wrappers for caller-owned pa
155
182
  - `createTypeScriptCompilerNativeImporterAdapter`
156
183
  - `createTreeSitterNativeImporterAdapter`
157
184
 
185
+ Adapter summaries include a structured `coverage` record so merge queues can distinguish exact parser AST imports from declaration scans. The record declares exactness, parser token/trivia support, diagnostics support, source-range and generated-range support, and semantic coverage. Built-in wrappers normalize native AST/CST nodes and declaration-level semantic indexes; they do not claim resolved references, types, control flow, generated ranges, or token/trivia fidelity unless the host adapter supplies that evidence.
186
+
158
187
  ## Related Packages
159
188
 
160
189
  The published Frontier package family is generated from one shared package catalog so READMEs stay in sync across packages:
package/bench/smoke.mjs CHANGED
@@ -3,6 +3,7 @@ import {
3
3
  compileFrontierSource,
4
4
  createEstreeNativeImporterAdapter,
5
5
  createNativeImportCoverageMatrix,
6
+ createNativeSourcePreservation,
6
7
  createSemanticImportSidecar,
7
8
  importNativeSource,
8
9
  projectNativeImportToSource,
@@ -67,6 +68,15 @@ const matrixStart = performance.now();
67
68
  const coverageMatrix = createNativeImportCoverageMatrix({ imports: nativeImportResults });
68
69
  const matrixDurationMs = performance.now() - matrixStart;
69
70
 
71
+ const preservationStart = performance.now();
72
+ const preservationRecords = nativeImportResults.map((imported) => imported.metadata.sourcePreservation ?? createNativeSourcePreservation({
73
+ language: imported.language,
74
+ sourcePath: imported.sourcePath,
75
+ sourceText: imported.metadata.sourcePreservation?.sourceText ?? ''
76
+ }));
77
+ const preservationDurationMs = performance.now() - preservationStart;
78
+ const preservationTokens = preservationRecords.reduce((sum, record) => sum + record.tokens.length + record.trivia.length, 0);
79
+
70
80
  const sidecarStart = performance.now();
71
81
  const semanticSidecars = nativeImportResults.map((imported) => createSemanticImportSidecar(imported));
72
82
  const sidecarDurationMs = performance.now() - sidecarStart;
@@ -87,6 +97,9 @@ console.log(JSON.stringify({
87
97
  coverageMatrixLanguages: coverageMatrix.summary.languages,
88
98
  coverageMatrixImports: coverageMatrix.summary.imports,
89
99
  coverageMatrixDurationMs: Number(matrixDurationMs.toFixed(2)),
100
+ sourcePreservationRecords: preservationRecords.length,
101
+ sourcePreservationTokens: preservationTokens,
102
+ sourcePreservationDurationMs: Number(preservationDurationMs.toFixed(2)),
90
103
  semanticSidecars: semanticSidecars.length,
91
104
  sidecarOwnershipRegions,
92
105
  sidecarDurationMs: Number(sidecarDurationMs.toFixed(2)),
package/dist/index.d.ts CHANGED
@@ -79,27 +79,43 @@ export type NativeImportTaxonomyKind =
79
79
  | 'opaqueBodies'
80
80
  | 'macroExpansion'
81
81
  | 'preprocessor'
82
+ | 'conditionalCompilation'
82
83
  | 'metaprogramming'
84
+ | 'reflection'
83
85
  | 'generatedCode'
86
+ | 'overloadTypeInference'
84
87
  | 'sourcePreservation'
88
+ | 'commentsTrivia'
85
89
  | 'parserDiagnostics'
86
90
  | 'unsupportedSyntax'
87
91
  | 'partialSemanticIndex'
88
92
  | 'sourceMapApproximation'
93
+ | 'targetProjectionLoss'
89
94
  | string;
90
95
 
91
96
  export type NativeImportKnownLossKind =
92
97
  | 'declarationOnlyCoverage'
93
98
  | 'opaqueNative'
94
99
  | 'macroExpansion'
100
+ | 'macroHygiene'
95
101
  | 'preprocessor'
102
+ | 'conditionalCompilation'
96
103
  | 'metaprogramming'
104
+ | 'reflection'
105
+ | 'dynamicRuntime'
106
+ | 'dynamicDispatch'
97
107
  | 'generatedCode'
108
+ | 'overloadResolution'
109
+ | 'typeInference'
98
110
  | 'sourcePreservation'
111
+ | 'commentsTrivia'
99
112
  | 'parserDiagnostic'
100
113
  | 'unsupportedSyntax'
114
+ | 'unsupportedSemantic'
115
+ | 'unverifiedNativeAst'
101
116
  | 'partialSemanticIndex'
102
117
  | 'sourceMapApproximation'
118
+ | 'targetProjectionLoss'
103
119
  | string;
104
120
 
105
121
  export interface NativeImportLossSummaryOptions {
@@ -201,6 +217,82 @@ export interface NativeImportCoverageMatrixOptions {
201
217
  readonly generatedAt?: number;
202
218
  }
203
219
 
220
+ export type NativeSourceTokenKind =
221
+ | 'identifier'
222
+ | 'keyword'
223
+ | 'number'
224
+ | 'string'
225
+ | 'operator'
226
+ | 'punctuation'
227
+ | 'comment'
228
+ | 'whitespace'
229
+ | 'newline'
230
+ | 'directive'
231
+ | 'unknown'
232
+ | string;
233
+
234
+ export interface NativeSourcePreservedToken {
235
+ readonly id: string;
236
+ readonly kind: NativeSourceTokenKind;
237
+ readonly text?: string;
238
+ readonly textHash: string;
239
+ readonly span: SourceSpan;
240
+ readonly metadata?: Record<string, unknown>;
241
+ }
242
+
243
+ export interface NativeSourcePreservedDirective {
244
+ readonly id: string;
245
+ readonly kind: string;
246
+ readonly text?: string;
247
+ readonly textHash: string;
248
+ readonly span: SourceSpan;
249
+ readonly metadata?: Record<string, unknown>;
250
+ }
251
+
252
+ export interface NativeSourcePreservation {
253
+ readonly kind: 'frontier.lang.nativeSourcePreservation';
254
+ readonly version: 1;
255
+ readonly id: string;
256
+ readonly language: FrontierSourceLanguage | string;
257
+ readonly sourcePath?: string;
258
+ readonly sourceHash: string;
259
+ readonly sourceBytes: number;
260
+ readonly lineCount: number;
261
+ readonly newline: 'lf' | 'crlf' | 'mixed' | 'none';
262
+ readonly encoding: string;
263
+ readonly sourceText?: string;
264
+ readonly tokens: readonly NativeSourcePreservedToken[];
265
+ readonly trivia: readonly NativeSourcePreservedToken[];
266
+ readonly directives: readonly NativeSourcePreservedDirective[];
267
+ readonly summary: {
268
+ readonly tokens: number;
269
+ readonly trivia: number;
270
+ readonly directives: number;
271
+ readonly comments: number;
272
+ readonly whitespace: number;
273
+ readonly exactSourceAvailable: boolean;
274
+ readonly truncated: boolean;
275
+ };
276
+ readonly metadata?: Record<string, unknown>;
277
+ }
278
+
279
+ export interface CreateNativeSourcePreservationOptions {
280
+ readonly id?: string;
281
+ readonly language?: FrontierSourceLanguage | string;
282
+ readonly sourcePath?: string;
283
+ readonly sourceHash?: string;
284
+ readonly sourceText: string;
285
+ readonly encoding?: string;
286
+ readonly includeSourceText?: boolean;
287
+ readonly includeTokens?: boolean;
288
+ readonly includeTrivia?: boolean;
289
+ readonly includeDirectives?: boolean;
290
+ readonly maxTokens?: number;
291
+ readonly maxTrivia?: number;
292
+ readonly maxDirectives?: number;
293
+ readonly metadata?: Record<string, unknown>;
294
+ }
295
+
204
296
  export interface SemanticImportOwnershipRegion {
205
297
  readonly id: string;
206
298
  readonly key: string;
@@ -322,6 +414,52 @@ export interface SemanticImportSidecarOptions {
322
414
  readonly metadata?: Record<string, unknown>;
323
415
  }
324
416
 
417
+ export type NativeImporterAdapterExactness =
418
+ | 'exact-parser-ast'
419
+ | 'parser-tree'
420
+ | 'adapter-reported-native-ast'
421
+ | 'loss-aware-native-ast'
422
+ | 'unknown'
423
+ | string;
424
+
425
+ export interface NativeImporterAdapterSemanticCoverage {
426
+ readonly level: 'native-ast' | 'declaration-index' | 'semantic-index' | string;
427
+ readonly declarations: boolean;
428
+ readonly symbols: boolean;
429
+ readonly references: boolean;
430
+ readonly types: boolean;
431
+ readonly controlFlow: boolean;
432
+ }
433
+
434
+ export interface NativeImporterAdapterCoverageObserved {
435
+ readonly diagnostics: number;
436
+ readonly losses: number;
437
+ readonly nativeAstNodes: number;
438
+ readonly semanticSymbols: number;
439
+ readonly sourceMapMappings: number;
440
+ readonly sourceRanges: boolean;
441
+ readonly generatedRanges: boolean;
442
+ }
443
+
444
+ export interface NativeImporterAdapterCoverageSummary {
445
+ readonly exactness: NativeImporterAdapterExactness;
446
+ readonly exactAst: boolean;
447
+ readonly tokens: boolean;
448
+ readonly trivia: boolean;
449
+ readonly diagnostics: boolean;
450
+ readonly sourceRanges: boolean;
451
+ readonly generatedRanges: boolean;
452
+ readonly semanticCoverage: NativeImporterAdapterSemanticCoverage;
453
+ readonly notes: readonly string[];
454
+ readonly observed?: NativeImporterAdapterCoverageObserved;
455
+ }
456
+
457
+ export type NativeImporterAdapterCoverageInput =
458
+ Omit<Partial<NativeImporterAdapterCoverageSummary>, 'semanticCoverage' | 'observed'> & {
459
+ readonly semanticCoverage?: Partial<NativeImporterAdapterSemanticCoverage>;
460
+ readonly observed?: Partial<NativeImporterAdapterCoverageObserved>;
461
+ };
462
+
325
463
  export interface NativeImporterAdapterDiagnostic {
326
464
  readonly id?: string;
327
465
  readonly severity?: 'info' | 'warning' | 'error';
@@ -362,6 +500,7 @@ export interface ImportNativeSourceOptions {
362
500
  readonly losses?: readonly NativeAstLossRecord[];
363
501
  readonly evidence?: readonly EvidenceRecord[];
364
502
  readonly evidenceId?: string;
503
+ readonly sourcePreservation?: NativeSourcePreservation;
365
504
  readonly patch?: SemanticPatchBundle;
366
505
  readonly patchId?: string;
367
506
  readonly author?: string;
@@ -373,6 +512,7 @@ export interface ImportNativeSourceOptions {
373
512
  readonly sourceMaps?: readonly SourceMapRecord[];
374
513
  readonly universalAstId?: string;
375
514
  readonly universalAstMetadata?: Record<string, unknown>;
515
+ readonly exactAst?: boolean;
376
516
  readonly metadata?: Record<string, unknown>;
377
517
  }
378
518
 
@@ -405,6 +545,7 @@ export interface NativeImporterAdapter {
405
545
  readonly parser: string;
406
546
  readonly version?: string;
407
547
  readonly capabilities?: readonly string[];
548
+ readonly coverage?: NativeImporterAdapterCoverageInput;
408
549
  readonly supportedExtensions?: readonly string[];
409
550
  readonly diagnostics?: readonly NativeImporterAdapterDiagnostic[];
410
551
  readonly parse: (input: NativeImporterAdapterParseInput) => NativeImporterAdapterParseResult | Promise<NativeImporterAdapterParseResult>;
@@ -416,6 +557,7 @@ export interface JavaScriptNativeImporterAdapterOptions {
416
557
  readonly parser?: string;
417
558
  readonly version?: string;
418
559
  readonly capabilities?: readonly string[];
560
+ readonly coverage?: NativeImporterAdapterCoverageInput;
419
561
  readonly supportedExtensions?: readonly string[];
420
562
  readonly diagnostics?: readonly NativeImporterAdapterDiagnostic[];
421
563
  readonly ast?: unknown;
@@ -432,6 +574,7 @@ export interface TypeScriptCompilerNativeImporterAdapterOptions {
432
574
  readonly parser?: string;
433
575
  readonly version?: string;
434
576
  readonly capabilities?: readonly string[];
577
+ readonly coverage?: NativeImporterAdapterCoverageInput;
435
578
  readonly supportedExtensions?: readonly string[];
436
579
  readonly diagnostics?: readonly NativeImporterAdapterDiagnostic[];
437
580
  readonly typescript?: unknown;
@@ -451,6 +594,7 @@ export interface TreeSitterNativeImporterAdapterOptions {
451
594
  readonly parserName?: string;
452
595
  readonly version?: string;
453
596
  readonly capabilities?: readonly string[];
597
+ readonly coverage?: NativeImporterAdapterCoverageInput;
454
598
  readonly supportedExtensions?: readonly string[];
455
599
  readonly diagnostics?: readonly NativeImporterAdapterDiagnostic[];
456
600
  readonly parserInstance?: { readonly parse: (sourceText: string) => unknown };
@@ -466,6 +610,7 @@ export interface NativeImporterAdapterSummary {
466
610
  readonly parser: string;
467
611
  readonly version?: string;
468
612
  readonly capabilities: readonly string[];
613
+ readonly coverage: NativeImporterAdapterCoverageSummary;
469
614
  readonly supportedExtensions: readonly string[];
470
615
  readonly diagnostics: readonly NativeImporterAdapterDiagnostic[];
471
616
  }
@@ -581,7 +726,62 @@ export interface NativeSourceProjectionResult {
581
726
  readonly metadata: Record<string, unknown>;
582
727
  }
583
728
 
729
+ export type NativeImportRoundtripReadinessStatus =
730
+ | 'exact'
731
+ | 'preserved-source'
732
+ | 'stub-only'
733
+ | 'blocked'
734
+ | 'needs-review';
735
+
736
+ export interface NativeImportRoundtripReadinessOptions extends ProjectNativeImportToSourceOptions {
737
+ readonly projection?: NativeSourceProjectionResult;
738
+ }
739
+
740
+ export interface NativeImportRoundtripReadinessClassification {
741
+ readonly kind: 'frontier.lang.nativeImportRoundtripReadiness';
742
+ readonly version: 1;
743
+ readonly status: NativeImportRoundtripReadinessStatus;
744
+ readonly semanticMergeReadiness: SemanticMergeReadiness;
745
+ readonly reasons: readonly string[];
746
+ readonly importReadiness: NativeImportReadinessClassification;
747
+ readonly projectionReadiness: NativeImportReadinessClassification;
748
+ readonly projectionMode: NativeSourceProjectionMode;
749
+ readonly checks: {
750
+ readonly nativeImport: {
751
+ readonly imports: number;
752
+ readonly exactAst: boolean;
753
+ readonly losses: number;
754
+ readonly readiness: SemanticMergeReadiness;
755
+ };
756
+ readonly universalAst: {
757
+ readonly present: boolean;
758
+ readonly valid: boolean;
759
+ readonly issues: readonly string[];
760
+ readonly nativeSources: number;
761
+ readonly semanticSymbols: number;
762
+ readonly sourceMaps: number;
763
+ readonly sourceMapMappings: number;
764
+ };
765
+ readonly projectedSource: {
766
+ readonly mode: NativeSourceProjectionMode;
767
+ readonly outputHash: string;
768
+ readonly expectedSourceHash?: string;
769
+ readonly sourceHashVerified: boolean;
770
+ readonly declarations: number;
771
+ readonly losses: number;
772
+ readonly readiness: SemanticMergeReadiness;
773
+ };
774
+ };
775
+ readonly evidence: {
776
+ readonly importEvidenceIds: readonly string[];
777
+ readonly projectionEvidenceIds: readonly string[];
778
+ readonly failedEvidenceIds: readonly string[];
779
+ };
780
+ readonly metadata: Record<string, unknown>;
781
+ }
782
+
584
783
  export declare const FrontierCompileTargets: readonly FrontierCompileTarget[];
784
+ export declare const NativeImportRoundtripReadinessStatuses: readonly NativeImportRoundtripReadinessStatus[];
585
785
  export declare const NativeImportTaxonomyKinds: readonly NativeImportTaxonomyKind[];
586
786
  export declare const NativeImportLossKinds: readonly NativeImportKnownLossKind[];
587
787
  export declare const NativeImportReadinessBySeverity: Readonly<Record<NativeImportLossSummary['highestSeverity'], SemanticMergeReadiness>>;
@@ -594,7 +794,9 @@ export declare function renderTargetAst(ast: FrontierTargetAst, target?: Frontie
594
794
  export declare function resolveCapabilityAdapters(document: FrontierLangDocument, target?: FrontierCompileOptions['target'], options?: { readonly platform?: string }): readonly CapabilityResolution[];
595
795
  export declare function summarizeNativeImportLosses(losses?: readonly NativeAstLossRecord[], options?: NativeImportLossSummaryOptions): NativeImportLossSummary;
596
796
  export declare function classifyNativeImportReadiness(losses?: readonly NativeAstLossRecord[], options?: NativeImportLossSummaryOptions): NativeImportReadinessClassification;
797
+ export declare function classifyNativeImportRoundtripReadiness(importResult: NativeSourceImportResult | NativeProjectImportResult, options?: NativeImportRoundtripReadinessOptions): NativeImportRoundtripReadinessClassification;
597
798
  export declare function createNativeImportCoverageMatrix(options?: NativeImportCoverageMatrixOptions): NativeImportCoverageMatrix;
799
+ export declare function createNativeSourcePreservation(options: CreateNativeSourcePreservationOptions): NativeSourcePreservation;
598
800
  export declare function createSemanticImportSidecar(importResult: NativeSourceImportResult | NativeProjectImportResult, options?: SemanticImportSidecarOptions): SemanticImportSidecar;
599
801
  export declare function createEstreeNativeImporterAdapter(options?: JavaScriptNativeImporterAdapterOptions): NativeImporterAdapter;
600
802
  export declare function createBabelNativeImporterAdapter(options?: JavaScriptNativeImporterAdapterOptions): NativeImporterAdapter;