@shapeshift-labs/frontier-lang-css 0.1.20 → 0.1.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +14 -28
- package/dist/scoped-cascade-proof.d.ts +52 -0
- package/dist/selector-target-proof.d.ts +46 -0
- package/dist/semantic-merge-scoped-cascade.js +167 -0
- package/dist/semantic-merge-selector-targets.js +108 -16
- package/dist/semantic-merge.js +11 -12
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FrontierLangDocument } from '@shapeshift-labs/frontier-lang-kernel'; import type { CssCascadeRuntimeProof, CssCascadeRuntimeProofRecord } from './cascade-runtime-proof.js'; import type { CssDependencyGraphEvidence, CssDependencyGraphProof, CssDependencyGraphProofRecord } from './dependency-graph.js'; import type { CssModuleContractProof, CssModuleContractProofRecord } from './css-module-contract-proof.js'; import type { CssSafeMergeShorthandExpansionEvidence, CssShorthandExpansionEvidence } from './shorthand-expansion.js'; export type { CssCascadeRuntimeProof, CssCascadeRuntimeProofRecord } from './cascade-runtime-proof.js'; export type { CssDependencyGraphChange, CssDependencyGraphEvidence, CssDependencyGraphProof, CssDependencyGraphProofRecord } from './dependency-graph.js'; export type { CssModuleContractProof, CssModuleContractProofRecord } from './css-module-contract-proof.js'; export type { CssSafeMergeChangedShorthandExpansion, CssSafeMergeShorthandExpansionEvidence, CssSafeMergeShorthandExpansionSideEvidence, CssShorthandExpansionEvidence, CssShorthandLonghandExpansion } from './shorthand-expansion.js';
|
|
1
|
+
import type { FrontierLangDocument } from '@shapeshift-labs/frontier-lang-kernel'; import type { CssCascadeRuntimeProof, CssCascadeRuntimeProofRecord } from './cascade-runtime-proof.js'; import type { CssDependencyGraphEvidence, CssDependencyGraphProof, CssDependencyGraphProofRecord } from './dependency-graph.js'; import type { CssModuleContractProof, CssModuleContractProofRecord } from './css-module-contract-proof.js'; import type { CssScopedCascadeProof, CssScopedCascadeProofRecord } from './scoped-cascade-proof.js'; import type { CssSafeMergeShorthandExpansionEvidence, CssShorthandExpansionEvidence } from './shorthand-expansion.js'; import type { CssSafeMergeSelectorTargetEvidence, CssSelectorTargetEquivalence, CssSelectorTargetProof } from './selector-target-proof.js'; export type { CssCascadeRuntimeProof, CssCascadeRuntimeProofRecord } from './cascade-runtime-proof.js'; export type { CssDependencyGraphChange, CssDependencyGraphEvidence, CssDependencyGraphProof, CssDependencyGraphProofRecord } from './dependency-graph.js'; export type { CssModuleContractProof, CssModuleContractProofRecord } from './css-module-contract-proof.js'; export type { CssScopedCascadeProof, CssScopedCascadeProofRecord } from './scoped-cascade-proof.js'; export type { CssSafeMergeChangedShorthandExpansion, CssSafeMergeShorthandExpansionEvidence, CssSafeMergeShorthandExpansionSideEvidence, CssShorthandExpansionEvidence, CssShorthandLonghandExpansion } from './shorthand-expansion.js'; export type { CssSafeMergeSelectorMove, CssSafeMergeSelectorTargetEvidence, CssSafeMergeSelectorTargetRebaseProof, CssSafeMergeSelectorTargetSideEvidence, CssSelectorTargetEquivalence, CssSelectorTargetProof } from './selector-target-proof.js';
|
|
2
2
|
|
|
3
3
|
export interface CssProjectionOptions {
|
|
4
4
|
readonly banner?: string;
|
|
@@ -13,6 +13,8 @@ export interface CssProjectionOptions {
|
|
|
13
13
|
readonly cssModuleCompositionGraphHash?: string;
|
|
14
14
|
readonly icssGraphHash?: string;
|
|
15
15
|
readonly scopedCascadeGraphHash?: string;
|
|
16
|
+
readonly cssScopedCascadeProof?: CssScopedCascadeProof; readonly cssScopedCascadeProofs?: readonly CssScopedCascadeProof[];
|
|
17
|
+
readonly cssSourceBoundScopedCascadeProof?: CssScopedCascadeProof; readonly cssSourceBoundScopedCascadeProofs?: readonly CssScopedCascadeProof[];
|
|
16
18
|
readonly cssCascadeRuntimeProof?: CssCascadeRuntimeProof; readonly cssCascadeRuntimeProofs?: readonly CssCascadeRuntimeProof[];
|
|
17
19
|
readonly cssSourceBoundCascadeProof?: CssCascadeRuntimeProof; readonly cssSourceBoundCascadeProofs?: readonly CssCascadeRuntimeProof[];
|
|
18
20
|
readonly selectorTargetGraphHash?: string;
|
|
@@ -228,6 +230,7 @@ export interface CssSafeMergeAdmission {
|
|
|
228
230
|
readonly reviewRequired: boolean; readonly reasonCodes: readonly string[];
|
|
229
231
|
readonly browserCascadeEquivalenceClaim?: true;
|
|
230
232
|
readonly cssCascadeRuntimeProofs?: readonly CssCascadeRuntimeProofRecord[];
|
|
233
|
+
readonly cssScopedCascadeProofs?: readonly CssScopedCascadeProofRecord[];
|
|
231
234
|
readonly cssDependencyGraphProofs?: readonly CssDependencyGraphProofRecord[];
|
|
232
235
|
readonly cssModuleContractProofs?: readonly CssModuleContractProofRecord[];
|
|
233
236
|
}
|
|
@@ -245,6 +248,7 @@ export interface CssSafeMergeResult {
|
|
|
245
248
|
readonly workerChangedCssModuleContracts?: number; readonly headChangedCssModuleContracts?: number;
|
|
246
249
|
readonly parserEvidence?: CssSafeMergeParserEvidence; readonly shorthandExpansionEvidence?: CssSafeMergeShorthandExpansionEvidence; readonly selectorTargetEvidence?: CssSafeMergeSelectorTargetEvidence; readonly dependencyGraphEvidence?: CssDependencyGraphEvidence;
|
|
247
250
|
readonly cssModuleContractProofs?: readonly CssModuleContractProofRecord[];
|
|
251
|
+
readonly scopedCascadeProofs?: readonly CssScopedCascadeProofRecord[];
|
|
248
252
|
readonly cascadeRuntimeProofs?: readonly CssCascadeRuntimeProofRecord[];
|
|
249
253
|
readonly dependencyGraphProofs?: readonly CssDependencyGraphProofRecord[];
|
|
250
254
|
}
|
|
@@ -260,37 +264,14 @@ export interface CssSafeMergeParserSideEvidence {
|
|
|
260
264
|
readonly scopedCascadeGraphHashPresent: boolean; readonly parseErrors: number; readonly recordCount: number; readonly declarationCount: number;
|
|
261
265
|
}
|
|
262
266
|
|
|
263
|
-
export interface CssSafeMergeSelectorTargetEvidence {
|
|
264
|
-
readonly kind: 'frontier.lang.cssSafeMergeSelectorTargetEvidence'; readonly version: 1; readonly selectorTargetGraphHashPresent: boolean; readonly parserBackedRuleSpans: boolean;
|
|
265
|
-
readonly selectorMoveCount: number; readonly workerSelectorMoves: number; readonly headSelectorMoves: number;
|
|
266
|
-
readonly sides: Readonly<Record<string, CssSafeMergeSelectorTargetSideEvidence>>;
|
|
267
|
-
readonly moves: Readonly<Record<'worker' | 'head', readonly CssSafeMergeSelectorMove[]>>;
|
|
268
|
-
readonly rebasedChangeCount?: number; readonly rebaseProofs?: readonly CssSafeMergeSelectorTargetRebaseProof[];
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
export interface CssSafeMergeSelectorTargetSideEvidence {
|
|
272
|
-
readonly ruleCount: number; readonly selectorCount: number; readonly declarationCount: number; readonly scopedRuleCount: number;
|
|
273
|
-
readonly selectorTargetGraphHashPresent: boolean; readonly parserBackedRuleSpans: boolean; readonly selectorSpecificityRecords: number;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
export interface CssSafeMergeSelectorMove {
|
|
277
|
-
readonly side: string; readonly property: string; readonly beforeRuleKey: string; readonly afterRuleKey: string;
|
|
278
|
-
readonly beforeSelectors?: readonly string[]; readonly afterSelectors?: readonly string[]; readonly beforeScopes?: readonly string[]; readonly afterScopes?: readonly string[];
|
|
279
|
-
readonly beforeSpecificity?: readonly (readonly number[])[]; readonly afterSpecificity?: readonly (readonly number[])[]; readonly specificityInvariant: boolean; readonly declarationHash: string; readonly beforeSelectorTargetGraphHash?: string; readonly afterSelectorTargetGraphHash?: string; readonly selectorTargetGraphHashPresent: boolean;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
export interface CssSafeMergeSelectorTargetRebaseProof {
|
|
283
|
-
readonly kind: 'css-selector-target-rebase'; readonly side: string; readonly fromRuleKey: string; readonly toRuleKey: string; readonly property: string; readonly cascadeKey: string; readonly selectorTargetGraphHash?: string; readonly specificityInvariant: true; readonly beforeSpecificity?: readonly (readonly number[])[]; readonly afterSpecificity?: readonly (readonly number[])[];
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
export interface CssSelectorTargetEquivalence {
|
|
287
|
-
readonly sourcePath?: string; readonly fromRuleKey?: string; readonly toRuleKey?: string; readonly fromSelectors?: readonly string[]; readonly toSelectors?: readonly string[]; readonly fromSpecificity?: readonly (readonly number[])[]; readonly toSpecificity?: readonly (readonly number[])[]; readonly graphHash?: string;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
267
|
export interface CssSafeMergeInput {
|
|
291
268
|
readonly id?: string; readonly sourcePath?: string; readonly baseSourceText?: string; readonly workerSourceText?: string; readonly headSourceText?: string;
|
|
292
269
|
readonly cssModule?: boolean; readonly cssModules?: boolean; readonly generatedClassNameMap?: Readonly<Record<string, string>>;
|
|
293
270
|
readonly generatedClassNameMapHash?: string; readonly jsTsUseSiteGraphHash?: string; readonly cssModuleCompositionGraphHash?: string; readonly icssGraphHash?: string; readonly scopedCascadeGraphHash?: string;
|
|
271
|
+
readonly cssScopedCascadeProof?: CssScopedCascadeProof; readonly cssScopedCascadeProofs?: readonly CssScopedCascadeProof[]; readonly cssScopedCascadeProofsByPath?: Readonly<Record<string, CssScopedCascadeProof | readonly CssScopedCascadeProof[]>>;
|
|
272
|
+
readonly cssSourceBoundScopedCascadeProof?: CssScopedCascadeProof; readonly cssSourceBoundScopedCascadeProofs?: readonly CssScopedCascadeProof[]; readonly cssSourceBoundScopedCascadeProofsByPath?: Readonly<Record<string, CssScopedCascadeProof | readonly CssScopedCascadeProof[]>>;
|
|
273
|
+
readonly scopedCascadeProof?: CssScopedCascadeProof; readonly scopedCascadeProofs?: readonly CssScopedCascadeProof[]; readonly scopedCascadeProofsByPath?: Readonly<Record<string, CssScopedCascadeProof | readonly CssScopedCascadeProof[]>>;
|
|
274
|
+
readonly sourceBoundScopedCascadeProof?: CssScopedCascadeProof; readonly sourceBoundScopedCascadeProofs?: readonly CssScopedCascadeProof[]; readonly sourceBoundScopedCascadeProofsByPath?: Readonly<Record<string, CssScopedCascadeProof | readonly CssScopedCascadeProof[]>>;
|
|
294
275
|
readonly cssCascadeRuntimeProof?: CssCascadeRuntimeProof; readonly cssCascadeRuntimeProofs?: readonly CssCascadeRuntimeProof[]; readonly cssCascadeRuntimeProofsByPath?: Readonly<Record<string, CssCascadeRuntimeProof | readonly CssCascadeRuntimeProof[]>>;
|
|
295
276
|
readonly cssSourceBoundCascadeProof?: CssCascadeRuntimeProof; readonly cssSourceBoundCascadeProofs?: readonly CssCascadeRuntimeProof[];
|
|
296
277
|
readonly cssSourceBoundCascadeProofsByPath?: Readonly<Record<string, CssCascadeRuntimeProof | readonly CssCascadeRuntimeProof[]>>;
|
|
@@ -301,6 +282,11 @@ export interface CssSafeMergeInput {
|
|
|
301
282
|
readonly cssDependencyGraphProofsByPath?: Readonly<Record<string, CssDependencyGraphProof | readonly CssDependencyGraphProof[]>>; readonly cssSourceBoundDependencyGraphProofsByPath?: Readonly<Record<string, CssDependencyGraphProof | readonly CssDependencyGraphProof[]>>;
|
|
302
283
|
readonly cssModuleContractProof?: CssModuleContractProof; readonly cssModuleContractProofs?: readonly CssModuleContractProof[]; readonly cssModuleContractProofsByPath?: Readonly<Record<string, CssModuleContractProof | readonly CssModuleContractProof[]>>; readonly cssSourceBoundModuleContractProof?: CssModuleContractProof; readonly cssSourceBoundModuleContractProofs?: readonly CssModuleContractProof[]; readonly cssSourceBoundModuleContractProofsByPath?: Readonly<Record<string, CssModuleContractProof | readonly CssModuleContractProof[]>>;
|
|
303
284
|
readonly selectorTargetGraphHash?: string; readonly selectorTargetEquivalences?: readonly CssSelectorTargetEquivalence[];
|
|
285
|
+
readonly cssSelectorTargetProof?: CssSelectorTargetProof; readonly cssSelectorTargetProofs?: readonly CssSelectorTargetProof[]; readonly cssSelectorTargetProofsByPath?: Readonly<Record<string, CssSelectorTargetProof | readonly CssSelectorTargetProof[]>>;
|
|
286
|
+
readonly cssSourceBoundSelectorTargetProof?: CssSelectorTargetProof; readonly cssSourceBoundSelectorTargetProofs?: readonly CssSelectorTargetProof[]; readonly cssSourceBoundSelectorTargetProofsByPath?: Readonly<Record<string, CssSelectorTargetProof | readonly CssSelectorTargetProof[]>>;
|
|
287
|
+
readonly selectorTargetProof?: CssSelectorTargetProof; readonly selectorTargetProofs?: readonly CssSelectorTargetProof[]; readonly selectorTargetProofsByPath?: Readonly<Record<string, CssSelectorTargetProof | readonly CssSelectorTargetProof[]>>;
|
|
288
|
+
readonly selectorTargetRebaseProof?: CssSelectorTargetProof; readonly selectorTargetRebaseProofs?: readonly CssSelectorTargetProof[]; readonly selectorTargetRebaseProofsByPath?: Readonly<Record<string, CssSelectorTargetProof | readonly CssSelectorTargetProof[]>>;
|
|
289
|
+
readonly sourceBoundSelectorTargetProof?: CssSelectorTargetProof; readonly sourceBoundSelectorTargetProofs?: readonly CssSelectorTargetProof[]; readonly sourceBoundSelectorTargetProofsByPath?: Readonly<Record<string, CssSelectorTargetProof | readonly CssSelectorTargetProof[]>>;
|
|
304
290
|
readonly baseGeneratedClassNameMap?: Readonly<Record<string, string>>; readonly workerGeneratedClassNameMap?: Readonly<Record<string, string>>; readonly headGeneratedClassNameMap?: Readonly<Record<string, string>>;
|
|
305
291
|
readonly baseGeneratedClassNameMapHash?: string; readonly workerGeneratedClassNameMapHash?: string; readonly headGeneratedClassNameMapHash?: string;
|
|
306
292
|
readonly baseJsTsUseSiteGraphHash?: string; readonly workerJsTsUseSiteGraphHash?: string; readonly headJsTsUseSiteGraphHash?: string;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export interface CssScopedCascadeProof {
|
|
2
|
+
readonly id?: string;
|
|
3
|
+
readonly kind: 'css-scoped-cascade-proof' | 'css-source-bound-scoped-cascade-proof' | 'css-scoped-cascade-runtime-proof' | 'css-source-bound-scoped-cascade-runtime-proof' | string;
|
|
4
|
+
readonly status: 'passed' | string;
|
|
5
|
+
readonly proofLevel?: string;
|
|
6
|
+
readonly sourcePath?: string;
|
|
7
|
+
readonly reasonCode?: string;
|
|
8
|
+
readonly reasonCodes?: readonly string[];
|
|
9
|
+
readonly side?: 'worker' | 'head' | string;
|
|
10
|
+
readonly sides?: readonly string[];
|
|
11
|
+
readonly cascadeKey?: string;
|
|
12
|
+
readonly cascadeKeys?: readonly string[];
|
|
13
|
+
readonly ruleKey?: string;
|
|
14
|
+
readonly ruleKeys?: readonly string[];
|
|
15
|
+
readonly selectors?: readonly string[];
|
|
16
|
+
readonly scopes?: readonly string[];
|
|
17
|
+
readonly property?: string;
|
|
18
|
+
readonly properties?: readonly string[];
|
|
19
|
+
readonly scopedCascadeGraphHash?: string;
|
|
20
|
+
readonly graphHash?: string;
|
|
21
|
+
readonly baseScopedCascadeGraphHash?: string;
|
|
22
|
+
readonly workerScopedCascadeGraphHash?: string;
|
|
23
|
+
readonly headScopedCascadeGraphHash?: string;
|
|
24
|
+
readonly scopedCascadeGraphHashes?: Readonly<Record<string, string>>;
|
|
25
|
+
readonly graphHashes?: Readonly<Record<string, string>>;
|
|
26
|
+
readonly baseSourceText?: string; readonly workerSourceText?: string; readonly headSourceText?: string; readonly outputSourceText?: string; readonly mergedSourceText?: string;
|
|
27
|
+
readonly baseSourceHash?: string; readonly workerSourceHash?: string; readonly headSourceHash?: string; readonly outputSourceHash?: string; readonly mergedSourceHash?: string;
|
|
28
|
+
readonly sourceTexts?: Readonly<Record<string, string>>;
|
|
29
|
+
readonly sources?: Readonly<Record<string, string>>;
|
|
30
|
+
readonly sourceHashes?: Readonly<Record<string, string>>;
|
|
31
|
+
readonly hashes?: Readonly<Record<string, string>>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface CssScopedCascadeProofRecord {
|
|
35
|
+
readonly id?: string;
|
|
36
|
+
readonly kind: string;
|
|
37
|
+
readonly status: 'passed';
|
|
38
|
+
readonly proofLevel: string;
|
|
39
|
+
readonly reasonCode: string;
|
|
40
|
+
readonly side: string;
|
|
41
|
+
readonly cascadeKey: string;
|
|
42
|
+
readonly ruleKey?: string;
|
|
43
|
+
readonly property?: string;
|
|
44
|
+
readonly scopes?: readonly string[];
|
|
45
|
+
readonly sourcePath?: string;
|
|
46
|
+
readonly scopedCascadeGraphHash?: string;
|
|
47
|
+
readonly scopedCascadeGraphHashes?: Readonly<Record<string, string>>;
|
|
48
|
+
readonly baseSourceHash?: string;
|
|
49
|
+
readonly workerSourceHash?: string;
|
|
50
|
+
readonly headSourceHash?: string;
|
|
51
|
+
readonly outputSourceHash?: string;
|
|
52
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export interface CssSelectorTargetProof {
|
|
2
|
+
readonly id?: string; readonly kind: 'css-selector-target-proof' | 'css-source-bound-selector-target-proof' | 'css-selector-target-rebase-proof' | 'css-source-bound-selector-target-rebase-proof' | string;
|
|
3
|
+
readonly status: 'passed' | string; readonly proofLevel?: string; readonly sourcePath?: string; readonly reasonCode?: string; readonly reasonCodes?: readonly string[];
|
|
4
|
+
readonly side?: string; readonly sides?: readonly string[]; readonly moveSide?: string; readonly moveSides?: readonly string[]; readonly selectorMoveSide?: string; readonly selectorMoveSides?: readonly string[];
|
|
5
|
+
readonly rebasedSide?: string; readonly rebasedSides?: readonly string[];
|
|
6
|
+
readonly fromRuleKey?: string; readonly toRuleKey?: string; readonly fromSelectors?: readonly string[]; readonly toSelectors?: readonly string[];
|
|
7
|
+
readonly fromSpecificity?: readonly (readonly number[])[]; readonly toSpecificity?: readonly (readonly number[])[];
|
|
8
|
+
readonly selectorTargetGraphHash?: string; readonly graphHash?: string; readonly beforeSelectorTargetGraphHash?: string; readonly afterSelectorTargetGraphHash?: string;
|
|
9
|
+
readonly selectorTargetGraphHashes?: Readonly<Record<string, string>>; readonly graphHashes?: Readonly<Record<string, string>>;
|
|
10
|
+
readonly baseSelectorTargetGraphHash?: string; readonly workerSelectorTargetGraphHash?: string; readonly headSelectorTargetGraphHash?: string;
|
|
11
|
+
readonly baseSourceText?: string; readonly workerSourceText?: string; readonly headSourceText?: string;
|
|
12
|
+
readonly baseSourceHash?: string; readonly workerSourceHash?: string; readonly headSourceHash?: string;
|
|
13
|
+
readonly sourceTexts?: Readonly<Record<string, string>>; readonly sourceHashes?: Readonly<Record<string, string>>;
|
|
14
|
+
readonly sources?: Readonly<Record<string, string>>; readonly hashes?: Readonly<Record<string, string>>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface CssSafeMergeSelectorTargetEvidence {
|
|
18
|
+
readonly kind: 'frontier.lang.cssSafeMergeSelectorTargetEvidence'; readonly version: 1; readonly selectorTargetGraphHashPresent: boolean; readonly parserBackedRuleSpans: boolean;
|
|
19
|
+
readonly selectorMoveCount: number; readonly workerSelectorMoves: number; readonly headSelectorMoves: number;
|
|
20
|
+
readonly sides: Readonly<Record<string, CssSafeMergeSelectorTargetSideEvidence>>;
|
|
21
|
+
readonly moves: Readonly<Record<'worker' | 'head', readonly CssSafeMergeSelectorMove[]>>;
|
|
22
|
+
readonly rebasedChangeCount?: number; readonly rebaseProofs?: readonly CssSafeMergeSelectorTargetRebaseProof[];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface CssSafeMergeSelectorTargetSideEvidence {
|
|
26
|
+
readonly ruleCount: number; readonly selectorCount: number; readonly declarationCount: number; readonly scopedRuleCount: number;
|
|
27
|
+
readonly selectorTargetGraphHashPresent: boolean; readonly parserBackedRuleSpans: boolean; readonly selectorSpecificityRecords: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface CssSafeMergeSelectorMove {
|
|
31
|
+
readonly side: string; readonly property: string; readonly beforeRuleKey: string; readonly afterRuleKey: string;
|
|
32
|
+
readonly beforeSelectors?: readonly string[]; readonly afterSelectors?: readonly string[]; readonly beforeScopes?: readonly string[]; readonly afterScopes?: readonly string[];
|
|
33
|
+
readonly beforeSpecificity?: readonly (readonly number[])[]; readonly afterSpecificity?: readonly (readonly number[])[]; readonly specificityInvariant: boolean; readonly declarationHash: string; readonly beforeSelectorTargetGraphHash?: string; readonly afterSelectorTargetGraphHash?: string; readonly selectorTargetGraphHashPresent: boolean;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface CssSafeMergeSelectorTargetRebaseProof {
|
|
37
|
+
readonly id?: string; readonly kind: 'css-selector-target-rebase'; readonly proofKind?: string; readonly status?: 'passed' | string; readonly proofLevel?: string;
|
|
38
|
+
readonly side: string; readonly moveSide?: string; readonly fromRuleKey: string; readonly toRuleKey: string; readonly fromSelectors?: readonly string[]; readonly toSelectors?: readonly string[];
|
|
39
|
+
readonly property: string; readonly cascadeKey: string; readonly selectorTargetGraphHash?: string; readonly beforeSelectorTargetGraphHash?: string; readonly afterSelectorTargetGraphHash?: string;
|
|
40
|
+
readonly specificityInvariant: true; readonly beforeSpecificity?: readonly (readonly number[])[]; readonly afterSpecificity?: readonly (readonly number[])[];
|
|
41
|
+
readonly baseSourceHash?: string; readonly workerSourceHash?: string; readonly headSourceHash?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface CssSelectorTargetEquivalence {
|
|
45
|
+
readonly sourcePath?: string; readonly fromRuleKey?: string; readonly toRuleKey?: string; readonly fromSelectors?: readonly string[]; readonly toSelectors?: readonly string[]; readonly fromSpecificity?: readonly (readonly number[])[]; readonly toSpecificity?: readonly (readonly number[])[]; readonly graphHash?: string;
|
|
46
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
function scopedCascadeChanges(changed, indexes) {
|
|
2
|
+
return [
|
|
3
|
+
...scopedCascadeChangesForSide(changed.worker, 'worker', indexes.base),
|
|
4
|
+
...scopedCascadeChangesForSide(changed.head, 'head', indexes.base)
|
|
5
|
+
];
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function scopedCascadeChangesForSide(changes, side, baseIndex) {
|
|
9
|
+
const baseScopeKeys = new Set([...baseIndex.declarations.values()]
|
|
10
|
+
.filter((entry) => entry.scopes?.length)
|
|
11
|
+
.map((entry) => scopeListKey(entry.scopes)));
|
|
12
|
+
return changes.flatMap((change) => {
|
|
13
|
+
const entries = [change.before, change.after].filter((entry) => entry?.scopes?.length);
|
|
14
|
+
if (!entries.length || !entries.some((entry) => baseScopeKeys.has(scopeListKey(entry.scopes)))) return [];
|
|
15
|
+
const entry = change.after ?? change.before;
|
|
16
|
+
const graphRoles = scopedCascadeGraphRoles(change, side);
|
|
17
|
+
return [{
|
|
18
|
+
side,
|
|
19
|
+
changeKind: change.kind,
|
|
20
|
+
reasonCode: 'css-scoped-cascade-equivalence-unproved',
|
|
21
|
+
reasonCodes: unique(['css-scoped-cascade-equivalence-unproved', ...entries.flatMap((item) => scopedCascadeReasonCodes(item.scopes))]),
|
|
22
|
+
cascadeKey: change.key,
|
|
23
|
+
ruleKey: entry.ruleKey,
|
|
24
|
+
selectors: entry.selectors,
|
|
25
|
+
scopes: entry.scopes,
|
|
26
|
+
property: entry.property,
|
|
27
|
+
specificity: entry.specificity,
|
|
28
|
+
scopedCascadeGraphReady: graphRoles.every((item) => typeof item.hash === 'string'),
|
|
29
|
+
scopedCascadeGraphHash: graphRoles.find((item) => typeof item.hash === 'string')?.hash,
|
|
30
|
+
scopedCascadeGraphHashes: Object.fromEntries(graphRoles.map((item) => [item.role, item.hash]).filter(([, value]) => typeof value === 'string')),
|
|
31
|
+
before: scopedCascadeDeclarationDetails(change.before),
|
|
32
|
+
after: scopedCascadeDeclarationDetails(change.after)
|
|
33
|
+
}];
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function admitScopedCascadeProofs({ id, sourcePath, input, changes, binding, hash }) {
|
|
38
|
+
const proofs = scopedCascadeProofCandidates(input, sourcePath);
|
|
39
|
+
const admitted = [];
|
|
40
|
+
const conflicts = [];
|
|
41
|
+
for (const change of changes) {
|
|
42
|
+
const proof = proofs.find((candidate) => isScopedCascadeProofForChange(candidate, change, sourcePath, binding, hash));
|
|
43
|
+
if (proof) admitted.push(scopedCascadeProofRecord(proof, change, sourcePath, binding, hash));
|
|
44
|
+
else conflicts.push(conflict(id, sourcePath, 'css-scoped-cascade-proof-blocked', change.reasonCode, change));
|
|
45
|
+
}
|
|
46
|
+
return { proofs: admitted, conflicts };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function scopedCascadeProofCandidates(input = {}, sourcePath) {
|
|
50
|
+
return [
|
|
51
|
+
input.cssScopedCascadeProof,
|
|
52
|
+
input.cssScopedCascadeProofs,
|
|
53
|
+
input.cssScopedCascadeProofsByPath?.[sourcePath],
|
|
54
|
+
input.cssSourceBoundScopedCascadeProof,
|
|
55
|
+
input.cssSourceBoundScopedCascadeProofs,
|
|
56
|
+
input.cssSourceBoundScopedCascadeProofsByPath?.[sourcePath],
|
|
57
|
+
input.scopedCascadeProof,
|
|
58
|
+
input.scopedCascadeProofs,
|
|
59
|
+
input.scopedCascadeProofsByPath?.[sourcePath],
|
|
60
|
+
input.sourceBoundScopedCascadeProof,
|
|
61
|
+
input.sourceBoundScopedCascadeProofs,
|
|
62
|
+
input.sourceBoundScopedCascadeProofsByPath?.[sourcePath]
|
|
63
|
+
].flatMap(asArray).filter(Boolean);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function isScopedCascadeProofForChange(proof, change, sourcePath, binding, hash) {
|
|
67
|
+
return Boolean(proof && typeof proof === 'object') &&
|
|
68
|
+
ScopedCascadeProofKinds.has(proof.kind) &&
|
|
69
|
+
proof.status === 'passed' &&
|
|
70
|
+
proof.sourcePath === sourcePath &&
|
|
71
|
+
change.scopedCascadeGraphReady === true &&
|
|
72
|
+
proofCoversAny(proof.reasonCode, proof.reasonCodes, change.reasonCodes) &&
|
|
73
|
+
proofCoversValue(proof.side, proof.sides, change.side) &&
|
|
74
|
+
proofCoversValue(proof.cascadeKey, proof.cascadeKeys, change.cascadeKey) &&
|
|
75
|
+
proofCoversValue(proof.property, proof.properties, change.property) &&
|
|
76
|
+
scopedCascadeRuleMatches(proof, change) &&
|
|
77
|
+
scopedCascadeGraphHashMatches(proof, change) &&
|
|
78
|
+
proofSourceMatches(proof, 'base', binding.base, hash) &&
|
|
79
|
+
proofSourceMatches(proof, 'worker', binding.worker, hash) &&
|
|
80
|
+
proofSourceMatches(proof, 'head', binding.head, hash) &&
|
|
81
|
+
proofSourceMatches(proof, 'output', binding.output, hash);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function scopedCascadeRuleMatches(proof, change) {
|
|
85
|
+
const ruleKeyMatches = proof.ruleKey === change.ruleKey || proof.ruleKeys?.includes(change.ruleKey);
|
|
86
|
+
const selectorsMatch = selectorListKey(proof.selectors) === selectorListKey(change.selectors);
|
|
87
|
+
const scopesMatch = scopeListKey(proof.scopes) === scopeListKey(change.scopes);
|
|
88
|
+
return ruleKeyMatches || (selectorsMatch && scopesMatch);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function scopedCascadeGraphHashMatches(proof, change) {
|
|
92
|
+
const hashes = Object.entries(change.scopedCascadeGraphHashes ?? {});
|
|
93
|
+
if (!hashes.length) return false;
|
|
94
|
+
return hashes.every(([role, expected]) => {
|
|
95
|
+
const sharedHash = firstString(proof.scopedCascadeGraphHash, proof.graphHash);
|
|
96
|
+
return sharedHash === expected ||
|
|
97
|
+
proof[`${role}ScopedCascadeGraphHash`] === expected ||
|
|
98
|
+
proof.scopedCascadeGraphHashes?.[role] === expected ||
|
|
99
|
+
proof.graphHashes?.[role] === expected;
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function scopedCascadeProofRecord(proof, change, sourcePath, binding, hash) {
|
|
104
|
+
return {
|
|
105
|
+
id: proof.id,
|
|
106
|
+
kind: proof.kind,
|
|
107
|
+
status: 'passed',
|
|
108
|
+
proofLevel: proof.proofLevel ?? 'css-scoped-cascade-source-bound',
|
|
109
|
+
reasonCode: change.reasonCode,
|
|
110
|
+
side: change.side,
|
|
111
|
+
cascadeKey: change.cascadeKey,
|
|
112
|
+
ruleKey: change.ruleKey,
|
|
113
|
+
property: change.property,
|
|
114
|
+
scopes: change.scopes,
|
|
115
|
+
sourcePath,
|
|
116
|
+
scopedCascadeGraphHash: change.scopedCascadeGraphHash,
|
|
117
|
+
scopedCascadeGraphHashes: change.scopedCascadeGraphHashes,
|
|
118
|
+
baseSourceHash: hash?.(binding.base),
|
|
119
|
+
workerSourceHash: hash?.(binding.worker),
|
|
120
|
+
headSourceHash: hash?.(binding.head),
|
|
121
|
+
outputSourceHash: hash?.(binding.output)
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function scopedCascadeGraphRoles(change, side) {
|
|
126
|
+
return [
|
|
127
|
+
change.before?.scopedCascadeGraphHash ? { role: 'base', hash: change.before.scopedCascadeGraphHash } : undefined,
|
|
128
|
+
change.after?.scopedCascadeGraphHash ? { role: side, hash: change.after.scopedCascadeGraphHash } : undefined
|
|
129
|
+
].filter(Boolean);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function scopedCascadeDeclarationDetails(entry) {
|
|
133
|
+
return entry ? { property: entry.property, value: entry.value, ruleKey: entry.ruleKey, cascadeKey: entry.key, scopes: entry.scopes, scopedCascadeGraphHash: entry.scopedCascadeGraphHash } : undefined;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function scopedCascadeReasonCodes(scopes = []) {
|
|
137
|
+
return scopes.map((scope) => /^@([-\w]+)/.exec(scope)?.[1]).filter(Boolean).map((name) => `css-${name}-cascade-scope-unproved`);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function proofSourceMatches(proof, role, sourceText, hash) {
|
|
141
|
+
if (typeof sourceText !== 'string') return false;
|
|
142
|
+
const sourceHash = hash?.(sourceText);
|
|
143
|
+
const textFields = role === 'output' ? ['outputSourceText', 'mergedSourceText'] : [`${role}SourceText`];
|
|
144
|
+
const hashFields = role === 'output' ? ['outputSourceHash', 'mergedSourceHash'] : [`${role}SourceHash`];
|
|
145
|
+
const aliases = role === 'output' ? ['output', 'merged'] : [role];
|
|
146
|
+
return textFields.some((field) => proof[field] === sourceText) ||
|
|
147
|
+
aliases.some((alias) => proof.sourceTexts?.[alias] === sourceText || proof.sources?.[alias] === sourceText) ||
|
|
148
|
+
hashFields.some((field) => sourceHash !== undefined && proof[field] === sourceHash) ||
|
|
149
|
+
aliases.some((alias) => sourceHash !== undefined && (proof.sourceHashes?.[alias] === sourceHash || proof.hashes?.[alias] === sourceHash));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function conflict(id, sourcePath, code, reasonCode, details = {}) {
|
|
153
|
+
return { code, gateId: 'css-semantic-merge', sourcePath, details: { reasonCode, conflictKey: `css#${id}#${reasonCode}#${details.cascadeKey ?? sourcePath ?? 'source'}`, ...details } };
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function proofCoversAny(value, values, expectedValues = []) { return expectedValues.some((expected) => proofCoversValue(value, values, expected)); }
|
|
157
|
+
function proofCoversValue(value, values, expected) { return value === expected || (Array.isArray(values) && values.includes(expected)); }
|
|
158
|
+
function asArray(value) { return Array.isArray(value) ? value : value === undefined ? [] : [value]; }
|
|
159
|
+
function selectorListKey(value = []) { return Array.isArray(value) ? value.join(',') : undefined; }
|
|
160
|
+
function scopeListKey(value = []) { return Array.isArray(value) ? value.join('::') : undefined; }
|
|
161
|
+
function firstString(...values) { return values.find((value) => typeof value === 'string' && value.length > 0); }
|
|
162
|
+
function unique(values) { return [...new Set(values.filter(Boolean))]; }
|
|
163
|
+
|
|
164
|
+
const ScopedCascadeProofKinds = new Set(['css-scoped-cascade-proof', 'css-source-bound-scoped-cascade-proof', 'css-scoped-cascade-runtime-proof', 'css-source-bound-scoped-cascade-runtime-proof']);
|
|
165
|
+
const ScopedCascadeProofGapCodes = new Set(['css-scoped-cascade-equivalence-unproved', 'css-media-cascade-scope-unproved', 'css-supports-cascade-scope-unproved', 'css-container-cascade-scope-unproved', 'css-layer-cascade-scope-unproved', 'css-scope-cascade-scope-unproved']);
|
|
166
|
+
|
|
167
|
+
export { ScopedCascadeProofGapCodes, admitScopedCascadeProofs, scopedCascadeChanges };
|
|
@@ -76,8 +76,9 @@ function selectorTargetMoveSidePlan(id, sourcePath, moves, oppositeMoves, opposi
|
|
|
76
76
|
for (let index = 0; index < oppositeChanges.length; index += 1) {
|
|
77
77
|
const change = oppositeChanges[index];
|
|
78
78
|
if (!selectorMoveTouchesChange(move, change)) continue;
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
const proof = selectorTargetRebaseProofForChange(move, change, options, sourcePath);
|
|
80
|
+
if (proof) {
|
|
81
|
+
const rebased = rebaseChangeToSelectorMove(change, move, proof, options);
|
|
81
82
|
oppositeChanges[index] = rebased.change;
|
|
82
83
|
rebaseProofs.push(rebased.proof);
|
|
83
84
|
} else conflicts.push(conflict(id, sourcePath, change.key, move, change));
|
|
@@ -86,27 +87,113 @@ function selectorTargetMoveSidePlan(id, sourcePath, moves, oppositeMoves, opposi
|
|
|
86
87
|
return { conflicts, rebaseProofs };
|
|
87
88
|
}
|
|
88
89
|
|
|
89
|
-
function
|
|
90
|
-
|
|
90
|
+
function selectorTargetRebaseProofForChange(move, change, options, sourcePath) {
|
|
91
|
+
if (change.kind !== 'add' || !change.after || !move.specificityInvariant) return undefined;
|
|
92
|
+
return selectorTargetProofCandidates(options, sourcePath)
|
|
93
|
+
.find((proof) => isSelectorTargetProofForChange(proof, move, change, sourcePath, options));
|
|
91
94
|
}
|
|
92
95
|
|
|
93
|
-
function
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
96
|
+
function selectorTargetProofCandidates(input = {}, sourcePath) {
|
|
97
|
+
return [
|
|
98
|
+
input.cssSelectorTargetProof,
|
|
99
|
+
input.cssSelectorTargetProofs,
|
|
100
|
+
input.cssSelectorTargetProofsByPath?.[sourcePath],
|
|
101
|
+
input.cssSourceBoundSelectorTargetProof,
|
|
102
|
+
input.cssSourceBoundSelectorTargetProofs,
|
|
103
|
+
input.cssSourceBoundSelectorTargetProofsByPath?.[sourcePath],
|
|
104
|
+
input.selectorTargetProof,
|
|
105
|
+
input.selectorTargetProofs,
|
|
106
|
+
input.selectorTargetProofsByPath?.[sourcePath],
|
|
107
|
+
input.selectorTargetRebaseProof,
|
|
108
|
+
input.selectorTargetRebaseProofs,
|
|
109
|
+
input.selectorTargetRebaseProofsByPath?.[sourcePath],
|
|
110
|
+
input.sourceBoundSelectorTargetProof,
|
|
111
|
+
input.sourceBoundSelectorTargetProofs,
|
|
112
|
+
input.sourceBoundSelectorTargetProofsByPath?.[sourcePath]
|
|
113
|
+
].flatMap(asArray).filter(Boolean);
|
|
103
114
|
}
|
|
104
115
|
|
|
105
|
-
function
|
|
116
|
+
function isSelectorTargetProofForChange(proof, move, change, sourcePath, options) {
|
|
117
|
+
const hash = options.hashSemanticValue;
|
|
118
|
+
const binding = options.sourceBinding ?? {};
|
|
119
|
+
return Boolean(proof && typeof proof === 'object') &&
|
|
120
|
+
SelectorTargetProofKinds.has(proof.kind) &&
|
|
121
|
+
proof.status === 'passed' &&
|
|
122
|
+
proof.sourcePath === sourcePath &&
|
|
123
|
+
proofCoversValue(proof.reasonCode, proof.reasonCodes, 'css-selector-target-rebase-unproved') &&
|
|
124
|
+
proofCoversValue(proof.moveSide ?? proof.selectorMoveSide, proof.moveSides ?? proof.selectorMoveSides ?? proof.sides, move.side) &&
|
|
125
|
+
proofCoversValue(proof.rebasedSide ?? proof.side, proof.rebasedSides, change.side) &&
|
|
126
|
+
selectorTargetRuleOrSelectorMatches(proof, move) &&
|
|
127
|
+
selectorTargetSpecificityMatches(proof, move) &&
|
|
128
|
+
selectorTargetGraphHashMatches(proof, move) &&
|
|
129
|
+
proofSourceMatches(proof, 'base', binding.base, hash) &&
|
|
130
|
+
proofSourceMatches(proof, 'worker', binding.worker, hash) &&
|
|
131
|
+
proofSourceMatches(proof, 'head', binding.head, hash);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function selectorTargetRuleOrSelectorMatches(proof, move) {
|
|
135
|
+
const ruleKeysMatch = proof.fromRuleKey === move.beforeRuleKey && proof.toRuleKey === move.afterRuleKey;
|
|
136
|
+
const selectorsMatch = selectorListKey(proof.fromSelectors) === selectorListKey(move.beforeSelectors) && selectorListKey(proof.toSelectors) === selectorListKey(move.afterSelectors);
|
|
137
|
+
return ruleKeysMatch || selectorsMatch;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function selectorTargetSpecificityMatches(proof, move) {
|
|
141
|
+
return move.specificityInvariant === true &&
|
|
142
|
+
specificityListKey(proof.fromSpecificity) === specificityListKey(move.beforeSpecificity) &&
|
|
143
|
+
specificityListKey(proof.toSpecificity) === specificityListKey(move.afterSpecificity);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function selectorTargetGraphHashMatches(proof, move) {
|
|
147
|
+
const beforeHash = move.beforeSelectorTargetGraphHash;
|
|
148
|
+
const afterHash = move.afterSelectorTargetGraphHash;
|
|
149
|
+
if (!beforeHash || !afterHash) return false;
|
|
150
|
+
const sharedHash = firstString(proof.selectorTargetGraphHash, proof.graphHash);
|
|
151
|
+
if (sharedHash && sharedHash === beforeHash && sharedHash === afterHash) return true;
|
|
152
|
+
return (proof.beforeSelectorTargetGraphHash === beforeHash && proof.afterSelectorTargetGraphHash === afterHash) ||
|
|
153
|
+
(proof.selectorTargetGraphHashes?.before === beforeHash && proof.selectorTargetGraphHashes?.after === afterHash) ||
|
|
154
|
+
(proof.graphHashes?.before === beforeHash && proof.graphHashes?.after === afterHash) ||
|
|
155
|
+
(proof.baseSelectorTargetGraphHash === beforeHash && proof[`${move.side}SelectorTargetGraphHash`] === afterHash);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function proofSourceMatches(proof, role, sourceText, hash) {
|
|
159
|
+
if (typeof sourceText !== 'string') return false;
|
|
160
|
+
const sourceHash = hash?.(sourceText);
|
|
161
|
+
return proof[`${role}SourceText`] === sourceText ||
|
|
162
|
+
proof.sourceTexts?.[role] === sourceText ||
|
|
163
|
+
proof.sources?.[role] === sourceText ||
|
|
164
|
+
(sourceHash !== undefined && proof[`${role}SourceHash`] === sourceHash) ||
|
|
165
|
+
(sourceHash !== undefined && proof.sourceHashes?.[role] === sourceHash) ||
|
|
166
|
+
(sourceHash !== undefined && proof.hashes?.[role] === sourceHash);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function rebaseChangeToSelectorMove(change, move, proof, options) {
|
|
106
170
|
const after = { ...change.after, ruleKey: move.afterRuleKey, selectors: move.afterSelectors, scopes: move.afterScopes ?? [], key: cascadeKey(move.afterScopes, move.afterSelectors, change.after.property), rebasedFromRuleKey: move.beforeRuleKey };
|
|
107
171
|
return {
|
|
108
172
|
change: { ...change, key: after.key, after },
|
|
109
|
-
proof: {
|
|
173
|
+
proof: {
|
|
174
|
+
id: proof.id,
|
|
175
|
+
kind: 'css-selector-target-rebase',
|
|
176
|
+
proofKind: proof.kind,
|
|
177
|
+
status: 'passed',
|
|
178
|
+
proofLevel: proof.proofLevel ?? 'css-selector-target-source-bound',
|
|
179
|
+
side: change.side,
|
|
180
|
+
moveSide: move.side,
|
|
181
|
+
fromRuleKey: move.beforeRuleKey,
|
|
182
|
+
toRuleKey: move.afterRuleKey,
|
|
183
|
+
fromSelectors: move.beforeSelectors,
|
|
184
|
+
toSelectors: move.afterSelectors,
|
|
185
|
+
property: change.after.property,
|
|
186
|
+
cascadeKey: after.key,
|
|
187
|
+
selectorTargetGraphHash: move.afterSelectorTargetGraphHash,
|
|
188
|
+
beforeSelectorTargetGraphHash: move.beforeSelectorTargetGraphHash,
|
|
189
|
+
afterSelectorTargetGraphHash: move.afterSelectorTargetGraphHash,
|
|
190
|
+
specificityInvariant: true,
|
|
191
|
+
beforeSpecificity: move.beforeSpecificity,
|
|
192
|
+
afterSpecificity: move.afterSpecificity,
|
|
193
|
+
baseSourceHash: options.hashSemanticValue?.(options.sourceBinding?.base),
|
|
194
|
+
workerSourceHash: options.hashSemanticValue?.(options.sourceBinding?.worker),
|
|
195
|
+
headSourceHash: options.hashSemanticValue?.(options.sourceBinding?.head)
|
|
196
|
+
}
|
|
110
197
|
};
|
|
111
198
|
}
|
|
112
199
|
|
|
@@ -142,5 +229,10 @@ function cascadeKey(scopes = [], selectors = [], property) { return [...scopes,
|
|
|
142
229
|
function selectorListKey(value = []) { return Array.isArray(value) ? value.join(',') : undefined; }
|
|
143
230
|
function specificityListKey(value = []) { return Array.isArray(value) ? value.map((item) => Array.isArray(item) ? item.join(',') : '').join('|') : undefined; }
|
|
144
231
|
function changeDetails(change) { return { kind: change.kind, property: (change.after ?? change.before)?.property, value: change.after?.value, important: change.after?.important }; }
|
|
232
|
+
function proofCoversValue(value, values, expected) { return value === expected || (Array.isArray(values) && values.includes(expected)); }
|
|
233
|
+
function asArray(value) { return Array.isArray(value) ? value : value === undefined ? [] : [value]; }
|
|
234
|
+
function firstString(...values) { return values.find((value) => typeof value === 'string' && value.length > 0); }
|
|
235
|
+
|
|
236
|
+
const SelectorTargetProofKinds = new Set(['css-selector-target-proof', 'css-source-bound-selector-target-proof', 'css-selector-target-rebase-proof', 'css-source-bound-selector-target-rebase-proof']);
|
|
145
237
|
|
|
146
238
|
export { mergeSelectorTargetEvidence, planSelectorTargetRebase };
|
package/dist/semantic-merge.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { cssModuleContractChanges, sheetOptions, unsupportedSourceShapeChanges } from './semantic-merge-css-modules.js';
|
|
2
2
|
import { admitCssModuleContractProofs } from './semantic-merge-css-module-proofs.js';
|
|
3
3
|
import { admitCascadeRuntimeProofs } from './semantic-merge-cascade-runtime.js';
|
|
4
|
+
import { ScopedCascadeProofGapCodes, admitScopedCascadeProofs, scopedCascadeChanges } from './semantic-merge-scoped-cascade.js';
|
|
4
5
|
import { admitCssDependencyGraphProofs, mergeCssDependencyGraphEvidence } from './dependency-graph.js';
|
|
5
6
|
import { mergeSelectorTargetEvidence, planSelectorTargetRebase } from './semantic-merge-selector-targets.js';
|
|
6
7
|
import { applyAtRuleBlockChanges, atRuleBlockEntry, atRuleBlockOverlapConflicts, atRuleOccurrenceKey, changedAtRuleBlocks, renderAtRuleBlock, renderAtRuleStatement } from './semantic-merge-at-rules.js';
|
|
@@ -45,22 +46,17 @@ function safeMergeCssSource(input = {}, context = {}) {
|
|
|
45
46
|
const parserEvidence = mergeParserEvidence(sheets);
|
|
46
47
|
const shorthandExpansionEvidence = mergeShorthandExpansionEvidence(indexes, changed);
|
|
47
48
|
const dependencyGraphEvidence = mergeCssDependencyGraphEvidence(sheets, changed);
|
|
48
|
-
const selectorTargetPlan = planSelectorTargetRebase(id, sourcePath, mergeSelectorTargetEvidence(sheets, changed), changed, input);
|
|
49
|
+
const selectorTargetPlan = planSelectorTargetRebase(id, sourcePath, mergeSelectorTargetEvidence(sheets, changed), changed, { ...input, sourceBinding: { base, worker, head }, hashSemanticValue: hash });
|
|
49
50
|
const shapeChanges = unsupportedSourceShapeChanges(sheets, changed, hash);
|
|
51
|
+
const scopedChanges = scopedCascadeChanges(selectorTargetPlan.changed, indexes);
|
|
50
52
|
const mergedIndex = applyAtRuleBlockChanges(applyAtRuleBlockChanges(applyDeclarationChanges(applyDeclarationChanges(indexes.base, selectorTargetPlan.changed.head), selectorTargetPlan.changed.worker), blockChanges.head), blockChanges.worker);
|
|
51
53
|
const mergedSourceText = renderDeclarationIndex(mergedIndex);
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
sourcePath,
|
|
55
|
-
input,
|
|
56
|
-
sourceShapeChanges: shapeChanges,
|
|
57
|
-
binding: { base, worker, head, output: mergedSourceText },
|
|
58
|
-
hash
|
|
59
|
-
});
|
|
54
|
+
const scopedCascadeAdmission = admitScopedCascadeProofs({ id, sourcePath, input, changes: scopedChanges, binding: { base, worker, head, output: mergedSourceText }, hash });
|
|
55
|
+
const cascadeRuntimeAdmission = admitCascadeRuntimeProofs({ id, sourcePath, input, sourceShapeChanges: shapeChanges, binding: { base, worker, head, output: mergedSourceText }, hash });
|
|
60
56
|
const dependencyGraphAdmission = admitCssDependencyGraphProofs({ id, sourcePath, input, dependencyGraphEvidence, binding: { base, worker, head, output: mergedSourceText }, hash });
|
|
61
57
|
const cssModuleAdmission = admitCssModuleContractProofs({ id, sourcePath, input, moduleChanges, binding: { base, worker, head, output: mergedSourceText }, hash });
|
|
62
|
-
const conflicts = [...parserConflicts, ...duplicateCascadeKeyConflicts, ...proofConflicts, ...overlapConflicts, ...cssModuleAdmission.conflicts, ...cascadeRuntimeAdmission.conflicts, ...dependencyGraphAdmission.conflicts, ...selectorTargetPlan.conflicts];
|
|
63
|
-
if (conflicts.length) return blocked(id, sourcePath, 'css-semantic-merge-conflict', conflicts, { parserEvidence, shorthandExpansionEvidence, dependencyGraphEvidence, selectorTargetEvidence: selectorTargetPlan.evidence, cssModuleContractProofs: cssModuleAdmission.proofs, cascadeRuntimeProofs: cascadeRuntimeAdmission.proofs, dependencyGraphProofs: dependencyGraphAdmission.proofs, ...blockedMergeCandidate(input, mergedSourceText, hash) });
|
|
58
|
+
const conflicts = [...parserConflicts, ...duplicateCascadeKeyConflicts, ...proofConflicts, ...overlapConflicts, ...cssModuleAdmission.conflicts, ...scopedCascadeAdmission.conflicts, ...cascadeRuntimeAdmission.conflicts, ...dependencyGraphAdmission.conflicts, ...selectorTargetPlan.conflicts];
|
|
59
|
+
if (conflicts.length) return blocked(id, sourcePath, 'css-semantic-merge-conflict', conflicts, { parserEvidence, shorthandExpansionEvidence, dependencyGraphEvidence, selectorTargetEvidence: selectorTargetPlan.evidence, cssModuleContractProofs: cssModuleAdmission.proofs, scopedCascadeProofs: scopedCascadeAdmission.proofs, cascadeRuntimeProofs: cascadeRuntimeAdmission.proofs, dependencyGraphProofs: dependencyGraphAdmission.proofs, ...blockedMergeCandidate(input, mergedSourceText, hash) });
|
|
64
60
|
return merged(id, sourcePath, mergedSourceText, 'semantic-declaration-merge', hash, {
|
|
65
61
|
baseSheetHash: sheets.base.sheetHash,
|
|
66
62
|
workerSheetHash: sheets.worker.sheetHash,
|
|
@@ -74,6 +70,7 @@ function safeMergeCssSource(input = {}, context = {}) {
|
|
|
74
70
|
dependencyGraphEvidence,
|
|
75
71
|
selectorTargetEvidence: selectorTargetPlan.evidence,
|
|
76
72
|
cssModuleContractProofs: cssModuleAdmission.proofs,
|
|
73
|
+
scopedCascadeProofs: scopedCascadeAdmission.proofs,
|
|
77
74
|
cascadeRuntimeProofs: cascadeRuntimeAdmission.proofs,
|
|
78
75
|
dependencyGraphProofs: dependencyGraphAdmission.proofs,
|
|
79
76
|
browserCascadeEquivalenceClaim: cascadeRuntimeAdmission.proofs.length > 0
|
|
@@ -109,6 +106,7 @@ function declarationIndex(sheet, hash) {
|
|
|
109
106
|
declarationOrdinal: declaration.ordinal,
|
|
110
107
|
declarationHash: declaration.declarationHash,
|
|
111
108
|
shorthandExpansion: deterministicShorthandExpansion(declaration.property, declaration.value, hash),
|
|
109
|
+
scopedCascadeGraphHash: record.scopedCascadeGraphHash,
|
|
112
110
|
selectorTargetGraphHash: record.selectorTargetGraphHash,
|
|
113
111
|
proofGaps: proofGapsForDeclaration(record, declaration)
|
|
114
112
|
};
|
|
@@ -209,6 +207,7 @@ function shorthandOverlapConflicts(id, sourcePath, workerChanges, headChanges) {
|
|
|
209
207
|
}
|
|
210
208
|
|
|
211
209
|
function canAdmitProofGap(gap, entry, changed, indexes) {
|
|
210
|
+
if (ScopedCascadeProofGapCodes.has(gap.code)) return true;
|
|
212
211
|
if (gap.code !== 'css-shorthand-expansion-unproved' || !entry) return false;
|
|
213
212
|
const group = shorthandGroupForProperty(entry.property);
|
|
214
213
|
if (!group || entry.shorthandExpansion?.status !== 'expanded' || hasRelatedExistingDeclaration(entry, indexes)) return false;
|
|
@@ -296,7 +295,7 @@ function result(id, sourcePath, status, body) {
|
|
|
296
295
|
reviewRequired: status !== 'merged',
|
|
297
296
|
reasonCodes: unique((body.conflicts ?? []).map((item) => item.details.reasonCode)),
|
|
298
297
|
browserCascadeEquivalenceClaim: browserCascadeEquivalenceClaim || undefined,
|
|
299
|
-
cssCascadeRuntimeProofs: body.cascadeRuntimeProofs?.length ? body.cascadeRuntimeProofs : undefined, cssDependencyGraphProofs: body.dependencyGraphProofs?.length ? body.dependencyGraphProofs : undefined, cssModuleContractProofs: body.cssModuleContractProofs?.length ? body.cssModuleContractProofs : undefined
|
|
298
|
+
cssCascadeRuntimeProofs: body.cascadeRuntimeProofs?.length ? body.cascadeRuntimeProofs : undefined, cssScopedCascadeProofs: body.scopedCascadeProofs?.length ? body.scopedCascadeProofs : undefined, cssDependencyGraphProofs: body.dependencyGraphProofs?.length ? body.dependencyGraphProofs : undefined, cssModuleContractProofs: body.cssModuleContractProofs?.length ? body.cssModuleContractProofs : undefined
|
|
300
299
|
}
|
|
301
300
|
};
|
|
302
301
|
}
|
package/package.json
CHANGED