@hanzogui/static 2.0.0

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 (207) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -0
  3. package/dist/check-dep-versions.cjs +267 -0
  4. package/dist/checkDeps.cjs +200 -0
  5. package/dist/constants.cjs +49 -0
  6. package/dist/exports.cjs +44 -0
  7. package/dist/extractor/accessSafe.cjs +46 -0
  8. package/dist/extractor/babelParse.cjs +54 -0
  9. package/dist/extractor/buildClassName.cjs +62 -0
  10. package/dist/extractor/bundle.cjs +185 -0
  11. package/dist/extractor/bundleConfig.cjs +513 -0
  12. package/dist/extractor/concatClassName.cjs +80 -0
  13. package/dist/extractor/createEvaluator.cjs +75 -0
  14. package/dist/extractor/createExtractor.cjs +1150 -0
  15. package/dist/extractor/createLogger.cjs +45 -0
  16. package/dist/extractor/detectModuleFormat.cjs +49 -0
  17. package/dist/extractor/ensureImportingConcat.cjs +48 -0
  18. package/dist/extractor/errors.cjs +26 -0
  19. package/dist/extractor/esbuildAliasPlugin.cjs +44 -0
  20. package/dist/extractor/esbuildTsconfigPaths.cjs +86 -0
  21. package/dist/extractor/evaluateAstNode.cjs +83 -0
  22. package/dist/extractor/extractHelpers.cjs +119 -0
  23. package/dist/extractor/extractMediaStyle.cjs +128 -0
  24. package/dist/extractor/extractToClassNames.cjs +321 -0
  25. package/dist/extractor/extractToNative.cjs +266 -0
  26. package/dist/extractor/findTopmostFunction.cjs +34 -0
  27. package/dist/extractor/generatedUid.cjs +47 -0
  28. package/dist/extractor/getGuiConfigPathFromOptionsConfig.cjs +35 -0
  29. package/dist/extractor/getPrefixLogs.cjs +29 -0
  30. package/dist/extractor/getPropValueFromAttributes.cjs +67 -0
  31. package/dist/extractor/getSourceModule.cjs +64 -0
  32. package/dist/extractor/getStaticBindingsForScope.cjs +150 -0
  33. package/dist/extractor/hoistClassNames.cjs +62 -0
  34. package/dist/extractor/literalToAst.cjs +84 -0
  35. package/dist/extractor/loadFile.cjs +11 -0
  36. package/dist/extractor/loadGui.cjs +322 -0
  37. package/dist/extractor/logLines.cjs +35 -0
  38. package/dist/extractor/normalizeTernaries.cjs +73 -0
  39. package/dist/extractor/propsToFontFamilyCache.cjs +38 -0
  40. package/dist/extractor/regenerateConfig.cjs +150 -0
  41. package/dist/extractor/removeUnusedHooks.cjs +76 -0
  42. package/dist/extractor/timer.cjs +43 -0
  43. package/dist/extractor/validHTMLAttributes.cjs +77 -0
  44. package/dist/extractor/watchGuiConfig.cjs +58 -0
  45. package/dist/getPragmaOptions.cjs +58 -0
  46. package/dist/helpers/memoize.cjs +37 -0
  47. package/dist/helpers/requireGuiCore.cjs +33 -0
  48. package/dist/index.cjs +40 -0
  49. package/dist/registerRequire.cjs +115 -0
  50. package/dist/server.cjs +75 -0
  51. package/dist/setup.cjs +0 -0
  52. package/dist/types.cjs +16 -0
  53. package/dist/worker.cjs +89 -0
  54. package/package.json +101 -0
  55. package/src/check-dep-versions.ts +738 -0
  56. package/src/checkDeps.ts +371 -0
  57. package/src/constants.ts +14 -0
  58. package/src/exports.ts +15 -0
  59. package/src/extractor/accessSafe.ts +22 -0
  60. package/src/extractor/babelParse.ts +37 -0
  61. package/src/extractor/buildClassName.ts +76 -0
  62. package/src/extractor/bundle.ts +277 -0
  63. package/src/extractor/bundleConfig.ts +958 -0
  64. package/src/extractor/concatClassName.ts +105 -0
  65. package/src/extractor/createEvaluator.ts +82 -0
  66. package/src/extractor/createExtractor.ts +2665 -0
  67. package/src/extractor/createLogger.ts +41 -0
  68. package/src/extractor/detectModuleFormat.ts +42 -0
  69. package/src/extractor/ensureImportingConcat.ts +36 -0
  70. package/src/extractor/errors.ts +1 -0
  71. package/src/extractor/esbuildAliasPlugin.ts +40 -0
  72. package/src/extractor/esbuildTsconfigPaths.ts +103 -0
  73. package/src/extractor/evaluateAstNode.ts +136 -0
  74. package/src/extractor/extractHelpers.ts +211 -0
  75. package/src/extractor/extractMediaStyle.ts +194 -0
  76. package/src/extractor/extractToClassNames.ts +631 -0
  77. package/src/extractor/extractToNative.ts +463 -0
  78. package/src/extractor/findTopmostFunction.ts +24 -0
  79. package/src/extractor/generatedUid.ts +41 -0
  80. package/src/extractor/getGuiConfigPathFromOptionsConfig.ts +24 -0
  81. package/src/extractor/getPrefixLogs.ts +9 -0
  82. package/src/extractor/getPropValueFromAttributes.ts +95 -0
  83. package/src/extractor/getSourceModule.ts +96 -0
  84. package/src/extractor/getStaticBindingsForScope.ts +237 -0
  85. package/src/extractor/hoistClassNames.ts +52 -0
  86. package/src/extractor/literalToAst.ts +85 -0
  87. package/src/extractor/loadFile.ts +17 -0
  88. package/src/extractor/loadGui.ts +487 -0
  89. package/src/extractor/logLines.ts +16 -0
  90. package/src/extractor/normalizeTernaries.ts +75 -0
  91. package/src/extractor/propsToFontFamilyCache.ts +18 -0
  92. package/src/extractor/regenerateConfig.ts +186 -0
  93. package/src/extractor/removeUnusedHooks.ts +83 -0
  94. package/src/extractor/timer.ts +25 -0
  95. package/src/extractor/validHTMLAttributes.ts +52 -0
  96. package/src/extractor/watchGuiConfig.ts +57 -0
  97. package/src/getPragmaOptions.ts +57 -0
  98. package/src/helpers/memoize.ts +24 -0
  99. package/src/helpers/requireGuiCore.ts +28 -0
  100. package/src/index.ts +4 -0
  101. package/src/registerRequire.ts +236 -0
  102. package/src/server.ts +43 -0
  103. package/src/setup.ts +0 -0
  104. package/src/types.ts +109 -0
  105. package/src/worker.ts +142 -0
  106. package/types/check-dep-versions.d.ts +37 -0
  107. package/types/check-dep-versions.d.ts.map +1 -0
  108. package/types/checkDeps.d.ts +19 -0
  109. package/types/checkDeps.d.ts.map +1 -0
  110. package/types/constants.d.ts +6 -0
  111. package/types/constants.d.ts.map +1 -0
  112. package/types/exports.d.ts +16 -0
  113. package/types/exports.d.ts.map +1 -0
  114. package/types/extractor/accessSafe.d.ts +3 -0
  115. package/types/extractor/accessSafe.d.ts.map +1 -0
  116. package/types/extractor/babelParse.d.ts +5 -0
  117. package/types/extractor/babelParse.d.ts.map +1 -0
  118. package/types/extractor/buildClassName.d.ts +7 -0
  119. package/types/extractor/buildClassName.d.ts.map +1 -0
  120. package/types/extractor/bundle.d.ts +121 -0
  121. package/types/extractor/bundle.d.ts.map +1 -0
  122. package/types/extractor/bundleConfig.d.ts +49 -0
  123. package/types/extractor/bundleConfig.d.ts.map +1 -0
  124. package/types/extractor/concatClassName.d.ts +8 -0
  125. package/types/extractor/concatClassName.d.ts.map +1 -0
  126. package/types/extractor/createEvaluator.d.ts +12 -0
  127. package/types/extractor/createEvaluator.d.ts.map +1 -0
  128. package/types/extractor/createExtractor.d.ts +32 -0
  129. package/types/extractor/createExtractor.d.ts.map +1 -0
  130. package/types/extractor/createLogger.d.ts +3 -0
  131. package/types/extractor/createLogger.d.ts.map +1 -0
  132. package/types/extractor/detectModuleFormat.d.ts +5 -0
  133. package/types/extractor/detectModuleFormat.d.ts.map +1 -0
  134. package/types/extractor/ensureImportingConcat.d.ts +4 -0
  135. package/types/extractor/ensureImportingConcat.d.ts.map +1 -0
  136. package/types/extractor/errors.d.ts +3 -0
  137. package/types/extractor/errors.d.ts.map +1 -0
  138. package/types/extractor/esbuildAliasPlugin.d.ts +18 -0
  139. package/types/extractor/esbuildAliasPlugin.d.ts.map +1 -0
  140. package/types/extractor/esbuildTsconfigPaths.d.ts +11 -0
  141. package/types/extractor/esbuildTsconfigPaths.d.ts.map +1 -0
  142. package/types/extractor/evaluateAstNode.d.ts +3 -0
  143. package/types/extractor/evaluateAstNode.d.ts.map +1 -0
  144. package/types/extractor/extractHelpers.d.ts +28 -0
  145. package/types/extractor/extractHelpers.d.ts.map +1 -0
  146. package/types/extractor/extractMediaStyle.d.ts +11 -0
  147. package/types/extractor/extractMediaStyle.d.ts.map +1 -0
  148. package/types/extractor/extractToClassNames.d.ts +25 -0
  149. package/types/extractor/extractToClassNames.d.ts.map +1 -0
  150. package/types/extractor/extractToNative.d.ts +13 -0
  151. package/types/extractor/extractToNative.d.ts.map +1 -0
  152. package/types/extractor/findTopmostFunction.d.ts +4 -0
  153. package/types/extractor/findTopmostFunction.d.ts.map +1 -0
  154. package/types/extractor/generatedUid.d.ts +5 -0
  155. package/types/extractor/generatedUid.d.ts.map +1 -0
  156. package/types/extractor/getGuiConfigPathFromOptionsConfig.d.ts +3 -0
  157. package/types/extractor/getGuiConfigPathFromOptionsConfig.d.ts.map +1 -0
  158. package/types/extractor/getPrefixLogs.d.ts +3 -0
  159. package/types/extractor/getPrefixLogs.d.ts.map +1 -0
  160. package/types/extractor/getPropValueFromAttributes.d.ts +19 -0
  161. package/types/extractor/getPropValueFromAttributes.d.ts.map +1 -0
  162. package/types/extractor/getSourceModule.d.ts +16 -0
  163. package/types/extractor/getSourceModule.d.ts.map +1 -0
  164. package/types/extractor/getStaticBindingsForScope.d.ts +5 -0
  165. package/types/extractor/getStaticBindingsForScope.d.ts.map +1 -0
  166. package/types/extractor/hoistClassNames.d.ts +6 -0
  167. package/types/extractor/hoistClassNames.d.ts.map +1 -0
  168. package/types/extractor/literalToAst.d.ts +4 -0
  169. package/types/extractor/literalToAst.d.ts.map +1 -0
  170. package/types/extractor/loadFile.d.ts +1 -0
  171. package/types/extractor/loadFile.d.ts.map +1 -0
  172. package/types/extractor/loadGui.d.ts +22 -0
  173. package/types/extractor/loadGui.d.ts.map +1 -0
  174. package/types/extractor/logLines.d.ts +2 -0
  175. package/types/extractor/logLines.d.ts.map +1 -0
  176. package/types/extractor/normalizeTernaries.d.ts +3 -0
  177. package/types/extractor/normalizeTernaries.d.ts.map +1 -0
  178. package/types/extractor/propsToFontFamilyCache.d.ts +4 -0
  179. package/types/extractor/propsToFontFamilyCache.d.ts.map +1 -0
  180. package/types/extractor/regenerateConfig.d.ts +9 -0
  181. package/types/extractor/regenerateConfig.d.ts.map +1 -0
  182. package/types/extractor/removeUnusedHooks.d.ts +3 -0
  183. package/types/extractor/removeUnusedHooks.d.ts.map +1 -0
  184. package/types/extractor/timer.d.ts +5 -0
  185. package/types/extractor/timer.d.ts.map +1 -0
  186. package/types/extractor/validHTMLAttributes.d.ts +52 -0
  187. package/types/extractor/validHTMLAttributes.d.ts.map +1 -0
  188. package/types/extractor/watchGuiConfig.d.ts +5 -0
  189. package/types/extractor/watchGuiConfig.d.ts.map +1 -0
  190. package/types/getPragmaOptions.d.ts +8 -0
  191. package/types/getPragmaOptions.d.ts.map +1 -0
  192. package/types/helpers/memoize.d.ts +8 -0
  193. package/types/helpers/memoize.d.ts.map +1 -0
  194. package/types/helpers/requireGuiCore.d.ts +3 -0
  195. package/types/helpers/requireGuiCore.d.ts.map +1 -0
  196. package/types/index.d.ts +4 -0
  197. package/types/index.d.ts.map +1 -0
  198. package/types/registerRequire.d.ts +10 -0
  199. package/types/registerRequire.d.ts.map +1 -0
  200. package/types/server.d.ts +3 -0
  201. package/types/server.d.ts.map +1 -0
  202. package/types/setup.d.ts +1 -0
  203. package/types/setup.d.ts.map +1 -0
  204. package/types/types.d.ts +92 -0
  205. package/types/types.d.ts.map +1 -0
  206. package/types/worker.d.ts +46 -0
  207. package/types/worker.d.ts.map +1 -0
@@ -0,0 +1,236 @@
1
+ import { register } from 'esbuild-register/dist/node'
2
+
3
+ import { esbuildIgnoreFilesRegex } from './extractor/bundle'
4
+ import { requireGuiCore } from './helpers/requireGuiCore'
5
+ import type { GuiPlatform } from './types'
6
+
7
+ const nameToPaths = {}
8
+
9
+ export const getNameToPaths = () => nameToPaths
10
+
11
+ const Module = require('node:module')
12
+ const proxyWorm = require('@hanzogui/proxy-worm')
13
+
14
+ let isRegistered = false
15
+ let og: any
16
+
17
+ const whitelisted = {
18
+ react: true,
19
+ }
20
+
21
+ const compiled = {}
22
+ export function setRequireResult(name: string, result: any) {
23
+ compiled[name] = result
24
+ }
25
+
26
+ export function registerRequire(
27
+ platform: GuiPlatform,
28
+ { proxyWormImports } = {
29
+ proxyWormImports: false,
30
+ }
31
+ ) {
32
+ // already registered
33
+ if (isRegistered) {
34
+ return {
35
+ guiRequire: require,
36
+ unregister: () => {},
37
+ }
38
+ }
39
+
40
+ // capture original resolve BEFORE esbuild-register patches it
41
+ // so we can use Node's native exports resolution for @gui packages
42
+ const originalResolveFilename = Module._resolveFilename
43
+
44
+ const { unregister } = register({
45
+ hookIgnoreNodeModules: false,
46
+ // don't transform @hanzo/gui packages - they have pre-built dist files
47
+ hookMatcher: (filename) => {
48
+ if (
49
+ filename.includes('@hanzo/gui') ||
50
+ filename.includes('@gui') ||
51
+ /\/(hanzo\/gui|gui)\/code\/(core|ui|packages)\//.test(filename)
52
+ ) {
53
+ return false
54
+ }
55
+ return true
56
+ },
57
+ })
58
+
59
+ // esbuild-register's registerTsconfigPaths replaces Module._resolveFilename
60
+ // but tsconfig paths resolution bypasses Node's package exports
61
+ // we need to restore Node's native resolution for @gui packages
62
+ const tsconfigPatchedResolve = Module._resolveFilename
63
+ Module._resolveFilename = function (request: string, ...args: any[]) {
64
+ // for @gui packages, use Node's native resolution (respects exports)
65
+ if (request.startsWith('@hanzogui/')) {
66
+ return originalResolveFilename.call(this, request, ...args)
67
+ }
68
+ // for everything else, use tsconfig-paths resolution
69
+ return tsconfigPatchedResolve.call(this, request, ...args)
70
+ }
71
+
72
+ if (!og) {
73
+ og = Module.prototype.require // capture esbuild require
74
+ }
75
+
76
+ isRegistered = true
77
+
78
+ Module.prototype.require = guiRequire
79
+
80
+ function guiRequire(this: any, path: string) {
81
+ if (path === '@hanzo/gui' && platform === 'native') {
82
+ return og.apply(this, ['@hanzo/gui/native'])
83
+ }
84
+
85
+ if (path === '@hanzogui/core') {
86
+ return requireGuiCore(platform, (path) => {
87
+ return og.apply(this, [path])
88
+ })
89
+ }
90
+
91
+ if (
92
+ path in knownIgnorableModules ||
93
+ path.startsWith('react-native-reanimated') ||
94
+ esbuildIgnoreFilesRegex.test(path)
95
+ ) {
96
+ return proxyWorm
97
+ }
98
+
99
+ if (path in compiled) {
100
+ return compiled[path]
101
+ }
102
+
103
+ if (path === 'react-native-svg') {
104
+ return og.apply(this, ['@hanzogui/react-native-svg'])
105
+ }
106
+
107
+ if (path === 'react-native/package.json') {
108
+ return og.apply(this, ['react-native-web/package.json'])
109
+ }
110
+
111
+ if (
112
+ path === '@hanzogui/react-native-web-lite' ||
113
+ path === 'react-native' ||
114
+ path.startsWith('react-native/')
115
+ ) {
116
+ try {
117
+ return og.apply('react-native')
118
+ } catch {
119
+ return og.apply(this, ['@hanzogui/react-native-web-lite'])
120
+ }
121
+ }
122
+
123
+ if (!whitelisted[path]) {
124
+ if (proxyWormImports && !path.includes('.gui-dynamic-eval')) {
125
+ // allow @hanzo/gui and its sub-packages through - they re-export components
126
+ // with staticConfig needed for dynamic eval optimization.
127
+ // also allow requires FROM within gui packages (relative imports like ./Separator.cjs)
128
+ const callerFile = this?.filename || this?.id || ''
129
+ const isFromGuiPkg =
130
+ callerFile.includes('@hanzo/gui') || callerFile.includes('@gui') || callerFile.includes('node_modules/@hanzo/')
131
+ if (path === '@hanzo/gui' || path.startsWith('@hanzogui/') || isFromGuiPkg) {
132
+ return og.apply(this, [path])
133
+ }
134
+ return proxyWorm
135
+ }
136
+ }
137
+
138
+ try {
139
+ const out = og.apply(this, arguments)
140
+ // only for studio disable for now
141
+ // if (!nameToPaths[path]) {
142
+ // if (out && typeof out === 'object') {
143
+ // for (const key in out) {
144
+ // try {
145
+ // const conf = out[key]?.staticConfig as StaticConfig
146
+ // if (conf) {
147
+ // if (conf.componentName) {
148
+ // nameToPaths[conf.componentName] ??= new Set()
149
+ // const fullName = path.startsWith('.')
150
+ // ? join(`${this.path.replace(/dist(\/cjs)?/, 'src')}`, path)
151
+ // : path
152
+ // nameToPaths[conf.componentName].add(fullName)
153
+ // } else {
154
+ // // console.log('no name component', path)
155
+ // }
156
+ // }
157
+ // } catch {
158
+ // // ok
159
+ // }
160
+ // }
161
+ // }
162
+ // }
163
+ return out
164
+ } catch (err: any) {
165
+ if (
166
+ !process.env.HANZO_GUI_ENABLE_WARN_DYNAMIC_LOAD &&
167
+ path.includes('gui-dynamic-eval')
168
+ ) {
169
+ // ok, dynamic eval fails
170
+ return
171
+ }
172
+ if (allowedIgnores[path] || IGNORES === 'true') {
173
+ // ignore
174
+ } else if (!process.env.HANZO_GUI_SHOW_FULL_BUNDLE_ERRORS && !process.env.DEBUG) {
175
+ if (hasWarnedForModules.has(path)) {
176
+ // ignore
177
+ } else {
178
+ hasWarnedForModules.add(path)
179
+ }
180
+ } else {
181
+ /**
182
+ * Allow errors to happen, we're just reading config and components but sometimes external modules cause problems
183
+ * We can't fix every problem, so just swap them out with proxyWorm which is a sort of generic object that can be read.
184
+ */
185
+
186
+ console.warn(
187
+ ` [hanzo-gui] skipped "${path}" (set HANZO_GUI_IGNORE_BUNDLE_ERRORS="${path}" to silence)`
188
+ )
189
+ }
190
+
191
+ return proxyWorm
192
+ }
193
+ }
194
+
195
+ return {
196
+ guiRequire,
197
+ unregister: () => {
198
+ if (hasWarnedForModules.size) {
199
+ console.info(
200
+ ` [hanzo-gui] skipped loading ${hasWarnedForModules.size} module, see: https://gui.hanzo.ai/docs/intro/errors#warning-001`
201
+ )
202
+ hasWarnedForModules.clear()
203
+ }
204
+
205
+ unregister()
206
+ isRegistered = false
207
+ Module.prototype.require = og
208
+ },
209
+ }
210
+ }
211
+
212
+ const IGNORES = process.env.HANZO_GUI_IGNORE_BUNDLE_ERRORS || process.env.HANZO_GUI_IGNORE_BUNDLE_ERRORS
213
+ const extraIgnores =
214
+ IGNORES === 'true' ? [] : IGNORES?.split(',')
215
+
216
+ const knownIgnorableModules = {
217
+ '@gorhom/bottom-sheet': true,
218
+ 'expo-modules': true,
219
+ solito: true,
220
+ 'expo-linear-gradient': true,
221
+ '@expo/vector-icons': true,
222
+ '@hanzo/gui/linear-gradient': true,
223
+ // animation libraries not needed for static extraction
224
+ '@emotion/is-prop-valid': true,
225
+ 'framer-motion': true,
226
+ motion: true,
227
+ ...Object.fromEntries(extraIgnores?.map((k) => [k, true]) || []),
228
+ }
229
+
230
+ const hasWarnedForModules = new Set<string>()
231
+
232
+ const allowedIgnores = {
233
+ 'expo-constants': true,
234
+ './ExpoHaptics': true,
235
+ './js/MaskedView': true,
236
+ }
package/src/server.ts ADDED
@@ -0,0 +1,43 @@
1
+ import type { GuiOptions } from './types'
2
+
3
+ import net from 'node:net'
4
+
5
+ export async function startServer(options: GuiOptions) {
6
+ const port = await getAvailablePort()
7
+ const server = net.createServer()
8
+ server.unref()
9
+
10
+ await new Promise((resolve, reject) => {
11
+ server.on('error', reject)
12
+ server.on('connection', (conn) => {
13
+ conn.on('data', (data) => {
14
+ console.info('got', data.toString())
15
+ })
16
+ })
17
+ server.listen({ port }, () => {
18
+ const { port } = server.address() as net.AddressInfo
19
+ server.close(() => {
20
+ resolve(port)
21
+ })
22
+ })
23
+ })
24
+ }
25
+
26
+ async function getAvailablePort(port = 8089): Promise<number> {
27
+ return checkAvailablePort(port).catch(() => getAvailablePort(port + 1))
28
+ }
29
+
30
+ function checkAvailablePort(port: number) {
31
+ return new Promise<number>((resolve, reject) => {
32
+ const server = net.createServer()
33
+ server.unref()
34
+ server.on('error', reject)
35
+
36
+ server.listen({ port }, () => {
37
+ const { port } = server.address() as net.AddressInfo
38
+ server.close(() => {
39
+ resolve(port)
40
+ })
41
+ })
42
+ })
43
+ }
package/src/setup.ts ADDED
File without changes
package/src/types.ts ADDED
@@ -0,0 +1,109 @@
1
+ import type { NodePath } from '@babel/traverse'
2
+ import type * as t from '@babel/types'
3
+ import type { PseudoStyles, StaticConfig, GuiConfig } from '@hanzogui/core'
4
+ import type { StyleObject } from '@hanzogui/helpers'
5
+ import type { GuiOptions } from '@hanzogui/types'
6
+ import type { ViewStyle } from 'react-native'
7
+
8
+ import type { LoadedComponents } from './extractor/bundleConfig'
9
+
10
+ export type GuiPlatform = 'native' | 'web'
11
+
12
+ export type { GuiOptions, GuiBuildOptions } from '@hanzogui/types'
13
+
14
+ export type { StyleObject } from '@hanzogui/helpers'
15
+
16
+ export type ClassNameObject = t.StringLiteral | t.Expression
17
+
18
+ export interface CacheObject {
19
+ [key: string]: any
20
+ }
21
+
22
+ export interface LogOptions {
23
+ clear?: boolean
24
+ timestamp?: boolean
25
+ error?: Error | null
26
+ }
27
+
28
+ export interface Logger {
29
+ info(msg: string, options?: LogOptions): void
30
+ warn(msg: string, options?: LogOptions): void
31
+ error(msg: string, options?: LogOptions): void
32
+ }
33
+
34
+ export type ExtractorOptions = {
35
+ logger?: Logger
36
+ platform?: GuiPlatform
37
+ }
38
+
39
+ export type ExtractedAttrAttr = {
40
+ type: 'attr'
41
+ value: t.JSXAttribute | t.JSXSpreadAttribute
42
+ extraClassNames?: string
43
+ }
44
+
45
+ export type ExtractedAttrStyle = {
46
+ type: 'style'
47
+ value: ViewStyle & PseudoStyles
48
+ attr?: t.JSXAttribute | t.JSXSpreadAttribute
49
+ name?: string
50
+ extraClassNames?: string
51
+ }
52
+
53
+ export type ExtractedTernaryAttr = {
54
+ type: 'ternary'
55
+ value: Ternary
56
+ }
57
+
58
+ export type ExtractedAttr = ExtractedAttrAttr | ExtractedTernaryAttr | ExtractedAttrStyle
59
+
60
+ export type ExtractTagProps = {
61
+ parserProps: GuiOptionsWithFileInfo
62
+ attrs: ExtractedAttr[]
63
+ node: t.JSXOpeningElement
64
+ attemptEval: (exprNode: t.Node, evalFn?: ((node: t.Node) => any) | undefined) => any
65
+ flatNodeName?: string
66
+ jsxPath: NodePath<t.JSXElement>
67
+ programPath: NodePath<t.Program>
68
+ originalNodeName: string
69
+ lineNumbers: string
70
+ filePath: string
71
+ completeProps: Record<string, any>
72
+ staticConfig: StaticConfig
73
+ config: GuiConfig
74
+ }
75
+
76
+ export type GuiOptionsWithFileInfo = GuiOptions & {
77
+ sourcePath?: string
78
+ allLoadedComponents: LoadedComponents[]
79
+ }
80
+
81
+ export type ExtractorParseProps = Omit<
82
+ GuiOptionsWithFileInfo,
83
+ 'allLoadedComponents'
84
+ > & {
85
+ platform: GuiPlatform
86
+ shouldPrintDebug?: boolean | 'verbose'
87
+ onExtractTag: (props: ExtractTagProps) => void
88
+ getFlattenedNode?: (props: { isTextView: boolean; tag: string }) => string
89
+ extractStyledDefinitions?: boolean
90
+ // identifer, rule
91
+ onStyledDefinitionRule?: (identifier: string, rules: string[]) => void
92
+ }
93
+
94
+ export interface Ternary {
95
+ test: t.Expression
96
+ remove: Function
97
+ consequent: object | null
98
+ alternate: object | null
99
+ fontFamily?: string
100
+ inlineMediaQuery?: string
101
+ }
102
+
103
+ export type ClassNameToStyleObj = {
104
+ [key: string]: StyleObject
105
+ }
106
+
107
+ export interface PluginContext {
108
+ write: (path: string, rules: { [key: string]: string }) => any
109
+ }
package/src/worker.ts ADDED
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Worker thread implementation for Hanzo GUI extraction
3
+ * Used by both piscina (async) and synckit (sync for babel)
4
+ */
5
+
6
+ import type { BabelFileResult } from '@babel/core'
7
+ import { createExtractor } from './extractor/createExtractor'
8
+ import type { ExtractedResponse } from './extractor/extractToClassNames'
9
+ import { extractToClassNames as extractToClassNamesImpl } from './extractor/extractToClassNames'
10
+ import { extractToNative as extractToNativeImpl } from './extractor/extractToNative'
11
+ import type { GuiOptions } from './types'
12
+
13
+ // Create extractors lazily to avoid loading unused ones
14
+ let webExtractor: ReturnType<typeof createExtractor> | null = null
15
+ let nativeExtractor: ReturnType<typeof createExtractor> | null = null
16
+
17
+ function getWebExtractor() {
18
+ if (!webExtractor) {
19
+ webExtractor = createExtractor({ platform: 'web' })
20
+ }
21
+ return webExtractor
22
+ }
23
+
24
+ function getNativeExtractor() {
25
+ if (!nativeExtractor) {
26
+ nativeExtractor = createExtractor({ platform: 'native' })
27
+ }
28
+ return nativeExtractor
29
+ }
30
+
31
+ // Cache config loading to avoid reloading
32
+ const configCache: Map<string, Promise<any>> = new Map()
33
+
34
+ export interface ExtractToClassNamesTask {
35
+ type: 'extractToClassNames'
36
+ source: string
37
+ sourcePath: string
38
+ options: GuiOptions
39
+ shouldPrintDebug: boolean | 'verbose'
40
+ }
41
+
42
+ export interface ExtractToNativeTask {
43
+ type: 'extractToNative'
44
+ sourceFileName: string
45
+ sourceCode: string
46
+ options: GuiOptions
47
+ }
48
+
49
+ export interface ClearCacheTask {
50
+ type: 'clearCache'
51
+ }
52
+
53
+ export type WorkerTask = ExtractToClassNamesTask | ExtractToNativeTask | ClearCacheTask
54
+
55
+ export type WorkerResult =
56
+ | { success: true; data: ExtractedResponse | null }
57
+ | { success: true; data: BabelFileResult }
58
+ | { success: false; error: string; stack?: string }
59
+
60
+ /**
61
+ * Main worker function that handles both extraction types
62
+ * This is called by piscina for async usage
63
+ */
64
+ export async function runTask(task: WorkerTask): Promise<WorkerResult> {
65
+ try {
66
+ if (task.type === 'extractToClassNames') {
67
+ // Load web config if needed (with caching)
68
+ // only skip if both extraction AND debug attrs are disabled (fully disabled)
69
+ const isFullyDisabled =
70
+ task.options.disableExtraction && task.options.disableDebugAttr
71
+ if (!isFullyDisabled && !task.options['_disableLoadGui']) {
72
+ const cacheKey = JSON.stringify({
73
+ config: task.options.config,
74
+ components: task.options.components,
75
+ })
76
+
77
+ if (!configCache.has(cacheKey)) {
78
+ configCache.set(cacheKey, getWebExtractor().loadGui(task.options))
79
+ }
80
+
81
+ await configCache.get(cacheKey)
82
+ }
83
+
84
+ const result = await extractToClassNamesImpl({
85
+ extractor: getWebExtractor(),
86
+ source: task.source,
87
+ sourcePath: task.sourcePath,
88
+ options: task.options,
89
+ shouldPrintDebug: task.shouldPrintDebug,
90
+ })
91
+
92
+ return { success: true, data: result }
93
+ }
94
+
95
+ if (task.type === 'extractToNative') {
96
+ // Load native config if needed (with caching)
97
+ const cacheKey = JSON.stringify({
98
+ config: task.options.config,
99
+ components: task.options.components,
100
+ })
101
+
102
+ if (!configCache.has(cacheKey)) {
103
+ configCache.set(cacheKey, getNativeExtractor().loadGui(task.options))
104
+ }
105
+
106
+ await configCache.get(cacheKey)
107
+
108
+ // extractToNative uses its own module-level extractor
109
+ // This is for babel plugin which uses visitor pattern
110
+ const result = extractToNativeImpl(
111
+ task.sourceFileName,
112
+ task.sourceCode,
113
+ task.options
114
+ )
115
+
116
+ return { success: true, data: result }
117
+ }
118
+
119
+ if (task.type === 'clearCache') {
120
+ // Clear config caches when files change
121
+ configCache.clear()
122
+ return { success: true, data: null }
123
+ }
124
+
125
+ return {
126
+ success: false,
127
+ error: `Unknown task type: ${(task as any).type}`,
128
+ }
129
+ } catch (error) {
130
+ return {
131
+ success: false,
132
+ error: error instanceof Error ? error.message : String(error),
133
+ stack: error instanceof Error ? error.stack : undefined,
134
+ }
135
+ }
136
+ }
137
+
138
+ /**
139
+ * For synckit compatibility - exports the runTask as default
140
+ * Synckit will call this function synchronously using worker threads
141
+ */
142
+ export default runTask
@@ -0,0 +1,37 @@
1
+ /**
2
+ * "license": "MIT",
3
+ "author": "Bryan Mishkin",
4
+ */
5
+ /** Relevant public data about a dependency. */
6
+ type Dependency = {
7
+ name: string;
8
+ isMismatching: boolean;
9
+ versions: readonly {
10
+ version: string;
11
+ packages: readonly {
12
+ pathRelative: string;
13
+ }[];
14
+ }[];
15
+ };
16
+ export declare class CDVC {
17
+ /** An object mapping each dependency in the workspace to information including the versions found of it. */
18
+ private readonly dependencies;
19
+ /**
20
+ * @param path - path to the workspace root
21
+ * @param options
22
+ * @param options.fix - Whether to autofix inconsistencies (using latest version present)
23
+ * @param options.ignoreDep - Dependency(s) to ignore mismatches for
24
+ * @param options.includeDepPattern - RegExp(s) of dependency names to ignore mismatches for
25
+ * @param options.ignorePackage - Workspace package(s) to ignore mismatches for
26
+ * @param options.ignorePackagePattern - RegExp(s) of package names to ignore mismatches for
27
+ * @param options.ignorePath - Workspace-relative path(s) of packages to ignore mismatches for
28
+ * @param options.ignorePathPattern - RegExp(s) of workspace-relative path of packages to ignore mismatches for
29
+ */
30
+ constructor(path: string);
31
+ toMismatchSummary(): string;
32
+ getDependencies(): readonly Dependency[];
33
+ getDependency(name: string): Dependency;
34
+ get hasMismatchingDependencies(): boolean;
35
+ }
36
+ export {};
37
+ //# sourceMappingURL=check-dep-versions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-dep-versions.d.ts","sourceRoot":"","sources":["../src/check-dep-versions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA8oBH,+CAA+C;AAC/C,KAAK,UAAU,GAAG;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,aAAa,EAAE,OAAO,CAAA;IACtB,QAAQ,EAAE,SAAS;QACjB,OAAO,EAAE,MAAM,CAAA;QACf,QAAQ,EAAE,SAAS;YAAE,YAAY,EAAE,MAAM,CAAA;SAAE,EAAE,CAAA;KAC9C,EAAE,CAAA;CACJ,CAAA;AAED,qBAAa,IAAI;IACf,4GAA4G;IAC5G,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAc;IAE3C;;;;;;;;;;OAUG;gBACS,IAAI,EAAE,MAAM;IAKjB,iBAAiB,IAAI,MAAM;IAI3B,eAAe,IAAI,SAAS,UAAU,EAAE;IAMxC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU;IAc9C,IAAW,0BAA0B,IAAI,OAAO,CAE/C;CACF"}
@@ -0,0 +1,19 @@
1
+ export declare enum DEPENDENCY_TYPE {
2
+ dependencies = "dependencies",
3
+ devDependencies = "devDependencies",
4
+ optionalDependencies = "optionalDependencies",
5
+ peerDependencies = "peerDependencies",
6
+ resolutions = "resolutions"
7
+ }
8
+ export type Options = {
9
+ depType?: readonly `${DEPENDENCY_TYPE}`[];
10
+ fix?: boolean;
11
+ ignoreDep?: readonly string[];
12
+ ignoreDepPattern?: readonly string[];
13
+ ignorePackage?: readonly string[];
14
+ ignorePackagePattern?: readonly string[];
15
+ ignorePath?: readonly string[];
16
+ ignorePathPattern?: readonly string[];
17
+ };
18
+ export declare function checkDeps(root: string): Promise<void>;
19
+ //# sourceMappingURL=checkDeps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkDeps.d.ts","sourceRoot":"","sources":["../src/checkDeps.ts"],"names":[],"mappings":"AAIA,oBAAY,eAAe;IACzB,YAAY,iBAAiB;IAC7B,eAAe,oBAAoB;IACnC,oBAAoB,yBAAyB;IAC7C,gBAAgB,qBAAqB;IACrC,WAAW,gBAAgB;CAC5B;AAED,MAAM,MAAM,OAAO,GAAG;IACpB,OAAO,CAAC,EAAE,SAAS,GAAG,eAAe,EAAE,EAAE,CAAA;IACzC,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC7B,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,oBAAoB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACxC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC9B,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CACtC,CAAA;AA+TD,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,iBA8B3C"}
@@ -0,0 +1,6 @@
1
+ export declare const CSS_FILE_NAME = "__snack.css";
2
+ export declare const MEDIA_SEP = "_";
3
+ export declare const cacheDir: any;
4
+ export declare const FAILED_EVAL: unique symbol;
5
+ export declare const SHOULD_DEBUG: boolean | undefined;
6
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,aAAa,gBAAgB,CAAA;AAG1C,eAAO,MAAM,SAAS,MAAM,CAAA;AAG5B,eAAO,MAAM,QAAQ,KAAoD,CAAA;AAEzE,eAAO,MAAM,WAAW,eAA8B,CAAA;AAEtD,eAAO,MAAM,YAAY,qBACiD,CAAA"}
@@ -0,0 +1,16 @@
1
+ export * from './checkDeps';
2
+ export * from './types';
3
+ export { createExtractor } from './extractor/createExtractor';
4
+ export { literalToAst } from './extractor/literalToAst';
5
+ export * from './constants';
6
+ export * from './extractor/extractToClassNames';
7
+ export * from './extractor/concatClassName';
8
+ export * from './extractor/extractToNative';
9
+ export * from './extractor/extractHelpers';
10
+ export * from './extractor/loadGui';
11
+ export * from './extractor/watchGuiConfig';
12
+ export * from './extractor/createLogger';
13
+ export * from './registerRequire';
14
+ export { detectModuleFormat, clearFormatCache } from './extractor/detectModuleFormat';
15
+ export * from './getPragmaOptions';
16
+ //# sourceMappingURL=exports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exports.d.ts","sourceRoot":"","sources":["../src/exports.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,SAAS,CAAA;AACvB,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACvD,cAAc,aAAa,CAAA;AAC3B,cAAc,iCAAiC,CAAA;AAC/C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,qBAAqB,CAAA;AACnC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,0BAA0B,CAAA;AACxC,cAAc,mBAAmB,CAAA;AACjC,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAA;AACrF,cAAc,oBAAoB,CAAA"}
@@ -0,0 +1,3 @@
1
+ import * as t from '@babel/types';
2
+ export declare function accessSafe(obj: t.Expression, member: string): t.LogicalExpression;
3
+ //# sourceMappingURL=accessSafe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accessSafe.d.ts","sourceRoot":"","sources":["../../src/extractor/accessSafe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,cAAc,CAAA;AAIjC,wBAAgB,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC,iBAAiB,CAiBjF"}
@@ -0,0 +1,5 @@
1
+ import * as babelParser from '@babel/parser';
2
+ import type * as t from '@babel/types';
3
+ export declare const parserOptions: babelParser.ParserOptions;
4
+ export declare function babelParse(code: string | Buffer, fileName?: string): t.File;
5
+ //# sourceMappingURL=babelParse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"babelParse.d.ts","sourceRoot":"","sources":["../../src/extractor/babelParse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,eAAe,CAAA;AAC5C,OAAO,KAAK,KAAK,CAAC,MAAM,cAAc,CAAA;AAiBtC,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,aAGtC,CAAA;AAIF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,CAW3E"}
@@ -0,0 +1,7 @@
1
+ import * as t from '@babel/types';
2
+ import type { ClassNameObject } from '../types';
3
+ type Builder = (objects: ClassNameObject[], extras?: string) => t.Expression | t.StringLiteral | null;
4
+ export declare const buildClassName: Builder;
5
+ export declare const buildClassNameLogic: Builder;
6
+ export {};
7
+ //# sourceMappingURL=buildClassName.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildClassName.d.ts","sourceRoot":"","sources":["../../src/extractor/buildClassName.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,cAAc,CAAA;AAEjC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAE/C,KAAK,OAAO,GAAG,CACb,OAAO,EAAE,eAAe,EAAE,EAC1B,MAAM,CAAC,EAAE,MAAM,KACZ,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,aAAa,GAAG,IAAI,CAAA;AAE1C,eAAO,MAAM,cAAc,EAAE,OAU5B,CAAA;AAED,eAAO,MAAM,mBAAmB,EAAE,OAsDjC,CAAA"}