bimba-cli 0.7.25 → 0.7.27
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/package.json +1 -1
- package/plugin.js +37 -7
- package/serve.js +53 -11
package/package.json
CHANGED
package/plugin.js
CHANGED
|
@@ -22,7 +22,7 @@ export let stats = {
|
|
|
22
22
|
const _activeCompileErrors = new Map();
|
|
23
23
|
|
|
24
24
|
function normalizeCompilePath(filepath) {
|
|
25
|
-
let value = String(filepath || '');
|
|
25
|
+
let value = String(filepath || '').split(/[?#]/)[0];
|
|
26
26
|
if (dir.isAbsolute(value)) {
|
|
27
27
|
const rel = dir.relative(process.cwd(), value);
|
|
28
28
|
if (!rel.startsWith('..')) value = rel;
|
|
@@ -30,6 +30,21 @@ function normalizeCompilePath(filepath) {
|
|
|
30
30
|
return value.replaceAll('\\', '/');
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
function physicalCompileKey(filepath) {
|
|
34
|
+
try {
|
|
35
|
+
const stat = fs.statSync(filepath);
|
|
36
|
+
if (!stat.isFile()) return null;
|
|
37
|
+
const real = fs.realpathSync(filepath).replaceAll('\\', '/');
|
|
38
|
+
return `fs:${stat.dev}:${stat.ino}:${real}`;
|
|
39
|
+
} catch(_) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function compileErrorKey(filepath) {
|
|
45
|
+
return physicalCompileKey(filepath) || `path:${normalizeCompilePath(filepath)}`;
|
|
46
|
+
}
|
|
47
|
+
|
|
33
48
|
function compileErrorMessage(error) {
|
|
34
49
|
return error?.message || String(error);
|
|
35
50
|
}
|
|
@@ -53,15 +68,25 @@ function compileErrorSignature(errors) {
|
|
|
53
68
|
}
|
|
54
69
|
|
|
55
70
|
function shouldPrintCompileError(filepath, errors) {
|
|
56
|
-
const key =
|
|
71
|
+
const key = compileErrorKey(filepath);
|
|
57
72
|
const signature = compileErrorSignature(errors);
|
|
58
73
|
const previous = _activeCompileErrors.get(key);
|
|
59
|
-
_activeCompileErrors.set(key, { signature, time: Date.now() });
|
|
74
|
+
_activeCompileErrors.set(key, { file: normalizeCompilePath(filepath), signature, time: Date.now() });
|
|
60
75
|
return previous?.signature !== signature;
|
|
61
76
|
}
|
|
62
77
|
|
|
63
78
|
function clearCompileError(filepath) {
|
|
64
|
-
_activeCompileErrors.delete(
|
|
79
|
+
_activeCompileErrors.delete(compileErrorKey(filepath));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function printCompileError(error) {
|
|
83
|
+
try {
|
|
84
|
+
printerr(error);
|
|
85
|
+
} catch(_) {
|
|
86
|
+
console.log('');
|
|
87
|
+
console.log(' ' + theme.error(' ' + compileErrorMessage(error) + ' '));
|
|
88
|
+
console.log('');
|
|
89
|
+
}
|
|
65
90
|
}
|
|
66
91
|
|
|
67
92
|
// Target platform for the Imba compiler: 'browser' or 'node'
|
|
@@ -98,11 +123,16 @@ export const imbaPlugin = {
|
|
|
98
123
|
// if no cached version read and compile it with the imba compiler
|
|
99
124
|
const file = await Bun.file(path).text();
|
|
100
125
|
const platform = target === 'node' || target === 'bun' ? 'node' : 'browser';
|
|
101
|
-
|
|
126
|
+
let out
|
|
127
|
+
try {
|
|
128
|
+
out = compiler.compile(file, {
|
|
102
129
|
sourcePath: path,
|
|
103
130
|
platform: platform,
|
|
104
131
|
comments: false
|
|
105
|
-
|
|
132
|
+
})
|
|
133
|
+
} catch (error) {
|
|
134
|
+
out = { js: '', errors: [error] }
|
|
135
|
+
}
|
|
106
136
|
|
|
107
137
|
// the file has been successfully compiled
|
|
108
138
|
if (!out.errors?.length) {
|
|
@@ -121,7 +151,7 @@ export const imbaPlugin = {
|
|
|
121
151
|
if (shouldPrint) {
|
|
122
152
|
stats.reported++;
|
|
123
153
|
for (let i = 0; i < out.errors.length; i++) {
|
|
124
|
-
if(out.errors[i])
|
|
154
|
+
if(out.errors[i]) printCompileError(out.errors[i]);
|
|
125
155
|
}
|
|
126
156
|
}
|
|
127
157
|
stats.errors++;
|
package/serve.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { serve as bunServe } from 'bun'
|
|
2
2
|
import * as compiler from 'imba/compiler'
|
|
3
|
-
import { mkdirSync, watch, existsSync, statSync, writeFileSync } from 'fs'
|
|
3
|
+
import { mkdirSync, watch, existsSync, statSync, writeFileSync, realpathSync } from 'fs'
|
|
4
4
|
import path from 'path'
|
|
5
5
|
import { theme } from './utils.js'
|
|
6
6
|
import { printerr } from './plugin.js'
|
|
@@ -707,7 +707,8 @@ export function serve(entrypoint, flags) {
|
|
|
707
707
|
_statusSaved = true
|
|
708
708
|
_statusKind = 'errors'
|
|
709
709
|
|
|
710
|
-
for (const
|
|
710
|
+
for (const item of _activeErrors.values()) {
|
|
711
|
+
const file = item.file
|
|
711
712
|
process.stdout.write(` ${theme.folder(item.time)} ${theme.filename(file)} ${theme.failure(' fail ')}\n`)
|
|
712
713
|
for (const err of item.errors) {
|
|
713
714
|
try { printerr(err) } catch(_) { process.stdout.write(' ' + err.message + '\n') }
|
|
@@ -738,8 +739,12 @@ export function serve(entrypoint, flags) {
|
|
|
738
739
|
const srcRoot = path.resolve(srcDir)
|
|
739
740
|
const srcRel = normalizeFile(srcRoot)
|
|
740
741
|
|
|
742
|
+
function unprefixFile(file) {
|
|
743
|
+
return normalizeFile(file).replace(/^(?:html|css|js|static):/, '')
|
|
744
|
+
}
|
|
745
|
+
|
|
741
746
|
function fileVariants(file) {
|
|
742
|
-
const key =
|
|
747
|
+
const key = unprefixFile(file)
|
|
743
748
|
const variants = new Set([key])
|
|
744
749
|
|
|
745
750
|
if (srcRel && key.startsWith(srcRel + '/')) variants.add(key.slice(srcRel.length + 1))
|
|
@@ -748,7 +753,38 @@ export function serve(entrypoint, flags) {
|
|
|
748
753
|
return Array.from(variants).filter(Boolean)
|
|
749
754
|
}
|
|
750
755
|
|
|
756
|
+
function fileCandidates(file) {
|
|
757
|
+
const candidates = []
|
|
758
|
+
for (const variant of fileVariants(file)) {
|
|
759
|
+
candidates.push(path.resolve(variant))
|
|
760
|
+
if (!variant.startsWith(srcRel + '/')) candidates.push(path.resolve(srcRoot, variant))
|
|
761
|
+
}
|
|
762
|
+
return candidates
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
function physicalFileKey(file) {
|
|
766
|
+
for (const candidate of fileCandidates(file)) {
|
|
767
|
+
try {
|
|
768
|
+
const stat = statSync(candidate)
|
|
769
|
+
if (!stat.isFile()) continue
|
|
770
|
+
const real = realpathSync(candidate).replaceAll('\\', '/')
|
|
771
|
+
return `fs:${stat.dev}:${stat.ino}:${real}`
|
|
772
|
+
} catch(_) {
|
|
773
|
+
// ignore non-existing aliases
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
return null
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
function errorKey(file) {
|
|
780
|
+
return physicalFileKey(file) || `path:${normalizeFile(file)}`
|
|
781
|
+
}
|
|
782
|
+
|
|
751
783
|
function sameFile(left, right) {
|
|
784
|
+
const leftPhysical = physicalFileKey(left)
|
|
785
|
+
const rightPhysical = physicalFileKey(right)
|
|
786
|
+
if (leftPhysical && rightPhysical && leftPhysical === rightPhysical) return true
|
|
787
|
+
|
|
752
788
|
const lefts = fileVariants(left)
|
|
753
789
|
const rights = fileVariants(right)
|
|
754
790
|
|
|
@@ -763,9 +799,12 @@ export function serve(entrypoint, flags) {
|
|
|
763
799
|
|
|
764
800
|
function takeError(file) {
|
|
765
801
|
let previous = null
|
|
802
|
+
const target = errorKey(file)
|
|
766
803
|
const keys = Array.from(_activeErrors.keys())
|
|
767
804
|
for (const key of keys) {
|
|
768
|
-
|
|
805
|
+
const item = _activeErrors.get(key)
|
|
806
|
+
const storedFile = item?.file || key.replace(/^path:/, '')
|
|
807
|
+
if (key !== target && !sameFile(storedFile, file)) continue
|
|
769
808
|
previous ||= _activeErrors.get(key)
|
|
770
809
|
_activeErrors.delete(key)
|
|
771
810
|
}
|
|
@@ -802,19 +841,22 @@ export function serve(entrypoint, flags) {
|
|
|
802
841
|
.join('\n---\n')
|
|
803
842
|
}
|
|
804
843
|
|
|
805
|
-
function showTrackedError(
|
|
844
|
+
function showTrackedError(item) {
|
|
845
|
+
const file = item.file
|
|
806
846
|
if (_isTTY) renderErrorPanel()
|
|
807
847
|
else printStatus(file, 'fail', item.errors)
|
|
808
848
|
broadcast({ type: 'error', file, time: item.time, errors: item.payload })
|
|
809
849
|
}
|
|
810
850
|
|
|
811
851
|
function reportError(file, errors) {
|
|
812
|
-
const
|
|
852
|
+
const display = normalizeFile(file)
|
|
853
|
+
const key = errorKey(display)
|
|
813
854
|
const list = Array.isArray(errors) ? errors : [errors]
|
|
814
855
|
const signature = errorSignature(list)
|
|
815
|
-
const previous = takeError(
|
|
856
|
+
const previous = takeError(display)
|
|
816
857
|
|
|
817
858
|
const item = {
|
|
859
|
+
file: display,
|
|
818
860
|
signature,
|
|
819
861
|
errors: list,
|
|
820
862
|
payload: serializeErrors(list),
|
|
@@ -822,11 +864,11 @@ export function serve(entrypoint, flags) {
|
|
|
822
864
|
}
|
|
823
865
|
_activeErrors.set(key, item)
|
|
824
866
|
if (previous?.signature === signature && !_isTTY) {
|
|
825
|
-
broadcast({ type: 'error', file:
|
|
867
|
+
broadcast({ type: 'error', file: display, time: item.time, errors: item.payload })
|
|
826
868
|
return
|
|
827
869
|
}
|
|
828
870
|
|
|
829
|
-
showTrackedError(
|
|
871
|
+
showTrackedError(item)
|
|
830
872
|
}
|
|
831
873
|
|
|
832
874
|
function errorText(errors) {
|
|
@@ -857,8 +899,8 @@ export function serve(entrypoint, flags) {
|
|
|
857
899
|
broadcast({ type: 'clear-error', file: key })
|
|
858
900
|
|
|
859
901
|
if (!_isTTY && wasStatusFile && _activeErrors.size) {
|
|
860
|
-
const
|
|
861
|
-
showTrackedError(
|
|
902
|
+
const nextItem = Array.from(_activeErrors.values()).at(-1)
|
|
903
|
+
showTrackedError(nextItem)
|
|
862
904
|
showedNext = true
|
|
863
905
|
}
|
|
864
906
|
|