@tamagui/static 1.0.0-alpha.5 → 1.0.0-alpha.9

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.
@@ -15,6 +15,7 @@ import { ensureImportingConcat } from "./ensureImportingConcat";
15
15
  import { isSimpleSpread } from "./extractHelpers";
16
16
  import { extractMediaStyle } from "./extractMediaStyle";
17
17
  import { hoistClassNames } from "./hoistClassNames";
18
+ import { logLines } from "./logLines";
18
19
  const CONCAT_CLASSNAME_IMPORT = "concatClassName";
19
20
  const mergeStyleGroups = {
20
21
  shadowOpacity: true,
@@ -48,16 +49,11 @@ function extractToClassNames({
48
49
  }
49
50
  const cssMap = new Map();
50
51
  const existingHoists = {};
51
- let flattened = 0;
52
- let optimized = 0;
53
- extractor.parse(ast, {
52
+ const res = extractor.parse(ast, {
54
53
  sourcePath,
55
54
  shouldPrintDebug,
56
55
  ...options,
57
56
  getFlattenedNode: ({ tag }) => tag,
58
- onDidFlatten() {
59
- flattened++;
60
- },
61
57
  onExtractTag: ({
62
58
  attrs,
63
59
  node,
@@ -68,7 +64,6 @@ function extractToClassNames({
68
64
  lineNumbers,
69
65
  programPath
70
66
  }) => {
71
- optimized++;
72
67
  let finalClassNames = [];
73
68
  let finalAttrs = [];
74
69
  let finalStyles = [];
@@ -94,11 +89,11 @@ function extractToClassNames({
94
89
  if (!style)
95
90
  return [];
96
91
  const styleWithPrev = ensureNeededPrevStyle(style);
97
- const res = getStylesAtomic(styleWithPrev);
98
- if (res.length) {
99
- finalStyles = [...finalStyles, ...res];
92
+ const res2 = getStylesAtomic(styleWithPrev);
93
+ if (res2.length) {
94
+ finalStyles = [...finalStyles, ...res2];
100
95
  }
101
- return res;
96
+ return res2;
102
97
  }, "addStyles");
103
98
  let lastMediaImportance = 1;
104
99
  for (const attr of attrs) {
@@ -106,9 +101,6 @@ function extractToClassNames({
106
101
  case "style":
107
102
  const styles2 = addStyles(attr.value);
108
103
  const newClassNames = concatClassName(styles2.map((x) => x.identifier).join(" "));
109
- if (shouldPrintDebug) {
110
- console.log(" classnames", newClassNames, finalClassNames);
111
- }
112
104
  const existing = finalClassNames.find((x) => x.type == "StringLiteral");
113
105
  if (existing) {
114
106
  existing.value = `${existing.value} ${newClassNames}`;
@@ -116,7 +108,7 @@ function extractToClassNames({
116
108
  finalClassNames = [...finalClassNames, t.stringLiteral(newClassNames)];
117
109
  }
118
110
  if (shouldPrintDebug) {
119
- console.log(" classnames (after)", finalClassNames.map((x) => x["value"]).join(" "));
111
+ console.log(" classnames (after)\n", logLines(finalClassNames.map((x) => x["value"]).join(" ")));
120
112
  }
121
113
  break;
122
114
  case "attr":
@@ -140,7 +132,7 @@ function extractToClassNames({
140
132
  finalAttrs.push(val);
141
133
  break;
142
134
  case "ternary":
143
- const mediaExtraction = extractMediaStyle(attr.value, jsxPath, extractor.getTamaguiConfig(), sourcePath, lastMediaImportance, shouldPrintDebug);
135
+ const mediaExtraction = extractMediaStyle(attr.value, jsxPath, extractor.getTamagui(), sourcePath, lastMediaImportance, shouldPrintDebug);
144
136
  if (mediaExtraction) {
145
137
  lastMediaImportance++;
146
138
  finalStyles = [...finalStyles, ...mediaExtraction.mediaStyles];
@@ -201,12 +193,10 @@ function extractToClassNames({
201
193
  }
202
194
  }
203
195
  });
204
- if (!optimized) {
196
+ if (!res || !res.modified) {
205
197
  return null;
206
198
  }
207
- const styles = Array.from(cssMap.values()).map((x) => {
208
- return x.css;
209
- }).join("\n").trim();
199
+ const styles = Array.from(cssMap.values()).map((x) => x.css).join("\n").trim();
210
200
  if (styles) {
211
201
  const cssQuery = threaded ? `cssData=${Buffer.from(styles).toString("base64")}` : `cssPath=${cssPath}`;
212
202
  const remReq = getRemainingRequest(loader);
@@ -226,7 +216,7 @@ function extractToClassNames({
226
216
  }
227
217
  if (shouldLogTiming && mem) {
228
218
  const memUsed = Math.round((process.memoryUsage().heapUsed - mem.heapUsed) / 1024 / 1204 * 10) / 10;
229
- console.log(` \u{1F95A} ${basename(sourcePath).padStart(40)} ${`${Date.now() - start}`.padStart(3)}ms \u05C1\xB7 ${`${optimized}`.padStart(4)} optimized \xB7 ${flattened} flattened ${memUsed > 10 ? `used ${memUsed}MB` : ""}`);
219
+ console.log(` \u{1F95A} ${basename(sourcePath).padStart(40)} ${`${Date.now() - start}`.padStart(3)}ms \u05C1\xB7 ${`${res.optimized}`.padStart(4)} optimized \xB7 ${res.flattened} flattened ${memUsed > 10 ? `used ${memUsed}MB` : ""}`);
230
220
  }
231
221
  return {
232
222
  ast,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/extractor/extractToClassNames.ts"],
4
- "sourcesContent": ["import * as path from 'path'\nimport { basename } from 'path'\nimport * as util from 'util'\n\nimport generate from '@babel/generator'\nimport * as t from '@babel/types'\nimport { getStylesAtomic } from '@tamagui/core-node'\nimport { concatClassName } from '@tamagui/helpers'\nimport invariant from 'invariant'\nimport { getRemainingRequest } from 'loader-utils'\nimport { ViewStyle } from 'react-native'\n\nimport { ClassNameObject, StyleObject, TamaguiOptions } from '../types'\nimport { babelParse } from './babelParse'\nimport { buildClassName } from './buildClassName'\nimport { Extractor } from './createExtractor'\nimport { ensureImportingConcat } from './ensureImportingConcat'\nimport { isSimpleSpread } from './extractHelpers'\nimport { extractMediaStyle } from './extractMediaStyle'\nimport { hoistClassNames } from './hoistClassNames'\n\nexport const CONCAT_CLASSNAME_IMPORT = 'concatClassName'\n\nconst mergeStyleGroups = {\n shadowOpacity: true,\n shadowRadius: true,\n shadowColor: true,\n shadowOffset: true,\n}\n\nexport function extractToClassNames({\n loader,\n extractor,\n source,\n sourcePath,\n options,\n shouldPrintDebug,\n threaded,\n cssPath,\n}: {\n loader: any\n extractor: Extractor\n source: string | Buffer\n sourcePath: string\n options: TamaguiOptions\n shouldPrintDebug: boolean\n cssPath: string\n threaded?: boolean\n}): null | {\n js: string | Buffer\n styles: string\n stylesPath?: string\n ast: t.File\n map: any // RawSourceMap from 'source-map'\n} {\n if (typeof source !== 'string') {\n throw new Error('`source` must be a string of javascript')\n }\n invariant(\n typeof sourcePath === 'string' && path.isAbsolute(sourcePath),\n '`sourcePath` must be an absolute path to a .js file'\n )\n\n const shouldLogTiming = shouldPrintDebug || options.logTimings\n const start = Date.now()\n const mem = shouldLogTiming ? process.memoryUsage() : null\n\n // Using a map for (officially supported) guaranteed insertion order\n let ast: t.File\n\n try {\n // @ts-ignore\n ast = babelParse(source)\n } catch (err) {\n console.error('babel parse error:', sourcePath)\n throw err\n }\n\n const cssMap = new Map<string, { css: string; commentTexts: string[] }>()\n const existingHoists: { [key: string]: t.Identifier } = {}\n\n let flattened = 0\n let optimized = 0\n\n extractor.parse(ast, {\n sourcePath,\n shouldPrintDebug,\n ...options,\n getFlattenedNode: ({ tag }) => tag,\n onDidFlatten() {\n flattened++\n },\n onExtractTag: ({\n attrs,\n node,\n attemptEval,\n jsxPath,\n originalNodeName,\n filePath,\n lineNumbers,\n programPath,\n }) => {\n optimized++\n\n let finalClassNames: ClassNameObject[] = []\n let finalAttrs: (t.JSXAttribute | t.JSXSpreadAttribute)[] = []\n let finalStyles: StyleObject[] = []\n\n const viewStyles = {}\n for (const attr of attrs) {\n if (attr.type === 'style') {\n Object.assign(viewStyles, attr.value)\n }\n }\n\n const ensureNeededPrevStyle = (style: ViewStyle) => {\n // ensure all group keys are merged\n const keys = Object.keys(style)\n if (!keys.some((key) => mergeStyleGroups[key])) {\n return style\n }\n for (const k in mergeStyleGroups) {\n if (k in viewStyles) {\n style[k] = style[k] ?? viewStyles[k]\n }\n }\n return style\n }\n\n const addStyles = (style: ViewStyle | null) => {\n if (!style) return []\n const styleWithPrev = ensureNeededPrevStyle(style)\n const res = getStylesAtomic(styleWithPrev)\n if (res.length) {\n finalStyles = [...finalStyles, ...res]\n }\n return res\n }\n\n // 1 to start above any :hover styles\n let lastMediaImportance = 1\n for (const attr of attrs) {\n switch (attr.type) {\n case 'style':\n const styles = addStyles(attr.value)\n const newClassNames = concatClassName(styles.map((x) => x.identifier).join(' '))\n if (shouldPrintDebug) {\n // console.log(' style', attr.value)\n console.log(' classnames', newClassNames, finalClassNames)\n }\n // prettier-ignore\n const existing = finalClassNames.find((x) => x.type == 'StringLiteral') as t.StringLiteral | null\n if (existing) {\n existing.value = `${existing.value} ${newClassNames}`\n } else {\n finalClassNames = [...finalClassNames, t.stringLiteral(newClassNames)]\n }\n if (shouldPrintDebug) {\n // prettier-ignore\n console.log(' classnames (after)', finalClassNames.map(x => x['value']).join(' '))\n }\n break\n case 'attr':\n const val = attr.value\n if (t.isJSXSpreadAttribute(val)) {\n if (isSimpleSpread(val)) {\n finalClassNames.push(\n t.logicalExpression(\n '&&',\n val.argument,\n t.memberExpression(val.argument, t.identifier('className'))\n )\n )\n }\n } else if (val.name.name === 'className') {\n const value = val.value\n if (value) {\n try {\n const evaluatedValue = attemptEval(value)\n finalClassNames.push(t.stringLiteral(evaluatedValue))\n } catch (e) {\n finalClassNames.push(value['expression'])\n }\n }\n continue\n }\n finalAttrs.push(val)\n break\n case 'ternary':\n const mediaExtraction = extractMediaStyle(\n attr.value,\n jsxPath,\n extractor.getTamaguiConfig(),\n sourcePath,\n lastMediaImportance,\n shouldPrintDebug\n )\n if (mediaExtraction) {\n lastMediaImportance++\n finalStyles = [...finalStyles, ...mediaExtraction.mediaStyles]\n finalClassNames = [\n ...finalClassNames,\n ...mediaExtraction.mediaStyles.map((x) => t.stringLiteral(x.identifier)),\n ]\n if (!mediaExtraction.ternaryWithoutMedia) {\n continue\n }\n }\n const ternary = mediaExtraction?.ternaryWithoutMedia || attr.value\n const consInfo = addStyles(ternary.consequent)\n const altInfo = addStyles(ternary.alternate)\n const cCN = consInfo.map((x) => x.identifier).join(' ')\n const aCN = altInfo.map((x) => x.identifier).join(' ')\n if (consInfo.length && altInfo.length) {\n finalClassNames.push(\n t.conditionalExpression(ternary.test, t.stringLiteral(cCN), t.stringLiteral(aCN))\n )\n } else {\n finalClassNames.push(\n t.conditionalExpression(\n ternary.test,\n t.stringLiteral(' ' + cCN),\n t.stringLiteral(' ' + aCN)\n )\n )\n }\n break\n }\n }\n\n node.attributes = finalAttrs\n\n if (finalClassNames.length) {\n // inserts the _cn variable and uses it for className\n const names = buildClassName(finalClassNames)\n const nameExpr = names ? hoistClassNames(jsxPath, existingHoists, names) : null\n let expr = nameExpr\n\n // if has some spreads, use concat helper\n if (nameExpr && !t.isIdentifier(nameExpr)) {\n ensureImportingConcat(programPath)\n const simpleSpreads = attrs.filter(\n (x) => t.isJSXSpreadAttribute(x.value) && isSimpleSpread(x.value)\n )\n expr = t.callExpression(t.identifier(CONCAT_CLASSNAME_IMPORT), [\n expr,\n ...simpleSpreads.map((val) => val.value['argument']),\n ])\n }\n\n node.attributes.push(\n t.jsxAttribute(t.jsxIdentifier('className'), t.jsxExpressionContainer(expr))\n )\n }\n\n const comment = util.format('/* %s:%s (%s) */', filePath, lineNumbers, originalNodeName)\n\n for (const { className, rules } of finalStyles) {\n if (cssMap.has(className)) {\n if (comment) {\n const val = cssMap.get(className)!\n val.commentTexts.push(comment)\n cssMap.set(className, val)\n }\n } else if (rules.length) {\n if (rules.length > 1) {\n console.log(' rules error', { rules })\n throw new Error(`Shouldn't have more than one rule`)\n }\n cssMap.set(className, {\n css: rules[0],\n commentTexts: [comment],\n })\n }\n }\n },\n })\n\n if (!optimized) {\n return null\n }\n\n const styles = Array.from(cssMap.values())\n .map((x) => {\n // remove comments\n return x.css //shouldInternalDedupe ? x.css : `${x.commentTexts.join('\\n')}\\n${x.css}`\n })\n .join('\\n')\n .trim()\n\n if (styles) {\n const cssQuery = threaded\n ? `cssData=${Buffer.from(styles).toString('base64')}`\n : `cssPath=${cssPath}`\n const remReq = getRemainingRequest(loader)\n const importPath = `${cssPath}!=!tamagui-loader?${cssQuery}!${remReq}`\n ast.program.body.unshift(t.importDeclaration([], t.stringLiteral(importPath)))\n }\n\n const result = generate(\n ast,\n {\n concise: false,\n filename: sourcePath,\n retainLines: false,\n sourceFileName: sourcePath,\n sourceMaps: true,\n },\n source\n )\n\n if (shouldPrintDebug) {\n console.log(\n '\\n -------- output code ------- \\n\\n',\n result.code\n .split('\\n')\n .filter((x) => !x.startsWith('//'))\n .join('\\n')\n )\n console.log('\\n -------- output style -------- \\n\\n', styles)\n }\n\n if (shouldLogTiming && mem) {\n // console.log(`${parseTime} / ${traverseTime} / ${generateTime}`)\n const memUsed =\n Math.round(((process.memoryUsage().heapUsed - mem.heapUsed) / 1024 / 1204) * 10) / 10\n // prettier-ignore\n console.log(` \uD83E\uDD5A ${basename(sourcePath).padStart(40)} ${`${Date.now() - start}`.padStart(3)}ms \u05C1\u00B7 ${`${optimized}`.padStart(4)} optimized \u00B7 ${flattened} flattened ${memUsed > 10 ? `used ${memUsed}MB` : ''}`)\n }\n\n return {\n ast,\n styles,\n js: result.code,\n map: result.map,\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import * as path from 'path'\nimport { basename } from 'path'\nimport * as util from 'util'\n\nimport generate from '@babel/generator'\nimport * as t from '@babel/types'\nimport { getStylesAtomic } from '@tamagui/core-node'\nimport { concatClassName } from '@tamagui/helpers'\nimport invariant from 'invariant'\nimport { getRemainingRequest } from 'loader-utils'\nimport { ViewStyle } from 'react-native'\n\nimport { ClassNameObject, StyleObject, TamaguiOptions } from '../types'\nimport { babelParse } from './babelParse'\nimport { buildClassName } from './buildClassName'\nimport { Extractor } from './createExtractor'\nimport { ensureImportingConcat } from './ensureImportingConcat'\nimport { isSimpleSpread } from './extractHelpers'\nimport { extractMediaStyle } from './extractMediaStyle'\nimport { hoistClassNames } from './hoistClassNames'\nimport { logLines } from './logLines'\n\nexport const CONCAT_CLASSNAME_IMPORT = 'concatClassName'\n\nconst mergeStyleGroups = {\n shadowOpacity: true,\n shadowRadius: true,\n shadowColor: true,\n shadowOffset: true,\n}\n\nexport function extractToClassNames({\n loader,\n extractor,\n source,\n sourcePath,\n options,\n shouldPrintDebug,\n threaded,\n cssPath,\n}: {\n loader: any\n extractor: Extractor\n source: string | Buffer\n sourcePath: string\n options: TamaguiOptions\n shouldPrintDebug: boolean\n cssPath: string\n threaded?: boolean\n}): null | {\n js: string | Buffer\n styles: string\n stylesPath?: string\n ast: t.File\n map: any // RawSourceMap from 'source-map'\n} {\n if (typeof source !== 'string') {\n throw new Error('`source` must be a string of javascript')\n }\n invariant(\n typeof sourcePath === 'string' && path.isAbsolute(sourcePath),\n '`sourcePath` must be an absolute path to a .js file'\n )\n\n const shouldLogTiming = shouldPrintDebug || options.logTimings\n const start = Date.now()\n const mem = shouldLogTiming ? process.memoryUsage() : null\n\n // Using a map for (officially supported) guaranteed insertion order\n let ast: t.File\n\n try {\n // @ts-ignore\n ast = babelParse(source)\n } catch (err) {\n console.error('babel parse error:', sourcePath)\n throw err\n }\n\n const cssMap = new Map<string, { css: string; commentTexts: string[] }>()\n const existingHoists: { [key: string]: t.Identifier } = {}\n\n const res = extractor.parse(ast, {\n sourcePath,\n shouldPrintDebug,\n ...options,\n getFlattenedNode: ({ tag }) => tag,\n onExtractTag: ({\n attrs,\n node,\n attemptEval,\n jsxPath,\n originalNodeName,\n filePath,\n lineNumbers,\n programPath,\n }) => {\n let finalClassNames: ClassNameObject[] = []\n let finalAttrs: (t.JSXAttribute | t.JSXSpreadAttribute)[] = []\n let finalStyles: StyleObject[] = []\n\n const viewStyles = {}\n for (const attr of attrs) {\n if (attr.type === 'style') {\n Object.assign(viewStyles, attr.value)\n }\n }\n\n const ensureNeededPrevStyle = (style: ViewStyle) => {\n // ensure all group keys are merged\n const keys = Object.keys(style)\n if (!keys.some((key) => mergeStyleGroups[key])) {\n return style\n }\n for (const k in mergeStyleGroups) {\n if (k in viewStyles) {\n style[k] = style[k] ?? viewStyles[k]\n }\n }\n return style\n }\n\n const addStyles = (style: ViewStyle | null) => {\n if (!style) return []\n const styleWithPrev = ensureNeededPrevStyle(style)\n const res = getStylesAtomic(styleWithPrev)\n if (res.length) {\n finalStyles = [...finalStyles, ...res]\n }\n return res\n }\n\n // 1 to start above any :hover styles\n let lastMediaImportance = 1\n for (const attr of attrs) {\n switch (attr.type) {\n case 'style':\n const styles = addStyles(attr.value)\n const newClassNames = concatClassName(styles.map((x) => x.identifier).join(' '))\n // prettier-ignore\n const existing = finalClassNames.find((x) => x.type == 'StringLiteral') as t.StringLiteral | null\n if (existing) {\n existing.value = `${existing.value} ${newClassNames}`\n } else {\n finalClassNames = [...finalClassNames, t.stringLiteral(newClassNames)]\n }\n if (shouldPrintDebug) {\n // prettier-ignore\n console.log(' classnames (after)\\n', logLines(finalClassNames.map(x => x['value']).join(' ')))\n }\n break\n case 'attr':\n const val = attr.value\n if (t.isJSXSpreadAttribute(val)) {\n if (isSimpleSpread(val)) {\n finalClassNames.push(\n t.logicalExpression(\n '&&',\n val.argument,\n t.memberExpression(val.argument, t.identifier('className'))\n )\n )\n }\n } else if (val.name.name === 'className') {\n const value = val.value\n if (value) {\n try {\n const evaluatedValue = attemptEval(value)\n finalClassNames.push(t.stringLiteral(evaluatedValue))\n } catch (e) {\n finalClassNames.push(value['expression'])\n }\n }\n continue\n }\n finalAttrs.push(val)\n break\n case 'ternary':\n const mediaExtraction = extractMediaStyle(\n attr.value,\n jsxPath,\n extractor.getTamagui(),\n sourcePath,\n lastMediaImportance,\n shouldPrintDebug\n )\n if (mediaExtraction) {\n lastMediaImportance++\n finalStyles = [...finalStyles, ...mediaExtraction.mediaStyles]\n finalClassNames = [\n ...finalClassNames,\n ...mediaExtraction.mediaStyles.map((x) => t.stringLiteral(x.identifier)),\n ]\n if (!mediaExtraction.ternaryWithoutMedia) {\n continue\n }\n }\n const ternary = mediaExtraction?.ternaryWithoutMedia || attr.value\n const consInfo = addStyles(ternary.consequent)\n const altInfo = addStyles(ternary.alternate)\n const cCN = consInfo.map((x) => x.identifier).join(' ')\n const aCN = altInfo.map((x) => x.identifier).join(' ')\n if (consInfo.length && altInfo.length) {\n finalClassNames.push(\n t.conditionalExpression(ternary.test, t.stringLiteral(cCN), t.stringLiteral(aCN))\n )\n } else {\n finalClassNames.push(\n t.conditionalExpression(\n ternary.test,\n t.stringLiteral(' ' + cCN),\n t.stringLiteral(' ' + aCN)\n )\n )\n }\n break\n }\n }\n\n node.attributes = finalAttrs\n\n if (finalClassNames.length) {\n // inserts the _cn variable and uses it for className\n const names = buildClassName(finalClassNames)\n const nameExpr = names ? hoistClassNames(jsxPath, existingHoists, names) : null\n let expr = nameExpr\n\n // if has some spreads, use concat helper\n if (nameExpr && !t.isIdentifier(nameExpr)) {\n ensureImportingConcat(programPath)\n const simpleSpreads = attrs.filter(\n (x) => t.isJSXSpreadAttribute(x.value) && isSimpleSpread(x.value)\n )\n expr = t.callExpression(t.identifier(CONCAT_CLASSNAME_IMPORT), [\n expr,\n ...simpleSpreads.map((val) => val.value['argument']),\n ])\n }\n\n node.attributes.push(\n t.jsxAttribute(t.jsxIdentifier('className'), t.jsxExpressionContainer(expr))\n )\n }\n\n const comment = util.format('/* %s:%s (%s) */', filePath, lineNumbers, originalNodeName)\n\n for (const { className, rules } of finalStyles) {\n if (cssMap.has(className)) {\n if (comment) {\n const val = cssMap.get(className)!\n val.commentTexts.push(comment)\n cssMap.set(className, val)\n }\n } else if (rules.length) {\n if (rules.length > 1) {\n console.log(' rules error', { rules })\n throw new Error(`Shouldn't have more than one rule`)\n }\n cssMap.set(className, {\n css: rules[0],\n commentTexts: [comment],\n })\n }\n }\n },\n })\n\n if (!res || !res.modified) {\n return null\n }\n\n const styles = Array.from(cssMap.values())\n .map((x) => x.css)\n .join('\\n')\n .trim()\n\n if (styles) {\n const cssQuery = threaded\n ? `cssData=${Buffer.from(styles).toString('base64')}`\n : `cssPath=${cssPath}`\n const remReq = getRemainingRequest(loader)\n const importPath = `${cssPath}!=!tamagui-loader?${cssQuery}!${remReq}`\n ast.program.body.unshift(t.importDeclaration([], t.stringLiteral(importPath)))\n }\n\n const result = generate(\n ast,\n {\n concise: false,\n filename: sourcePath,\n retainLines: false,\n sourceFileName: sourcePath,\n sourceMaps: true,\n },\n source\n )\n\n if (shouldPrintDebug) {\n console.log(\n '\\n -------- output code ------- \\n\\n',\n result.code\n .split('\\n')\n .filter((x) => !x.startsWith('//'))\n .join('\\n')\n )\n console.log('\\n -------- output style -------- \\n\\n', styles)\n }\n\n if (shouldLogTiming && mem) {\n // console.log(`${parseTime} / ${traverseTime} / ${generateTime}`)\n const memUsed =\n Math.round(((process.memoryUsage().heapUsed - mem.heapUsed) / 1024 / 1204) * 10) / 10\n // prettier-ignore\n console.log(` \uD83E\uDD5A ${basename(sourcePath).padStart(40)} ${`${Date.now() - start}`.padStart(3)}ms \u05C1\u00B7 ${`${res.optimized}`.padStart(4)} optimized \u00B7 ${res.flattened} flattened ${memUsed > 10 ? `used ${memUsed}MB` : ''}`)\n }\n\n return {\n ast,\n styles,\n js: result.code,\n map: result.map,\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,17 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+ const logLines = /* @__PURE__ */ __name((str) => {
4
+ let lines = [""];
5
+ const items = str.split(" ");
6
+ for (const item of items) {
7
+ if (item.length + lines[lines.length - 1].length > 100) {
8
+ lines.push("");
9
+ }
10
+ lines[lines.length - 1] += item + " ";
11
+ }
12
+ return lines.map((line, i) => " " + (i == 0 ? "" : " ") + line.trim()).join("\n");
13
+ }, "logLines");
14
+ export {
15
+ logLines
16
+ };
17
+ //# sourceMappingURL=logLines.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/extractor/logLines.ts"],
4
+ "sourcesContent": ["export const logLines = (str: string) => {\n let lines: string[] = ['']\n const items = str.split(' ')\n for (const item of items) {\n if (item.length + lines[lines.length - 1].length > 100) {\n lines.push('')\n }\n lines[lines.length - 1] += item + ' '\n }\n return lines.map((line, i) => ' ' + (i == 0 ? '' : ' ') + line.trim()).join('\\n')\n}\n"],
5
+ "mappings": ";;AAAO,MAAM,WAAW,wBAAC,QAAgB;AACvC,MAAI,QAAkB,CAAC;AACvB,QAAM,QAAQ,IAAI,MAAM;AACxB,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,SAAS,MAAM,MAAM,SAAS,GAAG,SAAS,KAAK;AACtD,YAAM,KAAK;AAAA;AAEb,UAAM,MAAM,SAAS,MAAM,OAAO;AAAA;AAEpC,SAAO,MAAM,IAAI,CAAC,MAAM,MAAM,gBAAiB,MAAK,IAAI,KAAK,OAAO,KAAK,QAAQ,KAAK;AAAA,GAThE;",
6
+ "names": []
7
+ }
package/dist/index.cjs CHANGED
@@ -574,6 +574,19 @@ function loadTamagui(props) {
574
574
  }
575
575
  __name(loadTamagui, "loadTamagui");
576
576
 
577
+ // src/extractor/logLines.ts
578
+ var logLines = /* @__PURE__ */ __name((str) => {
579
+ let lines = [""];
580
+ const items = str.split(" ");
581
+ for (const item of items) {
582
+ if (item.length + lines[lines.length - 1].length > 100) {
583
+ lines.push("");
584
+ }
585
+ lines[lines.length - 1] += item + " ";
586
+ }
587
+ return lines.map((line, i) => " " + (i == 0 ? "" : " ") + line.trim()).join("\n");
588
+ }, "logLines");
589
+
577
590
  // src/extractor/normalizeTernaries.ts
578
591
  var import_generator2 = __toModule(require("@babel/generator"));
579
592
  var t7 = __toModule(require("@babel/types"));
@@ -717,8 +730,9 @@ function createExtractor() {
717
730
  format: "cjs"
718
731
  });
719
732
  let loadedTamaguiConfig;
733
+ let hasLogged = false;
720
734
  return {
721
- getTamaguiConfig() {
735
+ getTamagui() {
722
736
  return loadedTamaguiConfig;
723
737
  },
724
738
  parse: (fileOrPath, _a) => {
@@ -730,7 +744,9 @@ function createExtractor() {
730
744
  sourcePath = "",
731
745
  onExtractTag,
732
746
  getFlattenedNode,
733
- onDidFlatten
747
+ disableExtraction,
748
+ disableExtractInlineMedia,
749
+ disableDebugAttr
734
750
  } = _b, props = __objRest(_b, [
735
751
  "config",
736
752
  "importsWhitelist",
@@ -739,7 +755,9 @@ function createExtractor() {
739
755
  "sourcePath",
740
756
  "onExtractTag",
741
757
  "getFlattenedNode",
742
- "onDidFlatten"
758
+ "disableExtraction",
759
+ "disableExtractInlineMedia",
760
+ "disableDebugAttr"
743
761
  ]);
744
762
  if (sourcePath === "") {
745
763
  throw new Error(`Must provide a source file name`);
@@ -753,16 +771,18 @@ function createExtractor() {
753
771
  });
754
772
  loadedTamaguiConfig = tamaguiConfig;
755
773
  const defaultTheme = tamaguiConfig.themes[Object.keys(tamaguiConfig.themes)[0]];
756
- let doesUseValidImport = false;
757
774
  const body = fileOrPath.type === "Program" ? fileOrPath.get("body") : fileOrPath.program.body;
758
- const isInternalImport = /* @__PURE__ */ __name((importStr) => isInsideTamagui(sourcePath) && importStr[0] === ".", "isInternalImport");
775
+ const isInternalImport = /* @__PURE__ */ __name((importStr) => {
776
+ return isInsideTamagui(sourcePath) && importStr[0] === ".";
777
+ }, "isInternalImport");
759
778
  const validComponents = Object.keys(components).filter((key) => {
760
779
  var _a2;
761
- return !!((_a2 = components[key]) == null ? void 0 : _a2.staticConfig);
780
+ return key[0].toUpperCase() === key[0] && !!((_a2 = components[key]) == null ? void 0 : _a2.staticConfig);
762
781
  }).reduce((obj, name) => {
763
782
  obj[name] = components[name];
764
783
  return obj;
765
784
  }, {});
785
+ let doesUseValidImport = false;
766
786
  for (const bodyPath of body) {
767
787
  if (bodyPath.type !== "ImportDeclaration")
768
788
  continue;
@@ -791,6 +811,11 @@ function createExtractor() {
791
811
  return fileOrPath.type === "File" ? (0, import_traverse.default)(fileOrPath, a) : fileOrPath.traverse(a);
792
812
  }, "callTraverse");
793
813
  let programPath;
814
+ const res = {
815
+ flattened: 0,
816
+ optimized: 0,
817
+ modified: 0
818
+ };
794
819
  callTraverse({
795
820
  Program: {
796
821
  enter(path3) {
@@ -823,8 +848,26 @@ function createExtractor() {
823
848
  if (!component || !component.staticConfig) {
824
849
  return;
825
850
  }
826
- const { staticConfig } = component;
827
851
  const originalNodeName = node.name.name;
852
+ if (shouldPrintDebug) {
853
+ console.log(`
854
+ <${originalNodeName} />`);
855
+ }
856
+ const filePath = sourcePath.replace(process.cwd(), ".");
857
+ const lineNumbers = node.loc ? node.loc.start.line + (node.loc.start.line !== node.loc.end.line ? `-${node.loc.end.line}` : "") : "";
858
+ if (shouldAddDebugProp && !disableDebugAttr) {
859
+ const preName = componentName ? `${componentName}:` : "";
860
+ res.modified++;
861
+ node.attributes.unshift(t9.jsxAttribute(t9.jsxIdentifier("data-is"), t9.stringLiteral(` ${preName}${node.name.name} ${filePath.replace("./", "")}:${lineNumbers} `)));
862
+ }
863
+ if (disableExtraction) {
864
+ if (!hasLogged) {
865
+ console.log("\u{1F95A} Tamagui disableExtraction set: no CSS or optimizations will be run");
866
+ hasLogged = true;
867
+ }
868
+ return;
869
+ }
870
+ const { staticConfig } = component;
828
871
  const isTextView = staticConfig.isText || false;
829
872
  const validStyles = (staticConfig == null ? void 0 : staticConfig.validStyles) ?? {};
830
873
  let tagName = ((_a2 = staticConfig.defaultProps) == null ? void 0 : _a2.tag) ?? (isTextView ? "span" : "div");
@@ -846,21 +889,17 @@ function createExtractor() {
846
889
  ]);
847
890
  const excludeProps = new Set(props.excludeProps ?? []);
848
891
  const isExcludedProp = /* @__PURE__ */ __name((name) => {
849
- const res = excludeProps.has(name);
850
- if (res && shouldPrintDebug)
892
+ const res2 = excludeProps.has(name);
893
+ if (res2 && shouldPrintDebug)
851
894
  console.log(` excluding ${name}`);
852
- return res;
895
+ return res2;
853
896
  }, "isExcludedProp");
854
897
  const isDeoptedProp = /* @__PURE__ */ __name((name) => {
855
- const res = deoptProps.has(name);
856
- if (res && shouldPrintDebug)
898
+ const res2 = deoptProps.has(name);
899
+ if (res2 && shouldPrintDebug)
857
900
  console.log(` deopting ${name}`);
858
- return res;
901
+ return res2;
859
902
  }, "isDeoptedProp");
860
- if (shouldPrintDebug) {
861
- console.log(`
862
- <${originalNodeName} />`);
863
- }
864
903
  const staticNamespace = getStaticBindingsForScope(traversePath.scope, importsWhitelist, sourcePath, bindingCache, shouldPrintDebug);
865
904
  const attemptEval = !evaluateVars ? evaluateAstNode : createEvaluator({
866
905
  tamaguiConfig,
@@ -933,11 +972,11 @@ function createExtractor() {
933
972
  let isFlattened = false;
934
973
  attrs = traversePath.get("openingElement").get("attributes").flatMap((path3) => {
935
974
  try {
936
- const res = evaluateAttribute(path3);
937
- if (!res) {
975
+ const res2 = evaluateAttribute(path3);
976
+ if (!res2) {
938
977
  path3.remove();
939
978
  }
940
- return res;
979
+ return res2;
941
980
  } catch (err) {
942
981
  console.log("Error extracting attribute", err.message, err.stack);
943
982
  console.log("node", path3.node);
@@ -1060,6 +1099,9 @@ function createExtractor() {
1060
1099
  return attr;
1061
1100
  }
1062
1101
  if (name[0] === "$" && t9.isJSXExpressionContainer(attribute == null ? void 0 : attribute.value)) {
1102
+ if (disableExtractInlineMedia) {
1103
+ return attr;
1104
+ }
1063
1105
  const shortname = name.slice(1);
1064
1106
  if (mediaQueryConfig[shortname]) {
1065
1107
  const expression = attribute.value.expression;
@@ -1119,7 +1161,9 @@ function createExtractor() {
1119
1161
  if (styleValue !== FAILED_EVAL) {
1120
1162
  return {
1121
1163
  type: "style",
1122
- value: { [name]: styleValue }
1164
+ value: { [name]: styleValue },
1165
+ name,
1166
+ attr: path3.node
1123
1167
  };
1124
1168
  }
1125
1169
  if (t9.isBinaryExpression(value)) {
@@ -1232,7 +1276,7 @@ function createExtractor() {
1232
1276
  }
1233
1277
  __name(evaluateAttribute, "evaluateAttribute");
1234
1278
  if (shouldPrintDebug) {
1235
- console.log(" - attrs (before): ", attrs.map(attrStr).join(", "));
1279
+ console.log(" - attrs (before):\n", logLines(attrs.map(attrStr).join(", ")));
1236
1280
  }
1237
1281
  node.attributes = attrs.filter(isAttr).map((x) => x.value);
1238
1282
  if (couldntParse) {
@@ -1246,8 +1290,6 @@ function createExtractor() {
1246
1290
  if (parentFn) {
1247
1291
  modifiedComponents.add(parentFn);
1248
1292
  }
1249
- const filePath = sourcePath.replace(process.cwd(), ".");
1250
- const lineNumbers = node.loc ? node.loc.start.line + (node.loc.start.line !== node.loc.end.line ? `-${node.loc.end.line}` : "") : "";
1251
1293
  let ternaries = [];
1252
1294
  attrs = attrs.reduce((out, cur) => {
1253
1295
  const next = attrs[attrs.indexOf(cur) + 1];
@@ -1306,17 +1348,19 @@ function createExtractor() {
1306
1348
  const shouldFlatten = !shouldDeopt && inlinePropCount === 0 && !hasSpread && staticConfig.neverFlatten !== true && (staticConfig.neverFlatten === "jsx" ? hasOnlyStringChildren : true);
1307
1349
  if (!shouldFlatten) {
1308
1350
  attrs = attrs.reduce((acc, cur) => {
1309
- var _a3;
1351
+ var _a3, _b2;
1310
1352
  if (cur.type === "style") {
1311
1353
  for (const key in cur.value) {
1312
- const shouldInsertNull = !!((_a3 = staticConfig.ensureOverriddenProp) == null ? void 0 : _a3[key]);
1354
+ const shouldEnsureOverridden = !!((_a3 = staticConfig.ensureOverriddenProp) == null ? void 0 : _a3[key]);
1313
1355
  const isSetInAttrsAlready = attrs.some((x) => x.type === "attr" && x.value.type === "JSXAttribute" && x.value.name.name === key);
1314
- const shouldInsertNullOverride = shouldInsertNull && !isSetInAttrsAlready;
1315
- if (shouldInsertNullOverride) {
1316
- acc.push({
1317
- type: "attr",
1318
- value: t9.jsxAttribute(t9.jsxIdentifier(key), t9.jsxExpressionContainer(t9.nullLiteral()))
1319
- });
1356
+ if (!isSetInAttrsAlready) {
1357
+ const isVariant = !!((_b2 = staticConfig.variants) == null ? void 0 : _b2[cur.name || ""]);
1358
+ if (isVariant || shouldEnsureOverridden) {
1359
+ acc.push({
1360
+ type: "attr",
1361
+ value: cur.attr || t9.jsxAttribute(t9.jsxIdentifier(key), t9.jsxExpressionContainer(t9.nullLiteral()))
1362
+ });
1363
+ }
1320
1364
  }
1321
1365
  }
1322
1366
  }
@@ -1325,7 +1369,7 @@ function createExtractor() {
1325
1369
  }, []);
1326
1370
  }
1327
1371
  if (shouldPrintDebug) {
1328
- console.log(" - attrs (flattened): ", attrs.map(attrStr).join(", "));
1372
+ console.log(" - attrs (flattened): \n", logLines(attrs.map(attrStr).join(", ")));
1329
1373
  }
1330
1374
  attrs = attrs.reduce((acc, cur) => {
1331
1375
  if (cur.type !== "attr" || !t9.isJSXAttribute(cur.value) || typeof cur.value.name.name !== "string") {
@@ -1343,7 +1387,7 @@ function createExtractor() {
1343
1387
  return acc;
1344
1388
  }, []);
1345
1389
  if (shouldPrintDebug) {
1346
- console.log(" - attrs (evaluated styles): ", attrs.map(attrStr).join(", "));
1390
+ console.log(" - attrs (evaluated styles): \n", logLines(attrs.map(attrStr).join(", ")));
1347
1391
  }
1348
1392
  let prev = null;
1349
1393
  attrs = attrs.reduce((acc, cur) => {
@@ -1358,7 +1402,7 @@ function createExtractor() {
1358
1402
  return acc;
1359
1403
  }, []);
1360
1404
  if (shouldPrintDebug) {
1361
- console.log(" - attrs (combined \u{1F500}): ", attrs.map(attrStr).join(", "));
1405
+ console.log(" - attrs (combined \u{1F500}): \n", logLines(attrs.map(attrStr).join(", ")));
1362
1406
  }
1363
1407
  const getStyles = /* @__PURE__ */ __name((props2) => {
1364
1408
  if (!props2)
@@ -1372,9 +1416,10 @@ function createExtractor() {
1372
1416
  const out = postProcessStyles(props2, staticConfig, defaultTheme);
1373
1417
  const next = (out == null ? void 0 : out.style) ?? props2;
1374
1418
  if (shouldPrintDebug) {
1375
- console.log(" >> getStyles: ", objToStr(props2), "==>>", objToStr(next));
1376
- console.log(" >> style: ", objToStr(out.style));
1377
- console.log(" >> viewp: ", objToStr(out.viewProps));
1419
+ console.log(" getStyles props >>\n", logLines(objToStr(props2)));
1420
+ console.log(" getStyles next >>\n", logLines(objToStr(next)));
1421
+ console.log(" getStyles style >>\n", logLines(objToStr(out.style)));
1422
+ console.log(" getStyles viewp >>\n", logLines(objToStr(out.viewProps)));
1378
1423
  }
1379
1424
  if (staticConfig.validStyles) {
1380
1425
  for (const key in next) {
@@ -1385,9 +1430,6 @@ function createExtractor() {
1385
1430
  }
1386
1431
  return next;
1387
1432
  }, "getStyles");
1388
- if (shouldPrintDebug) {
1389
- console.log(" staticConfig.defaultProps", staticConfig.defaultProps);
1390
- }
1391
1433
  const completeStylesProcessed = getStyles(__spreadValues(__spreadValues({}, staticConfig.defaultProps), completeStaticProps));
1392
1434
  const stylesToAddToInitialGroup = (0, import_lodash.difference)(Object.keys(completeStylesProcessed), Object.keys(completeStaticProps));
1393
1435
  if (stylesToAddToInitialGroup.length) {
@@ -1404,8 +1446,8 @@ function createExtractor() {
1404
1446
  }
1405
1447
  }
1406
1448
  if (shouldPrintDebug) {
1407
- console.log(" completeStaticProps", objToStr(completeStaticProps));
1408
- console.log(" completeStylesProcessed", objToStr(completeStylesProcessed));
1449
+ console.log(" completeStaticProps\n", logLines(objToStr(completeStaticProps)));
1450
+ console.log(" completeStylesProcessed\n", logLines(objToStr(completeStylesProcessed)));
1409
1451
  }
1410
1452
  for (const attr of attrs) {
1411
1453
  try {
@@ -1440,14 +1482,7 @@ function createExtractor() {
1440
1482
  }
1441
1483
  }
1442
1484
  if (shouldPrintDebug) {
1443
- console.log(" - attrs (after): ", attrs.map(attrStr).join(", "));
1444
- }
1445
- if (shouldAddDebugProp) {
1446
- const preName = componentName ? `${componentName}:` : "";
1447
- attrs.unshift({
1448
- type: "attr",
1449
- value: t9.jsxAttribute(t9.jsxIdentifier("data-is"), t9.stringLiteral(` ${preName}${node.name.name} ${filePath.replace("./", "")}:${lineNumbers} `))
1450
- });
1485
+ console.log(" - attrs (after):\n", logLines(attrs.map(attrStr).join(", ")));
1451
1486
  }
1452
1487
  if (shouldFlatten) {
1453
1488
  if (shouldPrintDebug) {
@@ -1455,15 +1490,16 @@ function createExtractor() {
1455
1490
  }
1456
1491
  isFlattened = true;
1457
1492
  node.name.name = flatNode;
1458
- onDidFlatten == null ? void 0 : onDidFlatten();
1493
+ res.flattened++;
1459
1494
  if (closingElement) {
1460
1495
  closingElement.name.name = flatNode;
1461
1496
  }
1462
1497
  }
1463
1498
  if (shouldPrintDebug) {
1464
1499
  console.log(" [\u274A] inline props ", inlinePropCount, shouldDeopt ? " deopted" : "", hasSpread ? " spread" : "", "!flatten", staticConfig.neverFlatten);
1465
- console.log(" - attrs (end): ", attrs.map(attrStr).join(", "));
1500
+ console.log(" - attrs (end):\n", logLines(attrs.map(attrStr).join(", ")));
1466
1501
  }
1502
+ res.optimized++;
1467
1503
  onExtractTag({
1468
1504
  attrs,
1469
1505
  node,
@@ -1486,6 +1522,7 @@ function createExtractor() {
1486
1522
  removeUnusedHooks(comp, shouldPrintDebug);
1487
1523
  }
1488
1524
  }
1525
+ return res;
1489
1526
  }
1490
1527
  };
1491
1528
  }
@@ -1803,16 +1840,11 @@ function extractToClassNames({
1803
1840
  }
1804
1841
  const cssMap = new Map();
1805
1842
  const existingHoists = {};
1806
- let flattened = 0;
1807
- let optimized = 0;
1808
- extractor.parse(ast, __spreadProps(__spreadValues({
1843
+ const res = extractor.parse(ast, __spreadProps(__spreadValues({
1809
1844
  sourcePath,
1810
1845
  shouldPrintDebug
1811
1846
  }, options), {
1812
1847
  getFlattenedNode: ({ tag }) => tag,
1813
- onDidFlatten() {
1814
- flattened++;
1815
- },
1816
1848
  onExtractTag: ({
1817
1849
  attrs,
1818
1850
  node,
@@ -1823,7 +1855,6 @@ function extractToClassNames({
1823
1855
  lineNumbers,
1824
1856
  programPath
1825
1857
  }) => {
1826
- optimized++;
1827
1858
  let finalClassNames = [];
1828
1859
  let finalAttrs = [];
1829
1860
  let finalStyles = [];
@@ -1849,11 +1880,11 @@ function extractToClassNames({
1849
1880
  if (!style)
1850
1881
  return [];
1851
1882
  const styleWithPrev = ensureNeededPrevStyle(style);
1852
- const res = (0, import_core_node3.getStylesAtomic)(styleWithPrev);
1853
- if (res.length) {
1854
- finalStyles = [...finalStyles, ...res];
1883
+ const res2 = (0, import_core_node3.getStylesAtomic)(styleWithPrev);
1884
+ if (res2.length) {
1885
+ finalStyles = [...finalStyles, ...res2];
1855
1886
  }
1856
- return res;
1887
+ return res2;
1857
1888
  }, "addStyles");
1858
1889
  let lastMediaImportance = 1;
1859
1890
  for (const attr of attrs) {
@@ -1861,9 +1892,6 @@ function extractToClassNames({
1861
1892
  case "style":
1862
1893
  const styles2 = addStyles(attr.value);
1863
1894
  const newClassNames = (0, import_helpers2.concatClassName)(styles2.map((x) => x.identifier).join(" "));
1864
- if (shouldPrintDebug) {
1865
- console.log(" classnames", newClassNames, finalClassNames);
1866
- }
1867
1895
  const existing = finalClassNames.find((x) => x.type == "StringLiteral");
1868
1896
  if (existing) {
1869
1897
  existing.value = `${existing.value} ${newClassNames}`;
@@ -1871,7 +1899,7 @@ function extractToClassNames({
1871
1899
  finalClassNames = [...finalClassNames, t14.stringLiteral(newClassNames)];
1872
1900
  }
1873
1901
  if (shouldPrintDebug) {
1874
- console.log(" classnames (after)", finalClassNames.map((x) => x["value"]).join(" "));
1902
+ console.log(" classnames (after)\n", logLines(finalClassNames.map((x) => x["value"]).join(" ")));
1875
1903
  }
1876
1904
  break;
1877
1905
  case "attr":
@@ -1895,7 +1923,7 @@ function extractToClassNames({
1895
1923
  finalAttrs.push(val);
1896
1924
  break;
1897
1925
  case "ternary":
1898
- const mediaExtraction = extractMediaStyle(attr.value, jsxPath, extractor.getTamaguiConfig(), sourcePath, lastMediaImportance, shouldPrintDebug);
1926
+ const mediaExtraction = extractMediaStyle(attr.value, jsxPath, extractor.getTamagui(), sourcePath, lastMediaImportance, shouldPrintDebug);
1899
1927
  if (mediaExtraction) {
1900
1928
  lastMediaImportance++;
1901
1929
  finalStyles = [...finalStyles, ...mediaExtraction.mediaStyles];
@@ -1956,12 +1984,10 @@ function extractToClassNames({
1956
1984
  }
1957
1985
  }
1958
1986
  }));
1959
- if (!optimized) {
1987
+ if (!res || !res.modified) {
1960
1988
  return null;
1961
1989
  }
1962
- const styles = Array.from(cssMap.values()).map((x) => {
1963
- return x.css;
1964
- }).join("\n").trim();
1990
+ const styles = Array.from(cssMap.values()).map((x) => x.css).join("\n").trim();
1965
1991
  if (styles) {
1966
1992
  const cssQuery = threaded ? `cssData=${Buffer.from(styles).toString("base64")}` : `cssPath=${cssPath}`;
1967
1993
  const remReq = (0, import_loader_utils.getRemainingRequest)(loader);
@@ -1981,7 +2007,7 @@ function extractToClassNames({
1981
2007
  }
1982
2008
  if (shouldLogTiming && mem) {
1983
2009
  const memUsed = Math.round((process.memoryUsage().heapUsed - mem.heapUsed) / 1024 / 1204 * 10) / 10;
1984
- console.log(` \u{1F95A} ${(0, import_path3.basename)(sourcePath).padStart(40)} ${`${Date.now() - start}`.padStart(3)}ms \u05C1\xB7 ${`${optimized}`.padStart(4)} optimized \xB7 ${flattened} flattened ${memUsed > 10 ? `used ${memUsed}MB` : ""}`);
2010
+ console.log(` \u{1F95A} ${(0, import_path3.basename)(sourcePath).padStart(40)} ${`${Date.now() - start}`.padStart(3)}ms \u05C1\xB7 ${`${res.optimized}`.padStart(4)} optimized \xB7 ${res.flattened} flattened ${memUsed > 10 ? `used ${memUsed}MB` : ""}`);
1985
2011
  }
1986
2012
  return {
1987
2013
  ast,
@@ -1997,8 +2023,24 @@ var fs = __toModule(require("fs"));
1997
2023
  var import_path4 = __toModule(require("path"));
1998
2024
  function patchReactNativeWeb() {
1999
2025
  const rootDir = require.resolve("react-native-web").replace(/\/dist.*/, "");
2000
- fs.writeFileSync(import_path4.default.join(rootDir, "dist", "tamagui-exports.js"), moduleExports);
2001
- fs.writeFileSync(import_path4.default.join(rootDir, "dist", "cjs", "tamagui-exports.js"), cjsExports);
2026
+ const modulePath = import_path4.default.join(rootDir, "dist", "tamagui-exports.js");
2027
+ const cjsPath = import_path4.default.join(rootDir, "dist", "cjs", "tamagui-exports.js");
2028
+ const isEqual = (() => {
2029
+ let res = false;
2030
+ try {
2031
+ res = fs.readFileSync(modulePath, "utf-8") === moduleExports && fs.readFileSync(cjsPath, "utf-8") == cjsExports;
2032
+ } catch {
2033
+ res = false;
2034
+ }
2035
+ return res;
2036
+ })();
2037
+ if (!isEqual) {
2038
+ console.log("\u{1F95A} Tamagui patching react-native-web to share atomic styling primitives");
2039
+ console.log(" > adding", modulePath);
2040
+ console.log(" > adding", cjsPath);
2041
+ fs.writeFileSync(modulePath, moduleExports);
2042
+ fs.writeFileSync(cjsPath, cjsExports);
2043
+ }
2002
2044
  const moduleEntry = import_path4.default.join(rootDir, "dist", "index.js");
2003
2045
  const moduleEntrySrc = fs.readFileSync(moduleEntry, "utf-8");
2004
2046
  if (!moduleEntrySrc.includes("// tamagui-patch-v4")) {
@@ -2019,7 +2061,6 @@ export const TamaguiExports = TExports
2019
2061
  exports.TamaguiExports = _interopRequireDefault(require("./tamagui-exports"));
2020
2062
  // tamagui-patch-end
2021
2063
  `);
2022
- console.log(`Tamagui patched react-native-web`);
2023
2064
  }
2024
2065
  }
2025
2066
  __name(patchReactNativeWeb, "patchReactNativeWeb");