snice 7.7.0 → 7.8.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/adapters/react/SniceProvider.js +1 -1
- package/adapters/react/SniceRouter.js +1 -1
- package/adapters/react/calendar.d.ts +1 -0
- package/adapters/react/calendar.d.ts.map +1 -1
- package/adapters/react/calendar.js +1 -1
- package/adapters/react/calendar.js.map +1 -1
- package/adapters/react/calendar.tsx +2 -1
- package/adapters/react/matchRoute.js +1 -1
- package/adapters/react/useRequestHandler.js +1 -1
- package/bin/analyzer-contracts.js +8 -2
- package/custom-elements.json +5 -1
- package/dist/cdn/accordion/snice-accordion.js +1 -1
- package/dist/cdn/action-bar/snice-action-bar.js +1 -1
- package/dist/cdn/activity-feed/snice-activity-feed.js +1 -1
- package/dist/cdn/alert/snice-alert.js +1 -1
- package/dist/cdn/app-tiles/snice-app-tiles.js +1 -1
- package/dist/cdn/approval-flow/snice-approval-flow.js +1 -1
- package/dist/cdn/audio-recorder/snice-audio-recorder.js +1 -1
- package/dist/cdn/availability/snice-availability.js +1 -1
- package/dist/cdn/avatar/snice-avatar.js +1 -1
- package/dist/cdn/avatar-group/snice-avatar-group.js +1 -1
- package/dist/cdn/badge/snice-badge.js +1 -1
- package/dist/cdn/banner/snice-banner.js +1 -1
- package/dist/cdn/binpack/snice-binpack.js +1 -1
- package/dist/cdn/book/snice-book.js +1 -1
- package/dist/cdn/booking/snice-booking.js +1 -1
- package/dist/cdn/breadcrumbs/snice-breadcrumbs.js +1 -1
- package/dist/cdn/button/snice-button.js +1 -1
- package/dist/cdn/calendar/README.md +2 -2
- package/dist/cdn/calendar/snice-calendar.js +26 -2
- package/dist/cdn/calendar/snice-calendar.js.map +1 -1
- package/dist/cdn/calendar/snice-calendar.min.js +2 -2
- package/dist/cdn/calendar/snice-calendar.min.js.map +1 -1
- package/dist/cdn/camera/snice-camera.js +1 -1
- package/dist/cdn/camera-annotate/snice-camera-annotate.js +1 -1
- package/dist/cdn/candlestick/snice-candlestick.js +1 -1
- package/dist/cdn/card/snice-card.js +1 -1
- package/dist/cdn/carousel/snice-carousel.js +1 -1
- package/dist/cdn/cart/snice-cart.js +1 -1
- package/dist/cdn/chart/snice-chart.js +1 -1
- package/dist/cdn/chat/snice-chat.js +1 -1
- package/dist/cdn/checkbox/snice-checkbox.js +1 -1
- package/dist/cdn/chip/snice-chip.js +1 -1
- package/dist/cdn/code-block/snice-code-block.js +1 -1
- package/dist/cdn/color-display/snice-color-display.js +1 -1
- package/dist/cdn/color-picker/snice-color-picker.js +1 -1
- package/dist/cdn/command-palette/snice-command-palette.js +1 -1
- package/dist/cdn/comments/snice-comments.js +1 -1
- package/dist/cdn/countdown/snice-countdown.js +1 -1
- package/dist/cdn/cropper/snice-cropper.js +1 -1
- package/dist/cdn/data-card/snice-data-card.js +1 -1
- package/dist/cdn/date-picker/snice-date-picker.js +1 -1
- package/dist/cdn/date-range-picker/snice-date-range-picker.js +1 -1
- package/dist/cdn/date-time-picker/snice-date-time-picker.js +1 -1
- package/dist/cdn/diff/snice-diff.js +1 -1
- package/dist/cdn/divider/snice-divider.js +1 -1
- package/dist/cdn/doc/snice-doc.js +1 -1
- package/dist/cdn/draw/snice-draw.js +1 -1
- package/dist/cdn/drawer/snice-drawer.js +1 -1
- package/dist/cdn/empty-state/snice-empty-state.js +1 -1
- package/dist/cdn/estimate/snice-estimate.js +1 -1
- package/dist/cdn/file-gallery/snice-file-gallery.js +1 -1
- package/dist/cdn/file-upload/snice-file-upload.js +1 -1
- package/dist/cdn/flip-card/snice-flip-card.js +1 -1
- package/dist/cdn/flow/snice-flow.js +1 -1
- package/dist/cdn/form-layout/snice-form-layout.js +1 -1
- package/dist/cdn/funnel/snice-funnel.js +1 -1
- package/dist/cdn/gantt/snice-gantt.js +1 -1
- package/dist/cdn/gauge/snice-gauge.js +1 -1
- package/dist/cdn/grid/snice-grid.js +1 -1
- package/dist/cdn/heatmap/snice-heatmap.js +1 -1
- package/dist/cdn/image/snice-image.js +1 -1
- package/dist/cdn/input/snice-input.js +1 -1
- package/dist/cdn/invoice/snice-invoice.js +1 -1
- package/dist/cdn/kanban/snice-kanban.js +1 -1
- package/dist/cdn/key-value/snice-key-value.js +1 -1
- package/dist/cdn/kpi/snice-kpi.js +1 -1
- package/dist/cdn/layout/snice-layout.js +1 -1
- package/dist/cdn/leaderboard/snice-leaderboard.js +1 -1
- package/dist/cdn/link/snice-link.js +1 -1
- package/dist/cdn/link-preview/snice-link-preview.js +1 -1
- package/dist/cdn/list/snice-list.js +1 -1
- package/dist/cdn/location/snice-location.js +1 -1
- package/dist/cdn/login/snice-login.js +1 -1
- package/dist/cdn/map/snice-map.js +1 -1
- package/dist/cdn/markdown/snice-markdown.js +1 -1
- package/dist/cdn/masonry/snice-masonry.js +1 -1
- package/dist/cdn/menu/snice-menu.js +1 -1
- package/dist/cdn/message-strip/snice-message-strip.js +1 -1
- package/dist/cdn/modal/snice-modal.js +1 -1
- package/dist/cdn/music-player/snice-music-player.js +1 -1
- package/dist/cdn/nav/snice-nav.js +1 -1
- package/dist/cdn/network-graph/snice-network-graph.js +1 -1
- package/dist/cdn/notification-center/snice-notification-center.js +1 -1
- package/dist/cdn/order-tracker/snice-order-tracker.js +1 -1
- package/dist/cdn/org-chart/snice-org-chart.js +1 -1
- package/dist/cdn/pagination/snice-pagination.js +1 -1
- package/dist/cdn/paint/snice-paint.js +1 -1
- package/dist/cdn/pdf-viewer/snice-pdf-viewer.js +1 -1
- package/dist/cdn/permission-matrix/snice-permission-matrix.js +1 -1
- package/dist/cdn/podcast-player/snice-podcast-player.js +1 -1
- package/dist/cdn/popover/snice-popover.js +1 -1
- package/dist/cdn/pricing-table/snice-pricing-table.js +1 -1
- package/dist/cdn/product-card/snice-product-card.js +1 -1
- package/dist/cdn/progress/snice-progress.js +1 -1
- package/dist/cdn/progress-ring/snice-progress-ring.js +1 -1
- package/dist/cdn/qr-code/snice-qr-code.js +1 -1
- package/dist/cdn/qr-reader/snice-qr-reader.js +1 -1
- package/dist/cdn/radio/snice-radio.js +1 -1
- package/dist/cdn/range-slider/snice-range-slider.js +1 -1
- package/dist/cdn/rating/snice-rating.js +1 -1
- package/dist/cdn/receipt/snice-receipt.js +1 -1
- package/dist/cdn/recipe/snice-recipe.js +1 -1
- package/dist/cdn/runtime/README.md +2 -2
- package/dist/cdn/runtime/snice-runtime.esm.js +130 -31
- package/dist/cdn/runtime/snice-runtime.esm.js.map +1 -1
- package/dist/cdn/runtime/snice-runtime.esm.min.js +1 -1
- package/dist/cdn/runtime/snice-runtime.esm.min.js.map +1 -1
- package/dist/cdn/runtime/snice-runtime.js +130 -31
- package/dist/cdn/runtime/snice-runtime.js.map +1 -1
- package/dist/cdn/runtime/snice-runtime.min.js +1 -1
- package/dist/cdn/runtime/snice-runtime.min.js.map +1 -1
- package/dist/cdn/sankey/snice-sankey.js +1 -1
- package/dist/cdn/segmented-control/snice-segmented-control.js +1 -1
- package/dist/cdn/select/snice-select.js +1 -1
- package/dist/cdn/skeleton/snice-skeleton.js +1 -1
- package/dist/cdn/slider/snice-slider.js +1 -1
- package/dist/cdn/sortable/snice-sortable.js +1 -1
- package/dist/cdn/sparkline/snice-sparkline.js +1 -1
- package/dist/cdn/spinner/snice-spinner.js +1 -1
- package/dist/cdn/split-button/snice-split-button.js +1 -1
- package/dist/cdn/split-pane/snice-split-pane.js +1 -1
- package/dist/cdn/spotlight/snice-spotlight.js +1 -1
- package/dist/cdn/stat-group/snice-stat-group.js +1 -1
- package/dist/cdn/step-input/snice-step-input.js +1 -1
- package/dist/cdn/stepper/snice-stepper.js +1 -1
- package/dist/cdn/switch/snice-switch.js +1 -1
- package/dist/cdn/table/README.md +2 -2
- package/dist/cdn/table/snice-table.esm.js +157 -33
- package/dist/cdn/table/snice-table.esm.js.map +1 -1
- package/dist/cdn/table/snice-table.esm.min.js +4 -4
- package/dist/cdn/table/snice-table.esm.min.js.map +1 -1
- package/dist/cdn/table/snice-table.js +157 -33
- package/dist/cdn/table/snice-table.js.map +1 -1
- package/dist/cdn/table/snice-table.min.js +33 -33
- package/dist/cdn/table/snice-table.min.js.map +1 -1
- package/dist/cdn/tabs/snice-tabs.js +1 -1
- package/dist/cdn/tag/snice-tag.js +1 -1
- package/dist/cdn/tag-input/README.md +2 -2
- package/dist/cdn/tag-input/snice-tag-input.js +10 -16
- package/dist/cdn/tag-input/snice-tag-input.js.map +1 -1
- package/dist/cdn/tag-input/snice-tag-input.min.js +2 -2
- package/dist/cdn/tag-input/snice-tag-input.min.js.map +1 -1
- package/dist/cdn/terminal/snice-terminal.js +1 -1
- package/dist/cdn/testimonial/snice-testimonial.js +1 -1
- package/dist/cdn/textarea/snice-textarea.js +1 -1
- package/dist/cdn/time-picker/snice-time-picker.js +1 -1
- package/dist/cdn/time-range-picker/snice-time-range-picker.js +1 -1
- package/dist/cdn/timeline/snice-timeline.js +1 -1
- package/dist/cdn/timer/snice-timer.js +1 -1
- package/dist/cdn/toast/snice-toast.js +1 -1
- package/dist/cdn/tooltip/snice-tooltip.js +1 -1
- package/dist/cdn/tree/snice-tree.js +1 -1
- package/dist/cdn/treemap/snice-treemap.js +1 -1
- package/dist/cdn/user-card/snice-user-card.js +1 -1
- package/dist/cdn/video-player/snice-video-player.js +1 -1
- package/dist/cdn/virtual-scroller/snice-virtual-scroller.js +1 -1
- package/dist/cdn/waterfall/snice-waterfall.js +1 -1
- package/dist/cdn/weather/snice-weather.js +1 -1
- package/dist/cdn/work-order/snice-work-order.js +1 -1
- package/dist/components/calendar/snice-calendar.d.ts +2 -0
- package/dist/components/calendar/snice-calendar.js +25 -1
- package/dist/components/calendar/snice-calendar.js.map +1 -1
- package/dist/components/table/snice-row.d.ts +6 -0
- package/dist/components/table/snice-row.js +11 -3
- package/dist/components/table/snice-row.js.map +1 -1
- package/dist/components/table/snice-table.d.ts +31 -3
- package/dist/components/table/snice-table.js +89 -16
- package/dist/components/table/snice-table.js.map +1 -1
- package/dist/components/table/table-cell-presentation.d.ts +11 -0
- package/dist/components/table/table-cell-presentation.js +25 -8
- package/dist/components/table/table-cell-presentation.js.map +1 -1
- package/dist/components/table/table-export.d.ts +6 -0
- package/dist/components/table/table-export.js +11 -2
- package/dist/components/table/table-export.js.map +1 -1
- package/dist/components/table/table-master-detail.d.ts +11 -2
- package/dist/components/table/table-master-detail.js +20 -3
- package/dist/components/table/table-master-detail.js.map +1 -1
- package/dist/components/tag-input/snice-tag-input.d.ts +2 -2
- package/dist/components/tag-input/snice-tag-input.js +9 -15
- package/dist/components/tag-input/snice-tag-input.js.map +1 -1
- package/dist/index.cjs +127 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +127 -28
- package/dist/index.esm.js.map +1 -1
- package/dist/index.iife.js +127 -28
- package/dist/index.iife.js.map +1 -1
- package/dist/react/SniceProvider.js +1 -1
- package/dist/react/SniceRouter.js +1 -1
- package/dist/react/index.js +1 -1
- package/dist/react/matchRoute.js +1 -1
- package/dist/react/useRequestHandler.js +1 -1
- package/dist/request-response.d.ts +24 -1
- package/dist/symbols.cjs +1 -1
- package/dist/symbols.esm.js +1 -1
- package/dist/testing-dom.cjs +1 -1
- package/dist/testing-dom.esm.js +1 -1
- package/dist/transitions.cjs +1 -1
- package/dist/transitions.esm.js +1 -1
- package/docs/ai/components/calendar.md +8 -0
- package/docs/ai/components/tag-input.md +4 -0
- package/docs/ai/controllers.md +22 -6
- package/docs/components/calendar.md +24 -0
- package/docs/components/tag-input.md +6 -1
- package/docs/controllers.md +57 -6
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* snice v7.
|
|
2
|
+
* snice v7.7.0
|
|
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.
|
|
@@ -8,7 +8,7 @@ var Snice = (function (exports) {
|
|
|
8
8
|
'use strict';
|
|
9
9
|
|
|
10
10
|
/*!
|
|
11
|
-
* snice v7.
|
|
11
|
+
* snice v7.7.0
|
|
12
12
|
* A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
|
|
13
13
|
* (c) 2024
|
|
14
14
|
* Released under the MIT License.
|
|
@@ -1566,17 +1566,33 @@ var Snice = (function (exports) {
|
|
|
1566
1566
|
});
|
|
1567
1567
|
};
|
|
1568
1568
|
}
|
|
1569
|
-
//
|
|
1570
|
-
|
|
1569
|
+
// Which handler descriptors an instance has already registered, so a second
|
|
1570
|
+
// setup pass only picks up what the first one deferred.
|
|
1571
|
+
const registeredHandlers = new WeakMap();
|
|
1572
|
+
/**
|
|
1573
|
+
* Helper to setup response handlers for elements and controllers.
|
|
1574
|
+
*
|
|
1575
|
+
* Safe to call more than once for the same instance: a handler already
|
|
1576
|
+
* registered is skipped rather than double-bound.
|
|
1577
|
+
*/
|
|
1578
|
+
function setupResponseHandlers(instance, element, options) {
|
|
1571
1579
|
const handlers = instance.constructor[CHANNEL_HANDLERS];
|
|
1572
1580
|
if (!handlers)
|
|
1573
1581
|
return;
|
|
1582
|
+
const claim = options?.claim;
|
|
1583
|
+
let registered = registeredHandlers.get(instance);
|
|
1584
|
+
if (!registered) {
|
|
1585
|
+
registered = new Set();
|
|
1586
|
+
registeredHandlers.set(instance, registered);
|
|
1587
|
+
}
|
|
1574
1588
|
// Store cleanup functions
|
|
1575
1589
|
// Initialize cleanup object if needed
|
|
1576
1590
|
if (!instance[CLEANUP]) {
|
|
1577
1591
|
instance[CLEANUP] = { events: [], channels: [] };
|
|
1578
1592
|
}
|
|
1579
1593
|
for (const handler of handlers) {
|
|
1594
|
+
if (registered.has(handler))
|
|
1595
|
+
continue;
|
|
1580
1596
|
const boundMethod = handler.method.bind(instance);
|
|
1581
1597
|
const eventName = `@request/${handler.channelName}`;
|
|
1582
1598
|
// Create timing variables for debounce/throttle per handler
|
|
@@ -1660,7 +1676,10 @@ var Snice = (function (exports) {
|
|
|
1660
1676
|
// Clear the discovery timeout immediately - we found a handler
|
|
1661
1677
|
discovery.resolve();
|
|
1662
1678
|
// Call the timed responder method and handle the result
|
|
1663
|
-
|
|
1679
|
+
const answer = claim
|
|
1680
|
+
? Promise.resolve(claim()).then(() => timedMethod(payload))
|
|
1681
|
+
: Promise.resolve(timedMethod(payload));
|
|
1682
|
+
answer
|
|
1664
1683
|
.then(result => {
|
|
1665
1684
|
data.resolve(result);
|
|
1666
1685
|
})
|
|
@@ -1675,10 +1694,17 @@ var Snice = (function (exports) {
|
|
|
1675
1694
|
responseTarget = requireDaemonTarget(instance, handler.options.daemon);
|
|
1676
1695
|
}
|
|
1677
1696
|
catch (error) {
|
|
1697
|
+
// The app context reaches a controller through its host element, so it
|
|
1698
|
+
// can be unreachable while the host is still disconnected. Leave the
|
|
1699
|
+
// handler for the later pass instead of dropping it permanently.
|
|
1700
|
+
if (options?.deferUnresolvableDaemons)
|
|
1701
|
+
continue;
|
|
1678
1702
|
console.warn(`[snice/@respond] ${error.message} Responder "${handler.channelName}" skipped.`);
|
|
1703
|
+
registered.add(handler);
|
|
1679
1704
|
continue;
|
|
1680
1705
|
}
|
|
1681
1706
|
}
|
|
1707
|
+
registered.add(handler);
|
|
1682
1708
|
responseTarget.addEventListener(eventName, responseHandler);
|
|
1683
1709
|
instance[CLEANUP].channels.push(() => {
|
|
1684
1710
|
responseTarget.removeEventListener(eventName, responseHandler);
|
|
@@ -1687,6 +1713,7 @@ var Snice = (function (exports) {
|
|
|
1687
1713
|
}
|
|
1688
1714
|
// Helper to cleanup response handlers
|
|
1689
1715
|
function cleanupResponseHandlers(instance) {
|
|
1716
|
+
registeredHandlers.delete(instance);
|
|
1690
1717
|
if (instance[CLEANUP]?.channels) {
|
|
1691
1718
|
for (const cleanup of instance[CLEANUP].channels) {
|
|
1692
1719
|
cleanup();
|
|
@@ -1812,6 +1839,8 @@ var Snice = (function (exports) {
|
|
|
1812
1839
|
* Use in elements or controllers to listen to DOM events or custom events
|
|
1813
1840
|
*/
|
|
1814
1841
|
const ON_HANDLERS = getSymbol('on-handlers');
|
|
1842
|
+
// Per-decoration-site counter — see the registration identity note in `on()`.
|
|
1843
|
+
let registrationCount = 0;
|
|
1815
1844
|
/**
|
|
1816
1845
|
* @on decorator for listening to events
|
|
1817
1846
|
*
|
|
@@ -1873,18 +1902,42 @@ var Snice = (function (exports) {
|
|
|
1873
1902
|
if (!selector && opts.target) {
|
|
1874
1903
|
selector = opts.target;
|
|
1875
1904
|
}
|
|
1905
|
+
const eventNames = Array.isArray(eventName) ? eventName : [eventName];
|
|
1906
|
+
// Registration identity — derived from EVERY decorator argument, so no
|
|
1907
|
+
// option can be forgotten here and silently collapse two distinct stacked
|
|
1908
|
+
// @on decorators into one (that is how { debounce: 300 } stacked on a plain
|
|
1909
|
+
// @on for the same event used to lose one of its two registrations).
|
|
1910
|
+
// Options are serialized generically (sorted, so literal key order doesn't
|
|
1911
|
+
// matter); values that can't be compared by value — an EventTarget or a
|
|
1912
|
+
// resolver function passed as `scope` — fall back to this decoration site's
|
|
1913
|
+
// own id, which is stable across instances but unique per @on application.
|
|
1914
|
+
const siteId = `site:${++registrationCount}`;
|
|
1915
|
+
let optionSignature = '';
|
|
1916
|
+
let hasOpaqueOption = false;
|
|
1917
|
+
for (const key of Object.keys(opts).sort()) {
|
|
1918
|
+
const value = opts[key];
|
|
1919
|
+
if (value === undefined)
|
|
1920
|
+
continue;
|
|
1921
|
+
if (value !== null && (typeof value === 'object' || typeof value === 'function')) {
|
|
1922
|
+
hasOpaqueOption = true;
|
|
1923
|
+
continue;
|
|
1924
|
+
}
|
|
1925
|
+
optionSignature += `${key}=${String(value)};`;
|
|
1926
|
+
}
|
|
1927
|
+
const argumentKey = `${eventNames.join(',')}::${selector ?? ''}::${optionSignature}${hasOpaqueOption ? `::${siteId}` : ''}`;
|
|
1876
1928
|
return function (originalMethod, context) {
|
|
1877
1929
|
const methodName = context.name;
|
|
1930
|
+
// Same decoration, same method name → same registration. A subclass that
|
|
1931
|
+
// re-declares an identically decorated method must NOT add a second
|
|
1932
|
+
// listener on top of the one its parent's initializer already registered.
|
|
1933
|
+
const registrationKey = `${methodName}::${argumentKey}`;
|
|
1878
1934
|
context.addInitializer(function () {
|
|
1879
1935
|
const constructor = this.constructor;
|
|
1880
|
-
// Dedup by registration identity
|
|
1881
|
-
//
|
|
1882
|
-
//
|
|
1883
|
-
//
|
|
1884
|
-
//
|
|
1885
|
-
// prototype chain.
|
|
1886
|
-
const eventNames = Array.isArray(eventName) ? eventName : [eventName];
|
|
1887
|
-
const registrationKey = `${methodName}::${eventNames.join(',')}::${selector ?? ''}::daemon:${opts.daemon ?? ''}::light:${opts.light ?? ''}::shadow:${opts.shadow ?? ''}`;
|
|
1936
|
+
// Dedup by registration identity, NOT by method reference — stacked @on
|
|
1937
|
+
// decorators share one method and must each register. Use hasOwnProperty
|
|
1938
|
+
// so subclasses get their OWN Set instead of inheriting — otherwise
|
|
1939
|
+
// parent and child share state and child registrations pollute parent
|
|
1940
|
+
// (and vice versa) via the prototype chain.
|
|
1888
1941
|
if (!Object.prototype.hasOwnProperty.call(constructor, ON_METHODS)) {
|
|
1889
1942
|
constructor[ON_METHODS] = new Set();
|
|
1890
1943
|
}
|
|
@@ -2899,6 +2952,35 @@ var Snice = (function (exports) {
|
|
|
2899
2952
|
// MutationObservers are guarded from treating it as a string attachment.
|
|
2900
2953
|
restoreDirectControllerAttribute(element);
|
|
2901
2954
|
}
|
|
2955
|
+
// @respond handlers are installed before the readiness gate below, exactly
|
|
2956
|
+
// as elements install theirs in connectedCallback. A child's mount-time
|
|
2957
|
+
// @request can be the very thing keeping the host from becoming ready, so
|
|
2958
|
+
// the responder has to be reachable while `ready` is still pending. Such a
|
|
2959
|
+
// request also releases the gate — it proves the host subtree is live and
|
|
2960
|
+
// that something is blocked on this attachment — and is answered once
|
|
2961
|
+
// attach() and the remaining setup have run.
|
|
2962
|
+
//
|
|
2963
|
+
// A `@respond({ daemon })` handler resolves its target through the host's app
|
|
2964
|
+
// context, which is unreachable while the host is still disconnected (attach
|
|
2965
|
+
// before appendChild). Those are deferred here and registered by the second
|
|
2966
|
+
// pass past the gate, where they behaved correctly before this ordering.
|
|
2967
|
+
let requestClaimed = false;
|
|
2968
|
+
let releaseReadyGate;
|
|
2969
|
+
let completeAttach;
|
|
2970
|
+
let failAttach;
|
|
2971
|
+
const attached = new Promise((resolve, reject) => {
|
|
2972
|
+
completeAttach = resolve;
|
|
2973
|
+
failAttach = reject;
|
|
2974
|
+
});
|
|
2975
|
+
attached.catch(() => { }); // No requester when nothing was claimed
|
|
2976
|
+
setupResponseHandlers(controllerInstance, element, {
|
|
2977
|
+
deferUnresolvableDaemons: true,
|
|
2978
|
+
claim: () => {
|
|
2979
|
+
requestClaimed = true;
|
|
2980
|
+
releaseReadyGate?.();
|
|
2981
|
+
return attached;
|
|
2982
|
+
},
|
|
2983
|
+
});
|
|
2902
2984
|
// Normally a controller waits for its host's full initialization. The sole
|
|
2903
2985
|
// exception is attachController(host, ...) from that host's own @ready
|
|
2904
2986
|
// handler: awaiting ready there would wait on the current handler itself.
|
|
@@ -2911,6 +2993,11 @@ var Snice = (function (exports) {
|
|
|
2911
2993
|
try {
|
|
2912
2994
|
await Promise.race([
|
|
2913
2995
|
element.ready,
|
|
2996
|
+
new Promise(resolve => {
|
|
2997
|
+
if (requestClaimed)
|
|
2998
|
+
return resolve();
|
|
2999
|
+
releaseReadyGate = resolve;
|
|
3000
|
+
}),
|
|
2914
3001
|
new Promise((_, reject) => {
|
|
2915
3002
|
const onAbort = () => {
|
|
2916
3003
|
// Tagged so fire-and-forget call sites can tell this designed
|
|
@@ -2929,8 +3016,10 @@ var Snice = (function (exports) {
|
|
|
2929
3016
|
}
|
|
2930
3017
|
catch (error) {
|
|
2931
3018
|
// Attach never got past `ready` (aborted or deadline). Roll back the
|
|
2932
|
-
// stored references so a later attach does not
|
|
2933
|
-
// instance whose attach() never ran.
|
|
3019
|
+
// stored references and the early responders so a later attach does not
|
|
3020
|
+
// short-circuit against an instance whose attach() never ran.
|
|
3021
|
+
cleanupResponseHandlers(controllerInstance);
|
|
3022
|
+
failAttach(error);
|
|
2934
3023
|
if (element[CONTROLLER_KEY] === controllerInstance) {
|
|
2935
3024
|
if (typeof controller !== 'string') {
|
|
2936
3025
|
writeControllerAttribute(element, null);
|
|
@@ -2952,20 +3041,30 @@ var Snice = (function (exports) {
|
|
|
2952
3041
|
}
|
|
2953
3042
|
// Past `ready` — mark the controller so detach knows attach was actually run.
|
|
2954
3043
|
controllerInstance[CONTROLLER_ATTACHED] = true;
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
await
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
3044
|
+
try {
|
|
3045
|
+
// Run attach in the controller's scope
|
|
3046
|
+
await scope.runOperation(async () => {
|
|
3047
|
+
await controllerInstance.attach(element);
|
|
3048
|
+
});
|
|
3049
|
+
// @context has the same managed lifecycle on controllers as @on,
|
|
3050
|
+
// @observe and @respond. Catch up controllers whose async attach completed
|
|
3051
|
+
// after the Router announced the current navigation.
|
|
3052
|
+
await setupContextHandler(controllerInstance, 'microtask');
|
|
3053
|
+
// Setup @observe observers for controller
|
|
3054
|
+
setupObservers(controllerInstance, element);
|
|
3055
|
+
// Second @respond pass: registers only what the pre-gate pass deferred —
|
|
3056
|
+
// daemon-scoped responders whose app context was not resolvable yet.
|
|
3057
|
+
setupResponseHandlers(controllerInstance, element);
|
|
3058
|
+
// Setup @on event handlers for controller
|
|
3059
|
+
setupEventHandlers(controllerInstance, element);
|
|
3060
|
+
}
|
|
3061
|
+
catch (error) {
|
|
3062
|
+
// A claimed request must not wait on an attachment that never completed.
|
|
3063
|
+
failAttach(error);
|
|
3064
|
+
throw error;
|
|
3065
|
+
}
|
|
3066
|
+
// Answer whatever was claimed while the host was still becoming ready.
|
|
3067
|
+
completeAttach();
|
|
2969
3068
|
element.dispatchEvent(new CustomEvent('controller-attached', {
|
|
2970
3069
|
detail: { name: controllerName, controller: controllerInstance }
|
|
2971
3070
|
}));
|
|
@@ -10170,7 +10269,7 @@ var Snice = (function (exports) {
|
|
|
10170
10269
|
}
|
|
10171
10270
|
|
|
10172
10271
|
/*!
|
|
10173
|
-
* snice v7.
|
|
10272
|
+
* snice v7.7.0
|
|
10174
10273
|
* A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
|
|
10175
10274
|
* (c) 2024
|
|
10176
10275
|
* Released under the MIT License.
|
|
@@ -10192,7 +10291,7 @@ var Snice = (function (exports) {
|
|
|
10192
10291
|
globalThis.snice.pendingControllerAttachments ??= new Map();
|
|
10193
10292
|
|
|
10194
10293
|
/*!
|
|
10195
|
-
* snice v7.
|
|
10294
|
+
* snice v7.7.0
|
|
10196
10295
|
* A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
|
|
10197
10296
|
* (c) 2024
|
|
10198
10297
|
* Released under the MIT License.
|