snice 7.3.0 → 7.4.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/.agents/skills/snice/SKILL.md +12 -16
- package/README.md +5 -1
- package/adapters/react/SniceProvider.js +1 -1
- package/adapters/react/SniceRouter.js +1 -1
- package/adapters/react/matchRoute.js +1 -1
- package/adapters/react/useRequestHandler.js +1 -1
- package/bin/analyzer-contracts.js +3 -1
- package/bin/project-analyzer.js +219 -6
- package/bin/snice.js +77 -13
- package/dist/app-context.d.ts +10 -10
- 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/snice-calendar.js +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 +309 -188
- 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 +309 -187
- 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/snice-table.esm.js +1 -1
- package/dist/cdn/table/snice-table.js +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/snice-tag-input.js +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/pagination/snice-pagination.types.d.ts +5 -0
- package/dist/context-provider.d.ts +11 -1
- package/dist/context.d.ts +5 -6
- package/dist/index.cjs +306 -184
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.esm.js +306 -185
- package/dist/index.esm.js.map +1 -1
- package/dist/index.iife.js +306 -184
- 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/symbols.cjs +1 -1
- package/dist/symbols.esm.js +1 -1
- package/dist/testing-dom.cjs +48 -0
- package/dist/testing-dom.cjs.map +1 -0
- package/dist/testing-dom.d.ts +23 -0
- package/dist/testing-dom.esm.js +45 -0
- package/dist/testing-dom.esm.js.map +1 -0
- package/dist/transitions.cjs +1 -1
- package/dist/transitions.esm.js +1 -1
- package/dist/types/context.d.ts +8 -8
- package/dist/utils.d.ts +3 -1
- package/docs/ai/api.md +12 -1
- package/docs/ai/architecture.md +7 -3
- package/docs/ai/bindings.md +1 -1
- package/docs/ai/cli.md +22 -0
- package/docs/ai/components/badge.md +4 -0
- package/docs/ai/components/pagination.md +4 -2
- package/docs/ai/components/segmented-control.md +5 -1
- package/docs/ai/controllers.md +30 -11
- package/docs/ai/decorators.md +2 -2
- package/docs/ai/events.md +8 -2
- package/docs/ai/fetcher.md +32 -1
- package/docs/ai/lifecycle.md +4 -1
- package/docs/ai/patterns.md +9 -4
- package/docs/ai/request-response.md +20 -6
- package/docs/ai/routing.md +8 -1
- package/docs/ai/testing.md +71 -0
- package/docs/bindings.md +1 -1
- package/docs/cli.md +23 -0
- package/docs/components/badge.md +4 -0
- package/docs/components/pagination.md +8 -5
- package/docs/components/segmented-control.md +5 -1
- package/docs/controllers.md +30 -11
- package/docs/events.md +11 -2
- package/docs/fetcher.md +32 -1
- package/docs/lifecycle.md +5 -1
- package/docs/request-response.md +25 -7
- package/docs/routing.md +10 -1
- package/docs/testing.md +71 -0
- package/package.json +6 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* snice v7.
|
|
2
|
+
* snice v7.4.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.3.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.
|
|
@@ -239,7 +239,7 @@ var Snice = (function (exports) {
|
|
|
239
239
|
*/
|
|
240
240
|
class Context {
|
|
241
241
|
constructor(context = {}, placards = [], currentRoute = '', routeParams = {}, fetcher) {
|
|
242
|
-
// Stores the SET of wrapped-method names per
|
|
242
|
+
// Stores the SET of wrapped-method names per subscriber so that classes with
|
|
243
243
|
// multiple @context() handlers register every method, not just the last one.
|
|
244
244
|
this[_a] = new WeakMap();
|
|
245
245
|
this[_b] = new Set();
|
|
@@ -263,7 +263,7 @@ var Snice = (function (exports) {
|
|
|
263
263
|
}
|
|
264
264
|
}
|
|
265
265
|
/**
|
|
266
|
-
* Register an element to receive context updates
|
|
266
|
+
* Register an element or controller to receive context updates
|
|
267
267
|
* @internal Used by @context decorator
|
|
268
268
|
*/
|
|
269
269
|
[(_a = REGISTERED_ELEMENTS, _b = REGISTERED_ELEMENTS_SET, _c = IS_UPDATING, CONTEXT_REGISTER)](element, methodName) {
|
|
@@ -277,10 +277,10 @@ var Snice = (function (exports) {
|
|
|
277
277
|
this[REGISTERED_ELEMENTS_SET].add(element);
|
|
278
278
|
}
|
|
279
279
|
/**
|
|
280
|
-
* Unregister
|
|
280
|
+
* Unregister a subscriber from context updates. With a methodName,
|
|
281
281
|
* removes only that one handler (so a `once` handler tearing itself down
|
|
282
282
|
* doesn't kill the element's other @context handlers); without one, removes
|
|
283
|
-
* the
|
|
283
|
+
* the subscriber entirely (used on disconnect/detach).
|
|
284
284
|
* @internal Used by @context decorator cleanup
|
|
285
285
|
*/
|
|
286
286
|
[CONTEXT_UNREGISTER](element, methodName) {
|
|
@@ -321,7 +321,7 @@ var Snice = (function (exports) {
|
|
|
321
321
|
return;
|
|
322
322
|
}
|
|
323
323
|
this[IS_UPDATING] = true;
|
|
324
|
-
// Notify all registered
|
|
324
|
+
// Notify all registered subscribers by calling EVERY registered method
|
|
325
325
|
// name on each. Classes with multiple @context() methods get all fired.
|
|
326
326
|
const elementsSet = this[REGISTERED_ELEMENTS_SET];
|
|
327
327
|
const elementsMap = this[REGISTERED_ELEMENTS];
|
|
@@ -343,7 +343,7 @@ var Snice = (function (exports) {
|
|
|
343
343
|
this[IS_UPDATING] = false;
|
|
344
344
|
}
|
|
345
345
|
/**
|
|
346
|
-
* Notify a specific
|
|
346
|
+
* Notify a specific subscriber of the current context state
|
|
347
347
|
* @internal Used by @context decorator
|
|
348
348
|
*/
|
|
349
349
|
[CONTEXT_NOTIFY_ELEMENT](element) {
|
|
@@ -352,7 +352,12 @@ var Snice = (function (exports) {
|
|
|
352
352
|
return;
|
|
353
353
|
for (const methodName of names) {
|
|
354
354
|
if (typeof element[methodName] === 'function') {
|
|
355
|
-
|
|
355
|
+
try {
|
|
356
|
+
element[methodName](this);
|
|
357
|
+
}
|
|
358
|
+
catch (error) {
|
|
359
|
+
console.error(`Error calling @context method ${methodName}:`, error);
|
|
360
|
+
}
|
|
356
361
|
}
|
|
357
362
|
}
|
|
358
363
|
}
|
|
@@ -684,11 +689,17 @@ var Snice = (function (exports) {
|
|
|
684
689
|
*/
|
|
685
690
|
function createDebounced(fn, delay) {
|
|
686
691
|
let timer = null;
|
|
687
|
-
|
|
692
|
+
const debounced = function (...args) {
|
|
688
693
|
if (timer !== null)
|
|
689
694
|
clearTimeout(timer);
|
|
690
695
|
timer = setTimeout(() => { fn.apply(this, args); timer = null; }, delay);
|
|
691
696
|
};
|
|
697
|
+
debounced.cancel = () => {
|
|
698
|
+
if (timer !== null)
|
|
699
|
+
clearTimeout(timer);
|
|
700
|
+
timer = null;
|
|
701
|
+
};
|
|
702
|
+
return debounced;
|
|
692
703
|
}
|
|
693
704
|
/**
|
|
694
705
|
* Create a throttled version of a function (leading + trailing edge)
|
|
@@ -1145,7 +1156,7 @@ var Snice = (function (exports) {
|
|
|
1145
1156
|
* boundary. Public callers use provideContext(), which also activates the
|
|
1146
1157
|
* daemon instances declared by the context.
|
|
1147
1158
|
*/
|
|
1148
|
-
function installContextProvider(root, context) {
|
|
1159
|
+
function installContextProvider(root, context, fetch, navigation) {
|
|
1149
1160
|
if (!root || typeof root.addEventListener !== 'function' || typeof root.removeEventListener !== 'function') {
|
|
1150
1161
|
throw new TypeError('provideContext() requires an EventTarget root.');
|
|
1151
1162
|
}
|
|
@@ -1157,9 +1168,26 @@ var Snice = (function (exports) {
|
|
|
1157
1168
|
}
|
|
1158
1169
|
const listener = (event) => {
|
|
1159
1170
|
const request = event;
|
|
1160
|
-
if (!request.detail
|
|
1171
|
+
if (!request.detail)
|
|
1172
|
+
return;
|
|
1173
|
+
if (request.detail.kind === 'application') {
|
|
1174
|
+
if (request.detail.context !== undefined)
|
|
1175
|
+
return;
|
|
1176
|
+
request.detail.context = context;
|
|
1177
|
+
}
|
|
1178
|
+
else if (request.detail.kind === 'fetch') {
|
|
1179
|
+
if (!fetch || request.detail.fetch !== undefined)
|
|
1180
|
+
return;
|
|
1181
|
+
request.detail.fetch = fetch;
|
|
1182
|
+
}
|
|
1183
|
+
else if (request.detail.kind === 'navigation') {
|
|
1184
|
+
if (!navigation || request.detail.navigation !== undefined)
|
|
1185
|
+
return;
|
|
1186
|
+
request.detail.navigation = navigation;
|
|
1187
|
+
}
|
|
1188
|
+
else {
|
|
1161
1189
|
return;
|
|
1162
|
-
|
|
1190
|
+
}
|
|
1163
1191
|
request.preventDefault();
|
|
1164
1192
|
request.stopPropagation();
|
|
1165
1193
|
};
|
|
@@ -1189,7 +1217,7 @@ var Snice = (function (exports) {
|
|
|
1189
1217
|
}
|
|
1190
1218
|
const target = contextTarget(source);
|
|
1191
1219
|
if (target) {
|
|
1192
|
-
const detail = {};
|
|
1220
|
+
const detail = { kind: 'application' };
|
|
1193
1221
|
target.dispatchEvent(new CustomEvent(CONTEXT_REQUEST_EVENT, {
|
|
1194
1222
|
bubbles: true,
|
|
1195
1223
|
composed: true,
|
|
@@ -1208,6 +1236,39 @@ var Snice = (function (exports) {
|
|
|
1208
1236
|
}
|
|
1209
1237
|
return undefined;
|
|
1210
1238
|
}
|
|
1239
|
+
/**
|
|
1240
|
+
* Resolve the fetch function supplied by the nearest context provider.
|
|
1241
|
+
* Router providers expose their ContextAwareFetcher-bound function here;
|
|
1242
|
+
* explicit providers may supply the same dependency for non-router apps and
|
|
1243
|
+
* tests without adding a reserved property to AppContext.
|
|
1244
|
+
*/
|
|
1245
|
+
function getContextFetch(source) {
|
|
1246
|
+
const target = contextTarget(source);
|
|
1247
|
+
if (!target)
|
|
1248
|
+
return undefined;
|
|
1249
|
+
const detail = { kind: 'fetch' };
|
|
1250
|
+
target.dispatchEvent(new CustomEvent(CONTEXT_REQUEST_EVENT, {
|
|
1251
|
+
bubbles: true,
|
|
1252
|
+
composed: true,
|
|
1253
|
+
cancelable: true,
|
|
1254
|
+
detail,
|
|
1255
|
+
}));
|
|
1256
|
+
return detail.fetch;
|
|
1257
|
+
}
|
|
1258
|
+
/** @internal Resolve the router Context visible to an element or controller. */
|
|
1259
|
+
function getNavigationContext(source) {
|
|
1260
|
+
const target = contextTarget(source);
|
|
1261
|
+
if (!target)
|
|
1262
|
+
return undefined;
|
|
1263
|
+
const detail = { kind: 'navigation' };
|
|
1264
|
+
target.dispatchEvent(new CustomEvent(CONTEXT_REQUEST_EVENT, {
|
|
1265
|
+
bubbles: true,
|
|
1266
|
+
composed: true,
|
|
1267
|
+
cancelable: true,
|
|
1268
|
+
detail,
|
|
1269
|
+
}));
|
|
1270
|
+
return detail.navigation;
|
|
1271
|
+
}
|
|
1211
1272
|
|
|
1212
1273
|
function isDaemonInstance(value) {
|
|
1213
1274
|
return !!value
|
|
@@ -1871,12 +1932,13 @@ var Snice = (function (exports) {
|
|
|
1871
1932
|
}
|
|
1872
1933
|
// Initialize cleanup object if needed
|
|
1873
1934
|
if (!instance[CLEANUP]) {
|
|
1874
|
-
instance[CLEANUP] = { events: [], channels: [], observers: [] };
|
|
1935
|
+
instance[CLEANUP] = { events: [], eventCancels: [], channels: [], observers: [] };
|
|
1875
1936
|
}
|
|
1876
|
-
|
|
1937
|
+
if (!instance[CLEANUP].events)
|
|
1877
1938
|
instance[CLEANUP].events = [];
|
|
1878
|
-
|
|
1879
|
-
|
|
1939
|
+
if (!instance[CLEANUP].eventCancels)
|
|
1940
|
+
instance[CLEANUP].eventCancels = [];
|
|
1941
|
+
if (instance[CLEANUP].events.length > 0 || instance[CLEANUP].eventCancels.length > 0) {
|
|
1880
1942
|
// Events already set up - clean them up first to avoid duplicates
|
|
1881
1943
|
cleanupEventHandlers(instance);
|
|
1882
1944
|
}
|
|
@@ -1906,7 +1968,9 @@ var Snice = (function (exports) {
|
|
|
1906
1968
|
warnIfModifierMisuse(handler.eventName);
|
|
1907
1969
|
// Apply debounce (takes precedence over throttle)
|
|
1908
1970
|
if (handlerOptions.debounce && handlerOptions.debounce > 0) {
|
|
1909
|
-
|
|
1971
|
+
const debounced = createDebounced(boundMethod, handlerOptions.debounce);
|
|
1972
|
+
instance[CLEANUP].eventCancels.push(() => debounced.cancel());
|
|
1973
|
+
boundMethod = debounced;
|
|
1910
1974
|
}
|
|
1911
1975
|
else if (handlerOptions.throttle && handlerOptions.throttle > 0) {
|
|
1912
1976
|
boundMethod = throttle$1(boundMethod, handlerOptions.throttle);
|
|
@@ -2079,12 +2143,190 @@ var Snice = (function (exports) {
|
|
|
2079
2143
|
function cleanupEventHandlers(instance) {
|
|
2080
2144
|
if (!instance[CLEANUP]?.events)
|
|
2081
2145
|
return;
|
|
2146
|
+
for (const cancel of instance[CLEANUP].eventCancels ?? [])
|
|
2147
|
+
cancel();
|
|
2148
|
+
instance[CLEANUP].eventCancels = [];
|
|
2082
2149
|
for (const { target, eventName, handler, options } of instance[CLEANUP].events) {
|
|
2083
2150
|
target.removeEventListener(eventName, handler, options);
|
|
2084
2151
|
}
|
|
2085
2152
|
instance[CLEANUP].events = [];
|
|
2086
2153
|
}
|
|
2087
2154
|
|
|
2155
|
+
/**
|
|
2156
|
+
* @context decorator for receiving router context updates
|
|
2157
|
+
*/
|
|
2158
|
+
const CONTEXT_HANDLERS = getSymbol('context-handlers');
|
|
2159
|
+
/**
|
|
2160
|
+
* @context decorator for receiving router context updates
|
|
2161
|
+
*
|
|
2162
|
+
* @example
|
|
2163
|
+
* ```typescript
|
|
2164
|
+
* @element('my-layout')
|
|
2165
|
+
* class MyLayout extends HTMLElement {
|
|
2166
|
+
* @context
|
|
2167
|
+
* handleContext(ctx: Context) {
|
|
2168
|
+
* this.renderNav(ctx.placards, ctx.currentRoute);
|
|
2169
|
+
* }
|
|
2170
|
+
*
|
|
2171
|
+
* @context({ debounce: 300 })
|
|
2172
|
+
* handleContextDebounced(ctx: Context) {
|
|
2173
|
+
* // Called after 300ms of no updates
|
|
2174
|
+
* }
|
|
2175
|
+
* }
|
|
2176
|
+
* ```
|
|
2177
|
+
*/
|
|
2178
|
+
function context$1(options = {}) {
|
|
2179
|
+
return function (originalMethod, context) {
|
|
2180
|
+
const methodName = context.name;
|
|
2181
|
+
context.addInitializer(function () {
|
|
2182
|
+
const constructor = this.constructor;
|
|
2183
|
+
// hasOwnProperty guards so subclasses don't mutate parent state via
|
|
2184
|
+
// the prototype chain.
|
|
2185
|
+
if (!Object.prototype.hasOwnProperty.call(constructor, CONTEXT_METHODS)) {
|
|
2186
|
+
constructor[CONTEXT_METHODS] = new Set();
|
|
2187
|
+
}
|
|
2188
|
+
if (constructor[CONTEXT_METHODS].has(originalMethod))
|
|
2189
|
+
return;
|
|
2190
|
+
constructor[CONTEXT_METHODS].add(originalMethod);
|
|
2191
|
+
if (!Object.prototype.hasOwnProperty.call(constructor, CONTEXT_HANDLERS)) {
|
|
2192
|
+
const inherited = constructor[CONTEXT_HANDLERS];
|
|
2193
|
+
constructor[CONTEXT_HANDLERS] = inherited ? [...inherited] : [];
|
|
2194
|
+
}
|
|
2195
|
+
constructor[CONTEXT_HANDLERS].push({
|
|
2196
|
+
methodName,
|
|
2197
|
+
method: originalMethod,
|
|
2198
|
+
options,
|
|
2199
|
+
});
|
|
2200
|
+
});
|
|
2201
|
+
return originalMethod;
|
|
2202
|
+
};
|
|
2203
|
+
}
|
|
2204
|
+
/**
|
|
2205
|
+
* Set up context handlers for an element or attached controller.
|
|
2206
|
+
* Called automatically by the corresponding managed lifecycle.
|
|
2207
|
+
*/
|
|
2208
|
+
function setupContextHandler(element, catchUp = false) {
|
|
2209
|
+
const handlers = element.constructor[CONTEXT_HANDLERS];
|
|
2210
|
+
if (!handlers || !Array.isArray(handlers) || handlers.length === 0) {
|
|
2211
|
+
return;
|
|
2212
|
+
}
|
|
2213
|
+
// Get the Context instance from the router
|
|
2214
|
+
const ctx = element[CONTEXT_HANDLER] ?? getNavigationContext(element);
|
|
2215
|
+
if (!ctx) {
|
|
2216
|
+
return;
|
|
2217
|
+
}
|
|
2218
|
+
// Store the Context instance for cleanup
|
|
2219
|
+
element[NAVIGATION_CONTEXT_INSTANCE] = ctx;
|
|
2220
|
+
// A controller can finish attaching after the Router has already announced
|
|
2221
|
+
// the current navigation. Track whether an update arrives during this turn;
|
|
2222
|
+
// if none does, catch it up once from the Context's current state.
|
|
2223
|
+
let receivedContextUpdate = false;
|
|
2224
|
+
// Register each handler with the Context
|
|
2225
|
+
for (const handler of handlers) {
|
|
2226
|
+
const { methodName, method, options } = handler;
|
|
2227
|
+
const wrappedMethodName = `__wrapped_${methodName}`;
|
|
2228
|
+
// Create wrapped method with timing controls
|
|
2229
|
+
element[wrappedMethodName] = function (context) {
|
|
2230
|
+
receivedContextUpdate = true;
|
|
2231
|
+
// `once` is tracked PER method (not a single element-level flag) so
|
|
2232
|
+
// multiple once handlers on the same element each fire.
|
|
2233
|
+
const called = element[CONTEXT_CALLED] ||
|
|
2234
|
+
(element[CONTEXT_CALLED] = new Set());
|
|
2235
|
+
if (options.once && called.has(methodName)) {
|
|
2236
|
+
return;
|
|
2237
|
+
}
|
|
2238
|
+
const callMethod = () => {
|
|
2239
|
+
method.call(element, context);
|
|
2240
|
+
// Handle once option
|
|
2241
|
+
if (options.once) {
|
|
2242
|
+
called.add(methodName);
|
|
2243
|
+
// Unregister ONLY this handler, not the whole element — otherwise the
|
|
2244
|
+
// element's other @context handlers would stop receiving updates.
|
|
2245
|
+
const ctx = element[NAVIGATION_CONTEXT_INSTANCE];
|
|
2246
|
+
if (ctx && typeof ctx[CONTEXT_UNREGISTER] === 'function') {
|
|
2247
|
+
ctx[CONTEXT_UNREGISTER](element, wrappedMethodName);
|
|
2248
|
+
}
|
|
2249
|
+
}
|
|
2250
|
+
};
|
|
2251
|
+
// Per-handler timer slot to avoid debounce/throttle handlers on the same
|
|
2252
|
+
// element overwriting each other's state.
|
|
2253
|
+
const timerSlot = element[CONTEXT_TIMER] ||
|
|
2254
|
+
(element[CONTEXT_TIMER] = {});
|
|
2255
|
+
const timerKey = methodName;
|
|
2256
|
+
if (options.debounce) {
|
|
2257
|
+
clearTimeout(timerSlot[timerKey]?.timeout);
|
|
2258
|
+
timerSlot[timerKey] = {
|
|
2259
|
+
timeout: setTimeout(callMethod, options.debounce),
|
|
2260
|
+
};
|
|
2261
|
+
return;
|
|
2262
|
+
}
|
|
2263
|
+
if (options.throttle) {
|
|
2264
|
+
const now = Date.now();
|
|
2265
|
+
const lastCall = timerSlot[timerKey]?.lastCall || 0;
|
|
2266
|
+
if (now - lastCall >= options.throttle) {
|
|
2267
|
+
timerSlot[timerKey] = { lastCall: now };
|
|
2268
|
+
callMethod();
|
|
2269
|
+
}
|
|
2270
|
+
return;
|
|
2271
|
+
}
|
|
2272
|
+
callMethod();
|
|
2273
|
+
};
|
|
2274
|
+
// Register with the Context using the wrapped method name
|
|
2275
|
+
if (typeof ctx[CONTEXT_REGISTER] === 'function') {
|
|
2276
|
+
ctx[CONTEXT_REGISTER](element, wrappedMethodName);
|
|
2277
|
+
}
|
|
2278
|
+
}
|
|
2279
|
+
if (catchUp && typeof ctx[CONTEXT_NOTIFY_ELEMENT] === 'function') {
|
|
2280
|
+
return new Promise((resolve) => {
|
|
2281
|
+
const notifyIfNeeded = () => {
|
|
2282
|
+
try {
|
|
2283
|
+
if (!receivedContextUpdate
|
|
2284
|
+
&& element[NAVIGATION_CONTEXT_INSTANCE] === ctx) {
|
|
2285
|
+
ctx[CONTEXT_NOTIFY_ELEMENT](element);
|
|
2286
|
+
}
|
|
2287
|
+
}
|
|
2288
|
+
finally {
|
|
2289
|
+
resolve();
|
|
2290
|
+
}
|
|
2291
|
+
};
|
|
2292
|
+
if (catchUp === 'task')
|
|
2293
|
+
setTimeout(notifyIfNeeded, 0);
|
|
2294
|
+
else
|
|
2295
|
+
queueMicrotask(notifyIfNeeded);
|
|
2296
|
+
});
|
|
2297
|
+
}
|
|
2298
|
+
}
|
|
2299
|
+
/**
|
|
2300
|
+
* Clean up context handlers for an element or attached controller.
|
|
2301
|
+
*/
|
|
2302
|
+
function cleanupContextHandler(element) {
|
|
2303
|
+
const handlers = element.constructor[CONTEXT_HANDLERS];
|
|
2304
|
+
if (!handlers || !Array.isArray(handlers) || handlers.length === 0) {
|
|
2305
|
+
return;
|
|
2306
|
+
}
|
|
2307
|
+
// Clear any pending debounce timers (per-handler slots)
|
|
2308
|
+
const timerSlot = element[CONTEXT_TIMER];
|
|
2309
|
+
if (timerSlot && typeof timerSlot === 'object') {
|
|
2310
|
+
for (const key of Object.keys(timerSlot)) {
|
|
2311
|
+
if (timerSlot[key]?.timeout)
|
|
2312
|
+
clearTimeout(timerSlot[key].timeout);
|
|
2313
|
+
}
|
|
2314
|
+
delete element[CONTEXT_TIMER];
|
|
2315
|
+
}
|
|
2316
|
+
for (const handler of handlers) {
|
|
2317
|
+
// Clean up wrapped method
|
|
2318
|
+
const wrappedMethodName = `__wrapped_${handler.methodName}`;
|
|
2319
|
+
delete element[wrappedMethodName];
|
|
2320
|
+
}
|
|
2321
|
+
// Unregister from Context if available
|
|
2322
|
+
const ctx = element[NAVIGATION_CONTEXT_INSTANCE];
|
|
2323
|
+
if (ctx && typeof ctx[CONTEXT_UNREGISTER] === 'function') {
|
|
2324
|
+
ctx[CONTEXT_UNREGISTER](element);
|
|
2325
|
+
}
|
|
2326
|
+
delete element[NAVIGATION_CONTEXT_INSTANCE];
|
|
2327
|
+
delete element[CONTEXT_CALLED];
|
|
2328
|
+
}
|
|
2329
|
+
|
|
2088
2330
|
// Controller-scoped cleanup registry
|
|
2089
2331
|
class ControllerScope {
|
|
2090
2332
|
constructor() {
|
|
@@ -2418,6 +2660,10 @@ var Snice = (function (exports) {
|
|
|
2418
2660
|
await scope.runOperation(async () => {
|
|
2419
2661
|
await controllerInstance.attach(element);
|
|
2420
2662
|
});
|
|
2663
|
+
// @context has the same managed lifecycle on controllers as @on,
|
|
2664
|
+
// @observe and @respond. Catch up controllers whose async attach completed
|
|
2665
|
+
// after the Router announced the current navigation.
|
|
2666
|
+
await setupContextHandler(controllerInstance, 'microtask');
|
|
2421
2667
|
// Setup @observe observers for controller
|
|
2422
2668
|
setupObservers(controllerInstance, element);
|
|
2423
2669
|
// Setup @channel handlers for controller
|
|
@@ -2483,6 +2729,8 @@ var Snice = (function (exports) {
|
|
|
2483
2729
|
cleanupResponseHandlers(controllerInstance);
|
|
2484
2730
|
// Cleanup @on event handlers for controller
|
|
2485
2731
|
cleanupEventHandlers(controllerInstance);
|
|
2732
|
+
// Cleanup @context handlers for controller
|
|
2733
|
+
cleanupContextHandler(controllerInstance);
|
|
2486
2734
|
// Cleanup the controller scope
|
|
2487
2735
|
if (scope) {
|
|
2488
2736
|
await scope.cleanup();
|
|
@@ -2616,158 +2864,6 @@ var Snice = (function (exports) {
|
|
|
2616
2864
|
globalThis.sniceNativeControllerObserver = observer;
|
|
2617
2865
|
}
|
|
2618
2866
|
|
|
2619
|
-
/**
|
|
2620
|
-
* @context decorator for receiving router context updates
|
|
2621
|
-
*/
|
|
2622
|
-
const CONTEXT_HANDLERS = getSymbol('context-handlers');
|
|
2623
|
-
/**
|
|
2624
|
-
* @context decorator for receiving router context updates
|
|
2625
|
-
*
|
|
2626
|
-
* @example
|
|
2627
|
-
* ```typescript
|
|
2628
|
-
* @element('my-layout')
|
|
2629
|
-
* class MyLayout extends HTMLElement {
|
|
2630
|
-
* @context
|
|
2631
|
-
* handleContext(ctx: Context) {
|
|
2632
|
-
* this.renderNav(ctx.placards, ctx.currentRoute);
|
|
2633
|
-
* }
|
|
2634
|
-
*
|
|
2635
|
-
* @context({ debounce: 300 })
|
|
2636
|
-
* handleContextDebounced(ctx: Context) {
|
|
2637
|
-
* // Called after 300ms of no updates
|
|
2638
|
-
* }
|
|
2639
|
-
* }
|
|
2640
|
-
* ```
|
|
2641
|
-
*/
|
|
2642
|
-
function context$1(options = {}) {
|
|
2643
|
-
return function (originalMethod, context) {
|
|
2644
|
-
const methodName = context.name;
|
|
2645
|
-
context.addInitializer(function () {
|
|
2646
|
-
const constructor = this.constructor;
|
|
2647
|
-
// hasOwnProperty guards so subclasses don't mutate parent state via
|
|
2648
|
-
// the prototype chain.
|
|
2649
|
-
if (!Object.prototype.hasOwnProperty.call(constructor, CONTEXT_METHODS)) {
|
|
2650
|
-
constructor[CONTEXT_METHODS] = new Set();
|
|
2651
|
-
}
|
|
2652
|
-
if (constructor[CONTEXT_METHODS].has(originalMethod))
|
|
2653
|
-
return;
|
|
2654
|
-
constructor[CONTEXT_METHODS].add(originalMethod);
|
|
2655
|
-
if (!Object.prototype.hasOwnProperty.call(constructor, CONTEXT_HANDLERS)) {
|
|
2656
|
-
const inherited = constructor[CONTEXT_HANDLERS];
|
|
2657
|
-
constructor[CONTEXT_HANDLERS] = inherited ? [...inherited] : [];
|
|
2658
|
-
}
|
|
2659
|
-
constructor[CONTEXT_HANDLERS].push({
|
|
2660
|
-
methodName,
|
|
2661
|
-
method: originalMethod,
|
|
2662
|
-
options,
|
|
2663
|
-
});
|
|
2664
|
-
});
|
|
2665
|
-
return originalMethod;
|
|
2666
|
-
};
|
|
2667
|
-
}
|
|
2668
|
-
/**
|
|
2669
|
-
* Setup context handler for an element instance
|
|
2670
|
-
* Called automatically during element connection
|
|
2671
|
-
*/
|
|
2672
|
-
function setupContextHandler(element) {
|
|
2673
|
-
const handlers = element.constructor[CONTEXT_HANDLERS];
|
|
2674
|
-
if (!handlers || !Array.isArray(handlers) || handlers.length === 0) {
|
|
2675
|
-
return;
|
|
2676
|
-
}
|
|
2677
|
-
// Get the Context instance from the router
|
|
2678
|
-
const ctx = element[CONTEXT_HANDLER];
|
|
2679
|
-
if (!ctx) {
|
|
2680
|
-
return;
|
|
2681
|
-
}
|
|
2682
|
-
// Store the Context instance for cleanup
|
|
2683
|
-
element[NAVIGATION_CONTEXT_INSTANCE] = ctx;
|
|
2684
|
-
// Register each handler with the Context
|
|
2685
|
-
for (const handler of handlers) {
|
|
2686
|
-
const { methodName, method, options } = handler;
|
|
2687
|
-
const wrappedMethodName = `__wrapped_${methodName}`;
|
|
2688
|
-
// Create wrapped method with timing controls
|
|
2689
|
-
element[wrappedMethodName] = function (context) {
|
|
2690
|
-
// `once` is tracked PER method (not a single element-level flag) so
|
|
2691
|
-
// multiple once handlers on the same element each fire.
|
|
2692
|
-
const called = element[CONTEXT_CALLED] ||
|
|
2693
|
-
(element[CONTEXT_CALLED] = new Set());
|
|
2694
|
-
if (options.once && called.has(methodName)) {
|
|
2695
|
-
return;
|
|
2696
|
-
}
|
|
2697
|
-
const callMethod = () => {
|
|
2698
|
-
method.call(element, context);
|
|
2699
|
-
// Handle once option
|
|
2700
|
-
if (options.once) {
|
|
2701
|
-
called.add(methodName);
|
|
2702
|
-
// Unregister ONLY this handler, not the whole element — otherwise the
|
|
2703
|
-
// element's other @context handlers would stop receiving updates.
|
|
2704
|
-
const ctx = element[NAVIGATION_CONTEXT_INSTANCE];
|
|
2705
|
-
if (ctx && typeof ctx[CONTEXT_UNREGISTER] === 'function') {
|
|
2706
|
-
ctx[CONTEXT_UNREGISTER](element, wrappedMethodName);
|
|
2707
|
-
}
|
|
2708
|
-
}
|
|
2709
|
-
};
|
|
2710
|
-
// Per-handler timer slot to avoid debounce/throttle handlers on the same
|
|
2711
|
-
// element overwriting each other's state.
|
|
2712
|
-
const timerSlot = element[CONTEXT_TIMER] ||
|
|
2713
|
-
(element[CONTEXT_TIMER] = {});
|
|
2714
|
-
const timerKey = methodName;
|
|
2715
|
-
if (options.debounce) {
|
|
2716
|
-
clearTimeout(timerSlot[timerKey]?.timeout);
|
|
2717
|
-
timerSlot[timerKey] = {
|
|
2718
|
-
timeout: setTimeout(callMethod, options.debounce),
|
|
2719
|
-
};
|
|
2720
|
-
return;
|
|
2721
|
-
}
|
|
2722
|
-
if (options.throttle) {
|
|
2723
|
-
const now = Date.now();
|
|
2724
|
-
const lastCall = timerSlot[timerKey]?.lastCall || 0;
|
|
2725
|
-
if (now - lastCall >= options.throttle) {
|
|
2726
|
-
timerSlot[timerKey] = { lastCall: now };
|
|
2727
|
-
callMethod();
|
|
2728
|
-
}
|
|
2729
|
-
return;
|
|
2730
|
-
}
|
|
2731
|
-
callMethod();
|
|
2732
|
-
};
|
|
2733
|
-
// Register with the Context using the wrapped method name
|
|
2734
|
-
if (typeof ctx[CONTEXT_REGISTER] === 'function') {
|
|
2735
|
-
ctx[CONTEXT_REGISTER](element, wrappedMethodName);
|
|
2736
|
-
}
|
|
2737
|
-
}
|
|
2738
|
-
}
|
|
2739
|
-
/**
|
|
2740
|
-
* Cleanup context handler for an element instance
|
|
2741
|
-
* Called automatically during element disconnection
|
|
2742
|
-
*/
|
|
2743
|
-
function cleanupContextHandler(element) {
|
|
2744
|
-
const handlers = element.constructor[CONTEXT_HANDLERS];
|
|
2745
|
-
if (!handlers || !Array.isArray(handlers) || handlers.length === 0) {
|
|
2746
|
-
return;
|
|
2747
|
-
}
|
|
2748
|
-
// Clear any pending debounce timers (per-handler slots)
|
|
2749
|
-
const timerSlot = element[CONTEXT_TIMER];
|
|
2750
|
-
if (timerSlot && typeof timerSlot === 'object') {
|
|
2751
|
-
for (const key of Object.keys(timerSlot)) {
|
|
2752
|
-
if (timerSlot[key]?.timeout)
|
|
2753
|
-
clearTimeout(timerSlot[key].timeout);
|
|
2754
|
-
}
|
|
2755
|
-
delete element[CONTEXT_TIMER];
|
|
2756
|
-
}
|
|
2757
|
-
for (const handler of handlers) {
|
|
2758
|
-
// Clean up wrapped method
|
|
2759
|
-
const wrappedMethodName = `__wrapped_${handler.methodName}`;
|
|
2760
|
-
delete element[wrappedMethodName];
|
|
2761
|
-
}
|
|
2762
|
-
// Unregister from Context if available
|
|
2763
|
-
const ctx = element[NAVIGATION_CONTEXT_INSTANCE];
|
|
2764
|
-
if (ctx && typeof ctx[CONTEXT_UNREGISTER] === 'function') {
|
|
2765
|
-
ctx[CONTEXT_UNREGISTER](element);
|
|
2766
|
-
}
|
|
2767
|
-
delete element[NAVIGATION_CONTEXT_INSTANCE];
|
|
2768
|
-
delete element[CONTEXT_CALLED];
|
|
2769
|
-
}
|
|
2770
|
-
|
|
2771
2867
|
/**
|
|
2772
2868
|
* Template system for Snice v3.0.0
|
|
2773
2869
|
* Provides html`` and css`` tagged template processors with differential rendering
|
|
@@ -3003,14 +3099,32 @@ var Snice = (function (exports) {
|
|
|
3003
3099
|
function markPreUpgradePropertyBinding(element, propertyName) {
|
|
3004
3100
|
const tagName = element.localName;
|
|
3005
3101
|
if (!tagName?.includes('-'))
|
|
3006
|
-
return;
|
|
3102
|
+
return false;
|
|
3007
3103
|
const registry = element.ownerDocument?.defaultView?.customElements ?? globalThis.customElements;
|
|
3008
3104
|
if (registry?.get(tagName))
|
|
3009
|
-
return;
|
|
3105
|
+
return false;
|
|
3010
3106
|
const target = element;
|
|
3011
3107
|
if (!target[PRE_UPGRADE_PROPERTY_BINDINGS])
|
|
3012
3108
|
target[PRE_UPGRADE_PROPERTY_BINDINGS] = new Set();
|
|
3013
3109
|
target[PRE_UPGRADE_PROPERTY_BINDINGS].add(propertyName);
|
|
3110
|
+
return true;
|
|
3111
|
+
}
|
|
3112
|
+
function commitPropertyValue(element, propertyName, value) {
|
|
3113
|
+
if (!markPreUpgradePropertyBinding(element, propertyName)) {
|
|
3114
|
+
element[propertyName] = value;
|
|
3115
|
+
return;
|
|
3116
|
+
}
|
|
3117
|
+
// An undefined custom element can inherit a native IDL setter with the same
|
|
3118
|
+
// name. Assignment would invoke that setter (for example HTMLElement.role),
|
|
3119
|
+
// stringify structured data into an attribute, and leave no own value for
|
|
3120
|
+
// @property's upgrade adoption. Park every pre-upgrade binding as the own,
|
|
3121
|
+
// configurable value that the initializer already knows how to replay.
|
|
3122
|
+
Object.defineProperty(element, propertyName, {
|
|
3123
|
+
configurable: true,
|
|
3124
|
+
enumerable: true,
|
|
3125
|
+
writable: true,
|
|
3126
|
+
value,
|
|
3127
|
+
});
|
|
3014
3128
|
}
|
|
3015
3129
|
// noChange sentinel - preserves the currently committed value
|
|
3016
3130
|
const noChange = Symbol.for('snice:no-change');
|
|
@@ -4647,15 +4761,13 @@ var Snice = (function (exports) {
|
|
|
4647
4761
|
commitProperties(next) {
|
|
4648
4762
|
for (const key of Object.keys(this.committed)) {
|
|
4649
4763
|
if (!Object.prototype.hasOwnProperty.call(next, key)) {
|
|
4650
|
-
|
|
4651
|
-
this.element[key] = undefined;
|
|
4764
|
+
commitPropertyValue(this.element, key, undefined);
|
|
4652
4765
|
}
|
|
4653
4766
|
}
|
|
4654
4767
|
for (const [key, value] of Object.entries(next)) {
|
|
4655
4768
|
if (Object.is(this.committed[key], value))
|
|
4656
4769
|
continue;
|
|
4657
|
-
|
|
4658
|
-
this.element[key] = value === nothing ? undefined : value;
|
|
4770
|
+
commitPropertyValue(this.element, key, value === nothing ? undefined : value);
|
|
4659
4771
|
}
|
|
4660
4772
|
}
|
|
4661
4773
|
commitAttributes(next) {
|
|
@@ -4782,8 +4894,7 @@ var Snice = (function (exports) {
|
|
|
4782
4894
|
return;
|
|
4783
4895
|
}
|
|
4784
4896
|
this._committedValue = value;
|
|
4785
|
-
|
|
4786
|
-
this.element[this.name] = value === nothing ? undefined : value;
|
|
4897
|
+
commitPropertyValue(this.element, this.name, value === nothing ? undefined : value);
|
|
4787
4898
|
}
|
|
4788
4899
|
clear() {
|
|
4789
4900
|
// This part is being destroyed with its owning template. The element is
|
|
@@ -6815,7 +6926,7 @@ var Snice = (function (exports) {
|
|
|
6815
6926
|
// Re-establish handlers that get cleaned up on disconnect
|
|
6816
6927
|
setupEventHandlers(this, this);
|
|
6817
6928
|
setupResponseHandlers(this, this);
|
|
6818
|
-
setupContextHandler(this);
|
|
6929
|
+
void setupContextHandler(this, 'task');
|
|
6819
6930
|
// Re-establish observers that get cleaned up on disconnect
|
|
6820
6931
|
try {
|
|
6821
6932
|
setupObservers(this, this);
|
|
@@ -6940,7 +7051,7 @@ var Snice = (function (exports) {
|
|
|
6940
7051
|
}
|
|
6941
7052
|
setupEventHandlers(this, this);
|
|
6942
7053
|
setupResponseHandlers(this, this);
|
|
6943
|
-
setupContextHandler(this);
|
|
7054
|
+
void setupContextHandler(this, 'task');
|
|
6944
7055
|
this[INITIALIZED] = true;
|
|
6945
7056
|
// One-time (per class) sanity check: a @watch name with no matching
|
|
6946
7057
|
// @property never fires — surface the typo instead of staying silent.
|
|
@@ -8645,10 +8756,11 @@ var Snice = (function (exports) {
|
|
|
8645
8756
|
*
|
|
8646
8757
|
* Daemon instances must already exist in context.daemons. The returned cleanup
|
|
8647
8758
|
* removes the provider and deactivates framework communication for daemons no
|
|
8648
|
-
* longer provided by any context.
|
|
8759
|
+
* longer provided by any context. An optional fetch function is exposed on the
|
|
8760
|
+
* same boundary through getContextFetch() without modifying the context object.
|
|
8649
8761
|
*/
|
|
8650
|
-
function
|
|
8651
|
-
const releaseProvider = installContextProvider(root, context);
|
|
8762
|
+
function provideContextBoundary(root, context, options, navigation) {
|
|
8763
|
+
const releaseProvider = installContextProvider(root, context, options.fetch, navigation);
|
|
8652
8764
|
let releaseDaemons;
|
|
8653
8765
|
try {
|
|
8654
8766
|
releaseDaemons = bindContextDaemons(context);
|
|
@@ -8666,6 +8778,15 @@ var Snice = (function (exports) {
|
|
|
8666
8778
|
releaseDaemons?.();
|
|
8667
8779
|
};
|
|
8668
8780
|
}
|
|
8781
|
+
function provideContext(root, context, options = {}) {
|
|
8782
|
+
return provideContextBoundary(root, context, options);
|
|
8783
|
+
}
|
|
8784
|
+
/** @internal Router-owned provider including live navigation state. */
|
|
8785
|
+
function provideRouterContext(root, navigation) {
|
|
8786
|
+
return provideContextBoundary(root, navigation.application, {
|
|
8787
|
+
fetch: navigation.fetch,
|
|
8788
|
+
}, navigation);
|
|
8789
|
+
}
|
|
8669
8790
|
|
|
8670
8791
|
// Router historically allows a later Router instance to take over the same
|
|
8671
8792
|
// target. Track only Router-owned provider releases so that handoff remains
|
|
@@ -8709,7 +8830,7 @@ var Snice = (function (exports) {
|
|
|
8709
8830
|
return;
|
|
8710
8831
|
releaseContextProvider?.();
|
|
8711
8832
|
routerContextProviders.get(target)?.();
|
|
8712
|
-
const releaseProvidedContext =
|
|
8833
|
+
const releaseProvidedContext = provideRouterContext(target, navigationContext);
|
|
8713
8834
|
let released = false;
|
|
8714
8835
|
const release = () => {
|
|
8715
8836
|
if (released)
|
|
@@ -9593,7 +9714,7 @@ var Snice = (function (exports) {
|
|
|
9593
9714
|
}
|
|
9594
9715
|
|
|
9595
9716
|
/*!
|
|
9596
|
-
* snice v7.
|
|
9717
|
+
* snice v7.3.0
|
|
9597
9718
|
* A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
|
|
9598
9719
|
* (c) 2024
|
|
9599
9720
|
* Released under the MIT License.
|
|
@@ -9615,7 +9736,7 @@ var Snice = (function (exports) {
|
|
|
9615
9736
|
globalThis.snice.pendingControllerAttachments ??= new Map();
|
|
9616
9737
|
|
|
9617
9738
|
/*!
|
|
9618
|
-
* snice v7.
|
|
9739
|
+
* snice v7.3.0
|
|
9619
9740
|
* A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
|
|
9620
9741
|
* (c) 2024
|
|
9621
9742
|
* Released under the MIT License.
|
|
@@ -9661,6 +9782,7 @@ var Snice = (function (exports) {
|
|
|
9661
9782
|
exports.escapeHtml = escapeHtml;
|
|
9662
9783
|
exports.getBodyScrollLockCount = getBodyScrollLockCount;
|
|
9663
9784
|
exports.getContext = getContext;
|
|
9785
|
+
exports.getContextFetch = getContextFetch;
|
|
9664
9786
|
exports.getController = getController;
|
|
9665
9787
|
exports.getSymbol = getSymbol;
|
|
9666
9788
|
exports.html = html;
|