@shapeshift-labs/frontier-lang-compiler 0.2.71 → 0.2.72
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 +1 -1
- package/dist/declarations/semantic-history-records.d.ts +8 -2
- package/dist/declarations/semantic-history.d.ts +7 -0
- package/dist/declarations/semantic-lineage.d.ts +145 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/internal/index-impl/semanticHistoryRecordOverlaps.js +20 -4
- package/dist/internal/index-impl/semanticHistoryRecords.js +29 -6
- package/dist/internal/index-impl/semanticLineageRecords.js +193 -0
- package/dist/native-region-scanner-js-helpers.js +13 -1
- package/dist/native-region-scanner-js-nested.js +147 -0
- package/dist/native-region-scanner-js.js +22 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -747,7 +747,7 @@ The published Frontier package family is generated from one shared package catal
|
|
|
747
747
|
- [`@shapeshift-labs/frontier-lang-go`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-go): Go source-language importer package for Frontier Lang semantic documents, including package-level metadata, Go AST adapter helpers, native import results, and semantic sidecar generation for go/ast File or Package trees.
|
|
748
748
|
- [`@shapeshift-labs/frontier-lang-csharp`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-csharp): C# Roslyn source-language importer package for Frontier Lang semantic documents, including package-level metadata, Roslyn adapter helpers, native import results, and semantic sidecar generation for SyntaxTree/SyntaxNode-shaped ASTs.
|
|
749
749
|
- [`@shapeshift-labs/frontier-lang-clang`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-clang): Clang AST source-language importer package for Frontier Lang semantic documents, including package-level metadata, Clang AST JSON adapter helpers, native import results, and semantic sidecar generation for C/C++ translation units.
|
|
750
|
-
- [`@shapeshift-labs/frontier-lang-cli`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-cli): Command line interface for parsing, checking, hashing, and
|
|
750
|
+
- [`@shapeshift-labs/frontier-lang-cli`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-cli): Command line interface for parsing, checking, hashing, emitting, native source import/projection, semantic slicing, and corpus roundtrip evidence for Frontier Lang projects.
|
|
751
751
|
- [`@shapeshift-labs/frontier-lang`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang): Umbrella package for Frontier Lang kernel, parser, checker, compiler facade, universal AST helpers, projection adapters, and source-language importer adapters.
|
|
752
752
|
- [`@shapeshift-labs/frontier-kv`](https://www.npmjs.com/package/@shapeshift-labs/frontier-kv): Serializable in-memory key/value state for Frontier apps, including TTL, versioned compare-and-set, batched patch mutations, scans, watchers, snapshots, JSONL event evidence, and replay verification.
|
|
753
753
|
- [`@shapeshift-labs/frontier-kv-locks`](https://www.npmjs.com/package/@shapeshift-labs/frontier-kv-locks): Lease-style lock records on top of Frontier KV, including acquire, renew, release, fencing tokens, expiration, owner evidence, and replayable lock events.
|
|
@@ -8,8 +8,8 @@ import type {
|
|
|
8
8
|
export type SemanticHistoryAdmissionStatus = 'proposed' | 'queued' | 'admitted' | 'needs-review' | 'blocked' | 'rejected' | string;
|
|
9
9
|
export type SemanticHistoryReviewerStatus = 'unreviewed' | 'approved' | 'changes-requested' | 'reviewed' | 'rejected' | string;
|
|
10
10
|
export type SemanticHistoryReplayLinkKind = 'patch' | 'slice' | 'sidecar' | 'run' | 'proof' | 'source' | 'command' | 'url' | 'replay' | string;
|
|
11
|
-
export type SemanticHistoryOverlapKind = 'ownership' | 'conflict-key' | 'source' | 'source-path' | 'import' | 'semantic-candidate' | 'semantic-claim' | 'claim-hash' | 'evidence' | 'proof' | 'replay' | 'patch' | 'merge-decision' | 'actor' | 'record-source' | 'base-hash' | 'target-hash';
|
|
12
|
-
export type SemanticHistoryConflictReason = 'ownership-overlap' | 'semantic-conflict-key-overlap' | 'base-hash-mismatch' | 'target-hash-mismatch' | 'admission-blocked' | 'reviewer-rejected' | 'source-path-overlap' | string;
|
|
11
|
+
export type SemanticHistoryOverlapKind = 'ownership' | 'conflict-key' | 'source' | 'source-path' | 'import' | 'semantic-candidate' | 'semantic-claim' | 'claim-hash' | 'semantic-lineage' | 'semantic-anchor' | 'crdt-operation' | 'crdt-head' | 'evidence' | 'proof' | 'replay' | 'patch' | 'merge-decision' | 'actor' | 'record-source' | 'base-hash' | 'target-hash';
|
|
12
|
+
export type SemanticHistoryConflictReason = 'ownership-overlap' | 'semantic-conflict-key-overlap' | 'semantic-anchor-overlap' | 'base-hash-mismatch' | 'target-hash-mismatch' | 'admission-blocked' | 'reviewer-rejected' | 'source-path-overlap' | string;
|
|
13
13
|
export type SemanticHistoryClaimKind = 'fact' | 'theory' | 'invariant' | 'semantic-claim' | string;
|
|
14
14
|
export type SemanticHistoryClaimStatus = 'accepted' | 'rejected' | 'proposed' | 'superseded' | string;
|
|
15
15
|
export type SemanticHistoryProofAttemptStatus = 'passed' | 'failed' | 'unknown' | 'blocked' | string;
|
|
@@ -262,6 +262,12 @@ export interface SemanticHistoryRecordIndex {
|
|
|
262
262
|
readonly semanticClaimHashes: readonly string[];
|
|
263
263
|
readonly acceptedFactIds: readonly string[];
|
|
264
264
|
readonly rejectedTheoryIds: readonly string[];
|
|
265
|
+
readonly lineageEventIds: readonly string[];
|
|
266
|
+
readonly semanticAnchorIds: readonly string[];
|
|
267
|
+
readonly semanticAnchorKeys: readonly string[];
|
|
268
|
+
readonly semanticLineageKinds: readonly string[];
|
|
269
|
+
readonly crdtOperationIds: readonly string[];
|
|
270
|
+
readonly crdtHeads: readonly string[];
|
|
265
271
|
readonly conflictKeys: readonly string[];
|
|
266
272
|
readonly evidenceIds: readonly string[];
|
|
267
273
|
readonly importedParserEvidenceIds: readonly string[];
|
|
@@ -6,6 +6,7 @@ import type {
|
|
|
6
6
|
SourceSpan
|
|
7
7
|
} from '@shapeshift-labs/frontier-lang-kernel';
|
|
8
8
|
import type { SemanticImportOwnershipRegion } from './semantic-sidecar.js';
|
|
9
|
+
import type { CreateSemanticLineageEventInput, SemanticLineageEvent } from './semantic-lineage.js';
|
|
9
10
|
|
|
10
11
|
import type { SemanticHistoryAdmissionStatus, SemanticHistoryReviewerStatus, SemanticHistoryReplayLinkKind, SemanticHistoryOverlapKind, SemanticHistoryConflictReason, SemanticHistoryClaimKind, SemanticHistoryClaimStatus, SemanticHistoryProofAttemptStatus, SemanticHistoryMergeDecisionStatus, SemanticHistoryActorRef, SemanticHistoryRecordSourceRef, SemanticHistorySourceRef, SemanticHistoryOwnershipRegionRef, SemanticHistoryCandidateRef, SemanticHistoryClaimRecord, SemanticHistoryImportedParserEvidenceRecord, SemanticHistoryProofAttemptRecord, SemanticHistoryPatchAncestryRecord, SemanticHistoryMergeDecisionRecord, SemanticHistoryClaimInput, SemanticHistoryImportedParserEvidenceInput, SemanticHistoryProofAttemptInput, SemanticHistoryPatchAncestryInput, SemanticHistoryMergeDecisionInput, SemanticHistoryReviewerState, SemanticHistoryAdmissionState, SemanticHistoryReplayLink, SemanticHistoryRecordIndex } from './semantic-history-records.js';
|
|
11
12
|
export type { SemanticHistoryAdmissionStatus, SemanticHistoryReviewerStatus, SemanticHistoryReplayLinkKind, SemanticHistoryOverlapKind, SemanticHistoryConflictReason, SemanticHistoryClaimKind, SemanticHistoryClaimStatus, SemanticHistoryProofAttemptStatus, SemanticHistoryMergeDecisionStatus, SemanticHistoryActorRef, SemanticHistoryRecordSourceRef, SemanticHistorySourceRef, SemanticHistoryOwnershipRegionRef, SemanticHistoryCandidateRef, SemanticHistoryClaimRecord, SemanticHistoryImportedParserEvidenceRecord, SemanticHistoryProofAttemptRecord, SemanticHistoryPatchAncestryRecord, SemanticHistoryMergeDecisionRecord, SemanticHistoryClaimInput, SemanticHistoryImportedParserEvidenceInput, SemanticHistoryProofAttemptInput, SemanticHistoryPatchAncestryInput, SemanticHistoryMergeDecisionInput, SemanticHistoryReviewerState, SemanticHistoryAdmissionState, SemanticHistoryReplayLink, SemanticHistoryRecordIndex } from './semantic-history-records.js';
|
|
@@ -31,6 +32,7 @@ export interface SemanticHistoryRecord {
|
|
|
31
32
|
readonly rejectedTheories: readonly SemanticHistoryClaimRecord[];
|
|
32
33
|
readonly importedParserEvidence: readonly SemanticHistoryImportedParserEvidenceRecord[];
|
|
33
34
|
readonly proofAttempts: readonly SemanticHistoryProofAttemptRecord[];
|
|
35
|
+
readonly lineageEvents: readonly SemanticLineageEvent[];
|
|
34
36
|
readonly patchAncestry: readonly SemanticHistoryPatchAncestryRecord[];
|
|
35
37
|
readonly mergeDecisions: readonly SemanticHistoryMergeDecisionRecord[];
|
|
36
38
|
readonly evidenceIds: readonly string[];
|
|
@@ -83,6 +85,9 @@ export interface CreateSemanticHistoryRecordInput {
|
|
|
83
85
|
readonly parserEvidence?: readonly SemanticHistoryImportedParserEvidenceInput[] | SemanticHistoryImportedParserEvidenceInput;
|
|
84
86
|
readonly proofAttempts?: readonly SemanticHistoryProofAttemptInput[] | SemanticHistoryProofAttemptInput;
|
|
85
87
|
readonly proofs?: readonly SemanticHistoryProofAttemptInput[] | SemanticHistoryProofAttemptInput;
|
|
88
|
+
readonly lineageEvents?: readonly CreateSemanticLineageEventInput[] | CreateSemanticLineageEventInput;
|
|
89
|
+
readonly semanticLineageEvents?: readonly CreateSemanticLineageEventInput[] | CreateSemanticLineageEventInput;
|
|
90
|
+
readonly lineage?: readonly CreateSemanticLineageEventInput[] | CreateSemanticLineageEventInput;
|
|
86
91
|
readonly patchAncestry?: readonly SemanticHistoryPatchAncestryInput[] | SemanticHistoryPatchAncestryInput;
|
|
87
92
|
readonly patchAncestors?: readonly SemanticHistoryPatchAncestryInput[] | SemanticHistoryPatchAncestryInput;
|
|
88
93
|
readonly ancestry?: readonly SemanticHistoryPatchAncestryInput[] | SemanticHistoryPatchAncestryInput;
|
|
@@ -107,6 +112,8 @@ export interface CreateSemanticHistoryRecordInput {
|
|
|
107
112
|
export interface SemanticHistoryOverlapQueryOptions {
|
|
108
113
|
readonly includeSourcePaths?: boolean;
|
|
109
114
|
readonly includeClaims?: boolean;
|
|
115
|
+
readonly includeLineage?: boolean;
|
|
116
|
+
readonly includeCrdt?: boolean;
|
|
110
117
|
readonly includeEvidence?: boolean;
|
|
111
118
|
readonly includeProofs?: boolean;
|
|
112
119
|
readonly includeReplay?: boolean;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import type { FrontierSourceLanguage, SourceSpan } from '@shapeshift-labs/frontier-lang-kernel';
|
|
2
|
+
|
|
3
|
+
export type SemanticLineageEventKind = 'unchanged' | 'moved' | 'renamed' | 'split' | 'merged' | 'deleted' | 'recreated' | 'unknown' | string;
|
|
4
|
+
|
|
5
|
+
export interface SemanticAnchor {
|
|
6
|
+
readonly id?: string;
|
|
7
|
+
readonly key?: string;
|
|
8
|
+
readonly kind?: string;
|
|
9
|
+
readonly language?: FrontierSourceLanguage | string;
|
|
10
|
+
readonly sourcePath?: string;
|
|
11
|
+
readonly sourceHash?: string;
|
|
12
|
+
readonly symbolId?: string;
|
|
13
|
+
readonly symbolName?: string;
|
|
14
|
+
readonly semanticPath?: readonly string[];
|
|
15
|
+
readonly signatureHash?: string;
|
|
16
|
+
readonly bodyHash?: string;
|
|
17
|
+
readonly sourceSpan?: SourceSpan;
|
|
18
|
+
readonly metadata?: Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface SemanticLineageCrdtClock {
|
|
22
|
+
readonly operationId?: string;
|
|
23
|
+
readonly actor?: string;
|
|
24
|
+
readonly seq?: number;
|
|
25
|
+
readonly deps?: readonly string[];
|
|
26
|
+
readonly heads?: readonly string[];
|
|
27
|
+
readonly stateVector?: Record<string, number>;
|
|
28
|
+
readonly versionFrame?: Record<string, unknown>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface SemanticLineageEvidence {
|
|
32
|
+
readonly pathMatch?: boolean;
|
|
33
|
+
readonly signatureHashMatch?: boolean;
|
|
34
|
+
readonly bodyHashMatch?: boolean;
|
|
35
|
+
readonly syntaxShapeMatch?: boolean;
|
|
36
|
+
readonly sourceSpanMoved?: boolean;
|
|
37
|
+
readonly confidence?: number;
|
|
38
|
+
readonly command?: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface SemanticLineageActor {
|
|
42
|
+
readonly id?: string;
|
|
43
|
+
readonly role?: string;
|
|
44
|
+
readonly lane?: string;
|
|
45
|
+
readonly taskId?: string;
|
|
46
|
+
readonly runId?: string;
|
|
47
|
+
readonly metadata?: Record<string, unknown>;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface SemanticLineageEvent {
|
|
51
|
+
readonly kind: 'frontier.lang.semanticLineageEvent';
|
|
52
|
+
readonly version: 1;
|
|
53
|
+
readonly id: string;
|
|
54
|
+
readonly stableId: string;
|
|
55
|
+
readonly hash: string;
|
|
56
|
+
readonly createdAt: number | string;
|
|
57
|
+
readonly eventKind: SemanticLineageEventKind;
|
|
58
|
+
readonly from?: SemanticAnchor;
|
|
59
|
+
readonly to: readonly SemanticAnchor[];
|
|
60
|
+
readonly confidence?: number;
|
|
61
|
+
readonly actor?: SemanticLineageActor;
|
|
62
|
+
readonly crdt?: SemanticLineageCrdtClock;
|
|
63
|
+
readonly evidence?: SemanticLineageEvidence;
|
|
64
|
+
readonly evidenceIds: readonly string[];
|
|
65
|
+
readonly proofIds: readonly string[];
|
|
66
|
+
readonly conflictKeys: readonly string[];
|
|
67
|
+
readonly metadata?: Record<string, unknown>;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface CreateSemanticLineageEventInput {
|
|
71
|
+
readonly id?: string;
|
|
72
|
+
readonly hash?: string;
|
|
73
|
+
readonly createdAt?: number | string;
|
|
74
|
+
readonly eventKind?: SemanticLineageEventKind;
|
|
75
|
+
readonly event?: SemanticLineageEventKind;
|
|
76
|
+
readonly kind?: SemanticLineageEventKind;
|
|
77
|
+
readonly from?: SemanticAnchor | string;
|
|
78
|
+
readonly fromAnchor?: SemanticAnchor | string;
|
|
79
|
+
readonly before?: SemanticAnchor | string;
|
|
80
|
+
readonly to?: readonly (SemanticAnchor | string)[] | SemanticAnchor | string;
|
|
81
|
+
readonly toAnchors?: readonly (SemanticAnchor | string)[] | SemanticAnchor | string;
|
|
82
|
+
readonly after?: readonly (SemanticAnchor | string)[] | SemanticAnchor | string;
|
|
83
|
+
readonly confidence?: number;
|
|
84
|
+
readonly actor?: SemanticLineageActor | string;
|
|
85
|
+
readonly actorId?: string;
|
|
86
|
+
readonly actorRole?: string;
|
|
87
|
+
readonly crdt?: SemanticLineageCrdtClock;
|
|
88
|
+
readonly clock?: SemanticLineageCrdtClock;
|
|
89
|
+
readonly operation?: SemanticLineageCrdtClock;
|
|
90
|
+
readonly operationId?: string;
|
|
91
|
+
readonly seq?: number;
|
|
92
|
+
readonly deps?: readonly string[] | string;
|
|
93
|
+
readonly heads?: readonly string[] | string;
|
|
94
|
+
readonly stateVector?: Record<string, number>;
|
|
95
|
+
readonly versionFrame?: Record<string, unknown>;
|
|
96
|
+
readonly evidence?: SemanticLineageEvidence | readonly { readonly id?: string }[];
|
|
97
|
+
readonly pathMatch?: boolean;
|
|
98
|
+
readonly signatureHashMatch?: boolean;
|
|
99
|
+
readonly bodyHashMatch?: boolean;
|
|
100
|
+
readonly syntaxShapeMatch?: boolean;
|
|
101
|
+
readonly sourceSpanMoved?: boolean;
|
|
102
|
+
readonly command?: string;
|
|
103
|
+
readonly evidenceIds?: readonly string[] | string;
|
|
104
|
+
readonly proofIds?: readonly string[] | string;
|
|
105
|
+
readonly proofs?: readonly { readonly id?: string }[];
|
|
106
|
+
readonly conflictKey?: string;
|
|
107
|
+
readonly conflictKeys?: readonly string[] | string;
|
|
108
|
+
readonly metadata?: Record<string, unknown>;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export interface SemanticLineageMap {
|
|
112
|
+
readonly kind: 'frontier.lang.semanticLineageMap';
|
|
113
|
+
readonly version: 1;
|
|
114
|
+
readonly id: string;
|
|
115
|
+
readonly generatedAt: number | string;
|
|
116
|
+
readonly events: readonly SemanticLineageEvent[];
|
|
117
|
+
readonly byAnchorKey: Readonly<Record<string, readonly string[]>>;
|
|
118
|
+
readonly byEventKind: Readonly<Record<string, readonly string[]>>;
|
|
119
|
+
readonly byOperationId: Readonly<Record<string, readonly string[]>>;
|
|
120
|
+
readonly bySourcePath: Readonly<Record<string, readonly string[]>>;
|
|
121
|
+
readonly summary: {
|
|
122
|
+
readonly eventCount: number;
|
|
123
|
+
readonly anchorCount: number;
|
|
124
|
+
readonly operationCount: number;
|
|
125
|
+
readonly eventKinds: readonly string[];
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export interface SemanticLineageQuery {
|
|
130
|
+
readonly eventKind?: SemanticLineageEventKind | readonly string[];
|
|
131
|
+
readonly anchorKey?: string | readonly string[];
|
|
132
|
+
readonly fromKey?: string | readonly string[];
|
|
133
|
+
readonly toKey?: string | readonly string[];
|
|
134
|
+
readonly sourcePath?: string | readonly string[];
|
|
135
|
+
readonly operationId?: string | readonly string[];
|
|
136
|
+
readonly head?: string | readonly string[];
|
|
137
|
+
readonly conflictKey?: string | readonly string[];
|
|
138
|
+
readonly evidenceId?: string | readonly string[];
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export declare const SemanticLineageEventKinds: readonly SemanticLineageEventKind[];
|
|
142
|
+
export declare function createSemanticAnchor(input?: SemanticAnchor | string, defaults?: Partial<SemanticAnchor>): SemanticAnchor | undefined;
|
|
143
|
+
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
|
+
export declare function createSemanticLineageMap(events?: readonly (SemanticLineageEvent | CreateSemanticLineageEventInput)[], options?: { readonly id?: string; readonly generatedAt?: number | string }): SemanticLineageMap;
|
|
145
|
+
export declare function querySemanticLineageEvents(events: SemanticLineageEvent | readonly SemanticLineageEvent[], query?: SemanticLineageQuery): readonly SemanticLineageEvent[];
|
package/dist/index.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export * from './declarations/source-preservation.js';
|
|
|
16
16
|
export * from './declarations/semantic-sidecar-admission.js';
|
|
17
17
|
export * from './declarations/semantic-merge-candidates.js';
|
|
18
18
|
export * from './declarations/semantic-merge-conflicts.js';
|
|
19
|
+
export * from './declarations/semantic-lineage.js';
|
|
19
20
|
export * from './declarations/semantic-history.js';
|
|
20
21
|
export * from './declarations/semantic-patch-bundle.js';
|
|
21
22
|
export * from './declarations/semantic-impact.js';
|
package/dist/index.js
CHANGED
|
@@ -68,6 +68,7 @@ export { createSemanticPatchBundleRecord, querySemanticPatchBundleRecords, Seman
|
|
|
68
68
|
export { createSemanticMergeCandidateAdmissionRecord, decorateSemanticMergeCandidateForAdmission, querySemanticMergeCandidateAdmissionOverlaps, SemanticMergeCandidateProjectionRisks, semanticMergeCandidateReadinessSortKey, sortSemanticMergeCandidateAdmissionRecords } from './internal/index-impl/semanticMergeCandidateRecords.js';
|
|
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
|
+
export { createSemanticAnchor, createSemanticLineageEvent, createSemanticLineageMap, querySemanticLineageEvents, SemanticLineageEventKinds } from './internal/index-impl/semanticLineageRecords.js';
|
|
71
72
|
export { createSemanticHistoryRecord, querySemanticHistoryRecordOverlaps, SemanticHistoryAdmissionStatuses, SemanticHistoryConflictReasons, SemanticHistoryOverlapKinds, SemanticHistoryReviewerStatuses, semanticHistoryRecordsConflict, semanticHistoryRecordsOverlap } from './internal/index-impl/semanticHistoryRecords.js';
|
|
72
73
|
export { readSemanticSliceJson } from './internal/index-impl/readSemanticSliceJson.js';
|
|
73
74
|
export { readUniversalAstJson } from './internal/index-impl/readUniversalAstJson.js';
|
|
@@ -32,6 +32,10 @@ function semanticHistoryOverlap(left,right,options){
|
|
|
32
32
|
'semantic-candidate':intersect(leftIndex.semanticCandidateIds,rightIndex.semanticCandidateIds),
|
|
33
33
|
'semantic-claim':options.includeClaims?intersect(leftIndex.semanticClaimIds,rightIndex.semanticClaimIds):[],
|
|
34
34
|
'claim-hash':options.includeClaims?intersect(leftIndex.semanticClaimHashes,rightIndex.semanticClaimHashes):[],
|
|
35
|
+
'semantic-lineage':options.includeLineage?intersect(leftIndex.lineageEventIds,rightIndex.lineageEventIds):[],
|
|
36
|
+
'semantic-anchor':intersect(leftIndex.semanticAnchorKeys,rightIndex.semanticAnchorKeys),
|
|
37
|
+
'crdt-operation':options.includeCrdt?intersect(leftIndex.crdtOperationIds,rightIndex.crdtOperationIds):[],
|
|
38
|
+
'crdt-head':options.includeCrdt?intersect(leftIndex.crdtHeads,rightIndex.crdtHeads):[],
|
|
35
39
|
evidence:options.includeEvidence?intersect(leftIndex.evidenceIds,rightIndex.evidenceIds):[],
|
|
36
40
|
proof:options.includeProofs?intersect(leftIndex.proofIds,rightIndex.proofIds):[],
|
|
37
41
|
replay:options.includeReplay?intersect(leftIndex.replayIds,rightIndex.replayIds):[],
|
|
@@ -43,10 +47,11 @@ function semanticHistoryOverlap(left,right,options){
|
|
|
43
47
|
'target-hash':options.includeTargetHashes?intersect(leftIndex.targetHashes,rightIndex.targetHashes):[]
|
|
44
48
|
});
|
|
45
49
|
const overlapKinds=Object.keys(overlap);
|
|
46
|
-
const semanticOverlap=Boolean(overlap.ownership?.length||overlap['conflict-key']?.length||overlap.source?.length||overlap['source-path']?.length||overlap.import?.length);
|
|
50
|
+
const semanticOverlap=Boolean(overlap.ownership?.length||overlap['conflict-key']?.length||overlap['semantic-anchor']?.length||overlap.source?.length||overlap['source-path']?.length||overlap.import?.length);
|
|
47
51
|
const conflictReasons=uniqueStrings([
|
|
48
52
|
overlap.ownership?.length?'ownership-overlap':undefined,
|
|
49
53
|
overlap['conflict-key']?.length?'semantic-conflict-key-overlap':undefined,
|
|
54
|
+
overlap['semantic-anchor']?.length?'semantic-anchor-overlap':undefined,
|
|
50
55
|
semanticOverlap&&disjointNonEmpty(leftIndex.baseHashes,rightIndex.baseHashes)?'base-hash-mismatch':undefined,
|
|
51
56
|
(overlap.ownership?.length||overlap['conflict-key']?.length)&&disjointNonEmpty(leftIndex.targetHashes,rightIndex.targetHashes)?'target-hash-mismatch':undefined,
|
|
52
57
|
semanticOverlap&&(blockedAdmission(left)||blockedAdmission(right))?'admission-blocked':undefined,
|
|
@@ -71,6 +76,7 @@ function historyIndex(record){
|
|
|
71
76
|
const rejectedTheories=record?.rejectedTheories??[];
|
|
72
77
|
const importedParserEvidence=record?.importedParserEvidence??[];
|
|
73
78
|
const proofAttempts=record?.proofAttempts??[];
|
|
79
|
+
const lineageEvents=record?.lineageEvents??[];
|
|
74
80
|
const patchAncestry=record?.patchAncestry??[];
|
|
75
81
|
const mergeDecisions=record?.mergeDecisions??[];
|
|
76
82
|
return record?.index??{
|
|
@@ -88,11 +94,21 @@ function historyIndex(record){
|
|
|
88
94
|
semanticClaimHashes:uniqueStrings([...acceptedFacts.map((claim)=>claim.hash),...rejectedTheories.map((claim)=>claim.hash)]),
|
|
89
95
|
acceptedFactIds:uniqueStrings(acceptedFacts.map((claim)=>claim.id)),
|
|
90
96
|
rejectedTheoryIds:uniqueStrings(rejectedTheories.map((claim)=>claim.id)),
|
|
91
|
-
|
|
92
|
-
|
|
97
|
+
lineageEventIds:uniqueStrings(lineageEvents.map((entry)=>entry.id)),
|
|
98
|
+
semanticAnchorIds:uniqueStrings(lineageEvents.flatMap((entry)=>[entry.from?.id,...(entry.to??[]).map((anchor)=>anchor.id)])),
|
|
99
|
+
semanticAnchorKeys:uniqueStrings([
|
|
100
|
+
...lineageEvents.flatMap((entry)=>[entry.from?.key,...(entry.to??[]).map((anchor)=>anchor.key)]),
|
|
101
|
+
...(record?.ownershipRegions??[]).map((region)=>region.key),
|
|
102
|
+
...(record?.semanticCandidates??[]).flatMap((candidate)=>candidate.ownershipKeys??[])
|
|
103
|
+
]),
|
|
104
|
+
semanticLineageKinds:uniqueStrings(lineageEvents.map((entry)=>entry.eventKind)),
|
|
105
|
+
crdtOperationIds:uniqueStrings(lineageEvents.map((entry)=>entry.crdt?.operationId)),
|
|
106
|
+
crdtHeads:uniqueStrings(lineageEvents.flatMap((entry)=>entry.crdt?.heads??[])),
|
|
107
|
+
conflictKeys:uniqueStrings([...(record?.semanticCandidates??[]).flatMap((candidate)=>candidate.conflictKeys??[]),...acceptedFacts.flatMap((claim)=>claim.conflictKeys??[]),...rejectedTheories.flatMap((claim)=>claim.conflictKeys??[]),...lineageEvents.flatMap((entry)=>entry.conflictKeys??[]),...patchAncestry.flatMap((patch)=>patch.conflictKeys??[]),...mergeDecisions.flatMap((decision)=>decision.conflictKeys??[])]),
|
|
108
|
+
evidenceIds:uniqueStrings([...(record?.evidenceIds??[]),...acceptedFacts.flatMap((claim)=>claim.evidenceIds??[]),...rejectedTheories.flatMap((claim)=>claim.evidenceIds??[]),...importedParserEvidence.flatMap((entry)=>[entry.evidenceId,...(entry.evidenceIds??[])]),...proofAttempts.flatMap((entry)=>entry.evidenceIds??[]),...lineageEvents.flatMap((entry)=>entry.evidenceIds??[]),...mergeDecisions.flatMap((entry)=>entry.evidenceIds??[])]),
|
|
93
109
|
importedParserEvidenceIds:uniqueStrings(importedParserEvidence.map((entry)=>entry.id)),
|
|
94
110
|
importedParserEvidenceHashes:uniqueStrings(importedParserEvidence.map((entry)=>entry.hash)),
|
|
95
|
-
proofIds:uniqueStrings([...(record?.proofIds??[]),...acceptedFacts.flatMap((claim)=>claim.proofIds??[]),...rejectedTheories.flatMap((claim)=>claim.proofIds??[]),...proofAttempts.flatMap((entry)=>[entry.proofId,...(entry.proofIds??[])]),...mergeDecisions.flatMap((entry)=>entry.proofIds??[])]),
|
|
111
|
+
proofIds:uniqueStrings([...(record?.proofIds??[]),...acceptedFacts.flatMap((claim)=>claim.proofIds??[]),...rejectedTheories.flatMap((claim)=>claim.proofIds??[]),...proofAttempts.flatMap((entry)=>[entry.proofId,...(entry.proofIds??[])]),...lineageEvents.flatMap((entry)=>entry.proofIds??[]),...mergeDecisions.flatMap((entry)=>entry.proofIds??[])]),
|
|
96
112
|
proofAttemptIds:uniqueStrings(proofAttempts.map((entry)=>entry.id)),
|
|
97
113
|
proofAttemptHashes:uniqueStrings(proofAttempts.map((entry)=>entry.hash)),
|
|
98
114
|
replayIds:uniqueStrings([...(record?.replayLinks??[]).map((link)=>link.id),...(record?.semanticCandidates??[]).flatMap((candidate)=>candidate.replayIds??[]),...acceptedFacts.flatMap((claim)=>claim.replayIds??[]),...rejectedTheories.flatMap((claim)=>claim.replayIds??[]),...proofAttempts.flatMap((entry)=>entry.replayIds??[])]),
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import{hashSemanticValue}from'@shapeshift-labs/frontier-lang-kernel';
|
|
2
2
|
import{ idFragment, maxSemanticMergeReadiness, normalizeSemanticMergeReadiness, uniqueStrings as uniqueRawStrings }from'../../native-import-utils.js';
|
|
3
3
|
import{normalizeOwnershipRegions,normalizeSemanticCandidates,normalizeSemanticClaims,normalizeSources,semanticClaimsByStatus}from'./semanticHistoryRecordNormalizers.js';
|
|
4
|
+
import{createSemanticLineageEvent,semanticLineageIndex}from'./semanticLineageRecords.js';
|
|
4
5
|
|
|
5
6
|
export const SemanticHistoryAdmissionStatuses=Object.freeze(['proposed','queued','admitted','needs-review','blocked','rejected']);
|
|
6
7
|
export const SemanticHistoryReviewerStatuses=Object.freeze(['unreviewed','approved','changes-requested','reviewed','rejected']);
|
|
7
|
-
export const SemanticHistoryOverlapKinds=Object.freeze(['ownership','conflict-key','source','source-path','import','semantic-candidate','semantic-claim','claim-hash','evidence','proof','replay','patch','merge-decision','actor','record-source','base-hash','target-hash']);
|
|
8
|
-
export const SemanticHistoryConflictReasons=Object.freeze(['ownership-overlap','semantic-conflict-key-overlap','base-hash-mismatch','target-hash-mismatch','admission-blocked','reviewer-rejected','source-path-overlap']);
|
|
8
|
+
export const SemanticHistoryOverlapKinds=Object.freeze(['ownership','conflict-key','source','source-path','import','semantic-candidate','semantic-claim','claim-hash','semantic-lineage','semantic-anchor','crdt-operation','crdt-head','evidence','proof','replay','patch','merge-decision','actor','record-source','base-hash','target-hash']);
|
|
9
|
+
export const SemanticHistoryConflictReasons=Object.freeze(['ownership-overlap','semantic-conflict-key-overlap','semantic-anchor-overlap','base-hash-mismatch','target-hash-mismatch','admission-blocked','reviewer-rejected','source-path-overlap']);
|
|
9
10
|
|
|
10
11
|
export function createSemanticHistoryRecord(input={},options={}){
|
|
11
12
|
const imported=input.importResult??input.imported;
|
|
@@ -36,18 +37,20 @@ export function createSemanticHistoryRecord(input={},options={}){
|
|
|
36
37
|
const proofAttempts=normalizeProofAttempts([...(array(input.proofAttempts)),...(array(input.proofs))],sourceContext);
|
|
37
38
|
const patchAncestry=normalizePatchAncestry(input.patchAncestry??input.patchAncestors??input.ancestry,sourceContext);
|
|
38
39
|
const mergeDecisions=normalizeMergeDecisions(input.mergeDecisions??input.decisions,sourceContext);
|
|
40
|
+
const lineageEvents=normalizeLineageEvents(input.lineageEvents??input.semanticLineageEvents??input.lineage,sourceContext);
|
|
41
|
+
const lineage=semanticLineageIndex(lineageEvents);
|
|
39
42
|
const semanticClaimIds=uniqueStrings([...acceptedFacts.map((claim)=>claim.id),...rejectedTheories.map((claim)=>claim.id)]);
|
|
40
43
|
const semanticClaimHashes=uniqueStrings([...acceptedFacts.map((claim)=>claim.hash),...rejectedTheories.map((claim)=>claim.hash)]);
|
|
41
|
-
const evidenceIds=uniqueStrings([...(strings(input.evidenceIds)),...(array(input.evidence)).map((record)=>record?.id),...(array(imported?.evidence)).map((record)=>record?.id),...semanticCandidates.flatMap((candidate)=>candidate.evidenceIds),...acceptedFacts.flatMap((claim)=>claim.evidenceIds),...rejectedTheories.flatMap((claim)=>claim.evidenceIds),...importedParserEvidence.flatMap((record)=>[record.evidenceId,...array(record.evidenceIds)]),...proofAttempts.flatMap((record)=>record.evidenceIds),...mergeDecisions.flatMap((decision)=>decision.evidenceIds),...(strings(input.reviewer?.evidenceIds)),...(strings(input.admission?.evidenceIds))]);
|
|
42
|
-
const proofIds=uniqueStrings([...(strings(input.proofIds)),...(array(input.proofs)).map((record)=>record?.id),...semanticCandidates.flatMap((candidate)=>candidate.proofIds),...acceptedFacts.flatMap((claim)=>claim.proofIds),...rejectedTheories.flatMap((claim)=>claim.proofIds),...proofAttempts.flatMap((record)=>[record.proofId,...array(record.proofIds)]),...mergeDecisions.flatMap((decision)=>decision.proofIds)]);
|
|
44
|
+
const evidenceIds=uniqueStrings([...(strings(input.evidenceIds)),...(array(input.evidence)).map((record)=>record?.id),...(array(imported?.evidence)).map((record)=>record?.id),...semanticCandidates.flatMap((candidate)=>candidate.evidenceIds),...acceptedFacts.flatMap((claim)=>claim.evidenceIds),...rejectedTheories.flatMap((claim)=>claim.evidenceIds),...importedParserEvidence.flatMap((record)=>[record.evidenceId,...array(record.evidenceIds)]),...proofAttempts.flatMap((record)=>record.evidenceIds),...lineageEvents.flatMap((record)=>record.evidenceIds),...mergeDecisions.flatMap((decision)=>decision.evidenceIds),...(strings(input.reviewer?.evidenceIds)),...(strings(input.admission?.evidenceIds))]);
|
|
45
|
+
const proofIds=uniqueStrings([...(strings(input.proofIds)),...(array(input.proofs)).map((record)=>record?.id),...semanticCandidates.flatMap((candidate)=>candidate.proofIds),...acceptedFacts.flatMap((claim)=>claim.proofIds),...rejectedTheories.flatMap((claim)=>claim.proofIds),...proofAttempts.flatMap((record)=>[record.proofId,...array(record.proofIds)]),...lineageEvents.flatMap((record)=>record.proofIds),...mergeDecisions.flatMap((decision)=>decision.proofIds)]);
|
|
43
46
|
const sourceIds=uniqueStrings([input.sourceId,...strings(input.sourceIds),...sources.map((source)=>source.id)]);
|
|
44
47
|
const importIds=uniqueStrings([input.importId,input.importResultId,imported?.id,...strings(input.importIds),...sources.map((source)=>source.importId),...semanticCandidates.map((candidate)=>candidate.importResultId)]);
|
|
45
48
|
const sourcePaths=uniqueStrings([input.sourcePath,imported?.sourcePath,...sources.map((source)=>source.sourcePath),...ownershipRegions.map((region)=>region.sourcePath),...semanticCandidates.map((candidate)=>candidate.sourcePath)]);
|
|
46
49
|
const sourceHashes=uniqueStrings([input.sourceHash,imported?.sourceHash,...sources.map((source)=>source.sourceHash),...ownershipRegions.map((region)=>region.sourceHash)]);
|
|
47
|
-
const conflictKeys=uniqueStrings([...(strings(input.conflictKeys)),...semanticCandidates.flatMap((candidate)=>candidate.conflictKeys),...acceptedFacts.flatMap((claim)=>claim.conflictKeys),...rejectedTheories.flatMap((claim)=>claim.conflictKeys),...patchAncestry.flatMap((patch)=>patch.conflictKeys),...mergeDecisions.flatMap((decision)=>decision.conflictKeys)]);
|
|
50
|
+
const conflictKeys=uniqueStrings([...(strings(input.conflictKeys)),...semanticCandidates.flatMap((candidate)=>candidate.conflictKeys),...acceptedFacts.flatMap((claim)=>claim.conflictKeys),...rejectedTheories.flatMap((claim)=>claim.conflictKeys),...lineageEvents.flatMap((event)=>event.conflictKeys),...patchAncestry.flatMap((patch)=>patch.conflictKeys),...mergeDecisions.flatMap((decision)=>decision.conflictKeys)]);
|
|
48
51
|
const reviewer=normalizeReviewer(input.reviewer);
|
|
49
52
|
const admission=normalizeAdmission(input.admission,semanticCandidates,reviewer);
|
|
50
|
-
const actorIds=uniqueStrings([actor?.id,actor?.actorId,...acceptedFacts.map((claim)=>claim.actor?.id),...rejectedTheories.map((claim)=>claim.actor?.id),...importedParserEvidence.map((record)=>record.actor?.id),...proofAttempts.map((record)=>record.actor?.id),...patchAncestry.map((record)=>record.actor?.id),...mergeDecisions.map((record)=>record.actor?.id)]);
|
|
53
|
+
const actorIds=uniqueStrings([actor?.id,actor?.actorId,...acceptedFacts.map((claim)=>claim.actor?.id),...rejectedTheories.map((claim)=>claim.actor?.id),...importedParserEvidence.map((record)=>record.actor?.id),...proofAttempts.map((record)=>record.actor?.id),...lineageEvents.map((record)=>record.actor?.id),...patchAncestry.map((record)=>record.actor?.id),...mergeDecisions.map((record)=>record.actor?.id)]);
|
|
51
54
|
const recordSourceIds=uniqueStrings([recordSource?.id,recordSource?.sourceId,...acceptedFacts.flatMap((claim)=>[claim.recordSource?.id,claim.recordSource?.sourceId]),...rejectedTheories.flatMap((claim)=>[claim.recordSource?.id,claim.recordSource?.sourceId]),...importedParserEvidence.flatMap((record)=>[record.recordSource?.id,record.recordSource?.sourceId]),...proofAttempts.flatMap((record)=>[record.recordSource?.id,record.recordSource?.sourceId]),...patchAncestry.flatMap((record)=>[record.recordSource?.id,record.recordSource?.sourceId]),...mergeDecisions.flatMap((record)=>[record.recordSource?.id,record.recordSource?.sourceId])]);
|
|
52
55
|
const patchIds=uniqueStrings([...semanticCandidates.map((candidate)=>candidate.patchId),...patchAncestry.flatMap((patch)=>[patch.patchId,...array(patch.parentPatchIds),...array(patch.ancestorPatchIds)]),...mergeDecisions.flatMap((decision)=>decision.patchIds)]);
|
|
53
56
|
const mergeDecisionIds=uniqueStrings(mergeDecisions.map((decision)=>decision.id));
|
|
@@ -66,6 +69,12 @@ export function createSemanticHistoryRecord(input={},options={}){
|
|
|
66
69
|
semanticClaimHashes,
|
|
67
70
|
acceptedFactIds:uniqueStrings(acceptedFacts.map((claim)=>claim.id)),
|
|
68
71
|
rejectedTheoryIds:uniqueStrings(rejectedTheories.map((claim)=>claim.id)),
|
|
72
|
+
lineageEventIds:lineage.lineageEventIds,
|
|
73
|
+
semanticAnchorIds:lineage.semanticAnchorIds,
|
|
74
|
+
semanticAnchorKeys:uniqueStrings([...lineage.semanticAnchorKeys,...ownershipRegions.map((region)=>region.key),...semanticCandidates.flatMap((candidate)=>candidate.ownershipKeys)]),
|
|
75
|
+
semanticLineageKinds:lineage.semanticLineageKinds,
|
|
76
|
+
crdtOperationIds:lineage.crdtOperationIds,
|
|
77
|
+
crdtHeads:lineage.crdtHeads,
|
|
69
78
|
conflictKeys,
|
|
70
79
|
evidenceIds,
|
|
71
80
|
importedParserEvidenceIds:uniqueStrings(importedParserEvidence.map((record)=>record.id)),
|
|
@@ -97,6 +106,7 @@ export function createSemanticHistoryRecord(input={},options={}){
|
|
|
97
106
|
rejectedTheories,
|
|
98
107
|
importedParserEvidence,
|
|
99
108
|
proofAttempts,
|
|
109
|
+
lineageEvents,
|
|
100
110
|
patchAncestry,
|
|
101
111
|
mergeDecisions,
|
|
102
112
|
evidenceIds,
|
|
@@ -170,6 +180,19 @@ function normalizeProofAttempts(records,defaults){
|
|
|
170
180
|
});
|
|
171
181
|
}
|
|
172
182
|
|
|
183
|
+
function normalizeLineageEvents(records,defaults){
|
|
184
|
+
return array(records).filter(Boolean).map((record)=>createSemanticLineageEvent(record,{
|
|
185
|
+
id:record.id,
|
|
186
|
+
createdAt:record.createdAt,
|
|
187
|
+
actor:record.actor??defaults.actor,
|
|
188
|
+
actorId:record.actorId??defaults.actor?.id
|
|
189
|
+
})).map((record)=>({
|
|
190
|
+
...record,
|
|
191
|
+
from:record.from?{...record.from,language:record.from.language??defaults.language,sourcePath:record.from.sourcePath??defaults.sourcePath,sourceHash:record.from.sourceHash??defaults.sourceHash}:record.from,
|
|
192
|
+
to:record.to.map((anchor)=>({...anchor,language:anchor.language??defaults.language,sourcePath:anchor.sourcePath??defaults.sourcePath,sourceHash:anchor.sourceHash??defaults.sourceHash}))
|
|
193
|
+
}));
|
|
194
|
+
}
|
|
195
|
+
|
|
173
196
|
function normalizePatchAncestry(records,defaults){
|
|
174
197
|
return array(records).filter(Boolean).map((record,index)=>{
|
|
175
198
|
const source=typeof record==='string'?{patchId:record}:record;
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { hashSemanticValue } from '@shapeshift-labs/frontier-lang-kernel';
|
|
2
|
+
import { idFragment, uniqueStrings as uniqueRawStrings } from '../../native-import-utils.js';
|
|
3
|
+
|
|
4
|
+
export const SemanticLineageEventKinds = Object.freeze(['unchanged', 'moved', 'renamed', 'split', 'merged', 'deleted', 'recreated', 'unknown']);
|
|
5
|
+
|
|
6
|
+
export function createSemanticAnchor(input = {}, defaults = {}) {
|
|
7
|
+
const source = typeof input === 'string' ? { key: input } : input;
|
|
8
|
+
const semanticPath = array(source.semanticPath ?? source.pathSegments).map((part) => String(part));
|
|
9
|
+
const key = firstString(source.key, source.ownershipKey, source.conflictKey, source.semanticKey, semanticPath.join('.'), source.symbolName, source.id);
|
|
10
|
+
const anchor = compactRecord({
|
|
11
|
+
id: source.id ?? (key ? `semantic_anchor_${idFragment(key)}` : undefined),
|
|
12
|
+
key,
|
|
13
|
+
kind: source.kind ?? source.anchorKind ?? source.regionKind ?? source.symbolKind,
|
|
14
|
+
language: source.language ?? defaults.language,
|
|
15
|
+
sourcePath: source.sourcePath ?? defaults.sourcePath,
|
|
16
|
+
sourceHash: source.sourceHash ?? source.hash ?? defaults.sourceHash,
|
|
17
|
+
symbolId: source.symbolId,
|
|
18
|
+
symbolName: source.symbolName ?? source.name,
|
|
19
|
+
semanticPath,
|
|
20
|
+
signatureHash: source.signatureHash,
|
|
21
|
+
bodyHash: source.bodyHash,
|
|
22
|
+
sourceSpan: source.sourceSpan ?? source.span,
|
|
23
|
+
metadata: source.metadata
|
|
24
|
+
});
|
|
25
|
+
return nonEmptyRecord(anchor);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function createSemanticLineageEvent(input = {}, options = {}) {
|
|
29
|
+
const from = createSemanticAnchor(input.from ?? input.fromAnchor ?? input.before, input);
|
|
30
|
+
const toAnchors = array(input.to ?? input.toAnchors ?? input.after).map((anchor) => createSemanticAnchor(anchor, input)).filter(Boolean);
|
|
31
|
+
const eventKind = normalizeEventKind(input.eventKind ?? input.event ?? input.kind);
|
|
32
|
+
const actor = normalizeActor(input.actor ?? options.actor ?? {
|
|
33
|
+
id: input.actorId ?? options.actorId,
|
|
34
|
+
role: input.actorRole ?? options.actorRole
|
|
35
|
+
});
|
|
36
|
+
const crdt = normalizeCrdtClock(input.crdt ?? input.clock ?? input.operation ?? input);
|
|
37
|
+
const evidence = compactRecord({
|
|
38
|
+
pathMatch: input.evidence?.pathMatch ?? input.pathMatch,
|
|
39
|
+
signatureHashMatch: input.evidence?.signatureHashMatch ?? input.signatureHashMatch,
|
|
40
|
+
bodyHashMatch: input.evidence?.bodyHashMatch ?? input.bodyHashMatch,
|
|
41
|
+
syntaxShapeMatch: input.evidence?.syntaxShapeMatch ?? input.syntaxShapeMatch,
|
|
42
|
+
sourceSpanMoved: input.evidence?.sourceSpanMoved ?? input.sourceSpanMoved,
|
|
43
|
+
confidence: input.evidence?.confidence ?? input.confidence,
|
|
44
|
+
command: input.evidence?.command ?? input.command
|
|
45
|
+
});
|
|
46
|
+
const core = {
|
|
47
|
+
kind: 'frontier.lang.semanticLineageEvent',
|
|
48
|
+
version: 1,
|
|
49
|
+
eventKind,
|
|
50
|
+
from,
|
|
51
|
+
to: toAnchors,
|
|
52
|
+
confidence: clampConfidence(input.confidence),
|
|
53
|
+
actor,
|
|
54
|
+
crdt,
|
|
55
|
+
evidence,
|
|
56
|
+
evidenceIds: uniqueStrings([...(strings(input.evidenceIds)), ...(array(input.evidence)).map((entry) => entry?.id)]),
|
|
57
|
+
proofIds: uniqueStrings([...(strings(input.proofIds)), ...(array(input.proofs)).map((entry) => entry?.id)]),
|
|
58
|
+
conflictKeys: uniqueStrings([
|
|
59
|
+
...(strings(input.conflictKeys)),
|
|
60
|
+
input.conflictKey,
|
|
61
|
+
from?.key,
|
|
62
|
+
...toAnchors.map((anchor) => anchor.key)
|
|
63
|
+
]),
|
|
64
|
+
metadata: compactRecord(input.metadata)
|
|
65
|
+
};
|
|
66
|
+
const hash = input.hash ?? hashSemanticValue(core);
|
|
67
|
+
return {
|
|
68
|
+
...core,
|
|
69
|
+
id: input.id ?? options.id ?? `semantic_lineage_${idFragment(firstString(from?.key, toAnchors[0]?.key, crdt.operationId, hash))}`,
|
|
70
|
+
stableId: `semantic_lineage_${idFragment(hash)}`,
|
|
71
|
+
hash,
|
|
72
|
+
createdAt: input.createdAt ?? options.createdAt ?? Date.now()
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function createSemanticLineageMap(events = [], options = {}) {
|
|
77
|
+
const records = array(events).map((event) => event?.kind === 'frontier.lang.semanticLineageEvent' ? event : createSemanticLineageEvent(event, options));
|
|
78
|
+
const byAnchorKey = {};
|
|
79
|
+
const byEventKind = {};
|
|
80
|
+
const byOperationId = {};
|
|
81
|
+
const bySourcePath = {};
|
|
82
|
+
for (const event of records) {
|
|
83
|
+
indexPush(byEventKind, event.eventKind, event.id);
|
|
84
|
+
indexPush(byOperationId, event.crdt?.operationId, event.id);
|
|
85
|
+
for (const anchor of [event.from, ...event.to].filter(Boolean)) {
|
|
86
|
+
indexPush(byAnchorKey, anchor.key, event.id);
|
|
87
|
+
indexPush(bySourcePath, anchor.sourcePath, event.id);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
kind: 'frontier.lang.semanticLineageMap',
|
|
92
|
+
version: 1,
|
|
93
|
+
id: options.id ?? `semantic_lineage_map_${idFragment(hashSemanticValue(records.map((event) => event.id)))}`,
|
|
94
|
+
generatedAt: options.generatedAt ?? Date.now(),
|
|
95
|
+
events: records,
|
|
96
|
+
byAnchorKey,
|
|
97
|
+
byEventKind,
|
|
98
|
+
byOperationId,
|
|
99
|
+
bySourcePath,
|
|
100
|
+
summary: {
|
|
101
|
+
eventCount: records.length,
|
|
102
|
+
anchorCount: Object.keys(byAnchorKey).length,
|
|
103
|
+
operationCount: Object.keys(byOperationId).length,
|
|
104
|
+
eventKinds: Object.keys(byEventKind)
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function querySemanticLineageEvents(events, query = {}) {
|
|
110
|
+
return array(events).filter((event) => {
|
|
111
|
+
const record = event?.kind === 'frontier.lang.semanticLineageEvent' ? event : createSemanticLineageEvent(event);
|
|
112
|
+
const anchors = [record.from, ...record.to].filter(Boolean);
|
|
113
|
+
return matchAny(query.eventKind, [record.eventKind])
|
|
114
|
+
&& matchAny(query.anchorKey, anchors.map((anchor) => anchor.key))
|
|
115
|
+
&& matchAny(query.fromKey, [record.from?.key])
|
|
116
|
+
&& matchAny(query.toKey, record.to.map((anchor) => anchor.key))
|
|
117
|
+
&& matchAny(query.sourcePath, anchors.map((anchor) => anchor.sourcePath))
|
|
118
|
+
&& matchAny(query.operationId, [record.crdt?.operationId])
|
|
119
|
+
&& matchAny(query.head, record.crdt?.heads)
|
|
120
|
+
&& matchAny(query.conflictKey, record.conflictKeys)
|
|
121
|
+
&& matchAny(query.evidenceId, record.evidenceIds);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export function semanticLineageIndex(events) {
|
|
126
|
+
const records = array(events).filter(Boolean);
|
|
127
|
+
const anchors = records.flatMap((event) => [event.from, ...(event.to ?? [])]).filter(Boolean);
|
|
128
|
+
return {
|
|
129
|
+
lineageEventIds: uniqueStrings(records.map((event) => event.id)),
|
|
130
|
+
semanticAnchorIds: uniqueStrings(anchors.map((anchor) => anchor.id)),
|
|
131
|
+
semanticAnchorKeys: uniqueStrings(anchors.map((anchor) => anchor.key)),
|
|
132
|
+
semanticLineageKinds: uniqueStrings(records.map((event) => event.eventKind)),
|
|
133
|
+
crdtOperationIds: uniqueStrings(records.map((event) => event.crdt?.operationId)),
|
|
134
|
+
crdtHeads: uniqueStrings(records.flatMap((event) => event.crdt?.heads ?? []))
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function normalizeCrdtClock(source) {
|
|
139
|
+
return nonEmptyRecord(compactRecord({
|
|
140
|
+
operationId: source.operationId ?? source.id,
|
|
141
|
+
actor: source.actorId ?? source.actor,
|
|
142
|
+
seq: source.seq,
|
|
143
|
+
deps: uniqueStrings(source.deps),
|
|
144
|
+
heads: uniqueStrings(source.heads),
|
|
145
|
+
stateVector: source.stateVector,
|
|
146
|
+
versionFrame: source.versionFrame ?? source.frame
|
|
147
|
+
}));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function normalizeActor(value) {
|
|
151
|
+
const actor = typeof value === 'string' ? { id: value } : value;
|
|
152
|
+
return nonEmptyRecord(compactRecord({
|
|
153
|
+
id: actor?.id ?? actor?.actorId,
|
|
154
|
+
role: actor?.role,
|
|
155
|
+
lane: actor?.lane,
|
|
156
|
+
taskId: actor?.taskId,
|
|
157
|
+
runId: actor?.runId,
|
|
158
|
+
metadata: actor?.metadata
|
|
159
|
+
}));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function normalizeEventKind(kind) {
|
|
163
|
+
const text = String(kind ?? 'unknown');
|
|
164
|
+
return SemanticLineageEventKinds.includes(text) ? text : text;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function clampConfidence(value) {
|
|
168
|
+
if (value === undefined || value === null || value === '') return undefined;
|
|
169
|
+
const number = Number(value);
|
|
170
|
+
if (!Number.isFinite(number)) return undefined;
|
|
171
|
+
return Math.max(0, Math.min(1, number));
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function indexPush(index, key, id) {
|
|
175
|
+
if (!key || !id) return;
|
|
176
|
+
const value = String(key);
|
|
177
|
+
if (!index[value]) index[value] = [];
|
|
178
|
+
if (!index[value].includes(id)) index[value].push(id);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function matchAny(queryValue, values) {
|
|
182
|
+
const queries = strings(queryValue);
|
|
183
|
+
if (queries.length === 0) return true;
|
|
184
|
+
const valueSet = new Set(strings(values));
|
|
185
|
+
return queries.some((query) => valueSet.has(query));
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function array(value) { return value === undefined || value === null ? [] : Array.isArray(value) ? value : [value]; }
|
|
189
|
+
function strings(value) { return array(value).map((entry) => String(entry ?? '')).filter(Boolean); }
|
|
190
|
+
function uniqueStrings(values) { return uniqueRawStrings(strings(values)); }
|
|
191
|
+
function firstString(...values) { return values.map((value) => value === undefined || value === null ? '' : String(value)).find(Boolean); }
|
|
192
|
+
function compactRecord(value) { return Object.fromEntries(Object.entries(value ?? {}).filter(([, entry]) => entry !== undefined && (!Array.isArray(entry) || entry.length > 0))); }
|
|
193
|
+
function nonEmptyRecord(value) { return Object.keys(value ?? {}).length ? value : undefined; }
|
|
@@ -176,7 +176,7 @@ function jsObjectPropertyDeclaration(input, lineNumber, trimmed, context) {
|
|
|
176
176
|
|
|
177
177
|
function jsRouteRecordDeclaration(input, lineNumber, trimmed, context) {
|
|
178
178
|
if (context.regionKind !== 'route') return undefined;
|
|
179
|
-
const match = trimmed.match(
|
|
179
|
+
const match = trimmed.match(/^(?:\{\s*)?(?:path|route|href|url)\s*:\s*(['"`])([^'"`]+)\1/);
|
|
180
180
|
if (!match) return undefined;
|
|
181
181
|
const routePath = match[2];
|
|
182
182
|
return nativeDeclaration(input, lineNumber, 'RouteRecord', 'route', `${context.name}.${routePath}`, {
|
|
@@ -224,7 +224,19 @@ function jsContainerWrapperLooksSemantic(callee, name, source) {
|
|
|
224
224
|
|
|
225
225
|
function jsContainerDelta(source) {
|
|
226
226
|
let delta = 0;
|
|
227
|
+
let quote;
|
|
228
|
+
let escaped = false;
|
|
227
229
|
for (const char of String(source ?? '')) {
|
|
230
|
+
if (quote) {
|
|
231
|
+
if (escaped) escaped = false;
|
|
232
|
+
else if (char === '\\') escaped = true;
|
|
233
|
+
else if (char === quote) quote = undefined;
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
if (char === '\'' || char === '"' || char === '`') {
|
|
237
|
+
quote = char;
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
228
240
|
if (char === '{' || char === '[') delta += 1;
|
|
229
241
|
if (char === '}' || char === ']') delta -= 1;
|
|
230
242
|
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { nativeDeclaration } from './native-region-scanner-core.js';
|
|
2
|
+
import { jsContainerDelta, jsRegionKindForDeclarationName } from './native-region-scanner-js-helpers.js';
|
|
3
|
+
|
|
4
|
+
function jsCurrentObjectContext(stack) {
|
|
5
|
+
return stack[stack.length - 1];
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function jsContextAllowsPropertyScan(context) {
|
|
9
|
+
return context?.initializerKind === 'object';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function jsNestedObjectContextFromDeclaration(declaration, lineNumber, source) {
|
|
13
|
+
const initializerKind = declaration?.fields?.initializerKind ?? declaration?.metadata?.initializerKind;
|
|
14
|
+
if (initializerKind !== 'object' && initializerKind !== 'array') return undefined;
|
|
15
|
+
const depth = jsContainerDelta(source);
|
|
16
|
+
if (depth <= 0) return undefined;
|
|
17
|
+
return {
|
|
18
|
+
name: declaration.name,
|
|
19
|
+
regionKind: declaration.regionKind ?? declaration.metadata?.regionKind,
|
|
20
|
+
initializerKind,
|
|
21
|
+
depth,
|
|
22
|
+
startLine: lineNumber
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function jsInlineNestedObjectDeclarations(input, lineNumber, source, parentDeclaration, depth = 0) {
|
|
27
|
+
const parentInitializerKind = parentDeclaration?.fields?.initializerKind ?? parentDeclaration?.metadata?.initializerKind;
|
|
28
|
+
if (depth > 4 || parentInitializerKind !== 'object') return [];
|
|
29
|
+
const body = inlineObjectBody(source);
|
|
30
|
+
if (body === undefined) return [];
|
|
31
|
+
const declarations = [];
|
|
32
|
+
for (const entry of splitTopLevelEntries(body)) {
|
|
33
|
+
const parsed = parseObjectEntry(entry);
|
|
34
|
+
if (!parsed) continue;
|
|
35
|
+
const initializerKind = nestedInitializerKind(parsed.value);
|
|
36
|
+
const name = `${parentDeclaration.name}.${parsed.key}`;
|
|
37
|
+
const regionKind = nestedPropertyRegionKind(parentDeclaration, parsed.key, parsed.value);
|
|
38
|
+
const declaration = nativeDeclaration(input, lineNumber, initializerKind === 'function' ? 'NestedObjectFunctionProperty' : 'NestedObjectProperty', initializerKind === 'function' ? 'function' : 'property', name, {
|
|
39
|
+
owner: parentDeclaration.name,
|
|
40
|
+
propertyName: parsed.key,
|
|
41
|
+
initializerKind
|
|
42
|
+
}, initializerKind === 'object' || initializerKind === 'array' || initializerKind === 'function', {
|
|
43
|
+
regionKind,
|
|
44
|
+
metadata: { owner: parentDeclaration.name, propertyName: parsed.key, initializerKind }
|
|
45
|
+
});
|
|
46
|
+
declarations.push(declaration);
|
|
47
|
+
declarations.push(...jsInlineNestedObjectDeclarations(input, lineNumber, parsed.value, declaration, depth + 1));
|
|
48
|
+
}
|
|
49
|
+
return declarations;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function updateJsObjectContextStack(stack, lineNumber, source) {
|
|
53
|
+
const delta = jsContainerDelta(source);
|
|
54
|
+
for (const context of stack) {
|
|
55
|
+
if (context.startLine !== lineNumber) context.depth += delta;
|
|
56
|
+
}
|
|
57
|
+
while (stack.length && stack[stack.length - 1].depth <= 0) stack.pop();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function inlineObjectBody(source) {
|
|
61
|
+
const text = String(source ?? '');
|
|
62
|
+
const open = text.indexOf('{');
|
|
63
|
+
if (open < 0) return undefined;
|
|
64
|
+
let quote;
|
|
65
|
+
let escaped = false;
|
|
66
|
+
let depth = 0;
|
|
67
|
+
for (let index = open; index < text.length; index += 1) {
|
|
68
|
+
const char = text[index];
|
|
69
|
+
if (quote) {
|
|
70
|
+
if (escaped) escaped = false;
|
|
71
|
+
else if (char === '\\') escaped = true;
|
|
72
|
+
else if (char === quote) quote = undefined;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (char === '\'' || char === '"' || char === '`') {
|
|
76
|
+
quote = char;
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (char === '{') depth += 1;
|
|
80
|
+
else if (char === '}') {
|
|
81
|
+
depth -= 1;
|
|
82
|
+
if (depth === 0) return text.slice(open + 1, index);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function splitTopLevelEntries(body) {
|
|
89
|
+
const entries = [];
|
|
90
|
+
let quote;
|
|
91
|
+
let escaped = false;
|
|
92
|
+
let depth = 0;
|
|
93
|
+
let start = 0;
|
|
94
|
+
const text = String(body ?? '');
|
|
95
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
96
|
+
const char = text[index];
|
|
97
|
+
if (quote) {
|
|
98
|
+
if (escaped) escaped = false;
|
|
99
|
+
else if (char === '\\') escaped = true;
|
|
100
|
+
else if (char === quote) quote = undefined;
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if (char === '\'' || char === '"' || char === '`') quote = char;
|
|
104
|
+
else if (char === '{' || char === '[' || char === '(') depth += 1;
|
|
105
|
+
else if (char === '}' || char === ']' || char === ')') depth -= 1;
|
|
106
|
+
else if (char === ',' && depth === 0) {
|
|
107
|
+
entries.push(text.slice(start, index).trim());
|
|
108
|
+
start = index + 1;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
entries.push(text.slice(start).trim());
|
|
112
|
+
return entries.filter(Boolean);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function parseObjectEntry(entry) {
|
|
116
|
+
if (!entry || entry.startsWith('...') || entry.startsWith('[')) return undefined;
|
|
117
|
+
const match = entry.match(/^(?:(['"])([^'"]+)\1|([A-Za-z_$][\w$-]*))\s*:\s*(.+)$/s);
|
|
118
|
+
if (!match) return undefined;
|
|
119
|
+
return { key: match[2] ?? match[3], value: match[4].trim() };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function nestedInitializerKind(value) {
|
|
123
|
+
const text = String(value ?? '').trim();
|
|
124
|
+
if (text.startsWith('{')) return 'object';
|
|
125
|
+
if (text.startsWith('[')) return 'array';
|
|
126
|
+
if (/^(?:async\s*)?(?:function\b|\([^)]*\)\s*=>|[A-Za-z_$][\w$]*\s*=>)/.test(text)) return 'function';
|
|
127
|
+
if (/^['"`]/.test(text)) return 'string';
|
|
128
|
+
if (/^(?:true|false)\b/.test(text)) return 'boolean';
|
|
129
|
+
if (/^[0-9]/.test(text)) return 'number';
|
|
130
|
+
return 'expression';
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function nestedPropertyRegionKind(parentDeclaration, propertyName, value) {
|
|
134
|
+
return jsRegionKindForDeclarationName(propertyName, value)
|
|
135
|
+
?? parentDeclaration.regionKind
|
|
136
|
+
?? parentDeclaration.metadata?.ownershipRegionKind
|
|
137
|
+
?? parentDeclaration.metadata?.regionKind
|
|
138
|
+
?? 'property';
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export {
|
|
142
|
+
jsContextAllowsPropertyScan,
|
|
143
|
+
jsCurrentObjectContext,
|
|
144
|
+
jsInlineNestedObjectDeclarations,
|
|
145
|
+
jsNestedObjectContextFromDeclaration,
|
|
146
|
+
updateJsObjectContextStack
|
|
147
|
+
};
|
|
@@ -20,6 +20,13 @@ import {
|
|
|
20
20
|
jsVariableHasBody,
|
|
21
21
|
jsVariableSymbolKind
|
|
22
22
|
} from './native-region-scanner-js-helpers.js';
|
|
23
|
+
import {
|
|
24
|
+
jsContextAllowsPropertyScan,
|
|
25
|
+
jsCurrentObjectContext,
|
|
26
|
+
jsInlineNestedObjectDeclarations,
|
|
27
|
+
jsNestedObjectContextFromDeclaration,
|
|
28
|
+
updateJsObjectContextStack
|
|
29
|
+
} from './native-region-scanner-js-nested.js';
|
|
23
30
|
|
|
24
31
|
function scanJavaScriptLike(input) {
|
|
25
32
|
const declarations = [];
|
|
@@ -32,7 +39,7 @@ function scanJavaScriptLike(input) {
|
|
|
32
39
|
};
|
|
33
40
|
let currentClass;
|
|
34
41
|
let classDepth = 0;
|
|
35
|
-
|
|
42
|
+
const objectStack = [];
|
|
36
43
|
let currentType;
|
|
37
44
|
const lexicalState = { inBlockComment: false, inTemplateString: false };
|
|
38
45
|
for (const { line, number } of lines) {
|
|
@@ -44,13 +51,19 @@ function scanJavaScriptLike(input) {
|
|
|
44
51
|
if (currentType && number !== currentType.startLine) {
|
|
45
52
|
pushDeclaration(jsTypeMemberDeclaration(input, number, declarationLine, currentType));
|
|
46
53
|
}
|
|
54
|
+
const currentObject = jsCurrentObjectContext(objectStack);
|
|
47
55
|
if (currentObject) {
|
|
48
56
|
const routeRecord = jsRouteRecordDeclaration(input, number, trimmed, currentObject);
|
|
49
57
|
if (routeRecord) {
|
|
50
58
|
pushDeclaration(routeRecord);
|
|
51
|
-
} else {
|
|
59
|
+
} else if (jsContextAllowsPropertyScan(currentObject)) {
|
|
52
60
|
const property = jsObjectPropertyDeclaration(input, number, trimmed, currentObject);
|
|
53
|
-
if (property)
|
|
61
|
+
if (property) {
|
|
62
|
+
pushDeclaration(property);
|
|
63
|
+
pushDeclarations(jsInlineNestedObjectDeclarations(input, number, trimmed, property));
|
|
64
|
+
const nestedContext = jsNestedObjectContextFromDeclaration(property, number, trimmed);
|
|
65
|
+
if (nestedContext) objectStack.push(nestedContext);
|
|
66
|
+
}
|
|
54
67
|
}
|
|
55
68
|
}
|
|
56
69
|
const importDeclarations = jsImportDeclarations(input, number, trimmed);
|
|
@@ -93,10 +106,13 @@ function scanJavaScriptLike(input) {
|
|
|
93
106
|
regionKind,
|
|
94
107
|
metadata: { initializerKind }
|
|
95
108
|
}));
|
|
96
|
-
|
|
109
|
+
pushDeclarations(jsInlineNestedObjectDeclarations(input, number, declarationLine, declarations[declarations.length - 1]));
|
|
110
|
+
const objectContext = jsObjectRegionContext(match[1], declarationLine, number, regionKind);
|
|
111
|
+
if (objectContext) objectStack.push(objectContext);
|
|
97
112
|
} else if ((match = jsExportedContainerDeclaration(input, number, trimmed))) {
|
|
98
113
|
pushDeclaration(match.declaration);
|
|
99
|
-
|
|
114
|
+
pushDeclarations(jsInlineNestedObjectDeclarations(input, number, trimmed, match.declaration));
|
|
115
|
+
if (match.context) objectStack.push(match.context);
|
|
100
116
|
} else if ((match = trimmed.match(/^(?:module\.)?exports\.([A-Za-z_$][\w$]*)\s*=\s*(?:async\s+)?function\*?\s*\(([^)]*)\)/))) {
|
|
101
117
|
pushDeclaration(nativeDeclaration(input, number, 'CommonJsFunctionExport', 'function', match[1], { parameters: splitParameters(match[2]) }, true));
|
|
102
118
|
} else if ((match = trimmed.match(/^(?:module\.)?exports\.([A-Za-z_$][\w$]*)\s*=/))) {
|
|
@@ -126,10 +142,7 @@ function scanJavaScriptLike(input) {
|
|
|
126
142
|
if (number !== currentType.startLine) currentType.depth += jsStructureDelta(trimmed).value;
|
|
127
143
|
if (currentType.depth <= 0) currentType = undefined;
|
|
128
144
|
}
|
|
129
|
-
|
|
130
|
-
if (number !== currentObject.startLine) currentObject.depth += jsContainerDelta(trimmed);
|
|
131
|
-
if (currentObject.depth <= 0) currentObject = undefined;
|
|
132
|
-
}
|
|
145
|
+
updateJsObjectContextStack(objectStack, number, trimmed);
|
|
133
146
|
}
|
|
134
147
|
return declarations;
|
|
135
148
|
}
|
package/package.json
CHANGED