@shapeshift-labs/frontier-lang-compiler 0.2.162 → 0.2.163

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.
Files changed (21) hide show
  1. package/dist/internal/index-impl/moduleHostResourceImportMetadata.js +47 -0
  2. package/dist/internal/index-impl/projectSymbolGraphCompilerAdvancedTypeMetadata.js +84 -12
  3. package/dist/internal/index-impl/projectSymbolGraphCompilerFacts.js +1 -1
  4. package/dist/internal/index-impl/projectSymbolGraphCssModules.js +48 -4
  5. package/dist/internal/index-impl/projectSymbolGraphJsxPropRecordFields.js +91 -0
  6. package/dist/internal/index-impl/projectSymbolGraphJsxPropValues.js +26 -135
  7. package/dist/internal/index-impl/projectSymbolGraphJsxRecords.js +4 -31
  8. package/dist/internal/index-impl/projectSymbolGraphJsxRenderReturnCollectionHelpers.js +201 -0
  9. package/dist/internal/index-impl/projectSymbolGraphJsxRenderReturnCollections.js +210 -0
  10. package/dist/internal/index-impl/projectSymbolGraphJsxRenderReturns.js +12 -5
  11. package/dist/internal/index-impl/projectSymbolGraphJsxSpreadPropValues.js +196 -0
  12. package/dist/internal/index-impl/projectSymbolGraphJsxStaticLiterals.js +207 -0
  13. package/dist/internal/index-impl/projectSymbolGraphModuleResolution.js +12 -14
  14. package/dist/internal/index-impl/projectSymbolGraphPackageConditions.js +22 -17
  15. package/dist/internal/index-impl/syntaxModuleDeclarationEntries.js +27 -1
  16. package/dist/js-ts-safe-project-merge-html-css-matrix.js +7 -2
  17. package/dist/js-ts-safe-project-merge-html-css-summary.js +90 -8
  18. package/dist/js-ts-safe-project-merge-html-css.js +137 -3
  19. package/dist/js-ts-safe-project-merge-jsx-graph-conflict-details.js +9 -0
  20. package/dist/js-ts-safe-project-merge.js +3 -0
  21. package/package.json +1 -1
@@ -0,0 +1,207 @@
1
+ import { hashSemanticValue } from '@shapeshift-labs/frontier-lang-kernel';
2
+
3
+ function parseStaticLiteralExpression(text) {
4
+ return parseStaticLiteralExpressionResult(text).value;
5
+ }
6
+
7
+ function parseStaticObjectLiteralExpression(text) {
8
+ const result = parseStaticLiteralExpressionResult(text);
9
+ return result.value?.kind === 'object-literal' ? result : { reasonCode: result.reasonCode };
10
+ }
11
+
12
+ function parseStaticLiteralExpressionResult(text) {
13
+ const state = { text: String(text ?? ''), index: 0 };
14
+ const parsed = parseStaticLiteralValue(state);
15
+ skipWhitespace(state);
16
+ return parsed && state.index === state.text.length
17
+ ? { value: parsed }
18
+ : { reasonCode: state.errorReason };
19
+ }
20
+
21
+ function parseStaticLiteralValue(state) {
22
+ skipWhitespace(state);
23
+ const char = state.text[state.index];
24
+ if (char === '"' || char === "'") return parseQuotedStaticString(state) ? { kind: 'string' } : undefined;
25
+ if (char === '`') return parseStaticTemplateString(state) ? { kind: 'template-string' } : undefined;
26
+ if (char === '{') {
27
+ const parsed = parseStaticObjectLiteral(state);
28
+ return parsed ? { kind: 'object-literal', entries: parsed.entries } : undefined;
29
+ }
30
+ if (char === '[') return parseStaticArrayLiteral(state) ? { kind: 'array-literal' } : undefined;
31
+ if (looksLikeCallExpression(state.text.slice(state.index))) state.errorReason ??= 'jsx-render-prop-spread-call-expression-unsupported';
32
+ const primitive = parseStaticPrimitiveToken(state);
33
+ return primitive ? { kind: primitive } : undefined;
34
+ }
35
+
36
+ function parseStaticObjectLiteral(state) {
37
+ state.index += 1;
38
+ skipWhitespace(state);
39
+ const entries = [];
40
+ if (consumeChar(state, '}')) return { entries };
41
+ while (state.index < state.text.length) {
42
+ if (state.text.startsWith('...', state.index)) {
43
+ state.errorReason ??= 'jsx-render-prop-spread-nested-spread-unsupported';
44
+ return undefined;
45
+ }
46
+ if (state.text[state.index] === '[') {
47
+ state.errorReason ??= 'jsx-render-prop-spread-computed-key-unsupported';
48
+ return undefined;
49
+ }
50
+ const key = parseStaticObjectKey(state);
51
+ if (!key) return undefined;
52
+ skipWhitespace(state);
53
+ if (!consumeChar(state, ':')) {
54
+ if (key.propName === 'get' || key.propName === 'set') state.errorReason ??= 'jsx-render-prop-spread-getter-unsupported';
55
+ else if (state.text[state.index] === '(') state.errorReason ??= 'jsx-render-prop-spread-method-unsupported';
56
+ else state.errorReason ??= 'jsx-render-prop-spread-dynamic-object-unsupported';
57
+ return undefined;
58
+ }
59
+ skipWhitespace(state);
60
+ const valueStart = state.index;
61
+ const value = parseStaticLiteralValue(state);
62
+ if (!value) return undefined;
63
+ const valueText = normalizedText(state.text.slice(valueStart, state.index));
64
+ entries.push(staticSpreadPropEntry(key, value, valueText, entries.length + 1));
65
+ skipWhitespace(state);
66
+ if (consumeChar(state, '}')) return { entries };
67
+ if (!consumeChar(state, ',')) return undefined;
68
+ skipWhitespace(state);
69
+ if (consumeChar(state, '}')) return { entries };
70
+ }
71
+ return undefined;
72
+ }
73
+
74
+ function parseStaticArrayLiteral(state) {
75
+ state.index += 1;
76
+ skipWhitespace(state);
77
+ if (consumeChar(state, ']')) return true;
78
+ while (state.index < state.text.length) {
79
+ if (state.text.startsWith('...', state.index) || state.text[state.index] === ',') {
80
+ state.errorReason ??= 'jsx-render-prop-spread-dynamic-object-unsupported';
81
+ return false;
82
+ }
83
+ if (!parseStaticLiteralValue(state)) return false;
84
+ skipWhitespace(state);
85
+ if (consumeChar(state, ']')) return true;
86
+ if (!consumeChar(state, ',')) return false;
87
+ skipWhitespace(state);
88
+ if (consumeChar(state, ']')) return true;
89
+ }
90
+ return false;
91
+ }
92
+
93
+ function parseStaticObjectKey(state) {
94
+ skipWhitespace(state);
95
+ const char = state.text[state.index];
96
+ const start = state.index;
97
+ if (char === '"' || char === "'") {
98
+ if (!parseQuotedStaticString(state)) return undefined;
99
+ const keyText = state.text.slice(start, state.index);
100
+ return { propName: staticStringLiteralValue(keyText), keyText };
101
+ }
102
+ const numberStart = state.index;
103
+ const number = parseStaticNumberToken(state);
104
+ if (number) return { propName: number, keyText: number };
105
+ state.index = numberStart;
106
+ const identifier = parseIdentifierToken(state);
107
+ return identifier ? { propName: identifier, keyText: identifier } : undefined;
108
+ }
109
+
110
+ function staticSpreadPropEntry(key, value, valueText, ordinal) {
111
+ return {
112
+ propName: key.propName,
113
+ keyText: key.keyText,
114
+ valueKind: value.kind,
115
+ valueText,
116
+ ordinal,
117
+ entryHash: hashSemanticValue({
118
+ kind: 'frontier.lang.projectJsxStaticObjectSpreadPropEntry',
119
+ propName: key.propName,
120
+ keyText: key.keyText,
121
+ valueKind: value.kind,
122
+ valueText,
123
+ ordinal
124
+ })
125
+ };
126
+ }
127
+
128
+ function parseQuotedStaticString(state) {
129
+ const quote = state.text[state.index];
130
+ if (quote !== '"' && quote !== "'") return false;
131
+ state.index += 1;
132
+ while (state.index < state.text.length) {
133
+ const char = state.text[state.index];
134
+ if (char === '\\') {
135
+ state.index += 2;
136
+ continue;
137
+ }
138
+ state.index += 1;
139
+ if (char === quote) return true;
140
+ }
141
+ return false;
142
+ }
143
+
144
+ function parseStaticTemplateString(state) {
145
+ if (state.text[state.index] !== '`') return false;
146
+ state.index += 1;
147
+ while (state.index < state.text.length) {
148
+ const char = state.text[state.index];
149
+ if (char === '\\') {
150
+ state.index += 2;
151
+ continue;
152
+ }
153
+ if (char === '$' && state.text[state.index + 1] === '{') return false;
154
+ state.index += 1;
155
+ if (char === '`') return true;
156
+ }
157
+ return false;
158
+ }
159
+
160
+ function parseStaticPrimitiveToken(state) {
161
+ const number = parseStaticNumberToken(state);
162
+ if (number) return 'number';
163
+ const identifierStart = state.index;
164
+ const identifier = parseIdentifierToken(state);
165
+ if (['true', 'false'].includes(identifier)) return 'boolean';
166
+ if (identifier === 'null') return 'null';
167
+ if (identifier === 'undefined') return 'undefined';
168
+ state.index = identifierStart;
169
+ return undefined;
170
+ }
171
+
172
+ function parseStaticNumberToken(state) {
173
+ const match = /^[-]?(?:0|[1-9]\d*)(?:\.\d+)?/.exec(state.text.slice(state.index));
174
+ if (!match) return undefined;
175
+ state.index += match[0].length;
176
+ return match[0];
177
+ }
178
+
179
+ function parseIdentifierToken(state) {
180
+ const match = /^[A-Za-z_$][\w$]*/.exec(state.text.slice(state.index));
181
+ if (!match) return undefined;
182
+ state.index += match[0].length;
183
+ return match[0];
184
+ }
185
+
186
+ function consumeChar(state, char) {
187
+ if (state.text[state.index] !== char) return false;
188
+ state.index += 1;
189
+ return true;
190
+ }
191
+
192
+ function skipWhitespace(state) {
193
+ while (/\s/.test(state.text[state.index] ?? '')) state.index += 1;
194
+ }
195
+
196
+ function staticStringLiteralValue(text) {
197
+ const value = String(text ?? '');
198
+ return value.slice(1, -1).replace(/\\([\s\S])/g, '$1');
199
+ }
200
+
201
+ function looksLikeCallExpression(text) {
202
+ return /^\s*[A-Za-z_$][\w$]*(?:\s*(?:\.|\?\.)\s*[A-Za-z_$][\w$]*)*\s*\(/.test(String(text ?? ''));
203
+ }
204
+
205
+ function normalizedText(text) { return String(text ?? '').trim().replace(/\s+/g, ' '); }
206
+
207
+ export { parseStaticLiteralExpression, parseStaticObjectLiteralExpression };
@@ -3,6 +3,7 @@ import { exportMapMatch, exportTargetsForValue, packageEnvironmentConditionAmbig
3
3
 
4
4
  const UNKNOWN_DYNAMIC_IMPORT_MODULE_SPECIFIER = '<dynamic-import>';
5
5
  const UNKNOWN_HOST_DEPENDENCY_MODULE_SPECIFIER = '<host-dependency>';
6
+ const PACKAGE_RUNTIME_CONDITION_HOST_RESOURCE_IMPORT_AMBIGUOUS_MISSING = 'package-runtime-condition-host-resource-import-ambiguous-missing';
6
7
 
7
8
  export function resolveRelativeProjectModule(sourcePath, moduleSpecifier, documentsByPath) {
8
9
  if (!sourcePath || !moduleSpecifier || !moduleSpecifier.startsWith('.')) return undefined;
@@ -115,6 +116,12 @@ function resolvePackageImportProjectModule(sourcePath, moduleSpecifier, document
115
116
  ...runtimeEvidence
116
117
  };
117
118
  if (match.value === null) return { kind: 'package-import-null-target-missing', packageImportKey: match.key, packageName: packageContext.packageName, ...runtimeEvidence };
119
+ if (runtimeEvidence.packageRuntimeConditionReasonCode === PACKAGE_RUNTIME_CONDITION_HOST_RESOURCE_IMPORT_AMBIGUOUS_MISSING) return {
120
+ kind: PACKAGE_RUNTIME_CONDITION_HOST_RESOURCE_IMPORT_AMBIGUOUS_MISSING,
121
+ packageImportKey: match.key,
122
+ packageName: packageContext.packageName,
123
+ ...runtimeEvidence
124
+ };
118
125
  const runtimeAmbiguity = packageRuntimeConditionAmbiguity(match.value, moduleResolution, sourcePath, packageContext, edgeMetadata);
119
126
  if (runtimeAmbiguity) return { kind: 'package-import-runtime-ambiguous-missing', packageImportKey: match.key, packageImportCondition: runtimeAmbiguity, packageName: packageContext.packageName, ...runtimeEvidence };
120
127
  const environmentEvidence = packageEnvironmentConditionEvidence(moduleResolution, edgeMetadata);
@@ -188,6 +195,7 @@ function packageCandidates(sourcePath, packageInfo, moduleResolution = {}, edgeM
188
195
  const fallbackPath = normalizeProjectPath(joinProjectPath(root, subpath || '.'));
189
196
  if (runtimeEvidence.packageRuntimeConditionConflict) return [{ kind: 'package', failClosedKind: 'package-runtime-condition-conflict-missing', path: fallbackPath, packageExportKey: exportMatch?.key, ...runtimeEvidence, ...packageInfo }];
190
197
  if (exportValue === undefined || exportValue === null) return [{ kind: 'package', failClosedKind: exportValue === null ? 'package-export-null-target-missing' : 'package-subpath-not-exported-missing', path: fallbackPath, packageExportKey: exportMatch?.key, ...runtimeEvidence, ...packageInfo }];
198
+ if (runtimeEvidence.packageRuntimeConditionReasonCode === PACKAGE_RUNTIME_CONDITION_HOST_RESOURCE_IMPORT_AMBIGUOUS_MISSING) return [{ kind: 'package', failClosedKind: PACKAGE_RUNTIME_CONDITION_HOST_RESOURCE_IMPORT_AMBIGUOUS_MISSING, path: fallbackPath, packageExportKey: exportMatch?.key, ...runtimeEvidence, ...packageInfo }];
191
199
  const runtimeAmbiguity = packageRuntimeConditionAmbiguity(exportValue, moduleResolution, sourcePath, undefined, edgeMetadata);
192
200
  if (runtimeAmbiguity) return [{ kind: 'package', failClosedKind: 'package-export-runtime-ambiguous-missing', path: fallbackPath, packageExportKey: exportMatch?.key, packageExportCondition: runtimeAmbiguity, ...runtimeEvidence, ...packageInfo }];
193
201
  const environmentAmbiguity = packageEnvironmentConditionAmbiguity(exportValue, moduleResolution, sourcePath, undefined, edgeMetadata);
@@ -251,15 +259,8 @@ function moduleTargetDocument(path, documentsByPath) {
251
259
  return undefined;
252
260
  }
253
261
 
254
- function targetExportName(edge) {
255
- const name = edge.importedName ?? edge.localName ?? edge.exportedName;
256
- if (!name || name === '*') return undefined;
257
- return String(name);
258
- }
259
-
260
- function symbolKey(documentId, name) {
261
- return `${documentId}\u0000${name}`;
262
- }
262
+ function targetExportName(edge) { const name = edge.importedName ?? edge.localName ?? edge.exportedName; return name && name !== '*' ? String(name) : undefined; }
263
+ function symbolKey(documentId, name) { return `${documentId}\u0000${name}`; }
263
264
 
264
265
  function patternCapture(value, pattern) {
265
266
  if (pattern === value) return '';
@@ -278,9 +279,7 @@ function uniquePaths(candidates) {
278
279
  });
279
280
  }
280
281
 
281
- function joinProjectPath(left, right) {
282
- return left ? `${left}/${right}` : String(right);
283
- }
282
+ function joinProjectPath(left, right) { return left ? `${left}/${right}` : String(right); }
284
283
 
285
284
  function packageSpecifierInfo(moduleSpecifier) {
286
285
  if (!moduleSpecifier || String(moduleSpecifier).startsWith('#')) return undefined;
@@ -295,11 +294,10 @@ function packageSpecifierInfo(moduleSpecifier) {
295
294
 
296
295
  function packageResolutionFields(candidate, packageInfo) {
297
296
  if (!candidate.packageName && candidate.kind !== 'package') return {};
298
- return { packageName: candidate.packageName ?? packageInfo?.packageName, packageSubpath: candidate.packageSubpath ?? packageInfo?.packageSubpath, packageExportKey: candidate.packageExportKey, packageExportCondition: candidate.packageExportCondition, packageExportTarget: candidate.packageExportTarget, packageImportKey: candidate.packageImportKey, packageImportCondition: candidate.packageImportCondition, packageImportTarget: candidate.packageImportTarget, packageRuntimeCondition: candidate.packageRuntimeCondition, packageRuntimeConditionEvidenceSource: candidate.packageRuntimeConditionEvidenceSource, packageRuntimeConditionEdgeKind: candidate.packageRuntimeConditionEdgeKind, packageRuntimeConditionCandidates: candidate.packageRuntimeConditionCandidates, packageRuntimeConditionExcludedConditions: candidate.packageRuntimeConditionExcludedConditions, packageRuntimeConditionReasonCode: candidate.packageRuntimeConditionReasonCode, packageEnvironmentCondition: candidate.packageEnvironmentCondition, packageEnvironmentConditionEvidenceSource: candidate.packageEnvironmentConditionEvidenceSource, packageEnvironmentConditionCandidates: candidate.packageEnvironmentConditionCandidates, packageEnvironmentConditionReasonCode: candidate.packageEnvironmentConditionReasonCode, packageType: candidate.packageType, packageWorkspaceRootAmbiguous: candidate.packageWorkspaceRootAmbiguous, packageWorkspaceRoots: candidate.packageWorkspaceRoots, packageResolutionReasonCode: candidate.packageResolutionReasonCode };
297
+ return { packageName: candidate.packageName ?? packageInfo?.packageName, packageSubpath: candidate.packageSubpath ?? packageInfo?.packageSubpath, packageExportKey: candidate.packageExportKey, packageExportCondition: candidate.packageExportCondition, packageExportTarget: candidate.packageExportTarget, packageImportKey: candidate.packageImportKey, packageImportCondition: candidate.packageImportCondition, packageImportTarget: candidate.packageImportTarget, packageRuntimeCondition: candidate.packageRuntimeCondition, packageRuntimeConditionEvidenceSource: candidate.packageRuntimeConditionEvidenceSource, packageRuntimeConditionEdgeKind: candidate.packageRuntimeConditionEdgeKind, packageRuntimeConditionCandidates: candidate.packageRuntimeConditionCandidates, packageRuntimeConditionExcludedConditions: candidate.packageRuntimeConditionExcludedConditions, packageRuntimeConditionReasonCode: candidate.packageRuntimeConditionReasonCode, packageRuntimeConditionHostResourceKind: candidate.packageRuntimeConditionHostResourceKind, packageEnvironmentCondition: candidate.packageEnvironmentCondition, packageEnvironmentConditionEvidenceSource: candidate.packageEnvironmentConditionEvidenceSource, packageEnvironmentConditionCandidates: candidate.packageEnvironmentConditionCandidates, packageEnvironmentConditionReasonCode: candidate.packageEnvironmentConditionReasonCode, packageType: candidate.packageType, packageWorkspaceRootAmbiguous: candidate.packageWorkspaceRootAmbiguous, packageWorkspaceRoots: candidate.packageWorkspaceRoots, packageResolutionReasonCode: candidate.packageResolutionReasonCode };
299
298
  }
300
299
 
301
300
  function environmentAmbiguityFields(ambiguity) { return { packageEnvironmentConditionCandidates: ambiguity.split('|'), packageEnvironmentConditionReasonCode: 'package-environment-condition-ambiguous-missing' }; }
302
-
303
301
  function isRecord(value) { return value && typeof value === 'object' && !Array.isArray(value); }
304
302
 
305
303
  function normalizeProjectPath(path) {
@@ -1,4 +1,5 @@
1
1
  import { runtimeAdmittedConditions, runtimeConditionRecord } from './projectSymbolGraphPackageRuntimeConditions.js';
2
+ import { hostResourceImportDependencyKind } from './moduleHostResourceImportMetadata.js';
2
3
 
3
4
  const EnvironmentPackageConditions = Object.freeze([
4
5
  'browser',
@@ -11,6 +12,7 @@ const EnvironmentPackageConditions = Object.freeze([
11
12
  'bun',
12
13
  'react-native'
13
14
  ]);
15
+ const PACKAGE_RUNTIME_CONDITION_HOST_RESOURCE_IMPORT_AMBIGUOUS_MISSING = 'package-runtime-condition-host-resource-import-ambiguous-missing';
14
16
 
15
17
  function exportTargetsForValue(value, conditions, condition) {
16
18
  if (!value) return [];
@@ -62,9 +64,11 @@ function packageEnvironmentConditionAmbiguity(value, moduleResolution, sourcePat
62
64
  }
63
65
 
64
66
  function packageRuntimeConditionEvidence(moduleResolution = {}, sourcePath, packageContext, edgeMetadata) {
67
+ const packageType = packageTypeForSource(moduleResolution, sourcePath, packageContext);
68
+ const hostResourceAmbiguity = packageRuntimeHostResourceConditionAmbiguity(edgeMetadata, packageType);
69
+ if (hostResourceAmbiguity) return hostResourceAmbiguity;
65
70
  const edgeCondition = packageRuntimeConditionFromEdge(edgeMetadata);
66
71
  const extensionCondition = packageRuntimeConditionFromExtension(sourcePath);
67
- const packageType = packageTypeForSource(moduleResolution, sourcePath, packageContext);
68
72
  const packageTypeCondition = packageType === 'module' ? 'import' : packageType === 'commonjs' ? 'require' : undefined;
69
73
  if (edgeCondition) {
70
74
  const conflict = edgeCondition.conflictsWithSource && (
@@ -182,6 +186,19 @@ function packageRuntimeHostConditionAmbiguity(edgeMetadata = {}, packageType) {
182
186
  });
183
187
  }
184
188
 
189
+ function packageRuntimeHostResourceConditionAmbiguity(edgeMetadata = {}, packageType) {
190
+ const hostKind = edgeMetadata.hostDependencyKind;
191
+ const hostResourceKind = hostResourceImportDependencyKind(hostKind);
192
+ if (!hostResourceKind) return undefined;
193
+ return compactRecord({
194
+ packageRuntimeConditionEvidenceSource: 'host-resource-import-ambiguous',
195
+ packageRuntimeConditionEdgeKind: `host-${hostKind}`,
196
+ packageRuntimeConditionReasonCode: PACKAGE_RUNTIME_CONDITION_HOST_RESOURCE_IMPORT_AMBIGUOUS_MISSING,
197
+ packageRuntimeConditionHostResourceKind: hostResourceKind,
198
+ packageType
199
+ });
200
+ }
201
+
185
202
  function edgeCondition(packageRuntimeCondition, packageRuntimeConditionEdgeKind, packageRuntimeConditionReasonCode, preferred, conflictsWithSource) {
186
203
  return runtimeConditionRecord({
187
204
  packageRuntimeCondition,
@@ -245,10 +262,7 @@ function packageTypeByRoot(typeMap, sourcePath) {
245
262
  .sort((left, right) => right.root.length - left.root.length)[0]?.value;
246
263
  }
247
264
 
248
- function normalizePackageType(value) {
249
- const type = typeof value === 'string' ? value : value?.type ?? value?.packageType;
250
- return type === 'module' || type === 'commonjs' ? type : undefined;
251
- }
265
+ function normalizePackageType(value) { const type = typeof value === 'string' ? value : value?.type ?? value?.packageType; return type === 'module' || type === 'commonjs' ? type : undefined; }
252
266
 
253
267
  function sameSet(left, right) {
254
268
  if (left.size !== right.size) return false;
@@ -256,13 +270,8 @@ function sameSet(left, right) {
256
270
  return true;
257
271
  }
258
272
 
259
- function uniqueStrings(values) {
260
- return [...new Set(values.filter((value) => typeof value === 'string' && value))];
261
- }
262
-
263
- function stringValue(value) {
264
- return typeof value === 'string' && value.length ? value : undefined;
265
- }
273
+ function uniqueStrings(values) { return [...new Set(values.filter((value) => typeof value === 'string' && value))]; }
274
+ function stringValue(value) { return typeof value === 'string' && value.length ? value : undefined; }
266
275
 
267
276
  function prioritizeConditions(conditions, preferred) {
268
277
  const entries = Array.isArray(conditions) ? conditions : [conditions];
@@ -276,7 +285,6 @@ function prioritizeConditions(conditions, preferred) {
276
285
  }
277
286
 
278
287
  function isRecord(value) { return value && typeof value === 'object' && !Array.isArray(value); }
279
-
280
288
  function compactRecord(record) { return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined)); }
281
289
 
282
290
  function replaceTargetCapture(target, capture) {
@@ -303,9 +311,6 @@ function patternCapture(value, pattern) {
303
311
  return String(value).slice(prefix.length, String(value).length - suffix.length);
304
312
  }
305
313
 
306
- function pathInsideRoot(sourcePath, root) {
307
- if (!root) return true;
308
- return sourcePath === root || sourcePath.startsWith(`${root}/`);
309
- }
314
+ function pathInsideRoot(sourcePath, root) { return !root || sourcePath === root || sourcePath.startsWith(`${root}/`); }
310
315
 
311
316
  export { exportMapMatch, exportTargetsForValue, packageConditions, packageEnvironmentConditionAmbiguity, packageEnvironmentConditionEvidence, packageRuntimeConditionAmbiguity, packageRuntimeConditionEvidence };
@@ -5,6 +5,7 @@ import {
5
5
  } from './syntaxCommonJsModuleDeclarationEntries.js';
6
6
  import { dynamicImportExpressionMetadata } from './dynamicImportExpressionMetadata.js';
7
7
  import { hostModuleDependencyMetadata } from './importMetaUrlDependencyMetadata.js';
8
+ import { moduleHostResourceImportMetadata } from './moduleHostResourceImportMetadata.js';
8
9
  import { moduleImportAttributeMetadata } from './moduleImportAttributeMetadata.js';
9
10
  import {
10
11
  declarationName,
@@ -38,10 +39,15 @@ function importDeclarationEntries(node, nativeNodeId, input) {
38
39
  if (!moduleSpecifier) return [];
39
40
  const typeOnly = node.importKind === 'type';
40
41
  const bindings = (node.specifiers ?? []).map((specifier) => importSpecifierBinding(specifier, typeOnly)).filter(Boolean);
42
+ const importKind = bindings.length === 0 ? 'side-effect' : 'module';
41
43
  return importModuleEntries(input, nativeNodeId, moduleSpecifier, bindings, {
42
44
  typeOnly,
43
45
  sideEffectOnly: bindings.length === 0,
44
- importKind: bindings.length === 0 ? 'side-effect' : 'module',
46
+ importKind,
47
+ ...moduleHostResourceImportMetadata(moduleSpecifier, {
48
+ hostDependencyBase: 'module-import',
49
+ expressionText: `import ${JSON.stringify(moduleSpecifier)}`
50
+ }),
45
51
  ...moduleImportAttributeMetadata(node)
46
52
  });
47
53
  }
@@ -54,6 +60,10 @@ function dynamicImportExpressionEntries(node, nativeNodeId, input) {
54
60
  importKind: 'dynamic-import',
55
61
  dynamicImport: true,
56
62
  ...dynamicImportExpressionMetadata(importArgument, moduleSpecifier),
63
+ ...moduleHostResourceImportMetadata(moduleSpecifier, {
64
+ hostDependencyBase: 'dynamic-import',
65
+ expressionText: `import(${JSON.stringify(moduleSpecifier)})`
66
+ }),
57
67
  ...moduleImportAttributeMetadata(node)
58
68
  });
59
69
  }
@@ -75,12 +85,20 @@ function exportNamedDeclarationEntries(node, nativeNodeId, input) {
75
85
  typeOnly,
76
86
  reexport: true,
77
87
  importKind: 'reexport',
88
+ ...moduleHostResourceImportMetadata(moduleSpecifier, {
89
+ hostDependencyBase: 'module-reexport',
90
+ expressionText: `export from ${JSON.stringify(moduleSpecifier)}`
91
+ }),
78
92
  ...moduleImportAttributeMetadata(node)
79
93
  }) : []),
80
94
  ...exportModuleEntries(input, nativeNodeId, moduleSpecifier, bindings, {
81
95
  typeOnly,
82
96
  reExport: Boolean(moduleSpecifier),
83
97
  exportKind: typeOnly ? 'type-named' : 'named',
98
+ ...moduleHostResourceImportMetadata(moduleSpecifier, {
99
+ hostDependencyBase: 'module-reexport',
100
+ expressionText: `export from ${JSON.stringify(moduleSpecifier)}`
101
+ }),
84
102
  ...moduleImportAttributeMetadata(node)
85
103
  })
86
104
  ];
@@ -107,6 +125,10 @@ function exportAllDeclarationEntries(node, nativeNodeId, input) {
107
125
  reexport: true,
108
126
  exportStar: !exportedName,
109
127
  importKind: exportedName ? 'namespace-reexport' : 'reexport',
128
+ ...moduleHostResourceImportMetadata(moduleSpecifier, {
129
+ hostDependencyBase: 'module-reexport',
130
+ expressionText: `export from ${JSON.stringify(moduleSpecifier)}`
131
+ }),
110
132
  ...moduleImportAttributeMetadata(node)
111
133
  }),
112
134
  ...exportModuleEntries(input, nativeNodeId, moduleSpecifier, bindings, {
@@ -114,6 +136,10 @@ function exportAllDeclarationEntries(node, nativeNodeId, input) {
114
136
  reExport: true,
115
137
  exportStar: !exportedName,
116
138
  exportKind: exportedName ? 'namespace-reexport' : 'export-star',
139
+ ...moduleHostResourceImportMetadata(moduleSpecifier, {
140
+ hostDependencyBase: 'module-reexport',
141
+ expressionText: `export from ${JSON.stringify(moduleSpecifier)}`
142
+ }),
117
143
  ...moduleImportAttributeMetadata(node)
118
144
  })
119
145
  ];
@@ -5,6 +5,7 @@ const HtmlCssProjectMergeMissingSignals = Object.freeze({
5
5
  cssSelectorTargetEvidence: 'css-selector-target-evidence-missing',
6
6
  htmlStructuralMerge: 'html-structural-merge-proof-blocked',
7
7
  cssCascadeMerge: 'css-cascade-merge-proof-blocked',
8
+ cssDependencyGraphEvidence: 'css-dependency-graph-evidence-missing',
8
9
  htmlCssBrowserRuntimeProof: 'html-css-browser-runtime-proof-not-available'
9
10
  });
10
11
 
@@ -16,6 +17,7 @@ function htmlCssProjectMergeMissingEvidenceRoutes(route, signals) {
16
17
  [signals.cssSelectorTargetEvidence]: route('prove-css-selector-target-evidence', 'layout-style-targets', 'supply-selector-target-graph-and-rebase-evidence'),
17
18
  [signals.htmlStructuralMerge]: route('admit-html-structural-merge', 'layout-markup-graph', 'supply-html-parser-reference-and-boundary-evidence'),
18
19
  [signals.cssCascadeMerge]: route('admit-css-cascade-merge', 'layout-style-graph', 'supply-css-parser-cascade-and-scope-evidence'),
20
+ [signals.cssDependencyGraphEvidence]: route('prove-css-dependency-graph', 'layout-style-graph', 'supply-css-custom-property-animation-font-and-asset-dependency-graph'),
19
21
  [signals.htmlCssBrowserRuntimeProof]: route('prove-html-css-browser-runtime', 'browser-proof', 'attach-browser-runtime-proof-bundle')
20
22
  };
21
23
  }
@@ -28,6 +30,7 @@ function htmlCssProjectMergeAdmissionMatrixRows(matrixRow, signals) {
28
30
  matrixRow('css-selector-target-evidence', 'bounded-evidence', ['css-selector-target-evidence'], [signals.cssSelectorTargetEvidence]),
29
31
  matrixRow('html-structural-merge-admission', 'partial', ['html-structural-merge'], [signals.htmlStructuralMerge]),
30
32
  matrixRow('css-cascade-merge-admission', 'partial', ['css-cascade-merge'], [signals.cssCascadeMerge]),
33
+ matrixRow('css-dependency-graph-evidence', 'bounded-evidence', ['css-dependency-graph'], [signals.cssDependencyGraphEvidence]),
31
34
  matrixRow('html-css-browser-runtime-proof', 'bounded-evidence', ['browser-runtime-proof'], [signals.htmlCssBrowserRuntimeProof])
32
35
  ];
33
36
  }
@@ -36,10 +39,11 @@ function htmlCssProjectMergeMissingEvidenceItems(summary, signals, missingEviden
36
39
  const items = [];
37
40
  if (summary.htmlFiles && summary.htmlParserEvidenceFiles !== summary.htmlFiles) items.push(missingEvidenceItem({ code: signals.htmlParserEvidence, scope: 'layout-markup-parser', kind: 'html-parser-source-evidence', proofLevel: 'html-parser-source-evidence', action: 'review', summary: `HTML project merge has parser/source evidence for ${summary.htmlParserEvidenceFiles}/${summary.htmlFiles} file(s); require parse5 source spans, zero parse errors, and attribute/trivia spans when those surfaces are present before parser evidence admission.` }));
38
41
  if (summary.cssFiles && summary.cssParserEvidenceFiles !== summary.cssFiles) items.push(missingEvidenceItem({ code: signals.cssParserEvidence, scope: 'layout-style-parser', kind: 'css-parser-source-evidence', proofLevel: 'css-parser-source-evidence', action: 'review', summary: `CSS project merge has parser/source evidence for ${summary.cssParserEvidenceFiles}/${summary.cssFiles} file(s); require PostCSS rule/declaration spans, raw trivia hashes, and zero parse errors before parser evidence admission.` }));
39
- if (summary.htmlFiles && summary.htmlIdentityEvidenceFiles !== summary.htmlFiles) items.push(missingEvidenceItem({ code: signals.htmlIdentityEvidence, scope: 'layout-markup-identity', kind: 'html-identity-evidence', proofLevel: 'html-identity-evidence', action: 'review', summary: `HTML project merge has structural identity evidence for ${summary.htmlIdentityEvidenceFiles}/${summary.htmlFiles} file(s); require parser-backed structural spans and stable explicit/path identity accounting before structural admission.` }));
42
+ if (summary.htmlFiles && summary.htmlIdentityEvidenceFiles !== summary.htmlFiles) items.push(missingEvidenceItem({ code: signals.htmlIdentityEvidence, scope: 'layout-markup-identity', kind: 'html-identity-evidence', proofLevel: 'html-identity-evidence', action: 'review', summary: `HTML project merge has structural identity evidence for ${summary.htmlIdentityEvidenceFiles}/${summary.htmlFiles} file(s) with ${summary.htmlDuplicateIdentityEvidenceFiles ?? 0} duplicate identity evidence file(s); require parser-backed structural spans, unique explicit identity keys, and stable explicit/path identity accounting before structural admission.` }));
40
43
  if (summary.cssFiles && (summary.cssSelectorTargetEvidenceFiles !== summary.cssFiles || summary.cssSelectorTargetConflictFiles)) items.push(missingEvidenceItem({ code: signals.cssSelectorTargetEvidence, scope: 'layout-style-targets', kind: 'css-selector-target-evidence', proofLevel: 'css-selector-target-evidence', action: 'review', summary: `CSS project merge has selector-target evidence for ${summary.cssSelectorTargetEvidenceFiles}/${summary.cssFiles} file(s) with ${summary.cssSelectorTargetConflictFiles} selector target conflict(s); require selector target graph and proven rebase before target-moving merges.` }));
41
44
  if (summary.htmlBlockedFiles) items.push(missingEvidenceItem({ code: signals.htmlStructuralMerge, scope: 'layout-markup-graph', kind: 'html-structural-merge-proof', proofLevel: 'html-structural-merge', action: 'review', summary: `HTML project merge has ${summary.htmlBlockedFiles} blocked file(s); supply parser/source-span evidence, stable element identity, and runtime-boundary proof before admission.` }));
42
- if (summary.cssBlockedFiles) items.push(missingEvidenceItem({ code: signals.cssCascadeMerge, scope: 'layout-style-graph', kind: 'css-cascade-merge-proof', proofLevel: 'css-cascade-merge', action: 'review', summary: `CSS project merge has ${summary.cssBlockedFiles} blocked file(s); supply parser/cascade/scope evidence and keep browser claims false until runtime proof passes.` }));
45
+ if (summary.cssBlockedFiles) items.push(missingEvidenceItem({ code: signals.cssCascadeMerge, scope: 'layout-style-graph', kind: 'css-cascade-merge-proof', proofLevel: 'css-cascade-merge', action: 'review', summary: `CSS project merge has ${summary.cssBlockedFiles} blocked file(s), including ${summary.cssScopedCascadeBlockedFiles} scoped cascade proof block(s); supply parser/cascade/scope evidence, require scopedCascadeGraphHash for changed declarations under @media/@supports/@container/@layer/@scope or nested scopes, and keep browser claims false until runtime proof passes.` }));
46
+ if (summary.cssDependencySurfaceFiles && (summary.cssDependencyGraphEvidenceFiles !== summary.cssDependencySurfaceFiles || summary.cssDependencyGraphMissingProofFiles || summary.cssDependencyGraphBlockedFiles)) items.push(missingEvidenceItem({ code: signals.cssDependencyGraphEvidence, scope: 'layout-style-graph', kind: 'css-dependency-graph-evidence', proofLevel: 'css-dependency-graph', action: 'review', summary: `CSS project merge has dependency graph evidence for ${summary.cssDependencyGraphEvidenceFiles}/${summary.cssDependencySurfaceFiles} dependency-surface file(s), ${summary.cssDependencyGraphMissingProofFiles} missing dependency graph proof(s), and ${summary.cssDependencyGraphBlockedFiles} dependency blocker(s); require custom property, var() fallback, @keyframes/animation-name, @font-face, and url() asset graph evidence before cascade/browser equivalence claims.`, suggestedInput: { cssDependencyGraphEvidence: true } }));
43
47
  if (summary.htmlCssMergedFiles && !summary.htmlCssBrowserRuntimeProofs) items.push(missingEvidenceItem({ code: signals.htmlCssBrowserRuntimeProof, scope: 'browser-proof', kind: 'browser-runtime-proof', proofLevel: 'browser-runtime-proof', action: 'review', summary: 'HTML/CSS structural source merge was available, but browser DOM/cascade/layout/runtime proof was not attached; keep browser equivalence claims false.', suggestedInput: { browserRuntimeProof: true } }));
44
48
  return items;
45
49
  }
@@ -51,6 +55,7 @@ function htmlCssProjectMergeMatrixProofStatus(level, summary) {
51
55
  if (level === 'css-selector-target-evidence') return summary.cssFiles ? (summary.cssSelectorTargetConflictFiles ? 'failed' : summary.cssSelectorTargetEvidenceFiles === summary.cssFiles ? 'passed' : 'missing') : 'absent';
52
56
  if (level === 'html-structural-merge') return summary.htmlFiles ? (summary.htmlBlockedFiles ? 'failed' : summary.htmlMergedFiles ? 'passed' : 'missing') : 'absent';
53
57
  if (level === 'css-cascade-merge') return summary.cssFiles ? (summary.cssBlockedFiles ? 'failed' : summary.cssMergedFiles ? 'passed' : 'missing') : 'absent';
58
+ if (level === 'css-dependency-graph') return summary.cssDependencySurfaceFiles ? (summary.cssDependencyGraphBlockedFiles ? 'failed' : summary.cssDependencyGraphEvidenceFiles === summary.cssDependencySurfaceFiles ? 'passed' : 'missing') : 'absent';
54
59
  if (level === 'browser-runtime-proof') return summary.htmlCssFiles ? (summary.htmlCssBrowserRuntimeProofs ? 'passed' : 'missing') : 'absent';
55
60
  return undefined;
56
61
  }