@hanzogui/static 3.0.6 → 4.3.1

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 (67) hide show
  1. package/dist/check-dep-versions.cjs +201 -96
  2. package/dist/checkDeps.cjs +163 -92
  3. package/dist/constants.cjs +32 -30
  4. package/dist/exports.cjs +15 -13
  5. package/dist/extractor/accessSafe.cjs +25 -23
  6. package/dist/extractor/babelParse.cjs +30 -28
  7. package/dist/extractor/buildClassName.cjs +59 -35
  8. package/dist/extractor/bundle.cjs +159 -104
  9. package/dist/extractor/bundleConfig.cjs +463 -263
  10. package/dist/extractor/concatClassName.cjs +41 -29
  11. package/dist/extractor/createEvaluator.cjs +54 -41
  12. package/dist/extractor/createExtractor.cjs +1338 -661
  13. package/dist/extractor/createLogger.cjs +30 -25
  14. package/dist/extractor/detectModuleFormat.cjs +22 -16
  15. package/dist/extractor/ensureImportingConcat.cjs +31 -25
  16. package/dist/extractor/errors.cjs +12 -10
  17. package/dist/extractor/esbuildAliasPlugin.cjs +28 -16
  18. package/dist/extractor/esbuildTsconfigPaths.cjs +58 -36
  19. package/dist/extractor/evaluateAstNode.cjs +104 -59
  20. package/dist/extractor/extractHelpers.cjs +130 -67
  21. package/dist/extractor/extractMediaStyle.cjs +110 -69
  22. package/dist/extractor/extractToClassNames.cjs +336 -230
  23. package/dist/extractor/extractToNative.cjs +244 -149
  24. package/dist/extractor/findTopmostFunction.cjs +22 -13
  25. package/dist/extractor/generatedUid.cjs +39 -28
  26. package/dist/extractor/getGuiConfigPathFromOptionsConfig.cjs +20 -14
  27. package/dist/extractor/getPrefixLogs.cjs +12 -10
  28. package/dist/extractor/getPropValueFromAttributes.cjs +52 -34
  29. package/dist/extractor/getSourceModule.cjs +73 -37
  30. package/dist/extractor/getStaticBindingsForScope.cjs +131 -68
  31. package/dist/extractor/hoistClassNames.cjs +46 -32
  32. package/dist/extractor/literalToAst.cjs +67 -42
  33. package/dist/extractor/loadFile.cjs +9 -3
  34. package/dist/extractor/loadGui.cjs +198 -109
  35. package/dist/extractor/logLines.cjs +27 -19
  36. package/dist/extractor/normalizeTernaries.cjs +66 -44
  37. package/dist/extractor/propsToFontFamilyCache.cjs +15 -11
  38. package/dist/extractor/regenerateConfig.cjs +109 -81
  39. package/dist/extractor/removeUnusedHooks.cjs +73 -41
  40. package/dist/extractor/timer.cjs +23 -14
  41. package/dist/extractor/validHTMLAttributes.cjs +61 -59
  42. package/dist/extractor/watchGuiConfig.cjs +35 -23
  43. package/dist/getPragmaOptions.cjs +34 -19
  44. package/dist/helpers/memoize.cjs +24 -16
  45. package/dist/helpers/requireGuiCore.cjs +22 -15
  46. package/dist/index.cjs +26 -24
  47. package/dist/registerRequire.cjs +132 -77
  48. package/dist/server.cjs +35 -28
  49. package/dist/types.cjs +7 -5
  50. package/dist/worker.cjs +62 -40
  51. package/package.json +2 -2
  52. package/src/checkDeps.ts +1 -1
  53. package/src/extractor/bundle.ts +1 -1
  54. package/src/extractor/bundleConfig.ts +5 -5
  55. package/src/extractor/createExtractor.ts +28 -13
  56. package/src/extractor/createLogger.ts +1 -3
  57. package/src/extractor/extractToNative.ts +35 -9
  58. package/src/extractor/loadGui.ts +4 -4
  59. package/src/extractor/regenerateConfig.ts +2 -2
  60. package/src/getPragmaOptions.ts +2 -2
  61. package/src/helpers/requireGuiCore.ts +6 -6
  62. package/src/registerRequire.ts +4 -4
  63. package/src/worker.ts +1 -1
  64. package/types/extractor/createExtractor.d.ts.map +1 -1
  65. package/types/extractor/createLogger.d.ts.map +1 -1
  66. package/types/extractor/extractToNative.d.ts.map +1 -1
  67. package/types/worker.d.ts +1 -1
package/dist/server.cjs CHANGED
@@ -2,33 +2,35 @@ var __create = Object.create;
2
2
  var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf,
6
- __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
7
  var __export = (target, all) => {
8
- for (var name in all) __defProp(target, name, {
9
- get: all[name],
10
- enumerable: !0
11
- });
12
- },
13
- __copyProps = (to, from, except, desc) => {
14
- if (from && typeof from == "object" || typeof from == "function") for (let key of __getOwnPropNames(from)) !__hasOwnProp.call(to, key) && key !== except && __defProp(to, key, {
8
+ for (var name in all) __defProp(target, name, {
9
+ get: all[name],
10
+ enumerable: true
11
+ });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
15
16
  get: () => from[key],
16
17
  enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
17
18
  });
18
- return to;
19
- };
19
+ }
20
+ return to;
21
+ };
20
22
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
26
- value: mod,
27
- enumerable: !0
28
- }) : target, mod)),
29
- __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
30
- value: !0
31
- }), mod);
23
+ // If the importer is in node compatibility mode or this is not an ESM
24
+ // file that has been converted to a CommonJS file using a Babel-
25
+ // compatible transform (i.e. "__esModule" has not been set), then set
26
+ // "default" to the CommonJS "module.exports" for node compatibility.
27
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
28
+ value: mod,
29
+ enumerable: true
30
+ }) : target, mod));
31
+ var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
32
+ value: true
33
+ }), mod);
32
34
  var server_exports = {};
33
35
  __export(server_exports, {
34
36
  startServer: () => startServer
@@ -36,14 +38,17 @@ __export(server_exports, {
36
38
  module.exports = __toCommonJS(server_exports);
37
39
  var import_node_net = __toESM(require("node:net"));
38
40
  async function startServer(options) {
39
- const port = await getAvailablePort(),
40
- server = import_node_net.default.createServer();
41
- server.unref(), await new Promise((resolve, reject) => {
42
- server.on("error", reject), server.on("connection", conn => {
41
+ const port = await getAvailablePort();
42
+ const server = import_node_net.default.createServer();
43
+ server.unref();
44
+ await new Promise((resolve, reject) => {
45
+ server.on("error", reject);
46
+ server.on("connection", conn => {
43
47
  conn.on("data", data => {
44
48
  console.info("got", data.toString());
45
49
  });
46
- }), server.listen({
50
+ });
51
+ server.listen({
47
52
  port
48
53
  }, () => {
49
54
  const {
@@ -61,7 +66,9 @@ async function getAvailablePort(port = 8089) {
61
66
  function checkAvailablePort(port) {
62
67
  return new Promise((resolve, reject) => {
63
68
  const server = import_node_net.default.createServer();
64
- server.unref(), server.on("error", reject), server.listen({
69
+ server.unref();
70
+ server.on("error", reject);
71
+ server.listen({
65
72
  port
66
73
  }, () => {
67
74
  const {
package/dist/types.cjs CHANGED
@@ -3,14 +3,16 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
4
4
  var __hasOwnProp = Object.prototype.hasOwnProperty;
5
5
  var __copyProps = (to, from, except, desc) => {
6
- if (from && typeof from == "object" || typeof from == "function") for (let key of __getOwnPropNames(from)) !__hasOwnProp.call(to, key) && key !== except && __defProp(to, key, {
7
- get: () => from[key],
8
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
9
- });
6
+ if (from && typeof from === "object" || typeof from === "function") {
7
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
8
+ get: () => from[key],
9
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
10
+ });
11
+ }
10
12
  return to;
11
13
  };
12
14
  var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
13
- value: !0
15
+ value: true
14
16
  }), mod);
15
17
  var types_exports = {};
16
18
  module.exports = __toCommonJS(types_exports);
package/dist/worker.cjs CHANGED
@@ -3,20 +3,22 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
4
4
  var __hasOwnProp = Object.prototype.hasOwnProperty;
5
5
  var __export = (target, all) => {
6
- for (var name in all) __defProp(target, name, {
7
- get: all[name],
8
- enumerable: !0
9
- });
10
- },
11
- __copyProps = (to, from, except, desc) => {
12
- if (from && typeof from == "object" || typeof from == "function") for (let key of __getOwnPropNames(from)) !__hasOwnProp.call(to, key) && key !== except && __defProp(to, key, {
6
+ for (var name in all) __defProp(target, name, {
7
+ get: all[name],
8
+ enumerable: true
9
+ });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
14
  get: () => from[key],
14
15
  enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
16
  });
16
- return to;
17
- };
17
+ }
18
+ return to;
19
+ };
18
20
  var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
19
- value: !0
21
+ value: true
20
22
  }), mod);
21
23
  var worker_exports = {};
22
24
  __export(worker_exports, {
@@ -24,41 +26,52 @@ __export(worker_exports, {
24
26
  runTask: () => runTask
25
27
  });
26
28
  module.exports = __toCommonJS(worker_exports);
27
- var import_createExtractor = require("./extractor/createExtractor.cjs"),
28
- import_extractToClassNames = require("./extractor/extractToClassNames.cjs"),
29
- import_extractToNative = require("./extractor/extractToNative.cjs");
30
- let webExtractor = null,
31
- nativeExtractor = null;
29
+ var import_createExtractor = require("./extractor/createExtractor.cjs");
30
+ var import_extractToClassNames = require("./extractor/extractToClassNames.cjs");
31
+ var import_extractToNative = require("./extractor/extractToNative.cjs");
32
+ let webExtractor = null;
33
+ let nativeExtractor = null;
32
34
  function getWebExtractor() {
33
- return webExtractor || (webExtractor = (0, import_createExtractor.createExtractor)({
34
- platform: "web"
35
- })), webExtractor;
35
+ if (!webExtractor) {
36
+ webExtractor = (0, import_createExtractor.createExtractor)({
37
+ platform: "web"
38
+ });
39
+ }
40
+ return webExtractor;
36
41
  }
37
42
  function getNativeExtractor() {
38
- return nativeExtractor || (nativeExtractor = (0, import_createExtractor.createExtractor)({
39
- platform: "native"
40
- })), nativeExtractor;
43
+ if (!nativeExtractor) {
44
+ nativeExtractor = (0, import_createExtractor.createExtractor)({
45
+ platform: "native"
46
+ });
47
+ }
48
+ return nativeExtractor;
41
49
  }
42
50
  const configCache = /* @__PURE__ */new Map();
43
51
  async function runTask(task) {
44
52
  try {
45
53
  if (task.type === "extractToClassNames") {
46
- if (!(task.options.disableExtraction && task.options.disableDebugAttr) && !task.options._disableLoadGui) {
54
+ const isFullyDisabled = task.options.disableExtraction && task.options.disableDebugAttr;
55
+ if (!isFullyDisabled && !task.options["_disableLoadGui"]) {
47
56
  const cacheKey = JSON.stringify({
48
57
  config: task.options.config,
49
58
  components: task.options.components
50
59
  });
51
- configCache.has(cacheKey) || configCache.set(cacheKey, getWebExtractor().loadGui(task.options)), await configCache.get(cacheKey);
60
+ if (!configCache.has(cacheKey)) {
61
+ configCache.set(cacheKey, getWebExtractor().loadGui(task.options));
62
+ }
63
+ await configCache.get(cacheKey);
52
64
  }
65
+ const result = await (0, import_extractToClassNames.extractToClassNames)({
66
+ extractor: getWebExtractor(),
67
+ source: task.source,
68
+ sourcePath: task.sourcePath,
69
+ options: task.options,
70
+ shouldPrintDebug: task.shouldPrintDebug
71
+ });
53
72
  return {
54
- success: !0,
55
- data: await (0, import_extractToClassNames.extractToClassNames)({
56
- extractor: getWebExtractor(),
57
- source: task.source,
58
- sourcePath: task.sourcePath,
59
- options: task.options,
60
- shouldPrintDebug: task.shouldPrintDebug
61
- })
73
+ success: true,
74
+ data: result
62
75
  };
63
76
  }
64
77
  if (task.type === "extractToNative") {
@@ -66,21 +79,30 @@ async function runTask(task) {
66
79
  config: task.options.config,
67
80
  components: task.options.components
68
81
  });
69
- return configCache.has(cacheKey) || configCache.set(cacheKey, getNativeExtractor().loadGui(task.options)), await configCache.get(cacheKey), {
70
- success: !0,
71
- data: (0, import_extractToNative.extractToNative)(task.sourceFileName, task.sourceCode, task.options)
82
+ if (!configCache.has(cacheKey)) {
83
+ configCache.set(cacheKey, getNativeExtractor().loadGui(task.options));
84
+ }
85
+ await configCache.get(cacheKey);
86
+ const result = (0, import_extractToNative.extractToNative)(task.sourceFileName, task.sourceCode, task.options);
87
+ return {
88
+ success: true,
89
+ data: result
90
+ };
91
+ }
92
+ if (task.type === "clearCache") {
93
+ configCache.clear();
94
+ return {
95
+ success: true,
96
+ data: null
72
97
  };
73
98
  }
74
- return task.type === "clearCache" ? (configCache.clear(), {
75
- success: !0,
76
- data: null
77
- }) : {
78
- success: !1,
99
+ return {
100
+ success: false,
79
101
  error: `Unknown task type: ${task.type}`
80
102
  };
81
103
  } catch (error) {
82
104
  return {
83
- success: !1,
105
+ success: false,
84
106
  error: error instanceof Error ? error.message : String(error),
85
107
  stack: error instanceof Error ? error.stack : void 0
86
108
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hanzogui/static",
3
- "version": "3.0.6",
3
+ "version": "4.3.1",
4
4
  "gitHead": "a49cc7ea6b93ba384e77a4880ae48ac4a5635c14",
5
5
  "license": "MIT",
6
6
  "source": "src/index.ts",
@@ -53,7 +53,7 @@
53
53
  "@hanzogui/cli-color": "3.0.6",
54
54
  "@hanzogui/config-default": "3.0.6",
55
55
  "@hanzogui/core": "3.0.6",
56
- "@hanzogui/fake-react-native": "3.0.6",
56
+ "@hanzogui/fake-react-native": "3.0.7",
57
57
  "@hanzogui/generate-themes": "3.0.6",
58
58
  "@hanzogui/helpers": "3.0.6",
59
59
  "@hanzogui/helpers-node": "3.0.6",
package/src/checkDeps.ts CHANGED
@@ -334,7 +334,7 @@ function checkConfigExists(root: string): string {
334
334
  'No gui.config file found.',
335
335
  '',
336
336
  'Gui requires a config file (e.g. gui.config.ts) that calls createGui().',
337
- 'Without it, components will throw "Can\'t find Hanzo GUI configuration" at runtime.',
337
+ 'Without it, components will throw "Can\'t find GUI configuration" at runtime.',
338
338
  '',
339
339
  'See: https://gui.hanzo.ai/docs/core/configuration',
340
340
  ].join('\n')
@@ -86,7 +86,7 @@ function getESBuildConfig(
86
86
  allowOverwrite: true,
87
87
  keepNames: true,
88
88
  resolveExtensions: [
89
- ...(process.env.HANZO_GUI_TARGET === 'web'
89
+ ...(process.env.GUI_TARGET === 'web'
90
90
  ? ['.web.tsx', '.web.ts', '.web.jsx', '.web.js']
91
91
  : ['.native.tsx', '.native.ts', '.native.jsx', '.native.js']),
92
92
  '.tsx',
@@ -459,7 +459,7 @@ export async function bundleConfig(props: GuiOptions) {
459
459
  component.moduleName
460
460
 
461
461
  if (!component.moduleName) {
462
- if (process.env.DEBUG?.includes('@hanzo/gui') || process.env.IS_HANZO_GUI_DEV) {
462
+ if (process.env.DEBUG?.includes('@hanzo/gui') || process.env.IS_GUI_DEV) {
463
463
  console.warn(
464
464
  `⚠️ no module name found: ${component.moduleName} ${JSON.stringify(
465
465
  baseComponents
@@ -673,7 +673,7 @@ export async function loadComponentsInner(
673
673
  try {
674
674
  loaded = await attemptLoad({ forceExports: false })
675
675
  } catch (err2) {
676
- if (process.env.HANZO_GUI_ENABLE_WARN_DYNAMIC_LOAD) {
676
+ if (process.env.GUI_ENABLE_WARN_DYNAMIC_LOAD) {
677
677
  console.info(
678
678
  `\nGui attempted but failed to dynamically optimize components in:\n ${name}\n`
679
679
  )
@@ -824,7 +824,7 @@ export function loadComponentsInnerSync(
824
824
  try {
825
825
  return attemptLoad({ forceExports: false })
826
826
  } catch (err) {
827
- if (process.env.HANZO_GUI_ENABLE_WARN_DYNAMIC_LOAD) {
827
+ if (process.env.GUI_ENABLE_WARN_DYNAMIC_LOAD) {
828
828
  console.info(
829
829
  `\nGui attempted but failed to dynamically optimize components in:\n ${name}\n`
830
830
  )
@@ -882,9 +882,9 @@ function getComponentStaticConfigByName(name: string, exported: any) {
882
882
  }
883
883
  }
884
884
  } catch (err) {
885
- if (process.env.HANZO_GUI_ENABLE_WARN_DYNAMIC_LOAD) {
885
+ if (process.env.GUI_ENABLE_WARN_DYNAMIC_LOAD) {
886
886
  console.error(
887
- `Gui failed getting components from ${name} (Disable error by setting environment variable HANZO_GUI_ENABLE_WARN_DYNAMIC_LOAD=1)`
887
+ `Gui failed getting components from ${name} (Disable error by setting environment variable GUI_ENABLE_WARN_DYNAMIC_LOAD=1)`
888
888
  )
889
889
  console.error(err)
890
890
  }
@@ -59,6 +59,11 @@ const UNTOUCHED_PROPS = {
59
59
  className: true,
60
60
  }
61
61
 
62
+ // Platform variants that can't be resolved at compile time on native builds.
63
+ // Defined at module level (not inside the loop) to avoid repeated Set allocations during compilation.
64
+ // (requires runtime Platform.OS + Platform.isTV checks via react-native-tvos)
65
+ const nativeOnlyPlatforms = new Set(['android', 'ios', 'tv', 'androidtv', 'tvos'])
66
+
62
67
  const createTernary = (x: Ternary) => x
63
68
 
64
69
  export type Extractor = ReturnType<typeof createExtractor>
@@ -74,10 +79,6 @@ function isFullyDisabled(props: GuiOptions) {
74
79
  export function createExtractor(
75
80
  { logger = console, platform = 'web' }: ExtractorOptions = { logger: console }
76
81
  ) {
77
- if (!process.env.HANZO_GUI_TARGET) {
78
- throw new Error('Please set process.env.HANZO_GUI_TARGET to either "web" or "native"')
79
- }
80
-
81
82
  const INLINE_EXTRACTABLE = {
82
83
  ref: 'ref',
83
84
  key: 'key',
@@ -125,7 +126,7 @@ export function createExtractor(
125
126
  } as const
126
127
 
127
128
  const styleProps: SplitStyleProps = {
128
- resolveValues: process.env.HANZO_GUI_TARGET === 'native' ? 'value' : 'variable',
129
+ resolveValues: platform === 'native' ? 'value' : 'variable',
129
130
  noClass: false,
130
131
  isAnimated: false,
131
132
  }
@@ -133,7 +134,7 @@ export function createExtractor(
133
134
  const shouldAddDebugProp =
134
135
  // really basic disable this for next.js because it messes with ssr
135
136
  !process.env.npm_package_dependencies_next &&
136
- process.env.HANZO_GUI_TARGET !== 'native' &&
137
+ platform !== 'native' &&
137
138
  process.env.IDENTIFY_TAGS !== 'false' &&
138
139
  (process.env.NODE_ENV === 'development' || process.env.IDENTIFY_TAGS)
139
140
 
@@ -400,7 +401,7 @@ export function createExtractor(
400
401
  console.error(
401
402
  `⛔️ Error: Missing "themes" in your gui.config file:
402
403
 
403
- You may not need the compiler! Remember you can run Hanzo GUI with no configuration at all.
404
+ You may not need the compiler! Remember you can run GUI with no configuration at all.
404
405
 
405
406
  You may have not "export default" your config (you can also "export const config").
406
407
 
@@ -442,7 +443,7 @@ export function createExtractor(
442
443
  if (!isFullyDisabled(options)) {
443
444
  if (Object.keys(components || []).length === 0) {
444
445
  console.warn(
445
- `Warning: Hanzo GUI didn't find any valid components (DEBUG=hanzo-gui for more)`
446
+ `Warning: GUI didn't find any valid components (DEBUG=hanzo-gui for more)`
446
447
  )
447
448
  if (process.env.DEBUG === '@hanzo/gui') {
448
449
  console.info(`components`, Object.keys(components || []), components)
@@ -683,7 +684,7 @@ export function createExtractor(
683
684
  if (foundNames) {
684
685
  colorLog(
685
686
  Color.FgYellow,
686
- ` | Hanzo GUI found dynamic components: ${foundNames}`
687
+ ` | GUI found dynamic components: ${foundNames}`
687
688
  )
688
689
  }
689
690
  }
@@ -970,7 +971,7 @@ export function createExtractor(
970
971
  getValidComponent(propsWithFileInfo, moduleName, node.name.name)
971
972
  if (!component || !component.staticConfig) {
972
973
  if (shouldPrintDebug) {
973
- logger.info(`\n - No Hanzo GUI conf for: ${node.name.name}\n`)
974
+ logger.info(`\n - No GUI conf for: ${node.name.name}\n`)
974
975
  }
975
976
  return
976
977
  }
@@ -1510,7 +1511,7 @@ export function createExtractor(
1510
1511
  return attr
1511
1512
  }
1512
1513
 
1513
- // $platform-web, $platform-native, $platform-ios, $platform-android
1514
+ // $platform-web, $platform-native, $platform-ios, $platform-android, $platform-tv, $platform-androidtv, $platform-tvos
1514
1515
  if (name.startsWith('$platform-')) {
1515
1516
  const platformName = name.slice(10) // remove '$platform-'
1516
1517
  const isMatchingPlatform =
@@ -1532,6 +1533,20 @@ export function createExtractor(
1532
1533
  attr: path.node,
1533
1534
  }))
1534
1535
  } else {
1536
+ // On native builds, sub-platform variants (android, ios, tv, androidtv, tvos)
1537
+ // can't be resolved at compile time - leave for runtime evaluation
1538
+ if (
1539
+ platform === 'native' &&
1540
+ nativeOnlyPlatforms.has(platformName)
1541
+ ) {
1542
+ if (shouldPrintDebug) {
1543
+ logger.info(
1544
+ ` ! keeping platform-specific style for runtime evaluation: ${name}`
1545
+ )
1546
+ }
1547
+ inlined.set(name, true)
1548
+ return attr
1549
+ }
1535
1550
  // Platform doesn't match, skip these styles entirely
1536
1551
  if (shouldPrintDebug) {
1537
1552
  logger.info(` ! skipping non-matching platform style: ${name}`)
@@ -2636,9 +2651,9 @@ export function createExtractor(
2636
2651
 
2637
2652
  if (!(err instanceof BailOptimizationError)) {
2638
2653
  console.error(
2639
- `@hanzogui/static error, reverting optimization. In ${filePath} ${lineNumbers} on ${originalNodeName}: ${err.message}. For stack trace set environment HANZO_GUI_DEBUG=1`
2654
+ `@hanzogui/static error, reverting optimization. In ${filePath} ${lineNumbers} on ${originalNodeName}: ${err.message}. For stack trace set environment GUI_DEBUG=1`
2640
2655
  )
2641
- if (process.env.HANZO_GUI_DEBUG === '1') {
2656
+ if (process.env.GUI_DEBUG === '1') {
2642
2657
  console.error(err.stack)
2643
2658
  }
2644
2659
  }
@@ -7,9 +7,7 @@ export function createLogger(sourcePath: string, options: GuiOptions) {
7
7
  const shouldLogTiming = options.logTimings ?? true
8
8
  const start = Date.now()
9
9
  const mem =
10
- process.env.HANZO_GUI_SHOW_MEMORY_USAGE && shouldLogTiming
11
- ? process.memoryUsage()
12
- : null
10
+ process.env.GUI_SHOW_MEMORY_USAGE && shouldLogTiming ? process.memoryUsage() : null
13
11
 
14
12
  return (res) => {
15
13
  if (!shouldLogTiming) {
@@ -210,7 +210,7 @@ export function getBabelParseDefinition(options: GuiOptions) {
210
210
  const finalAttrs: (t.JSXAttribute | t.JSXSpreadAttribute)[] = []
211
211
  const themeKeysUsed = new Set<string>()
212
212
 
213
- function getStyleExpression(style: object | null) {
213
+ function getStyleExpression(style: object | null, forTernary = false) {
214
214
  if (!style) return
215
215
 
216
216
  // split theme properties and leave them as props since RN has no concept of theme
@@ -226,13 +226,24 @@ export function getBabelParseDefinition(options: GuiOptions) {
226
226
  // make a sub-array
227
227
  themeExpr = getThemedStyleExpression(themed)
228
228
  }
229
- const ident = addSheetStyle(plain, props.node)
229
+ const hasPlainKeys = Object.keys(plain).length > 0
230
+ const ident = hasPlainKeys ? addSheetStyle(plain, props.node) : null
230
231
  if (themeExpr) {
231
- addStyleExpression(ident)
232
- addStyleExpression(ident, true)
232
+ if (forTernary) {
233
+ // for ternary branches, return combined expression
234
+ // without adding plain styles unconditionally
235
+ if (ident) {
236
+ return t.arrayExpression([ident, themeExpr])
237
+ }
238
+ return themeExpr
239
+ }
240
+ // for base styles, add unconditionally
241
+ if (ident) {
242
+ addStyleExpression(ident)
243
+ addStyleExpression(ident, true)
244
+ }
233
245
  return themeExpr
234
246
  }
235
- // since we only do flattened disabling this path
236
247
  return ident
237
248
  }
238
249
 
@@ -268,6 +279,7 @@ export function getBabelParseDefinition(options: GuiOptions) {
268
279
  }
269
280
 
270
281
  let hasDynamicStyle = false
282
+ let hasMediaKeys = false
271
283
 
272
284
  for (const attr of props.attrs) {
273
285
  switch (attr.type) {
@@ -280,8 +292,12 @@ export function getBabelParseDefinition(options: GuiOptions) {
280
292
 
281
293
  case 'ternary': {
282
294
  const { consequent, alternate } = attr.value
283
- const consExpr = getStyleExpression(consequent)
284
- const altExpr = getStyleExpression(alternate)
295
+ const consExpr = getStyleExpression(consequent, true)
296
+ const altExpr = getStyleExpression(alternate, true)
297
+
298
+ if (attr.value.inlineMediaQuery) {
299
+ hasMediaKeys = true
300
+ }
285
301
 
286
302
  expressions.push(attr.value.test)
287
303
  addStyleExpression(
@@ -338,6 +354,7 @@ export function getBabelParseDefinition(options: GuiOptions) {
338
354
  const WrapperIdentifier = t.identifier(wrapperName)
339
355
  const WrapperJSXIdentifier = t.jsxIdentifier(wrapperName)
340
356
 
357
+ const hasThemeKeysFlag = themeKeysUsed.size > 0
341
358
  root.pushContainer(
342
359
  'body',
343
360
  t.variableDeclaration('const', [
@@ -350,6 +367,8 @@ export function getBabelParseDefinition(options: GuiOptions) {
350
367
  // return styles directly - no useMemo, theme changes must trigger style recalc
351
368
  t.arrayExpression([...hocStylesExpr.elements])
352
369
  ),
370
+ t.booleanLiteral(hasThemeKeysFlag),
371
+ t.booleanLiteral(hasMediaKeys),
353
372
  ])
354
373
  ),
355
374
  ])
@@ -365,10 +384,17 @@ export function getBabelParseDefinition(options: GuiOptions) {
365
384
  }
366
385
 
367
386
  if (expressions.length) {
387
+ // coerce runtime expressions to boolean so they can't be
388
+ // confused with string media keys at runtime
389
+ const safeExpressions = expressions.map((expr) =>
390
+ t.isStringLiteral(expr)
391
+ ? expr
392
+ : t.unaryExpression('!', t.unaryExpression('!', expr))
393
+ )
368
394
  props.node.attributes.push(
369
395
  t.jsxAttribute(
370
396
  t.jsxIdentifier('_expressions'),
371
- t.jsxExpressionContainer(t.arrayExpression(expressions))
397
+ t.jsxExpressionContainer(t.arrayExpression(safeExpressions))
372
398
  )
373
399
  )
374
400
  }
@@ -393,7 +419,7 @@ export function getBabelParseDefinition(options: GuiOptions) {
393
419
  if (message.includes('Unexpected return value from visitor method')) {
394
420
  message = 'Unexpected return value from visitor method'
395
421
  }
396
- console.warn('Error in Hanzo GUI parse, skipping', message, err.stack)
422
+ console.warn('Error in GUI parse, skipping', message, err.stack)
397
423
  return
398
424
  }
399
425
  }
@@ -27,7 +27,7 @@ import {
27
27
 
28
28
  const getFilledOptions = (propsIn: Partial<GuiOptions>): GuiOptions => ({
29
29
  // defaults
30
- platform: (process.env.HANZO_GUI_TARGET as any) || 'web',
30
+ platform: (process.env.GUI_TARGET as any) || 'web',
31
31
  config: 'gui.config.ts',
32
32
  components: ['@hanzo/gui'],
33
33
  ...(propsIn as Partial<GuiOptions>),
@@ -248,7 +248,7 @@ export function loadGuiSync({
248
248
  // lets shim require and avoid importing react-native + react-native-web
249
249
  // we just need to read the config around them
250
250
  process.env.IS_STATIC = 'is_static'
251
- process.env.HANZO_GUI_IS_SERVER = 'true'
251
+ process.env.GUI_IS_SERVER = 'true'
252
252
 
253
253
  const { unregister } = registerRequire(props.platform || 'web', {
254
254
  proxyWormImports: !!forceExports,
@@ -370,7 +370,7 @@ export async function getOptions({
370
370
  debug,
371
371
  tsconfigPath,
372
372
  guiOptions: {
373
- platform: (process.env.HANZO_GUI_TARGET as any) || 'web',
373
+ platform: (process.env.GUI_TARGET as any) || 'web',
374
374
  components: ['@hanzo/gui'],
375
375
  ...guiOptions,
376
376
  config:
@@ -390,7 +390,7 @@ export function resolveWebOrNativeSpecificEntry(entry: string) {
390
390
  const resolved = require.resolve(entry, { paths: [workspaceRoot] })
391
391
  const ext = extname(resolved)
392
392
  const fileName = basename(resolved).replace(ext, '')
393
- const specificExt = process.env.HANZO_GUI_TARGET === 'web' ? 'web' : 'native'
393
+ const specificExt = process.env.GUI_TARGET === 'web' ? 'web' : 'native'
394
394
  const specificFile = join(dirname(resolved), fileName + '.' + specificExt + ext)
395
395
  if (fsExtra.existsSync(specificFile)) {
396
396
  return specificFile
@@ -33,7 +33,7 @@ export async function regenerateConfig(
33
33
  spaces: 2,
34
34
  })
35
35
  } catch (err) {
36
- if (process.env.DEBUG?.includes('@hanzo/gui') || process.env.IS_HANZO_GUI_DEV) {
36
+ if (process.env.DEBUG?.includes('@hanzo/gui') || process.env.IS_GUI_DEV) {
37
37
  console.warn('regenerateConfig error', err)
38
38
  }
39
39
  // ignore for now
@@ -47,7 +47,7 @@ export function regenerateConfigSync(_guiOptions: GuiOptions, config: BundledCon
47
47
  spaces: 2,
48
48
  })
49
49
  } catch (err) {
50
- if (process.env.DEBUG?.includes('@hanzo/gui') || process.env.IS_HANZO_GUI_DEV) {
50
+ if (process.env.DEBUG?.includes('@hanzo/gui') || process.env.IS_GUI_DEV) {
51
51
  console.warn('regenerateConfig error', err)
52
52
  }
53
53
  // ignore for now
@@ -36,8 +36,8 @@ export function getPragmaOptions({ source, path }: { source: string; path: strin
36
36
  break
37
37
  }
38
38
 
39
- if (process.env.HANZO_GUI_DEBUG_FILE) {
40
- if (path.includes(process.env.HANZO_GUI_DEBUG_FILE)) {
39
+ if (process.env.GUI_DEBUG_FILE) {
40
+ if (path.includes(process.env.GUI_DEBUG_FILE)) {
41
41
  shouldPrintDebug = 'verbose'
42
42
  }
43
43
  }