snice 7.1.0 → 7.1.1

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 (177) hide show
  1. package/README.md +5 -0
  2. package/adapters/react/SniceProvider.js +1 -1
  3. package/adapters/react/SniceRouter.js +1 -1
  4. package/adapters/react/matchRoute.js +1 -1
  5. package/adapters/react/useRequestHandler.js +1 -1
  6. package/dist/cdn/accordion/snice-accordion.js +1 -1
  7. package/dist/cdn/action-bar/snice-action-bar.js +1 -1
  8. package/dist/cdn/activity-feed/snice-activity-feed.js +1 -1
  9. package/dist/cdn/alert/snice-alert.js +1 -1
  10. package/dist/cdn/app-tiles/snice-app-tiles.js +1 -1
  11. package/dist/cdn/approval-flow/snice-approval-flow.js +1 -1
  12. package/dist/cdn/audio-recorder/snice-audio-recorder.js +1 -1
  13. package/dist/cdn/availability/snice-availability.js +1 -1
  14. package/dist/cdn/avatar/snice-avatar.js +1 -1
  15. package/dist/cdn/avatar-group/snice-avatar-group.js +1 -1
  16. package/dist/cdn/badge/snice-badge.js +1 -1
  17. package/dist/cdn/banner/snice-banner.js +1 -1
  18. package/dist/cdn/binpack/snice-binpack.js +1 -1
  19. package/dist/cdn/book/snice-book.js +1 -1
  20. package/dist/cdn/booking/snice-booking.js +1 -1
  21. package/dist/cdn/breadcrumbs/snice-breadcrumbs.js +1 -1
  22. package/dist/cdn/button/snice-button.js +1 -1
  23. package/dist/cdn/calendar/snice-calendar.js +1 -1
  24. package/dist/cdn/camera/snice-camera.js +1 -1
  25. package/dist/cdn/camera-annotate/snice-camera-annotate.js +1 -1
  26. package/dist/cdn/candlestick/snice-candlestick.js +1 -1
  27. package/dist/cdn/card/snice-card.js +1 -1
  28. package/dist/cdn/carousel/snice-carousel.js +1 -1
  29. package/dist/cdn/cart/snice-cart.js +1 -1
  30. package/dist/cdn/chart/snice-chart.js +1 -1
  31. package/dist/cdn/chat/snice-chat.js +1 -1
  32. package/dist/cdn/checkbox/snice-checkbox.js +1 -1
  33. package/dist/cdn/chip/snice-chip.js +1 -1
  34. package/dist/cdn/code-block/snice-code-block.js +1 -1
  35. package/dist/cdn/color-display/snice-color-display.js +1 -1
  36. package/dist/cdn/color-picker/snice-color-picker.js +1 -1
  37. package/dist/cdn/command-palette/snice-command-palette.js +1 -1
  38. package/dist/cdn/comments/snice-comments.js +1 -1
  39. package/dist/cdn/countdown/snice-countdown.js +1 -1
  40. package/dist/cdn/cropper/snice-cropper.js +1 -1
  41. package/dist/cdn/data-card/snice-data-card.js +1 -1
  42. package/dist/cdn/date-picker/snice-date-picker.js +1 -1
  43. package/dist/cdn/date-range-picker/snice-date-range-picker.js +1 -1
  44. package/dist/cdn/date-time-picker/snice-date-time-picker.js +1 -1
  45. package/dist/cdn/diff/snice-diff.js +1 -1
  46. package/dist/cdn/divider/snice-divider.js +1 -1
  47. package/dist/cdn/doc/snice-doc.js +1 -1
  48. package/dist/cdn/draw/snice-draw.js +1 -1
  49. package/dist/cdn/drawer/snice-drawer.js +1 -1
  50. package/dist/cdn/empty-state/snice-empty-state.js +1 -1
  51. package/dist/cdn/estimate/snice-estimate.js +1 -1
  52. package/dist/cdn/file-gallery/snice-file-gallery.js +1 -1
  53. package/dist/cdn/file-upload/snice-file-upload.js +1 -1
  54. package/dist/cdn/flip-card/snice-flip-card.js +1 -1
  55. package/dist/cdn/flow/snice-flow.js +1 -1
  56. package/dist/cdn/form-layout/snice-form-layout.js +1 -1
  57. package/dist/cdn/funnel/snice-funnel.js +1 -1
  58. package/dist/cdn/gantt/snice-gantt.js +1 -1
  59. package/dist/cdn/gauge/snice-gauge.js +1 -1
  60. package/dist/cdn/grid/snice-grid.js +1 -1
  61. package/dist/cdn/heatmap/snice-heatmap.js +1 -1
  62. package/dist/cdn/image/snice-image.js +1 -1
  63. package/dist/cdn/input/snice-input.js +1 -1
  64. package/dist/cdn/invoice/snice-invoice.js +1 -1
  65. package/dist/cdn/kanban/snice-kanban.js +1 -1
  66. package/dist/cdn/key-value/snice-key-value.js +1 -1
  67. package/dist/cdn/kpi/snice-kpi.js +1 -1
  68. package/dist/cdn/layout/snice-layout.js +1 -1
  69. package/dist/cdn/leaderboard/snice-leaderboard.js +1 -1
  70. package/dist/cdn/link/snice-link.js +1 -1
  71. package/dist/cdn/link-preview/snice-link-preview.js +1 -1
  72. package/dist/cdn/list/snice-list.js +1 -1
  73. package/dist/cdn/location/snice-location.js +1 -1
  74. package/dist/cdn/login/snice-login.js +1 -1
  75. package/dist/cdn/map/snice-map.js +1 -1
  76. package/dist/cdn/markdown/snice-markdown.js +1 -1
  77. package/dist/cdn/masonry/snice-masonry.js +1 -1
  78. package/dist/cdn/menu/snice-menu.js +1 -1
  79. package/dist/cdn/message-strip/snice-message-strip.js +1 -1
  80. package/dist/cdn/modal/snice-modal.js +1 -1
  81. package/dist/cdn/music-player/snice-music-player.js +1 -1
  82. package/dist/cdn/nav/snice-nav.js +1 -1
  83. package/dist/cdn/network-graph/snice-network-graph.js +1 -1
  84. package/dist/cdn/notification-center/snice-notification-center.js +1 -1
  85. package/dist/cdn/order-tracker/snice-order-tracker.js +1 -1
  86. package/dist/cdn/org-chart/snice-org-chart.js +1 -1
  87. package/dist/cdn/pagination/snice-pagination.js +1 -1
  88. package/dist/cdn/paint/snice-paint.js +1 -1
  89. package/dist/cdn/pdf-viewer/snice-pdf-viewer.js +1 -1
  90. package/dist/cdn/permission-matrix/snice-permission-matrix.js +1 -1
  91. package/dist/cdn/podcast-player/snice-podcast-player.js +1 -1
  92. package/dist/cdn/popover/snice-popover.js +1 -1
  93. package/dist/cdn/pricing-table/snice-pricing-table.js +1 -1
  94. package/dist/cdn/product-card/snice-product-card.js +1 -1
  95. package/dist/cdn/progress/snice-progress.js +1 -1
  96. package/dist/cdn/progress-ring/snice-progress-ring.js +1 -1
  97. package/dist/cdn/qr-code/snice-qr-code.js +1 -1
  98. package/dist/cdn/qr-reader/snice-qr-reader.js +1 -1
  99. package/dist/cdn/radio/snice-radio.js +1 -1
  100. package/dist/cdn/range-slider/snice-range-slider.js +1 -1
  101. package/dist/cdn/rating/snice-rating.js +1 -1
  102. package/dist/cdn/receipt/snice-receipt.js +1 -1
  103. package/dist/cdn/recipe/snice-recipe.js +1 -1
  104. package/dist/cdn/runtime/README.md +2 -2
  105. package/dist/cdn/runtime/snice-runtime.esm.js +114 -15
  106. package/dist/cdn/runtime/snice-runtime.esm.js.map +1 -1
  107. package/dist/cdn/runtime/snice-runtime.esm.min.js +1 -1
  108. package/dist/cdn/runtime/snice-runtime.esm.min.js.map +1 -1
  109. package/dist/cdn/runtime/snice-runtime.js +114 -15
  110. package/dist/cdn/runtime/snice-runtime.js.map +1 -1
  111. package/dist/cdn/runtime/snice-runtime.min.js +1 -1
  112. package/dist/cdn/runtime/snice-runtime.min.js.map +1 -1
  113. package/dist/cdn/sankey/snice-sankey.js +1 -1
  114. package/dist/cdn/segmented-control/snice-segmented-control.js +1 -1
  115. package/dist/cdn/select/snice-select.js +1 -1
  116. package/dist/cdn/skeleton/snice-skeleton.js +1 -1
  117. package/dist/cdn/slider/snice-slider.js +1 -1
  118. package/dist/cdn/sortable/snice-sortable.js +1 -1
  119. package/dist/cdn/sparkline/snice-sparkline.js +1 -1
  120. package/dist/cdn/spinner/snice-spinner.js +1 -1
  121. package/dist/cdn/split-button/snice-split-button.js +1 -1
  122. package/dist/cdn/split-pane/snice-split-pane.js +1 -1
  123. package/dist/cdn/spotlight/snice-spotlight.js +1 -1
  124. package/dist/cdn/stat-group/snice-stat-group.js +1 -1
  125. package/dist/cdn/step-input/snice-step-input.js +1 -1
  126. package/dist/cdn/stepper/snice-stepper.js +1 -1
  127. package/dist/cdn/switch/snice-switch.js +1 -1
  128. package/dist/cdn/table/snice-table.esm.js +1 -1
  129. package/dist/cdn/table/snice-table.js +1 -1
  130. package/dist/cdn/tabs/snice-tabs.js +1 -1
  131. package/dist/cdn/tag/snice-tag.js +1 -1
  132. package/dist/cdn/tag-input/snice-tag-input.js +1 -1
  133. package/dist/cdn/terminal/snice-terminal.js +1 -1
  134. package/dist/cdn/testimonial/snice-testimonial.js +1 -1
  135. package/dist/cdn/textarea/snice-textarea.js +1 -1
  136. package/dist/cdn/time-picker/snice-time-picker.js +1 -1
  137. package/dist/cdn/time-range-picker/snice-time-range-picker.js +1 -1
  138. package/dist/cdn/timeline/snice-timeline.js +1 -1
  139. package/dist/cdn/timer/snice-timer.js +1 -1
  140. package/dist/cdn/toast/snice-toast.js +1 -1
  141. package/dist/cdn/tooltip/snice-tooltip.js +1 -1
  142. package/dist/cdn/tree/snice-tree.js +1 -1
  143. package/dist/cdn/treemap/snice-treemap.js +1 -1
  144. package/dist/cdn/user-card/snice-user-card.js +1 -1
  145. package/dist/cdn/video-player/snice-video-player.js +1 -1
  146. package/dist/cdn/virtual-scroller/snice-virtual-scroller.js +1 -1
  147. package/dist/cdn/waterfall/snice-waterfall.js +1 -1
  148. package/dist/cdn/weather/snice-weather.js +1 -1
  149. package/dist/cdn/work-order/snice-work-order.js +1 -1
  150. package/dist/controller.d.ts +5 -0
  151. package/dist/index.cjs +111 -12
  152. package/dist/index.cjs.map +1 -1
  153. package/dist/index.esm.js +111 -12
  154. package/dist/index.esm.js.map +1 -1
  155. package/dist/index.iife.js +111 -12
  156. package/dist/index.iife.js.map +1 -1
  157. package/dist/parts.d.ts +2 -2
  158. package/dist/react/SniceProvider.js +1 -1
  159. package/dist/react/SniceRouter.js +1 -1
  160. package/dist/react/index.js +1 -1
  161. package/dist/react/matchRoute.js +1 -1
  162. package/dist/react/useRequestHandler.js +1 -1
  163. package/dist/symbols.cjs +9 -1
  164. package/dist/symbols.cjs.map +1 -1
  165. package/dist/symbols.d.ts +2 -0
  166. package/dist/symbols.esm.js +8 -2
  167. package/dist/symbols.esm.js.map +1 -1
  168. package/dist/transitions.cjs +1 -1
  169. package/dist/transitions.esm.js +1 -1
  170. package/docs/ai/architecture.md +1 -1
  171. package/docs/ai/bindings.md +1 -1
  172. package/docs/ai/controllers.md +1 -1
  173. package/docs/ai/decorators.md +1 -1
  174. package/docs/ai/patterns.md +4 -3
  175. package/docs/bindings.md +1 -1
  176. package/docs/controllers.md +8 -2
  177. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -17,8 +17,8 @@ Load the runtime once, then load any CDN components:
17
17
  ```
18
18
 
19
19
  ## Size
20
- - Minified: 105.7 KB
21
- - Gzipped: 30.7 KB
20
+ - Minified: 106.4 KB
21
+ - Gzipped: 30.9 KB
22
22
 
23
23
  ## Documentation
24
24
  https://snice.dev
@@ -1,11 +1,11 @@
1
1
  /*!
2
- * snice v7.1.0
2
+ * snice v7.1.1
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
6
6
  */
7
7
  /*!
8
- * snice v7.0.3
8
+ * snice v7.1.0
9
9
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
10
10
  * (c) 2024
11
11
  * Released under the MIT License.
@@ -66,9 +66,15 @@ const CONTROLLER_NAME_KEY = getSymbol('controller-name');
66
66
  const CONTROLLER_ID = getSymbol('controller-id');
67
67
  const CONTROLLER_OPERATIONS = getSymbol('controller-operations');
68
68
  const NATIVE_CONTROLLER = getSymbol('native-controller');
69
+ // Decorator name stored on the class so direct class bindings can expose the
70
+ // same useful DOM label without resolving the controller through the registry.
71
+ const CONTROLLER_REGISTRY_NAME = getSymbol('controller-registry-name');
69
72
  // Set while a controller CLASS (not a registry name) is attached — the
70
73
  // attribute/MutationObserver channel must not attach over or detach it.
71
74
  const DIRECT_CONTROLLER = getSymbol('direct-controller');
75
+ // Guards framework-authored diagnostic controller attribute writes from the
76
+ // synchronous custom-element attributeChangedCallback path.
77
+ const CONTROLLER_ATTRIBUTE_SYNC = getSymbol('controller-attribute-sync');
72
78
  // A controller class bound by a template before the custom element was
73
79
  // defined/upgraded. Picked up by connectedCallback on first initialization.
74
80
  const PENDING_CONTROLLER_BINDING = getSymbol('pending-controller-binding');
@@ -2126,6 +2132,12 @@ function controller(name) {
2126
2132
  registry.set(name, constructor);
2127
2133
  // Mark as controller class for channel decorator detection
2128
2134
  constructor.prototype[IS_CONTROLLER_CLASS] = true;
2135
+ // Preserve the registry name on the class. Direct class attachments still
2136
+ // skip registry lookup; this is only their inspectable DOM label.
2137
+ Object.defineProperty(constructor, CONTROLLER_REGISTRY_NAME, {
2138
+ value: name,
2139
+ configurable: true
2140
+ });
2129
2141
  const pending = snice.pendingControllerAttachments.get(name);
2130
2142
  if (pending) {
2131
2143
  snice.pendingControllerAttachments.delete(name);
@@ -2197,6 +2209,52 @@ function controllerLabel(controller) {
2197
2209
  ? controller
2198
2210
  : (controller?.name || '(anonymous controller class)');
2199
2211
  }
2212
+ /** Registry/decorator name used for a direct class attachment's DOM marker. */
2213
+ function directControllerAttributeName(controllerClass) {
2214
+ const registeredName = Object.prototype.hasOwnProperty.call(controllerClass, CONTROLLER_REGISTRY_NAME)
2215
+ ? controllerClass[CONTROLLER_REGISTRY_NAME]
2216
+ : undefined;
2217
+ return typeof registeredName === 'string'
2218
+ ? registeredName
2219
+ : controllerLabel(controllerClass);
2220
+ }
2221
+ /**
2222
+ * Write the inspectable controller marker without feeding it back into the
2223
+ * custom-element attribute channel. Native MutationObservers are asynchronous
2224
+ * and are excluded independently by DIRECT_CONTROLLER.
2225
+ */
2226
+ function writeControllerAttribute(element, value) {
2227
+ if (value === null) {
2228
+ if (!element.hasAttribute('controller'))
2229
+ return;
2230
+ }
2231
+ else if (element.getAttribute('controller') === value) {
2232
+ return;
2233
+ }
2234
+ element[CONTROLLER_ATTRIBUTE_SYNC] = true;
2235
+ try {
2236
+ if (value === null)
2237
+ element.removeAttribute('controller');
2238
+ else
2239
+ element.setAttribute('controller', value);
2240
+ }
2241
+ finally {
2242
+ delete element[CONTROLLER_ATTRIBUTE_SYNC];
2243
+ }
2244
+ }
2245
+ /**
2246
+ * Restore the diagnostic attribute for an attached class controller. Returns
2247
+ * true when the direct class channel owns the element.
2248
+ */
2249
+ function restoreDirectControllerAttribute(element) {
2250
+ if (!element[DIRECT_CONTROLLER])
2251
+ return false;
2252
+ const source = element[CONTROLLER_NAME_KEY];
2253
+ if (typeof source !== 'function')
2254
+ return false;
2255
+ writeControllerAttribute(element, directControllerAttributeName(source));
2256
+ return true;
2257
+ }
2200
2258
  /**
2201
2259
  * Attaches a controller to an element
2202
2260
  * @param element The element to attach the controller to
@@ -2226,11 +2284,26 @@ async function attachController(element, controller) {
2226
2284
  }
2227
2285
  if (existingSource === controller && existingController) {
2228
2286
  // Already attached and controller exists (name or class reference match)
2287
+ if (typeof controller !== 'string') {
2288
+ restoreDirectControllerAttribute(element);
2289
+ }
2229
2290
  return;
2230
2291
  }
2231
2292
  // If there's an existing controller, detach it first
2232
2293
  if (existingController) {
2233
2294
  await detachController(element);
2295
+ // Light-DOM reconciliation can issue commit() and reconnected() requests
2296
+ // for the same class while the previous controller is still detaching.
2297
+ // If the other request already installed that exact source, this request
2298
+ // is redundant. Different sources retain the established rapid-switch
2299
+ // behavior and continue through the normal replacement path.
2300
+ const replacement = element[CONTROLLER_KEY];
2301
+ const replacementSource = element[CONTROLLER_NAME_KEY];
2302
+ if (replacement && replacementSource === controller) {
2303
+ if (typeof controller !== 'string')
2304
+ restoreDirectControllerAttribute(element);
2305
+ return;
2306
+ }
2234
2307
  }
2235
2308
  let ControllerClass;
2236
2309
  if (typeof controller === 'string') {
@@ -2246,13 +2319,16 @@ async function attachController(element, controller) {
2246
2319
  }
2247
2320
  else {
2248
2321
  ControllerClass = controller;
2249
- // The class channel owns the element from here on: the attribute /
2250
- // MutationObserver channel goes inert and its bookkeeping is dropped.
2251
- element[DIRECT_CONTROLLER] = true;
2252
- delete element[NATIVE_CONTROLLER];
2253
2322
  }
2254
2323
  // Create controller instance with unique ID and scope
2255
2324
  const controllerInstance = new ControllerClass();
2325
+ if (typeof controller !== 'string') {
2326
+ // Construction succeeded, so the class channel can safely take ownership.
2327
+ // Setting this before construction would leave a stale observer guard when
2328
+ // a controller constructor throws.
2329
+ element[DIRECT_CONTROLLER] = true;
2330
+ delete element[NATIVE_CONTROLLER];
2331
+ }
2256
2332
  snice.controllerIdCounter += 1;
2257
2333
  const controllerId = snice.controllerIdCounter;
2258
2334
  const scope = new ControllerScope();
@@ -2271,6 +2347,12 @@ async function attachController(element, controller) {
2271
2347
  element[CONTROLLER_KEY] = controllerInstance;
2272
2348
  element[CONTROLLER_NAME_KEY] = controller;
2273
2349
  element[CONTROLLER_OPERATIONS] = scope;
2350
+ if (typeof controller !== 'string') {
2351
+ // The class reference remains the sole attachment authority. This
2352
+ // attribute is diagnostic only; custom-element callbacks and native
2353
+ // MutationObservers are guarded from treating it as a string attachment.
2354
+ restoreDirectControllerAttribute(element);
2355
+ }
2274
2356
  // Wait for element to be ready. Race against abort (detachController) and
2275
2357
  // a 30s deadline so a caller that forgets to append the element gets a
2276
2358
  // clear error instead of an unresolvable promise.
@@ -2302,6 +2384,9 @@ async function attachController(element, controller) {
2302
2384
  // attached — otherwise a later attach short-circuits as "already attached"
2303
2385
  // and a detach would run detach() on it.
2304
2386
  if (element[CONTROLLER_KEY] === controllerInstance) {
2387
+ if (typeof controller !== 'string') {
2388
+ writeControllerAttribute(element, null);
2389
+ }
2305
2390
  delete element[CONTROLLER_KEY];
2306
2391
  delete element[CONTROLLER_NAME_KEY];
2307
2392
  delete element[CONTROLLER_OPERATIONS];
@@ -2353,6 +2438,12 @@ async function detachController(element) {
2353
2438
  // controller reassignment) finds no instance and returns, instead of running
2354
2439
  // detach() a second time on the same controller. The rest of this function
2355
2440
  // works off the locals captured above.
2441
+ if (typeof controllerSource === 'function') {
2442
+ // Remove the class channel's diagnostic marker while its guards are still
2443
+ // active. A queued native MutationObserver therefore sees no attribute and
2444
+ // cannot resurrect a registry attachment after detach.
2445
+ writeControllerAttribute(element, null);
2446
+ }
2356
2447
  delete element[CONTROLLER_KEY];
2357
2448
  delete element[CONTROLLER_NAME_KEY];
2358
2449
  delete element[CONTROLLER_OPERATIONS];
@@ -2427,8 +2518,12 @@ function useNativeElementControllers() {
2427
2518
  // attachController(el, Class)). The class channel owns the element:
2428
2519
  // attribute writes must not attach over it, and insertion sweeps must
2429
2520
  // not detach it.
2430
- if (element[DIRECT_CONTROLLER])
2521
+ if (element[DIRECT_CONTROLLER]) {
2522
+ // External writes cannot replace a class binding. Keep the DOM marker
2523
+ // honest about the class that is actually attached.
2524
+ restoreDirectControllerAttribute(element);
2431
2525
  return;
2526
+ }
2432
2527
  const controllerName = element.getAttribute('controller');
2433
2528
  const currentControllerName = element[NATIVE_CONTROLLER];
2434
2529
  // No change
@@ -4666,8 +4761,8 @@ class PropertyPart extends Part {
4666
4761
  * Accepts a controller class decorated with @controller (attached directly,
4667
4762
  * no registry lookup) or a registry name string (delegated to the attribute
4668
4763
  * channel with the exact semantics of a static controller="name"). While a
4669
- * class is bound it owns the element: the attribute/MutationObserver channel
4670
- * is inert until the class is unbound.
4764
+ * class is bound it owns the element: the decorator name is reflected for
4765
+ * inspection, while the attribute/MutationObserver attach channel stays inert.
4671
4766
  *
4672
4767
  * Renders commit while the tree is detached and connect afterwards, so
4673
4768
  * attachment happens on reconnected()/connected commits; every hook is
@@ -4706,10 +4801,6 @@ class ControllerPart extends Part {
4706
4801
  }
4707
4802
  }
4708
4803
  if (typeof next === 'function') {
4709
- // Class binding takes over — drop any attribute so the string channel
4710
- // cannot fight it.
4711
- if (this.element.hasAttribute('controller'))
4712
- this.element.removeAttribute('controller');
4713
4804
  if (this.isConnected) {
4714
4805
  this._apply(next);
4715
4806
  }
@@ -6781,6 +6872,14 @@ function applyElementFunctionality(constructor) {
6781
6872
  constructor.prototype.attributeChangedCallback = function (name, oldValue, newValue) {
6782
6873
  originalAttributeChangedCallback?.call(this, name, oldValue, newValue);
6783
6874
  if (name === 'controller') {
6875
+ // A class attachment reflects its decorator name for DOM diagnostics,
6876
+ // but the class reference remains the only attachment authority.
6877
+ if (this[CONTROLLER_ATTRIBUTE_SYNC])
6878
+ return;
6879
+ if (this[DIRECT_CONTROLLER]) {
6880
+ restoreDirectControllerAttribute(this);
6881
+ return;
6882
+ }
6784
6883
  this.controller = newValue;
6785
6884
  return;
6786
6885
  }
@@ -9254,7 +9353,7 @@ if (typeof document !== 'undefined') {
9254
9353
  }
9255
9354
 
9256
9355
  /*!
9257
- * snice v7.0.3
9356
+ * snice v7.1.0
9258
9357
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
9259
9358
  * (c) 2024
9260
9359
  * Released under the MIT License.
@@ -9276,7 +9375,7 @@ if (!globalThis.snice) {
9276
9375
  globalThis.snice.pendingControllerAttachments ??= new Map();
9277
9376
 
9278
9377
  /*!
9279
- * snice v7.0.3
9378
+ * snice v7.1.0
9280
9379
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
9281
9380
  * (c) 2024
9282
9381
  * Released under the MIT License.