bimba-cli 0.7.25 → 0.7.26

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 (2) hide show
  1. package/package.json +1 -1
  2. package/serve.js +53 -11
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bimba-cli",
3
- "version": "0.7.25",
3
+ "version": "0.7.26",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/HeapVoid/bimba.git"
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 [file, item] of _activeErrors.entries()) {
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 = normalizeFile(file)
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
- if (!sameFile(key, file)) continue
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(file, item) {
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 key = normalizeFile(file)
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(key)
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: key, time: item.time, errors: item.payload })
867
+ broadcast({ type: 'error', file: display, time: item.time, errors: item.payload })
826
868
  return
827
869
  }
828
870
 
829
- showTrackedError(key, item)
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 [nextFile, nextItem] = Array.from(_activeErrors.entries()).at(-1)
861
- showTrackedError(nextFile, nextItem)
902
+ const nextItem = Array.from(_activeErrors.values()).at(-1)
903
+ showTrackedError(nextItem)
862
904
  showedNext = true
863
905
  }
864
906