bimba-cli 0.7.5 → 0.7.7

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 +29 -28
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bimba-cli",
3
- "version": "0.7.5",
3
+ "version": "0.7.7",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/HeapVoid/bimba.git"
package/serve.js CHANGED
@@ -113,6 +113,8 @@ const hmrClient = `
113
113
  _collector = prev;
114
114
  }
115
115
 
116
+ console.log('[bimba HMR]', file, 'slots=' + slots, 'tags:', collected.join(', '));
117
+
116
118
  // Sync _ns_ (CSS namespace) from the new classes. imba_defineTag sets
117
119
  // _ns_ on NewClass.prototype AFTER register$ calls customElements.define,
118
120
  // so _patchClass missed it. Now that import is done, all _ns_ values are set.
@@ -144,6 +146,7 @@ const hmrClient = `
144
146
  if (slots !== 'stable') {
145
147
  for (const tag of collected) {
146
148
  const els = document.querySelectorAll(tag);
149
+ console.log('[bimba HMR] destructive:', tag, 'instances:', els.length);
147
150
  els.forEach(el => {
148
151
  const state = {};
149
152
  for (const k of Object.keys(el)) state[k] = el[k];
@@ -159,10 +162,36 @@ const hmrClient = `
159
162
  try { el.mount && el.mount(); } catch(_) {}
160
163
  });
161
164
  }
165
+ } else {
166
+ for (const tag of collected) {
167
+ const els = document.querySelectorAll(tag);
168
+ console.log('[bimba HMR] stable:', tag, 'instances:', els.length);
169
+ }
170
+ }
171
+
172
+ // Snapshot DOM before commit to detect duplication
173
+ const _domBefore = {};
174
+ for (const tag of collected) {
175
+ _domBefore[tag] = {
176
+ count: document.querySelectorAll(tag).length,
177
+ bodyChildren: document.body.children.length,
178
+ };
162
179
  }
163
180
 
164
181
  if (typeof imba !== 'undefined') imba.commit();
165
182
 
183
+ // Check DOM after commit (delayed to let rAF fire)
184
+ requestAnimationFrame(() => {
185
+ for (const tag of collected) {
186
+ const after = document.querySelectorAll(tag).length;
187
+ const before = _domBefore[tag]?.count || 0;
188
+ if (after !== before) {
189
+ console.warn('[bimba HMR] DUPLICATION:', tag, before, '->', after);
190
+ }
191
+ console.log('[bimba HMR] after commit:', tag, 'count:', after, 'body children:', document.body.children.length);
192
+ }
193
+ });
194
+
166
195
  // Patch className on ALL custom elements: replace old CSS namespace
167
196
  // hashes with new ones. Must be global because subclass elements
168
197
  // (e.g. panel-agent < basic-panel) inherit the parent's _ns_ hash
@@ -307,21 +336,6 @@ function updateImportGraph(fromAbs, newDeps) {
307
336
  _imports.set(fromAbs, newDeps)
308
337
  }
309
338
 
310
- function transitiveImporters(absFile, skip) {
311
- const out = new Set()
312
- const stack = [absFile]
313
- while (stack.length) {
314
- const cur = stack.pop()
315
- const ups = _importers.get(cur)
316
- if (!ups) continue
317
- for (const u of ups) {
318
- if (out.has(u) || (skip && skip.has(u))) continue
319
- out.add(u)
320
- stack.push(u)
321
- }
322
- }
323
- return out
324
- }
325
339
 
326
340
  // Imba compiles tag render-cache slots as anonymous local Symbols at module top
327
341
  // level: `var $4 = Symbol(), $11 = Symbol(), ...; let c$0 = Symbol();`. Each
@@ -497,7 +511,6 @@ export function serve(entrypoint, flags) {
497
511
  const htmlDir = path.dirname(htmlPath)
498
512
  const srcDir = path.dirname(entrypoint)
499
513
  const sockets = new Set()
500
- const entryAbs = path.resolve(entrypoint)
501
514
  let importMapTag = null
502
515
 
503
516
  // ── Status line (prints current compile result, fades out on success) ──────
@@ -597,18 +610,6 @@ export function serve(entrypoint, flags) {
597
610
  printStatus(rel, 'ok')
598
611
  broadcast({ type: 'clear-error' })
599
612
  broadcast({ type: 'update', file: rel, slots: out.slots || 'shifted' })
600
-
601
- // Cascade: re-import modules that transitively import this file.
602
- // Skip the entry point — re-importing it re-runs imba.mount and
603
- // recreates global services, and traversing through it would
604
- // cascade to the entire project.
605
- const ups = transitiveImporters(path.resolve(filepath), new Set([entryAbs]))
606
- for (const upAbs of ups) {
607
- const upRel = path.relative('.', upAbs).replaceAll('\\', '/')
608
- const cached = _compileCache.get(upAbs)
609
- const slots = cached?.result?.slots || 'shifted'
610
- broadcast({ type: 'update', file: upRel, slots })
611
- }
612
613
  } catch(e) {
613
614
  printStatus(rel, 'fail', [{ message: e.message }])
614
615
  broadcast({ type: 'error', file: rel, errors: [{ message: e.message, snippet: e.stack || e.message }] })