coralite-scripts 0.25.0 → 0.27.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/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ > ⚠️ **NOTE: This is a read-only mirror.** Development happens on [Codeberg](https://codeberg.org/tjdavid/coralite).
2
+
1
3
  # Coralite Development Environment Guide
2
4
 
3
5
  Welcome to **Coralite starter script**, a lightweight Static Site Generator (SSG) built for rapid development and clean output. This guide walks you through setting up your local development environment using the provided `coralite-scripts` package and configuration files.
@@ -11,9 +13,9 @@ Coralite expects a standard folder layout:
11
13
  ```
12
14
  my-coralite-site/
13
15
  ├── src/
14
- │ ├── pages/ # Your page templates (e.g., `about.html`, `index.html`)
16
+ │ ├── pages/ # Your page components (e.g., `about.html`, `index.html`)
15
17
  │ ├── scss/ # SCSS/Sass styles
16
- │ └── templates/ # Reusable template files
18
+ │ └── components/ # Reusable component files
17
19
  ├── public/ # Static assets (CSS, JS, images)
18
20
  ├── dist/ # Output directory for built site (auto-generated)
19
21
  ├── coralite.config.js # Configuration file
@@ -33,7 +35,7 @@ export default defineConfig({
33
35
  output: 'dist',
34
36
  public: 'public',
35
37
  pages: 'src/pages',
36
- templates: 'src/templates',
38
+ components: 'src/components',
37
39
  sass: {
38
40
  input: 'src/scss'
39
41
  }
@@ -74,7 +76,7 @@ Coralite provides real-time development workflows out of the box:
74
76
  |-------|-------------|
75
77
  | **Live Reload** | Automatically reloads browser when any `.html`, `.scss`, or `.sass` file changes. |
76
78
  | **Hot CSS Updates** | Sass/SCSS files are compiled instantly and injected into your page via Server-Sent Events (SSE). |
77
- | **File Watching** | Monitors `src/pages`, `src/scss`, `public`, and `src/templates`. |
79
+ | **File Watching** | Monitors `src/pages`, `src/scss`, `public`, and `src/components`. |
78
80
  | **Dev Logs** | Shows real-time build times, file changes, and status codes in terminal. |
79
81
 
80
82
  ---
package/bin/index.js CHANGED
@@ -59,7 +59,7 @@ if (mode === 'dev') {
59
59
  const start = process.hrtime()
60
60
  // start coralite
61
61
  const coralite = new Coralite({
62
- templates: config.templates,
62
+ components: config.components,
63
63
  pages: config.pages,
64
64
  plugins: config.plugins
65
65
  })
@@ -80,7 +80,7 @@ if (mode === 'dev') {
80
80
  const outFile = join(outDir, result.path.filename)
81
81
 
82
82
  await mkdir(outDir, { recursive: true })
83
- await writeFile(outFile, result.html)
83
+ await writeFile(outFile, result.content)
84
84
 
85
85
  if (options.verbose) {
86
86
  process.stdout.write(toTime() + toMS(result.duration) + dash + result.path.pathname + '\n')
@@ -16,7 +16,7 @@
16
16
  *
17
17
  * export default defineConfig({
18
18
  * output: './dist',
19
- * templates: './src/templates',
19
+ * components: './src/components',
20
20
  * pages: './src/pages',
21
21
  * public: './public',
22
22
  * server: {
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../libs/config.js"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,sCArBW,oBAAoB,GAClB,oBAAoB,CAuEhC;0CAjFsC,mBAAmB"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../libs/config.js"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,sCArBW,oBAAoB,GAClB,oBAAoB,CAmHhC;0CA7HsC,mBAAmB"}
package/libs/build-css.js CHANGED
@@ -21,8 +21,7 @@ import path from 'path'
21
21
  async function buildCSS ({
22
22
  input,
23
23
  output,
24
- plugins = [],
25
- start
24
+ plugins = []
26
25
  }) {
27
26
  try {
28
27
  // ensure output directory exists
@@ -31,9 +30,8 @@ async function buildCSS ({
31
30
  // read all files from src/scss directory
32
31
  const cssFiles = await fs.readdir(input)
33
32
  const filteredCssFiles = cssFiles.filter(file => file.endsWith('.css'))
34
- const results = []
35
33
 
36
- for (const file of filteredCssFiles) {
34
+ const results = await Promise.all(filteredCssFiles.map(async (file) => {
37
35
  const filePath = path.join(input, file)
38
36
  const outputFile = path.join(output, file)
39
37
  const css = await fs.readFile(filePath)
@@ -49,16 +47,16 @@ async function buildCSS ({
49
47
 
50
48
  await fs.writeFile(outputFile, result.css)
51
49
 
52
- if ( result.map ) {
50
+ if (result.map) {
53
51
  await fs.writeFile(outputFile + '.map', result.map.toString())
54
52
  }
55
53
 
56
- results.push({
54
+ return {
57
55
  input: filePath,
58
56
  output: outputFile,
59
57
  duration
60
- })
61
- }
58
+ }
59
+ }))
62
60
 
63
61
  return results
64
62
  } catch (error) {
@@ -31,10 +31,10 @@ async function buildSass ({
31
31
  silenceDeprecations: [
32
32
  'color-functions',
33
33
  'import',
34
- 'global-builtin'
34
+ 'global-builtin',
35
+ 'elseif'
35
36
  ]
36
- },
37
- start
37
+ }
38
38
  }) {
39
39
  try {
40
40
  // ensure output directory exists
@@ -43,33 +43,33 @@ async function buildSass ({
43
43
  // read all files from src/scss directory
44
44
  const scssFiles = await fs.readdir(input)
45
45
  const filteredScssFiles = scssFiles.filter(file => file.endsWith('.scss') && file[0] !== '_')
46
- const results = []
47
46
 
48
- for (const file of filteredScssFiles) {
47
+ const results = await Promise.all(filteredScssFiles.map(async (file) => {
49
48
  const filePath = path.join(input, file)
50
49
  const outputFile = path.join(output, file.replace('.scss', '.css'))
51
50
 
51
+ // start duration timer.
52
52
  const fileStart = process.hrtime()
53
53
 
54
+ // compile sass
54
55
  const result = await sass.compileAsync(filePath, options)
55
56
 
57
+ // record duration
56
58
  const duration = process.hrtime(fileStart)
57
59
 
58
- // write the compiled CSS
59
60
  await fs.writeFile(outputFile, result.css)
60
61
 
61
- // write source map if enabled
62
62
  if (result.sourceMap) {
63
63
  const sourceMapPath = outputFile + '.map'
64
64
  await fs.writeFile(sourceMapPath, JSON.stringify(result.sourceMap))
65
65
  }
66
66
 
67
- results.push({
67
+ return {
68
68
  input: filePath,
69
69
  output: outputFile,
70
70
  duration
71
- })
72
- }
71
+ }
72
+ }))
73
73
 
74
74
  return results
75
75
  } catch (error) {
package/libs/config.js CHANGED
@@ -17,7 +17,7 @@
17
17
  *
18
18
  * export default defineConfig({
19
19
  * output: './dist',
20
- * templates: './src/templates',
20
+ * components: './src/components',
21
21
  * pages: './src/pages',
22
22
  * public: './public',
23
23
  * server: {
@@ -39,8 +39,8 @@ export function defineConfig (options) {
39
39
  throw new Error('Configuration must contain a valid "output" property')
40
40
  }
41
41
 
42
- if (!options.templates || typeof options.templates !== 'string') {
43
- throw new Error('Configuration must contain a valid "templates" property')
42
+ if (!options.components || typeof options.components !== 'string') {
43
+ throw new Error('Configuration must contain a valid "components" property')
44
44
  }
45
45
 
46
46
  if (!options.pages || typeof options.pages !== 'string') {
@@ -79,5 +79,49 @@ export function defineConfig (options) {
79
79
  throw new Error('Configuration must contain a valid "public" property')
80
80
  }
81
81
 
82
+ if (options.ignoreByAttribute) {
83
+ if (!Array.isArray(options.ignoreByAttribute)) {
84
+ throw new Error('Configuration "ignoreByAttribute" must be an array')
85
+ }
86
+
87
+ for (let i = 0; i < options.ignoreByAttribute.length; i++) {
88
+ const item = options.ignoreByAttribute[i]
89
+ if (typeof item === 'string') {
90
+ continue
91
+ }
92
+ if (!item || typeof item !== 'object') {
93
+ throw new Error('Configuration "ignoreByAttribute" items must be strings or objects')
94
+ }
95
+ if (typeof item.name !== 'string') {
96
+ throw new Error('Configuration "ignoreByAttribute" items must have a string "name" property')
97
+ }
98
+ if (typeof item.value !== 'string') {
99
+ throw new Error('Configuration "ignoreByAttribute" items must have a string "value" property')
100
+ }
101
+ }
102
+ }
103
+
104
+ if (options.skipRenderByAttribute) {
105
+ if (!Array.isArray(options.skipRenderByAttribute)) {
106
+ throw new Error('Configuration "skipRenderByAttribute" must be an array')
107
+ }
108
+
109
+ for (let i = 0; i < options.skipRenderByAttribute.length; i++) {
110
+ const item = options.skipRenderByAttribute[i]
111
+ if (typeof item === 'string') {
112
+ continue
113
+ }
114
+ if (!item || typeof item !== 'object') {
115
+ throw new Error('Configuration "skipRenderByAttribute" items must be strings or objects')
116
+ }
117
+ if (typeof item.name !== 'string') {
118
+ throw new Error('Configuration "skipRenderByAttribute" items must have a string "name" property')
119
+ }
120
+ if (typeof item.value !== 'string') {
121
+ throw new Error('Configuration "skipRenderByAttribute" items must have a string "value" property')
122
+ }
123
+ }
124
+ }
125
+
82
126
  return options
83
127
  }
package/libs/server.js CHANGED
@@ -34,9 +34,11 @@ async function server (config, options) {
34
34
  // start coralite
35
35
  displayInfo('Initializing Coralite...')
36
36
  const coralite = new Coralite({
37
- templates: config.templates,
37
+ components: config.components,
38
38
  pages: config.pages,
39
39
  plugins: config.plugins,
40
+ ignoreByAttribute: config.ignoreByAttribute,
41
+ skipRenderByAttribute: config.skipRenderByAttribute,
40
42
  mode: 'development'
41
43
  })
42
44
  await coralite.initialise()
@@ -53,7 +55,7 @@ async function server (config, options) {
53
55
  const watchPath = [
54
56
  config.public,
55
57
  config.pages,
56
- config.templates
58
+ config.components
57
59
  ]
58
60
 
59
61
  // no cache middleware
@@ -258,7 +260,7 @@ async function server (config, options) {
258
260
  // build the HTML for this page using the built-in compiler.
259
261
  const documents = await coralite.build(pathname, (result) => {
260
262
  // inject a script to enable live reload via Server-Sent Events
261
- const injectedHtml = result.html.replace(/<\/body>/i, rebuildScript)
263
+ const injectedHtml = result.content.replace(/<\/body>/i, rebuildScript)
262
264
 
263
265
  const relPath = relative(config.pages, result.path.pathname)
264
266
  const normalizedKey = relPath.split(sep).join('/')
@@ -275,7 +277,7 @@ async function server (config, options) {
275
277
 
276
278
  return {
277
279
  path: result.path,
278
- html: injectedHtml,
280
+ content: injectedHtml,
279
281
  duration: result.duration
280
282
  }
281
283
  })
@@ -292,7 +294,7 @@ async function server (config, options) {
292
294
  })
293
295
 
294
296
  if (doc) {
295
- res.send(doc.html)
297
+ res.send(doc.content)
296
298
  } else {
297
299
  res.sendStatus(404)
298
300
  }
@@ -313,7 +315,7 @@ async function server (config, options) {
313
315
  ignoreInitial: true
314
316
  })
315
317
 
316
- const templatePath = normalize(config.templates)
318
+ const componentPath = normalize(config.components)
317
319
  const pagesPath = normalize(config.pages)
318
320
 
319
321
  // Debouncing and compilation state management
@@ -341,14 +343,14 @@ async function server (config, options) {
341
343
 
342
344
  // Group changes by type
343
345
  const pagesChanges = changes.filter(p => p.startsWith(pagesPath))
344
- const templateChanges = changes.filter(p => p.startsWith(templatePath))
346
+ const componentChanges = changes.filter(p => p.startsWith(componentPath))
345
347
  const sassChanges = changes.filter(p => p.endsWith('.scss') || p.endsWith('.sass'))
346
348
  const cssChanges = changes.filter(p => p.endsWith('.css'))
347
349
 
348
350
  try {
349
- // Handle template changes
350
- for (const path of templateChanges) {
351
- await coralite.templates.setItem(path)
351
+ // Handle component changes
352
+ for (const path of componentChanges) {
353
+ await coralite.components.setItem(path)
352
354
  }
353
355
 
354
356
  // Handle SASS changes - rebuild all SASS files once
@@ -381,7 +383,7 @@ async function server (config, options) {
381
383
 
382
384
  // Notify clients to reload
383
385
  if (pagesChanges.length > 0
384
- || templateChanges.length > 0
386
+ || componentChanges.length > 0
385
387
  || sassChanges.length > 0
386
388
  || cssChanges.length > 0) {
387
389
  clients.forEach(client => {
@@ -399,8 +401,8 @@ async function server (config, options) {
399
401
  watcher
400
402
  .on('unlink', async (path) => {
401
403
  try {
402
- if (path.startsWith(templatePath)) {
403
- await coralite.templates.deleteItem(path)
404
+ if (path.startsWith(componentPath)) {
405
+ await coralite.components.deleteItem(path)
404
406
  } else if (path.startsWith(pagesPath)) {
405
407
  await coralite.pages.deleteItem(path)
406
408
  }
@@ -415,9 +417,9 @@ async function server (config, options) {
415
417
  })
416
418
  .on('add', async (path) => {
417
419
  try {
418
- if (path.startsWith(templatePath)) {
419
- // set template item
420
- coralite.templates.setItem(path)
420
+ if (path.startsWith(componentPath)) {
421
+ // set component item
422
+ coralite.components.setItem(path)
421
423
  } else if (path.endsWith('.scss') || path.endsWith('.sass')) {
422
424
  // Add to pending changes and trigger debounced compilation
423
425
  pendingChanges.add(path)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coralite-scripts",
3
- "version": "0.25.0",
3
+ "version": "0.27.0",
4
4
  "description": "Configuration and scripts for Create Coralite.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -58,7 +58,7 @@
58
58
  "portfinder": "^1.0.38",
59
59
  "postcss": "^8.5.6",
60
60
  "sass": "^1.91.0",
61
- "coralite": "0.25.0"
61
+ "coralite": "0.27.0"
62
62
  },
63
63
  "scripts": {
64
64
  "build": "premove dist && pnpm build-types",