@shapeshift-labs/frontier-lang-css 0.1.21 → 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 +9 -1
- package/dist/scoped-cascade-proof.d.ts +52 -0
- package/dist/semantic-merge-scoped-cascade.js +167 -0
- package/dist/semantic-merge.js +10 -11
- 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'; 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 { CssSafeMergeChangedShorthandExpansion, CssSafeMergeShorthandExpansionEvidence, CssSafeMergeShorthandExpansionSideEvidence, CssShorthandExpansionEvidence, CssShorthandLonghandExpansion } from './shorthand-expansion.js'; export type { CssSafeMergeSelectorMove, CssSafeMergeSelectorTargetEvidence, CssSafeMergeSelectorTargetRebaseProof, CssSafeMergeSelectorTargetSideEvidence, CssSelectorTargetEquivalence, CssSelectorTargetProof } from './selector-target-proof.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
|
}
|
|
@@ -264,6 +268,10 @@ export interface CssSafeMergeInput {
|
|
|
264
268
|
readonly id?: string; readonly sourcePath?: string; readonly baseSourceText?: string; readonly workerSourceText?: string; readonly headSourceText?: string;
|
|
265
269
|
readonly cssModule?: boolean; readonly cssModules?: boolean; readonly generatedClassNameMap?: Readonly<Record<string, string>>;
|
|
266
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[]>>;
|
|
267
275
|
readonly cssCascadeRuntimeProof?: CssCascadeRuntimeProof; readonly cssCascadeRuntimeProofs?: readonly CssCascadeRuntimeProof[]; readonly cssCascadeRuntimeProofsByPath?: Readonly<Record<string, CssCascadeRuntimeProof | readonly CssCascadeRuntimeProof[]>>;
|
|
268
276
|
readonly cssSourceBoundCascadeProof?: CssCascadeRuntimeProof; readonly cssSourceBoundCascadeProofs?: readonly CssCascadeRuntimeProof[];
|
|
269
277
|
readonly cssSourceBoundCascadeProofsByPath?: Readonly<Record<string, CssCascadeRuntimeProof | readonly CssCascadeRuntimeProof[]>>;
|
|
@@ -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,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 };
|
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';
|
|
@@ -47,20 +48,15 @@ function safeMergeCssSource(input = {}, context = {}) {
|
|
|
47
48
|
const dependencyGraphEvidence = mergeCssDependencyGraphEvidence(sheets, changed);
|
|
48
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