@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 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
- if (canRebaseChange(move, change, options, sourcePath)) {
80
- const rebased = rebaseChangeToSelectorMove(change, move);
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 canRebaseChange(move, change, options, sourcePath) {
90
- return change.kind === 'add' && change.after && hasSelectorTargetEquivalence(move, options, sourcePath);
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 hasSelectorTargetEquivalence(move, options, sourcePath) {
94
- if (!move.specificityInvariant) return false;
95
- return (options.selectorTargetEquivalences ?? []).some((entry) => {
96
- const sourceMatches = !entry.sourcePath || entry.sourcePath === sourcePath;
97
- const ruleKeysMatch = entry.fromRuleKey === move.beforeRuleKey && entry.toRuleKey === move.afterRuleKey;
98
- const selectorsMatch = selectorListKey(entry.fromSelectors) === selectorListKey(move.beforeSelectors) && selectorListKey(entry.toSelectors) === selectorListKey(move.afterSelectors);
99
- const graphMatches = Boolean(entry.graphHash && entry.graphHash === move.beforeSelectorTargetGraphHash && entry.graphHash === move.afterSelectorTargetGraphHash);
100
- const specificityMatches = (!entry.fromSpecificity || specificityListKey(entry.fromSpecificity) === specificityListKey(move.beforeSpecificity)) && (!entry.toSpecificity || specificityListKey(entry.toSpecificity) === specificityListKey(move.afterSpecificity));
101
- return sourceMatches && graphMatches && specificityMatches && (ruleKeysMatch || selectorsMatch);
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 rebaseChangeToSelectorMove(change, move) {
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: { kind: 'css-selector-target-rebase', side: change.side, fromRuleKey: move.beforeRuleKey, toRuleKey: move.afterRuleKey, property: change.after.property, cascadeKey: after.key, selectorTargetGraphHash: move.afterSelectorTargetGraphHash, specificityInvariant: true, beforeSpecificity: move.beforeSpecificity, afterSpecificity: move.afterSpecificity }
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 };
@@ -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 cascadeRuntimeAdmission = admitCascadeRuntimeProofs({
53
- id,
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shapeshift-labs/frontier-lang-css",
3
- "version": "0.1.20",
3
+ "version": "0.1.22",
4
4
  "description": "CSS semantic merge evidence and projection adapter for Frontier Lang semantic source documents.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",