@bookklik/senangstart-css 0.2.9 → 0.2.12
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/.agent/skills/add-utility/SKILL.md +65 -0
- package/.agent/workflows/add-utility.md +2 -0
- package/.agent/workflows/build.md +2 -0
- package/.agent/workflows/dev.md +2 -0
- package/AGENTS.md +30 -0
- package/dist/senangstart-css.js +607 -180
- package/dist/senangstart-css.min.js +234 -195
- package/dist/senangstart-tw.js +274 -8
- package/dist/senangstart-tw.min.js +1 -1
- package/docs/SYNTAX-REFERENCE.md +1731 -1590
- package/docs/guide/preflight.md +20 -1
- package/docs/ms/guide/preflight.md +19 -0
- package/docs/ms/reference/breakpoints.md +14 -0
- package/docs/ms/reference/visual/border-radius.md +50 -10
- package/docs/ms/reference/visual/contain.md +57 -0
- package/docs/ms/reference/visual/content-visibility.md +53 -0
- package/docs/ms/reference/visual/placeholder-color.md +92 -0
- package/docs/ms/reference/visual/ring-color.md +2 -2
- package/docs/ms/reference/visual/ring-offset.md +3 -3
- package/docs/ms/reference/visual/ring.md +5 -5
- package/docs/ms/reference/visual/writing-mode.md +53 -0
- package/docs/ms/reference/visual.md +6 -0
- package/docs/public/assets/senangstart-css.min.js +234 -195
- package/docs/public/llms.txt +45 -12
- package/docs/reference/breakpoints.md +14 -0
- package/docs/reference/visual/border-radius.md +50 -10
- package/docs/reference/visual/contain.md +57 -0
- package/docs/reference/visual/content-visibility.md +53 -0
- package/docs/reference/visual/placeholder-color.md +92 -0
- package/docs/reference/visual/ring-color.md +2 -2
- package/docs/reference/visual/ring-offset.md +3 -3
- package/docs/reference/visual/ring.md +5 -5
- package/docs/reference/visual/writing-mode.md +53 -0
- package/docs/reference/visual.md +7 -0
- package/docs/syntax-reference.json +2185 -2009
- package/package.json +1 -1
- package/scripts/convert-tailwind.js +300 -26
- package/scripts/generate-docs.js +403 -403
- package/src/cdn/senangstart-engine.js +5 -5
- package/src/cdn/tw-conversion-engine.js +305 -8
- package/src/cli/commands/build.js +51 -13
- package/src/cli/commands/dev.js +157 -93
- package/src/compiler/generators/css.js +467 -208
- package/src/compiler/generators/preflight.js +26 -13
- package/src/compiler/generators/typescript.js +3 -1
- package/src/compiler/index.js +27 -3
- package/src/compiler/parser.js +13 -6
- package/src/compiler/tokenizer.js +25 -23
- package/src/config/defaults.js +3 -0
- package/src/core/tokenizer-core.js +46 -19
- package/src/definitions/index.js +4 -1
- package/src/definitions/visual-borders.js +10 -10
- package/src/definitions/visual-performance.js +126 -0
- package/src/definitions/visual.js +25 -9
- package/src/utils/common.js +456 -27
- package/src/utils/node-io.js +82 -0
- package/tests/integration/dev-recovery.test.js +231 -0
- package/tests/unit/cli/memory-limits.test.js +169 -0
- package/tests/unit/compiler/css-generation-error-handling.test.js +204 -0
- package/tests/unit/compiler/generators/css-errors.test.js +102 -0
- package/tests/unit/compiler/generators/css.test.js +102 -5
- package/tests/unit/convert-tailwind.test.js +518 -431
- package/tests/unit/utils/common.test.js +376 -26
- package/tests/unit/utils/file-timeout.test.js +154 -0
- package/tests/unit/utils/theme-validation.test.js +181 -0
- package/tests/unit/compiler/generators/css.coverage.test.js +0 -833
- package/tests/unit/convert-tailwind.cli.test.js +0 -95
- package/tests/unit/security.test.js +0 -206
- /package/tests/unit/{convert-tailwind.coverage.test.js → convert-tailwind-edgecases.test.js} +0 -0
package/src/cli/commands/dev.js
CHANGED
|
@@ -1,93 +1,157 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SenangStart CSS - Dev Command
|
|
3
|
-
* Watch mode with live compilation
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import chokidar from 'chokidar';
|
|
7
|
-
import { build } from './build.js';
|
|
8
|
-
import logger from '../../utils/logger.js';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Dev command handler - watches files and rebuilds on changes
|
|
12
|
-
*/
|
|
13
|
-
export async function dev(options = {}) {
|
|
14
|
-
logger.watch('Starting development mode...');
|
|
15
|
-
|
|
16
|
-
//
|
|
17
|
-
let
|
|
18
|
-
let
|
|
19
|
-
|
|
20
|
-
//
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
'
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
.on('
|
|
86
|
-
logger.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
1
|
+
/**
|
|
2
|
+
* SenangStart CSS - Dev Command
|
|
3
|
+
* Watch mode with live compilation
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import chokidar from 'chokidar';
|
|
7
|
+
import { build } from './build.js';
|
|
8
|
+
import logger from '../../utils/logger.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Dev command handler - watches files and rebuilds on changes
|
|
12
|
+
*/
|
|
13
|
+
export async function dev(options = {}) {
|
|
14
|
+
logger.watch('Starting development mode...');
|
|
15
|
+
|
|
16
|
+
// Error tracking for cooldown mechanism
|
|
17
|
+
let consecutiveErrors = 0;
|
|
18
|
+
let lastErrorTime = 0;
|
|
19
|
+
const MAX_CONSECUTIVE_ERRORS = 5;
|
|
20
|
+
const COOLDOWN_DURATION = 30000; // 30 seconds
|
|
21
|
+
|
|
22
|
+
// Build lock to prevent overlapping builds
|
|
23
|
+
let buildInProgress = false;
|
|
24
|
+
let pendingBuild = false;
|
|
25
|
+
|
|
26
|
+
async function runBuild() {
|
|
27
|
+
// Check if we're in cooldown
|
|
28
|
+
if (consecutiveErrors >= MAX_CONSECUTIVE_ERRORS) {
|
|
29
|
+
const timeSinceLastError = Date.now() - lastErrorTime;
|
|
30
|
+
if (timeSinceLastError < COOLDOWN_DURATION) {
|
|
31
|
+
const cooldownRemaining = Math.ceil((COOLDOWN_DURATION - timeSinceLastError) / 1000);
|
|
32
|
+
logger.warn(`Cooldown active: ${cooldownRemaining}s remaining. Skipping build.`);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
// Cooldown expired, reset error count
|
|
36
|
+
consecutiveErrors = 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
await build(options);
|
|
41
|
+
// Reset error count on successful build
|
|
42
|
+
consecutiveErrors = 0;
|
|
43
|
+
} catch (error) {
|
|
44
|
+
consecutiveErrors++;
|
|
45
|
+
lastErrorTime = Date.now();
|
|
46
|
+
logger.error(`Build failed (${consecutiveErrors}/${MAX_CONSECUTIVE_ERRORS}): ${error.message}`);
|
|
47
|
+
|
|
48
|
+
// Enter cooldown if max errors reached
|
|
49
|
+
if (consecutiveErrors >= MAX_CONSECUTIVE_ERRORS) {
|
|
50
|
+
logger.warn(`Maximum consecutive errors (${MAX_CONSECUTIVE_ERRORS}) reached.`);
|
|
51
|
+
logger.warn(`Entering ${COOLDOWN_DURATION / 1000}s cooldown to prevent resource exhaustion.`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Initial build
|
|
57
|
+
await runBuild();
|
|
58
|
+
|
|
59
|
+
function createWatcher() {
|
|
60
|
+
// Watch patterns
|
|
61
|
+
const watchPatterns = [
|
|
62
|
+
'./**/*.html',
|
|
63
|
+
'./**/*.htm',
|
|
64
|
+
'./src/**/*.{html,jsx,tsx,vue,svelte}',
|
|
65
|
+
'./pages/**/*.{html,jsx,tsx}',
|
|
66
|
+
'./components/**/*.{html,jsx,tsx,vue,svelte}'
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
// Ignore patterns
|
|
70
|
+
const ignorePatterns = [
|
|
71
|
+
'**/node_modules/**',
|
|
72
|
+
'**/dist/**',
|
|
73
|
+
'**/.git/**',
|
|
74
|
+
'**/public/**'
|
|
75
|
+
];
|
|
76
|
+
|
|
77
|
+
// Create watcher
|
|
78
|
+
const watcher = chokidar.watch(watchPatterns, {
|
|
79
|
+
ignored: ignorePatterns,
|
|
80
|
+
persistent: true,
|
|
81
|
+
ignoreInitial: true
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Handle watcher errors
|
|
85
|
+
watcher.on('error', (error) => {
|
|
86
|
+
logger.error(`Watcher error: ${error.message}`);
|
|
87
|
+
consecutiveErrors++;
|
|
88
|
+
lastErrorTime = Date.now();
|
|
89
|
+
|
|
90
|
+
// Try to restart watcher after error
|
|
91
|
+
logger.info('Attempting to restart watcher...');
|
|
92
|
+
try {
|
|
93
|
+
watcher.close();
|
|
94
|
+
setTimeout(() => {
|
|
95
|
+
const newWatcher = createWatcher();
|
|
96
|
+
Object.assign(watcher, newWatcher);
|
|
97
|
+
logger.success('Watcher restarted successfully');
|
|
98
|
+
}, 1000);
|
|
99
|
+
} catch (restartError) {
|
|
100
|
+
logger.error(`Failed to restart watcher: ${restartError.message}`);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
return watcher;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Initialize watcher
|
|
108
|
+
const watcher = createWatcher();
|
|
109
|
+
|
|
110
|
+
// Debounce timer
|
|
111
|
+
let debounceTimer = null;
|
|
112
|
+
|
|
113
|
+
async function debouncedBuild() {
|
|
114
|
+
if (buildInProgress) {
|
|
115
|
+
pendingBuild = true;
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
buildInProgress = true;
|
|
120
|
+
|
|
121
|
+
if (debounceTimer) {
|
|
122
|
+
clearTimeout(debounceTimer);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
debounceTimer = setTimeout(async () => {
|
|
126
|
+
logger.watch('Change detected, rebuilding...');
|
|
127
|
+
await runBuild();
|
|
128
|
+
buildInProgress = false;
|
|
129
|
+
|
|
130
|
+
// Handle pending build
|
|
131
|
+
if (pendingBuild) {
|
|
132
|
+
pendingBuild = false;
|
|
133
|
+
debouncedBuild();
|
|
134
|
+
}
|
|
135
|
+
}, 100);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Watch events
|
|
139
|
+
watcher
|
|
140
|
+
.on('change', (path) => {
|
|
141
|
+
logger.info(`Changed: ${path}`);
|
|
142
|
+
debouncedBuild();
|
|
143
|
+
})
|
|
144
|
+
.on('add', (path) => {
|
|
145
|
+
logger.info(`Added: ${path}`);
|
|
146
|
+
debouncedBuild();
|
|
147
|
+
})
|
|
148
|
+
.on('unlink', (path) => {
|
|
149
|
+
logger.info(`Removed: ${path}`);
|
|
150
|
+
debouncedBuild();
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
logger.watch('Watching for changes... (Ctrl+C to stop)');
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export default dev;
|
|
157
|
+
|