@hanzogui/static 7.3.0 → 8.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.
- package/dist/check-dep-versions.cjs +1 -1
- package/dist/checkDeps.cjs +10 -10
- package/dist/constants.cjs +2 -2
- package/dist/exports.cjs +2 -0
- package/dist/extractor/bundle.cjs +14 -4
- package/dist/extractor/bundleConfig.cjs +40 -27
- package/dist/extractor/concatClassName.cjs +40 -11
- package/dist/extractor/createExtractor.cjs +137 -30
- package/dist/extractor/extractHelpers.cjs +1 -1
- package/dist/extractor/extractMediaStyle.cjs +5 -5
- package/dist/extractor/extractToClassNames.cjs +52 -4
- package/dist/extractor/extractToNative.cjs +16 -8
- package/dist/extractor/getPrefixLogs.cjs +1 -1
- package/dist/extractor/getStaticBindingsForScope.cjs +2 -2
- package/dist/extractor/loadGui.cjs +52 -46
- package/dist/extractor/regenerateConfig.cjs +17 -17
- package/dist/extractor/watchGuiConfig.cjs +9 -9
- package/dist/getPragmaOptions.cjs +4 -4
- package/dist/registerRequire.cjs +17 -16
- package/package.json +22 -24
- package/src/check-dep-versions.ts +1 -1
- package/src/checkDeps.ts +25 -25
- package/src/constants.ts +2 -2
- package/src/exports.ts +1 -0
- package/src/extractor/bundle.ts +35 -6
- package/src/extractor/bundleConfig.ts +48 -28
- package/src/extractor/concatClassName.ts +37 -20
- package/src/extractor/createExtractor.ts +256 -36
- package/src/extractor/extractHelpers.ts +2 -2
- package/src/extractor/extractMediaStyle.ts +5 -5
- package/src/extractor/extractToClassNames.ts +109 -7
- package/src/extractor/extractToNative.ts +27 -10
- package/src/extractor/getPrefixLogs.ts +1 -1
- package/src/extractor/getStaticBindingsForScope.ts +2 -2
- package/src/extractor/loadGui.ts +66 -51
- package/src/extractor/regenerateConfig.ts +17 -17
- package/src/extractor/watchGuiConfig.ts +14 -9
- package/src/getPragmaOptions.ts +4 -4
- package/src/registerRequire.ts +32 -19
- package/types/constants.d.ts.map +1 -1
- package/types/exports.d.ts +1 -0
- package/types/exports.d.ts.map +1 -1
- package/types/extractor/bundle.d.ts.map +1 -1
- package/types/extractor/bundleConfig.d.ts +1 -1
- package/types/extractor/bundleConfig.d.ts.map +1 -1
- package/types/extractor/createExtractor.d.ts.map +1 -1
- package/types/extractor/extractMediaStyle.d.ts +1 -1
- package/types/extractor/extractMediaStyle.d.ts.map +1 -1
- package/types/extractor/extractToClassNames.d.ts.map +1 -1
- package/types/extractor/extractToNative.d.ts.map +1 -1
- package/types/extractor/loadGui.d.ts +5 -5
- package/types/extractor/loadGui.d.ts.map +1 -1
- package/types/extractor/regenerateConfig.d.ts +3 -3
- package/types/extractor/regenerateConfig.d.ts.map +1 -1
- package/types/extractor/watchGuiConfig.d.ts +1 -1
- package/types/extractor/watchGuiConfig.d.ts.map +1 -1
- package/types/registerRequire.d.ts +1 -1
- package/types/registerRequire.d.ts.map +1 -1
- package/LICENSE +0 -42
package/src/checkDeps.ts
CHANGED
|
@@ -22,10 +22,10 @@ export type Options = {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
// critical packages that must not be duplicated at runtime
|
|
25
|
-
const CRITICAL_PACKAGES = ['@hanzogui/web', '@hanzogui/core', '
|
|
25
|
+
const CRITICAL_PACKAGES = ['@hanzogui/web', '@hanzogui/core', 'hanzogui']
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
* Walks node_modules to find duplicate physical copies of critical
|
|
28
|
+
* Walks node_modules to find duplicate physical copies of critical hanzogui packages.
|
|
29
29
|
* Detects nested node_modules that would cause multiple runtime instances.
|
|
30
30
|
*/
|
|
31
31
|
function checkDuplicateInstalls(root: string): string {
|
|
@@ -60,7 +60,7 @@ function checkDuplicateInstalls(root: string): string {
|
|
|
60
60
|
if (duplicates.size === 0) return ''
|
|
61
61
|
|
|
62
62
|
const lines: string[] = [
|
|
63
|
-
'Found duplicate
|
|
63
|
+
'Found duplicate hanzogui installations in node_modules:',
|
|
64
64
|
'',
|
|
65
65
|
'This causes multiple runtime instances, which breaks theme/config detection.',
|
|
66
66
|
'',
|
|
@@ -92,7 +92,7 @@ function checkDuplicateInstalls(root: string): string {
|
|
|
92
92
|
|
|
93
93
|
/**
|
|
94
94
|
* Recursively find all instances of a package in node_modules.
|
|
95
|
-
* Handles both scoped (@hanzogui/web) and unscoped (
|
|
95
|
+
* Handles both scoped (@hanzogui/web) and unscoped (hanzogui) packages.
|
|
96
96
|
*/
|
|
97
97
|
function findAllInstances(
|
|
98
98
|
nodeModulesDir: string,
|
|
@@ -139,7 +139,7 @@ function findAllInstances(
|
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
/**
|
|
142
|
-
* Checks lockfile for multiple resolved versions of
|
|
142
|
+
* Checks lockfile for multiple resolved versions of hanzogui packages.
|
|
143
143
|
* Supports bun.lock, yarn.lock, and package-lock.json.
|
|
144
144
|
*/
|
|
145
145
|
function checkLockfileDuplicates(root: string): string {
|
|
@@ -162,7 +162,7 @@ function checkBunLockDuplicates(lockPath: string): string {
|
|
|
162
162
|
|
|
163
163
|
// match patterns like "@hanzogui/web@version" or "hanzogui@version" in resolved entries
|
|
164
164
|
// bun.lock format: "package@version": ["resolved-url", ...]
|
|
165
|
-
const packagePattern = /["'](@hanzogui\/[\w-]+|
|
|
165
|
+
const packagePattern = /["'](@hanzogui\/[\w-]+|hanzogui)@([^"'\s,]+)["']/g
|
|
166
166
|
let match: RegExpExecArray | null
|
|
167
167
|
while ((match = packagePattern.exec(content)) !== null) {
|
|
168
168
|
const name = match[1]
|
|
@@ -189,7 +189,7 @@ function checkYarnLockDuplicates(lockPath: string): string {
|
|
|
189
189
|
// yarn.lock format:
|
|
190
190
|
// "@hanzogui/web@^1.0.0":
|
|
191
191
|
// version "1.0.1"
|
|
192
|
-
const entryPattern = /^"?(@hanzogui\/[\w-]+|
|
|
192
|
+
const entryPattern = /^"?(@hanzogui\/[\w-]+|hanzogui)@[^":\n]+[":]?\s*$/gm
|
|
193
193
|
const versionPattern = /^\s+version\s+"([^"]+)"/gm
|
|
194
194
|
|
|
195
195
|
let entryMatch: RegExpExecArray | null
|
|
@@ -260,21 +260,21 @@ function formatLockfileDuplicates(
|
|
|
260
260
|
lines.push(
|
|
261
261
|
'Multiple versions cause duplicate runtime instances, breaking config/theme detection.'
|
|
262
262
|
)
|
|
263
|
-
lines.push('Fix: ensure all
|
|
263
|
+
lines.push('Fix: ensure all hanzogui packages use the same version range, then dedupe.')
|
|
264
264
|
|
|
265
265
|
return lines.join('\n')
|
|
266
266
|
}
|
|
267
267
|
|
|
268
268
|
/**
|
|
269
|
-
* Checks that a
|
|
269
|
+
* Checks that a hanzogui config file exists in common locations.
|
|
270
270
|
*/
|
|
271
271
|
function checkConfigExists(root: string): string {
|
|
272
272
|
const configNames = [
|
|
273
|
-
'
|
|
274
|
-
'
|
|
275
|
-
'
|
|
276
|
-
'
|
|
277
|
-
'
|
|
273
|
+
'hanzogui.config.ts',
|
|
274
|
+
'hanzogui.config.tsx',
|
|
275
|
+
'hanzogui.config.js',
|
|
276
|
+
'hanzogui.config.mjs',
|
|
277
|
+
'hanzogui.config.cjs',
|
|
278
278
|
]
|
|
279
279
|
|
|
280
280
|
const searchDirs = [root, join(root, 'src'), join(root, 'app'), join(root, 'config')]
|
|
@@ -287,12 +287,12 @@ function checkConfigExists(root: string): string {
|
|
|
287
287
|
}
|
|
288
288
|
}
|
|
289
289
|
|
|
290
|
-
// check if
|
|
290
|
+
// check if hanzogui.build.ts references a config path
|
|
291
291
|
const buildConfigNames = [
|
|
292
|
-
'
|
|
293
|
-
'
|
|
294
|
-
'
|
|
295
|
-
'
|
|
292
|
+
'hanzogui.build.ts',
|
|
293
|
+
'hanzogui.build.js',
|
|
294
|
+
'hanzogui.build.mjs',
|
|
295
|
+
'hanzogui.build.cjs',
|
|
296
296
|
]
|
|
297
297
|
for (const name of buildConfigNames) {
|
|
298
298
|
const buildPath = join(root, name)
|
|
@@ -308,13 +308,13 @@ function checkConfigExists(root: string): string {
|
|
|
308
308
|
}
|
|
309
309
|
}
|
|
310
310
|
|
|
311
|
-
// also check if there's a
|
|
311
|
+
// also check if there's a hanzogui config referenced in package.json
|
|
312
312
|
const pkgJsonPath = join(root, 'package.json')
|
|
313
313
|
if (existsSync(pkgJsonPath)) {
|
|
314
314
|
try {
|
|
315
315
|
const pkg = JSON.parse(readFileSync(pkgJsonPath, 'utf8'))
|
|
316
|
-
if (pkg.
|
|
317
|
-
const configPath = join(root, pkg.
|
|
316
|
+
if (pkg.hanzogui?.config) {
|
|
317
|
+
const configPath = join(root, pkg.hanzogui.config)
|
|
318
318
|
if (existsSync(configPath)) return ''
|
|
319
319
|
}
|
|
320
320
|
} catch {}
|
|
@@ -329,12 +329,12 @@ function checkConfigExists(root: string): string {
|
|
|
329
329
|
}
|
|
330
330
|
|
|
331
331
|
return [
|
|
332
|
-
'No
|
|
332
|
+
'No hanzogui.config file found.',
|
|
333
333
|
'',
|
|
334
|
-
'Gui requires a config file (e.g.
|
|
334
|
+
'Gui requires a config file (e.g. hanzogui.config.ts) that calls createGui().',
|
|
335
335
|
'Without it, components will throw "Can\'t find Gui configuration" at runtime.',
|
|
336
336
|
'',
|
|
337
|
-
'See: https://
|
|
337
|
+
'See: https://hanzogui.dev/docs/core/configuration',
|
|
338
338
|
].join('\n')
|
|
339
339
|
}
|
|
340
340
|
|
package/src/constants.ts
CHANGED
|
@@ -6,9 +6,9 @@ export const CSS_FILE_NAME = '__snack.css'
|
|
|
6
6
|
export const MEDIA_SEP = '_'
|
|
7
7
|
|
|
8
8
|
// ensure cache dir
|
|
9
|
-
export const cacheDir = findCacheDir({ name: '
|
|
9
|
+
export const cacheDir = findCacheDir({ name: 'hanzogui', create: true })
|
|
10
10
|
|
|
11
11
|
export const FAILED_EVAL = Symbol('failed_style_eval')
|
|
12
12
|
|
|
13
13
|
export const SHOULD_DEBUG =
|
|
14
|
-
process.env.DEBUG === '*' || process.env.DEBUG?.startsWith('
|
|
14
|
+
process.env.DEBUG === '*' || process.env.DEBUG?.startsWith('hanzogui')
|
package/src/exports.ts
CHANGED
|
@@ -12,4 +12,5 @@ export * from './extractor/watchGuiConfig'
|
|
|
12
12
|
export * from './extractor/createLogger'
|
|
13
13
|
export * from './registerRequire'
|
|
14
14
|
export { detectModuleFormat, clearFormatCache } from './extractor/detectModuleFormat'
|
|
15
|
+
export { esbundleGuiConfig } from './extractor/bundle'
|
|
15
16
|
export * from './getPragmaOptions'
|
package/src/extractor/bundle.ts
CHANGED
|
@@ -53,25 +53,54 @@ type Props = Omit<Partial<esbuild.BuildOptions>, 'entryPoints'> & {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
function getESBuildConfig(
|
|
56
|
-
{
|
|
56
|
+
{
|
|
57
|
+
entryPoints,
|
|
58
|
+
resolvePlatformSpecificEntries,
|
|
59
|
+
define: callerDefine,
|
|
60
|
+
...options
|
|
61
|
+
}: Props,
|
|
57
62
|
platform: GuiPlatform,
|
|
58
63
|
aliases?: Record<string, string>
|
|
59
64
|
) {
|
|
60
|
-
if (process.env.DEBUG?.startsWith('
|
|
65
|
+
if (process.env.DEBUG?.startsWith('hanzogui')) {
|
|
61
66
|
console.info(`Building`, entryPoints)
|
|
62
67
|
}
|
|
63
68
|
|
|
64
69
|
const resolvedEntryPoints = !resolvePlatformSpecificEntries
|
|
65
70
|
? entryPoints
|
|
66
|
-
: entryPoints.map(resolveWebOrNativeSpecificEntry)
|
|
71
|
+
: entryPoints.map((entry) => resolveWebOrNativeSpecificEntry(entry, platform))
|
|
67
72
|
|
|
68
73
|
// detect format from entry points if not explicitly provided by caller
|
|
69
74
|
const detectedFormat = options.format || detectEntryFormat(resolvedEntryPoints[0])
|
|
70
75
|
|
|
76
|
+
// inline platform env vars for the bundled config + components.
|
|
77
|
+
// the bundled output runs in node afterward (CSS extraction time), at which
|
|
78
|
+
// point process.env reflects whatever the build tool's parent process had —
|
|
79
|
+
// not necessarily the platform we're bundling for. inlining via esbuild's
|
|
80
|
+
// define makes the bundle self-consistent regardless of host env, which
|
|
81
|
+
// matters most for vite/vxrn (which doesn't set GUI_TARGET globally
|
|
82
|
+
// because the same plugin handles native too) and for any code in the bundle
|
|
83
|
+
// graph that reads EXPO_OS (expo-modules-core's Platform.OS, etc.).
|
|
84
|
+
const platformDefines: Record<string, string> =
|
|
85
|
+
platform === 'web'
|
|
86
|
+
? {
|
|
87
|
+
'process.env.GUI_TARGET': '"web"',
|
|
88
|
+
'process.env.EXPO_OS': '"web"',
|
|
89
|
+
}
|
|
90
|
+
: {
|
|
91
|
+
'process.env.GUI_TARGET': '"native"',
|
|
92
|
+
// EXPO_OS doesn't have a useful "native" value (it's ios/android),
|
|
93
|
+
// so leave it alone here and let the consumer set it if needed.
|
|
94
|
+
}
|
|
95
|
+
|
|
71
96
|
const res: esbuild.BuildOptions = {
|
|
72
97
|
bundle: true,
|
|
73
98
|
entryPoints: resolvedEntryPoints,
|
|
74
99
|
format: detectedFormat,
|
|
100
|
+
define: {
|
|
101
|
+
...platformDefines,
|
|
102
|
+
...callerDefine,
|
|
103
|
+
},
|
|
75
104
|
// for ESM: prefer "module" field for resolution, add require() shim for bundled CJS deps
|
|
76
105
|
...(detectedFormat === 'esm'
|
|
77
106
|
? {
|
|
@@ -87,7 +116,7 @@ function getESBuildConfig(
|
|
|
87
116
|
allowOverwrite: true,
|
|
88
117
|
keepNames: true,
|
|
89
118
|
resolveExtensions: [
|
|
90
|
-
...(
|
|
119
|
+
...(platform === 'web'
|
|
91
120
|
? ['.web.tsx', '.web.ts', '.web.jsx', '.web.js']
|
|
92
121
|
: ['.native.tsx', '.native.ts', '.native.jsx', '.native.js']),
|
|
93
122
|
'.tsx',
|
|
@@ -148,8 +177,8 @@ function getESBuildConfig(
|
|
|
148
177
|
|
|
149
178
|
// stub files with top-level await - they're typically runtime-only
|
|
150
179
|
if (hasTopLevelAwait(contents, args.path)) {
|
|
151
|
-
if (process.env.DEBUG?.startsWith('
|
|
152
|
-
console.info(`[
|
|
180
|
+
if (process.env.DEBUG?.startsWith('hanzogui')) {
|
|
181
|
+
console.info(`[hanzogui] stubbing file with top-level await: ${args.path}`)
|
|
153
182
|
}
|
|
154
183
|
return {
|
|
155
184
|
// Keep this as an ESM-shaped stub so esbuild doesn't inline a
|
|
@@ -33,7 +33,7 @@ function getDynamicEvalOutfile(name: string, format: 'esm' | 'cjs', contents: st
|
|
|
33
33
|
.update(contents)
|
|
34
34
|
.digest('hex')
|
|
35
35
|
.slice(0, 10)
|
|
36
|
-
return join(process.cwd(), '.
|
|
36
|
+
return join(process.cwd(), '.hanzogui', `dynamic-eval-${hash}-${basename(name)}.${ext}`)
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
function getEsbuildStdinLoader(filePath: string): esbuild.Loader {
|
|
@@ -101,7 +101,7 @@ export type LoadedComponents = {
|
|
|
101
101
|
|
|
102
102
|
export type GuiProjectInfo = {
|
|
103
103
|
components?: LoadedComponents[]
|
|
104
|
-
|
|
104
|
+
hanzoguiConfig?: GuiInternalConfig | null
|
|
105
105
|
nameToPaths?: NameToPaths
|
|
106
106
|
cached?: boolean
|
|
107
107
|
}
|
|
@@ -161,8 +161,8 @@ const handleEsmFeaturesPlugin: esbuild.Plugin = {
|
|
|
161
161
|
|
|
162
162
|
// stub files with top-level await - they're typically runtime-only
|
|
163
163
|
if (hasTopLevelAwait(contents, args.path)) {
|
|
164
|
-
if (process.env.DEBUG?.startsWith('
|
|
165
|
-
console.info(`[
|
|
164
|
+
if (process.env.DEBUG?.startsWith('hanzogui')) {
|
|
165
|
+
console.info(`[hanzogui] stubbing file with top-level await: ${args.path}`)
|
|
166
166
|
}
|
|
167
167
|
return {
|
|
168
168
|
// Keep this as an ESM-shaped stub so esbuild doesn't inline a top-level
|
|
@@ -214,6 +214,7 @@ export type BundledConfig = Exclude<Awaited<ReturnType<typeof bundleConfig>>, un
|
|
|
214
214
|
|
|
215
215
|
// will use cached one if watching
|
|
216
216
|
let currentBundle: BundledConfig | null = null
|
|
217
|
+
let currentBundleKey = ''
|
|
217
218
|
let isBundling = false
|
|
218
219
|
let lastBundle: BundledConfig | null = null
|
|
219
220
|
const waitForBundle = new Set<Function>()
|
|
@@ -230,22 +231,35 @@ let loadedConfig: GuiInternalConfig | null = null
|
|
|
230
231
|
|
|
231
232
|
export const getLoadedConfig = () => loadedConfig
|
|
232
233
|
|
|
234
|
+
function getBundleKey(props: GuiOptions) {
|
|
235
|
+
return JSON.stringify({
|
|
236
|
+
components: props.components,
|
|
237
|
+
config: props.config,
|
|
238
|
+
platform: props.platform,
|
|
239
|
+
})
|
|
240
|
+
}
|
|
241
|
+
|
|
233
242
|
export async function getBundledConfig(props: GuiOptions, rebuild = false) {
|
|
243
|
+
const bundleKey = getBundleKey(props)
|
|
234
244
|
if (isBundling) {
|
|
235
245
|
await new Promise((res) => {
|
|
236
246
|
waitForBundle.add(res)
|
|
237
247
|
})
|
|
238
|
-
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (!currentBundle || currentBundleKey !== bundleKey || rebuild) {
|
|
239
251
|
return await bundleConfig(props)
|
|
240
252
|
}
|
|
253
|
+
|
|
241
254
|
return currentBundle
|
|
242
255
|
}
|
|
243
256
|
|
|
244
|
-
global.
|
|
257
|
+
global.hanzoguiLastLoaded ||= 0
|
|
245
258
|
|
|
246
|
-
function updateLastLoaded(config: any) {
|
|
247
|
-
global.
|
|
248
|
-
global.
|
|
259
|
+
function updateLastLoaded(config: any, bundleKey: string) {
|
|
260
|
+
global.hanzoguiLastLoaded = Date.now()
|
|
261
|
+
global.hanzoguiLastBundledConfig = config
|
|
262
|
+
global.hanzoguiLastBundledConfigKey = bundleKey
|
|
249
263
|
}
|
|
250
264
|
|
|
251
265
|
let hasBundledOnce = false
|
|
@@ -256,10 +270,15 @@ let hasBundledOnce = false
|
|
|
256
270
|
let hasLoggedBuild = false
|
|
257
271
|
|
|
258
272
|
export async function bundleConfig(props: GuiOptions) {
|
|
273
|
+
const bundleKey = getBundleKey(props)
|
|
259
274
|
// webpack is calling this a ton for no reason
|
|
260
|
-
if (
|
|
275
|
+
if (
|
|
276
|
+
global.hanzoguiLastBundledConfig &&
|
|
277
|
+
global.hanzoguiLastBundledConfigKey === bundleKey &&
|
|
278
|
+
Date.now() - global.hanzoguiLastLoaded < 3000
|
|
279
|
+
) {
|
|
261
280
|
// just loaded recently
|
|
262
|
-
return global.
|
|
281
|
+
return global.hanzoguiLastBundledConfig
|
|
263
282
|
}
|
|
264
283
|
|
|
265
284
|
try {
|
|
@@ -268,11 +287,11 @@ export async function bundleConfig(props: GuiOptions) {
|
|
|
268
287
|
const configEntry = props.config
|
|
269
288
|
? getGuiConfigPathFromOptionsConfig(props.config)
|
|
270
289
|
: ''
|
|
271
|
-
const tmpDir = join(process.cwd(), '.
|
|
290
|
+
const tmpDir = join(process.cwd(), '.hanzogui')
|
|
272
291
|
// detect module format from config entry point
|
|
273
292
|
const configFormat = configEntry ? detectModuleFormat(configEntry) : 'cjs'
|
|
274
293
|
const configExt = configFormat === 'esm' ? '.mjs' : '.cjs'
|
|
275
|
-
const configOutPath = join(tmpDir, `
|
|
294
|
+
const configOutPath = join(tmpDir, `hanzogui.config${configExt}`)
|
|
276
295
|
const baseComponents = (props.components || []).filter((x) => x !== '@hanzogui/core')
|
|
277
296
|
// detect format per component module
|
|
278
297
|
const componentFormats: Array<'esm' | 'cjs'> = baseComponents.map((mod) => {
|
|
@@ -297,7 +316,7 @@ export async function bundleConfig(props: GuiOptions) {
|
|
|
297
316
|
|
|
298
317
|
if (
|
|
299
318
|
process.env.NODE_ENV === 'development' &&
|
|
300
|
-
process.env.DEBUG?.startsWith('
|
|
319
|
+
process.env.DEBUG?.startsWith('hanzogui')
|
|
301
320
|
) {
|
|
302
321
|
console.info(`Building config entry`, configEntry)
|
|
303
322
|
}
|
|
@@ -371,10 +390,10 @@ export async function bundleConfig(props: GuiOptions) {
|
|
|
371
390
|
colorLog(
|
|
372
391
|
Color.FgYellow,
|
|
373
392
|
`
|
|
374
|
-
➡ [
|
|
393
|
+
➡ [hanzogui] built config, components, prompt (${Date.now() - start}ms)`
|
|
375
394
|
)
|
|
376
395
|
|
|
377
|
-
if (process.env.DEBUG?.startsWith('
|
|
396
|
+
if (process.env.DEBUG?.startsWith('hanzogui')) {
|
|
378
397
|
colorLog(
|
|
379
398
|
Color.Dim,
|
|
380
399
|
`
|
|
@@ -427,7 +446,7 @@ export async function bundleConfig(props: GuiOptions) {
|
|
|
427
446
|
// check for ProxyWorm - indicates a module loading error
|
|
428
447
|
if (config._isProxyWorm) {
|
|
429
448
|
throw new Error(
|
|
430
|
-
`Got a proxied config - likely a module loading error. Set DEBUG=
|
|
449
|
+
`Got a proxied config - likely a module loading error. Set DEBUG=hanzogui for details.`
|
|
431
450
|
)
|
|
432
451
|
}
|
|
433
452
|
|
|
@@ -459,7 +478,7 @@ export async function bundleConfig(props: GuiOptions) {
|
|
|
459
478
|
component.moduleName
|
|
460
479
|
|
|
461
480
|
if (!component.moduleName) {
|
|
462
|
-
if (process.env.DEBUG?.includes('
|
|
481
|
+
if (process.env.DEBUG?.includes('hanzogui') || process.env.IS_GUI_DEV) {
|
|
463
482
|
console.warn(
|
|
464
483
|
`⚠️ no module name found: ${component.moduleName} ${JSON.stringify(
|
|
465
484
|
baseComponents
|
|
@@ -471,7 +490,7 @@ export async function bundleConfig(props: GuiOptions) {
|
|
|
471
490
|
|
|
472
491
|
if (
|
|
473
492
|
process.env.NODE_ENV === 'development' &&
|
|
474
|
-
process.env.DEBUG?.startsWith('
|
|
493
|
+
process.env.DEBUG?.startsWith('hanzogui')
|
|
475
494
|
) {
|
|
476
495
|
console.info('Loaded components', components)
|
|
477
496
|
}
|
|
@@ -479,18 +498,19 @@ export async function bundleConfig(props: GuiOptions) {
|
|
|
479
498
|
const res = {
|
|
480
499
|
components,
|
|
481
500
|
nameToPaths: {},
|
|
482
|
-
|
|
501
|
+
hanzoguiConfig: config,
|
|
483
502
|
}
|
|
484
503
|
|
|
485
504
|
currentBundle = res
|
|
486
|
-
|
|
505
|
+
currentBundleKey = bundleKey
|
|
506
|
+
updateLastLoaded(res, bundleKey)
|
|
487
507
|
|
|
488
508
|
return res
|
|
489
509
|
} catch (err: any) {
|
|
490
510
|
console.error(
|
|
491
|
-
`Error bundling
|
|
511
|
+
`Error bundling hanzogui config: ${err?.message} (run with DEBUG=hanzogui to see stack)`
|
|
492
512
|
)
|
|
493
|
-
if (process.env.DEBUG?.includes('
|
|
513
|
+
if (process.env.DEBUG?.includes('hanzogui')) {
|
|
494
514
|
console.error(err.stack)
|
|
495
515
|
}
|
|
496
516
|
} finally {
|
|
@@ -502,7 +522,7 @@ export async function bundleConfig(props: GuiOptions) {
|
|
|
502
522
|
|
|
503
523
|
export async function writeGuiCSS(outputCSS: string, config: GuiInternalConfig) {
|
|
504
524
|
const flush = async () => {
|
|
505
|
-
colorLog(Color.FgYellow, ` ➡ [
|
|
525
|
+
colorLog(Color.FgYellow, ` ➡ [hanzogui] output css: ${outputCSS}`)
|
|
506
526
|
await FS.writeFile(outputCSS, css)
|
|
507
527
|
}
|
|
508
528
|
|
|
@@ -624,7 +644,7 @@ export async function loadComponentsInner(
|
|
|
624
644
|
})
|
|
625
645
|
}
|
|
626
646
|
|
|
627
|
-
if (process.env.DEBUG === '
|
|
647
|
+
if (process.env.DEBUG === 'hanzogui') {
|
|
628
648
|
console.info(`loadModule`, loadModule, format)
|
|
629
649
|
}
|
|
630
650
|
|
|
@@ -666,7 +686,7 @@ export async function loadComponentsInner(
|
|
|
666
686
|
} catch (err) {
|
|
667
687
|
console.info('babel err', err, writtenContents)
|
|
668
688
|
writtenContents = fileContents
|
|
669
|
-
if (process.env.DEBUG?.startsWith('
|
|
689
|
+
if (process.env.DEBUG?.startsWith('hanzogui')) {
|
|
670
690
|
console.info(`Error parsing babel likely`, err)
|
|
671
691
|
}
|
|
672
692
|
|
|
@@ -779,7 +799,7 @@ export function loadComponentsInnerSync(
|
|
|
779
799
|
})
|
|
780
800
|
}
|
|
781
801
|
|
|
782
|
-
if (process.env.DEBUG === '
|
|
802
|
+
if (process.env.DEBUG === 'hanzogui') {
|
|
783
803
|
console.info(`loadModule`, loadModule, require.resolve(loadModule))
|
|
784
804
|
}
|
|
785
805
|
|
|
@@ -814,7 +834,7 @@ export function loadComponentsInnerSync(
|
|
|
814
834
|
} catch (err) {
|
|
815
835
|
console.info('babel err', err, writtenContents)
|
|
816
836
|
writtenContents = fileContents
|
|
817
|
-
if (process.env.DEBUG?.startsWith('
|
|
837
|
+
if (process.env.DEBUG?.startsWith('hanzogui')) {
|
|
818
838
|
console.info(`Error parsing babel likely`, err)
|
|
819
839
|
}
|
|
820
840
|
} finally {
|
|
@@ -45,24 +45,9 @@ export function concatClassName(_cn: Record<string, any> | null | undefined): st
|
|
|
45
45
|
continue
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
const nextChar = name[splitIndex + 1]
|
|
49
|
-
// synced to static-ui constants
|
|
50
|
-
// MEDIA_SEP
|
|
51
|
-
const isMediaQuery = nextChar === '_'
|
|
52
|
-
// PSEUDO_SEP
|
|
53
|
-
// commenting out three things to make pseudos override properly
|
|
54
|
-
// (leave in for a bit to see if other bugs pop up later):
|
|
55
|
-
// 1. const isPseudoQuery = nextChar === '0'
|
|
56
48
|
const styleKey = name.slice(1, name.indexOf('-'))
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
// by finding the underscore after the media key name
|
|
60
|
-
const mediaStart = splitIndex + 2
|
|
61
|
-
const mediaEnd = name.indexOf('_', mediaStart)
|
|
62
|
-
const mediaKey =
|
|
63
|
-
isMediaQuery && mediaEnd > mediaStart ? name.slice(mediaStart, mediaEnd) : null
|
|
64
|
-
const uid = mediaKey ? styleKey + mediaKey : styleKey
|
|
65
|
-
// 3. && !isPseudoQuery
|
|
49
|
+
const { mediaKey, pseudoKey } = getClassNameScope(name, splitIndex)
|
|
50
|
+
const uid = `${styleKey}${mediaKey ? `@${mediaKey}` : ''}${pseudoKey ? `:${pseudoKey}` : ''}`
|
|
66
51
|
|
|
67
52
|
if (usedPrefixes.has(uid)) {
|
|
68
53
|
// if (shouldDebug) console.log('debug exclude:', usedPrefixes, name)
|
|
@@ -75,8 +60,8 @@ export function concatClassName(_cn: Record<string, any> | null | undefined): st
|
|
|
75
60
|
if (propName && propObjects) {
|
|
76
61
|
if (
|
|
77
62
|
propObjects.some((po) => {
|
|
78
|
-
if (
|
|
79
|
-
const propKey = pseudoInvert[
|
|
63
|
+
if (pseudoKey) {
|
|
64
|
+
const propKey = pseudoInvert[pseudoKey]
|
|
80
65
|
return po && po[propKey] && propName in po[propKey] && po[propKey] !== null
|
|
81
66
|
}
|
|
82
67
|
const res = po && propName in po && po[propName] !== null
|
|
@@ -95,11 +80,43 @@ export function concatClassName(_cn: Record<string, any> | null | undefined): st
|
|
|
95
80
|
return final.trim()
|
|
96
81
|
}
|
|
97
82
|
|
|
83
|
+
function getClassNameScope(name: string, splitIndex: number) {
|
|
84
|
+
let mediaKey = ''
|
|
85
|
+
let pseudoKey = ''
|
|
86
|
+
let valueStart = splitIndex + 1
|
|
87
|
+
|
|
88
|
+
if (name[valueStart] === '_') {
|
|
89
|
+
const mediaEnd = name.indexOf('_', valueStart + 1)
|
|
90
|
+
if (mediaEnd > valueStart + 1) {
|
|
91
|
+
mediaKey = name.slice(valueStart + 1, mediaEnd)
|
|
92
|
+
valueStart = mediaEnd + 1
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (name[valueStart] === '0') {
|
|
97
|
+
const pseudoStart = valueStart + 1
|
|
98
|
+
for (const nextPseudoKey of pseudoKeys) {
|
|
99
|
+
if (name.startsWith(`${nextPseudoKey}-`, pseudoStart)) {
|
|
100
|
+
pseudoKey = nextPseudoKey
|
|
101
|
+
break
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return { mediaKey, pseudoKey }
|
|
107
|
+
}
|
|
108
|
+
|
|
98
109
|
const pseudoInvert = {
|
|
99
110
|
hover: 'hoverStyle',
|
|
111
|
+
active: 'pressStyle',
|
|
100
112
|
focus: 'focusStyle',
|
|
101
|
-
|
|
113
|
+
'focus-visible': 'focusVisibleStyle',
|
|
114
|
+
'focus-within': 'focusWithinStyle',
|
|
102
115
|
focusVisible: 'focusVisibleStyle',
|
|
103
116
|
focusWithin: 'focusWithinStyle',
|
|
104
117
|
disabled: 'disabledStyle',
|
|
118
|
+
enter: 'enterStyle',
|
|
119
|
+
exit: 'exitStyle',
|
|
105
120
|
}
|
|
121
|
+
|
|
122
|
+
const pseudoKeys = Object.keys(pseudoInvert).sort((a, b) => b.length - a.length)
|