@shapeshift-labs/frontier-lang-css 0.1.20 → 0.1.21

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 { 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';
2
2
 
3
3
  export interface CssProjectionOptions {
4
4
  readonly banner?: string;
@@ -260,33 +260,6 @@ export interface CssSafeMergeParserSideEvidence {
260
260
  readonly scopedCascadeGraphHashPresent: boolean; readonly parseErrors: number; readonly recordCount: number; readonly declarationCount: number;
261
261
  }
262
262
 
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
263
  export interface CssSafeMergeInput {
291
264
  readonly id?: string; readonly sourcePath?: string; readonly baseSourceText?: string; readonly workerSourceText?: string; readonly headSourceText?: string;
292
265
  readonly cssModule?: boolean; readonly cssModules?: boolean; readonly generatedClassNameMap?: Readonly<Record<string, string>>;
@@ -301,6 +274,11 @@ export interface CssSafeMergeInput {
301
274
  readonly cssDependencyGraphProofsByPath?: Readonly<Record<string, CssDependencyGraphProof | readonly CssDependencyGraphProof[]>>; readonly cssSourceBoundDependencyGraphProofsByPath?: Readonly<Record<string, CssDependencyGraphProof | readonly CssDependencyGraphProof[]>>;
302
275
  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
276
  readonly selectorTargetGraphHash?: string; readonly selectorTargetEquivalences?: readonly CssSelectorTargetEquivalence[];
277
+ readonly cssSelectorTargetProof?: CssSelectorTargetProof; readonly cssSelectorTargetProofs?: readonly CssSelectorTargetProof[]; readonly cssSelectorTargetProofsByPath?: Readonly<Record<string, CssSelectorTargetProof | readonly CssSelectorTargetProof[]>>;
278
+ readonly cssSourceBoundSelectorTargetProof?: CssSelectorTargetProof; readonly cssSourceBoundSelectorTargetProofs?: readonly CssSelectorTargetProof[]; readonly cssSourceBoundSelectorTargetProofsByPath?: Readonly<Record<string, CssSelectorTargetProof | readonly CssSelectorTargetProof[]>>;
279
+ readonly selectorTargetProof?: CssSelectorTargetProof; readonly selectorTargetProofs?: readonly CssSelectorTargetProof[]; readonly selectorTargetProofsByPath?: Readonly<Record<string, CssSelectorTargetProof | readonly CssSelectorTargetProof[]>>;
280
+ readonly selectorTargetRebaseProof?: CssSelectorTargetProof; readonly selectorTargetRebaseProofs?: readonly CssSelectorTargetProof[]; readonly selectorTargetRebaseProofsByPath?: Readonly<Record<string, CssSelectorTargetProof | readonly CssSelectorTargetProof[]>>;
281
+ readonly sourceBoundSelectorTargetProof?: CssSelectorTargetProof; readonly sourceBoundSelectorTargetProofs?: readonly CssSelectorTargetProof[]; readonly sourceBoundSelectorTargetProofsByPath?: Readonly<Record<string, CssSelectorTargetProof | readonly CssSelectorTargetProof[]>>;
304
282
  readonly baseGeneratedClassNameMap?: Readonly<Record<string, string>>; readonly workerGeneratedClassNameMap?: Readonly<Record<string, string>>; readonly headGeneratedClassNameMap?: Readonly<Record<string, string>>;
305
283
  readonly baseGeneratedClassNameMapHash?: string; readonly workerGeneratedClassNameMapHash?: string; readonly headGeneratedClassNameMapHash?: string;
306
284
  readonly baseJsTsUseSiteGraphHash?: string; readonly workerJsTsUseSiteGraphHash?: string; readonly headJsTsUseSiteGraphHash?: string;
@@ -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
+ }
@@ -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 };
@@ -45,7 +45,7 @@ function safeMergeCssSource(input = {}, context = {}) {
45
45
  const parserEvidence = mergeParserEvidence(sheets);
46
46
  const shorthandExpansionEvidence = mergeShorthandExpansionEvidence(indexes, changed);
47
47
  const dependencyGraphEvidence = mergeCssDependencyGraphEvidence(sheets, changed);
48
- const selectorTargetPlan = planSelectorTargetRebase(id, sourcePath, mergeSelectorTargetEvidence(sheets, changed), changed, input);
48
+ const selectorTargetPlan = planSelectorTargetRebase(id, sourcePath, mergeSelectorTargetEvidence(sheets, changed), changed, { ...input, sourceBinding: { base, worker, head }, hashSemanticValue: hash });
49
49
  const shapeChanges = unsupportedSourceShapeChanges(sheets, changed, hash);
50
50
  const mergedIndex = applyAtRuleBlockChanges(applyAtRuleBlockChanges(applyDeclarationChanges(applyDeclarationChanges(indexes.base, selectorTargetPlan.changed.head), selectorTargetPlan.changed.worker), blockChanges.head), blockChanges.worker);
51
51
  const mergedSourceText = renderDeclarationIndex(mergedIndex);
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.21",
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",