mnfst 0.5.258 → 0.5.260
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/lib/manifest.appwrite.data.js +1 -1
- package/lib/manifest.charts.js +12 -5
- package/lib/manifest.data.js +1 -1
- package/lib/manifest.datepicker.js +1 -1
- package/lib/manifest.dropdowns.js +63 -23
- package/lib/manifest.integrity.json +7 -7
- package/lib/manifest.status.js +1 -1
- package/lib/manifest.sw.js +1 -1
- package/package.json +2 -1
package/lib/manifest.charts.js
CHANGED
|
@@ -336,18 +336,21 @@
|
|
|
336
336
|
},
|
|
337
337
|
|
|
338
338
|
activate() {
|
|
339
|
-
if (this.active) return;
|
|
339
|
+
if (this.active || this.disposed) return;
|
|
340
340
|
this.active = true;
|
|
341
|
-
loadD3().then(d3 => { this.d3 = d3; this.bindReactive(); })
|
|
341
|
+
loadD3().then(d3 => { if (this.disposed) return; this.d3 = d3; this.bindReactive(); })
|
|
342
342
|
.catch(() => { this.renderError('Chart engine failed to load.'); });
|
|
343
343
|
},
|
|
344
344
|
|
|
345
345
|
bindReactive() {
|
|
346
346
|
const self = this;
|
|
347
347
|
const getCfg = self.expression ? Alpine.evaluateLater(self.el, self.expression) : null;
|
|
348
|
-
Alpine.effect
|
|
348
|
+
// Kept so cleanup can release it: an unreleased Alpine.effect stays subscribed
|
|
349
|
+
// to the long-lived data store, which pins this state, its element and the
|
|
350
|
+
// whole destroyed subtree for the life of the page (and keeps redrawing it).
|
|
351
|
+
self._effect = Alpine.effect(() => {
|
|
349
352
|
// Subscribe to the data store heartbeat so $x loads/locale reloads re-run.
|
|
350
|
-
try {
|
|
353
|
+
try { const ds = Alpine.store('data'); if (ds) void ds._dataVersion; } catch (_) { }
|
|
351
354
|
// Every effect fire re-evaluates the expression (it may read live reactive
|
|
352
355
|
// state — realtime rows, presence, staged $x hydration — that changes far
|
|
353
356
|
// more often than the resulting config). applyConfig() short-circuits a
|
|
@@ -393,7 +396,8 @@
|
|
|
393
396
|
try { console.warn('[Manifest Charts] "' + (this.el.id || this.expression || 'chart') + '" redrew ' + this._scheduleWindowCount + '+ times within one second — likely a reactive dependency changing on every read (or, for a map, a legitimately busy data feed hitting its per-draw geometry cost).'); } catch (_) { }
|
|
394
397
|
}
|
|
395
398
|
}
|
|
396
|
-
|
|
399
|
+
if (this.disposed) return;
|
|
400
|
+
this._t = setTimeout(() => { this._t = null; if (!this.disposed) this.draw(); }, 0);
|
|
397
401
|
},
|
|
398
402
|
|
|
399
403
|
renderError(msg) { this.el.innerHTML = ''; const d = document.createElement('small'); d.textContent = msg; this.el.appendChild(d); },
|
|
@@ -1241,6 +1245,9 @@
|
|
|
1241
1245
|
el.style.minHeight = (hm ? +hm[1] : 240) + 'px';
|
|
1242
1246
|
observer().observe(el);
|
|
1243
1247
|
cleanup(() => {
|
|
1248
|
+
state.disposed = true;
|
|
1249
|
+
if (state._effect) { Alpine.release(state._effect); state._effect = null; }
|
|
1250
|
+
if (state._t) { clearTimeout(state._t); state._t = null; }
|
|
1244
1251
|
if (state._ro) state._ro.disconnect();
|
|
1245
1252
|
if (state._onLocale) window.removeEventListener('localechange', state._onLocale);
|
|
1246
1253
|
if (io) io.unobserve(el);
|
package/lib/manifest.data.js
CHANGED
|
@@ -1000,7 +1000,7 @@
|
|
|
1000
1000
|
Alpine.effect(() => {
|
|
1001
1001
|
let locale = '', dir = '';
|
|
1002
1002
|
try { const ls = Alpine.store('locale'); locale = ls?.current || document.documentElement.lang || ''; dir = ls?.direction || ''; } catch (_) { }
|
|
1003
|
-
try {
|
|
1003
|
+
try { const ds = Alpine.store('data'); if (ds) void ds._dataVersion; } catch (_) { }
|
|
1004
1004
|
const ui = window.ManifestUI.resolve('date', UI_FALLBACK);
|
|
1005
1005
|
const key = locale + '|' + dir + '|' + JSON.stringify(ui);
|
|
1006
1006
|
if (state._uiKey === key) return;
|
|
@@ -13,6 +13,31 @@ let lastPointerTarget = null;
|
|
|
13
13
|
document.addEventListener('keydown', () => { lastInputModality = 'keyboard'; }, true);
|
|
14
14
|
document.addEventListener('pointerdown', (e) => { lastInputModality = 'mouse'; lastPointerTarget = e.target; }, true);
|
|
15
15
|
|
|
16
|
+
// Context-menu dismiss (click outside / Escape). Module scope on purpose: a closure
|
|
17
|
+
// made inside the directive shares its V8 context with every sibling closure, so it
|
|
18
|
+
// would pin the trigger and, through it, the trigger's whole subtree.
|
|
19
|
+
function bindContextDismiss(menu, signal) {
|
|
20
|
+
document.addEventListener('pointerdown', (e) => {
|
|
21
|
+
if (menu.matches(':popover-open') && !menu.contains(e.target)) menu.hidePopover();
|
|
22
|
+
}, { signal });
|
|
23
|
+
document.addEventListener('keydown', (e) => {
|
|
24
|
+
if (e.key === 'Escape' && menu.matches(':popover-open')) {
|
|
25
|
+
menu.hidePopover();
|
|
26
|
+
const host = menu._triggerHost;
|
|
27
|
+
if (host && host.isConnected) host.focus();
|
|
28
|
+
}
|
|
29
|
+
}, { signal });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function ensureContextDismiss(menu, owner) {
|
|
33
|
+
if (menu.__mnfstContextDismissBound) return;
|
|
34
|
+
menu.__mnfstContextDismissBound = true;
|
|
35
|
+
const ctxAbort = new AbortController();
|
|
36
|
+
menu.__mnfstContextAbort = ctxAbort;
|
|
37
|
+
menu.__mnfstCtxOwner = owner;
|
|
38
|
+
bindContextDismiss(menu, ctxAbort.signal);
|
|
39
|
+
}
|
|
40
|
+
|
|
16
41
|
function initializeDropdownPlugin() {
|
|
17
42
|
// Ensure an Alpine context exists. Keep the scope empty — seeding properties
|
|
18
43
|
// collides with author state and the tabs plugin's `tab` property.
|
|
@@ -51,18 +76,42 @@ function initializeDropdownPlugin() {
|
|
|
51
76
|
ensureAlpineContext();
|
|
52
77
|
|
|
53
78
|
// Register dropdown directive
|
|
54
|
-
registerDirective('dropdown', (el, { modifiers, expression }, { effect, evaluateLater }) => {
|
|
79
|
+
registerDirective('dropdown', (el, { modifiers, expression }, { effect, evaluateLater, cleanup }) => {
|
|
55
80
|
let menu;
|
|
56
81
|
|
|
82
|
+
// Listeners this trigger adds to things that outlive it (its menu, document)
|
|
83
|
+
// are bound with this run's signal and aborted when Alpine tears the trigger
|
|
84
|
+
// down, or when the effect re-runs setup. Without it every re-rendered trigger
|
|
85
|
+
// left its closures (and through them its whole detached subtree) on the
|
|
86
|
+
// shared menu / document forever.
|
|
87
|
+
let runAbort = null;
|
|
88
|
+
cleanup(() => {
|
|
89
|
+
if (runAbort) runAbort.abort();
|
|
90
|
+
runAbort = null;
|
|
91
|
+
if (menu && menu.__mnfstCtxOwner === el) {
|
|
92
|
+
menu.__mnfstContextAbort?.abort();
|
|
93
|
+
menu.__mnfstContextDismissBound = false;
|
|
94
|
+
menu.__mnfstContextAbort = null;
|
|
95
|
+
menu.__mnfstCtxOwner = null;
|
|
96
|
+
}
|
|
97
|
+
if (menu && menu.__mnfstTrigger === el) menu.__mnfstTrigger = null;
|
|
98
|
+
if (menu && menu._triggerHost === el) { menu._triggerHost = null; menu._triggerEl = null; }
|
|
99
|
+
});
|
|
100
|
+
|
|
57
101
|
// Shared hover state for all dropdown types
|
|
58
102
|
let hoverTimeout;
|
|
59
103
|
let autoCloseTimeout;
|
|
60
104
|
let startAutoCloseTimer;
|
|
61
105
|
|
|
62
106
|
effect(() => {
|
|
107
|
+
if (runAbort) runAbort.abort();
|
|
108
|
+
const runCtl = new AbortController();
|
|
109
|
+
runAbort = runCtl;
|
|
110
|
+
const signal = runCtl.signal;
|
|
63
111
|
|
|
64
112
|
// Defer processing to ensure Alpine is fully ready
|
|
65
113
|
setTimeout(() => {
|
|
114
|
+
if (signal.aborted) return;
|
|
66
115
|
if (!window.Alpine) {
|
|
67
116
|
console.warn('[Manifest] Alpine not available for dropdown processing');
|
|
68
117
|
return;
|
|
@@ -154,7 +203,7 @@ function initializeDropdownPlugin() {
|
|
|
154
203
|
if (window.__manifestComponentsInitialized) {
|
|
155
204
|
waitForComponent();
|
|
156
205
|
} else {
|
|
157
|
-
window.addEventListener('manifest:components-ready', waitForComponent);
|
|
206
|
+
window.addEventListener('manifest:components-ready', waitForComponent, { once: true, signal });
|
|
158
207
|
}
|
|
159
208
|
return; // Exit early, setup will happen in waitForComponent
|
|
160
209
|
}
|
|
@@ -174,7 +223,7 @@ function initializeDropdownPlugin() {
|
|
|
174
223
|
setupDropdown();
|
|
175
224
|
|
|
176
225
|
function setupDropdown() {
|
|
177
|
-
if (!menu) return;
|
|
226
|
+
if (!menu || signal.aborted) return;
|
|
178
227
|
|
|
179
228
|
// Context menus use manual popover (no light-dismiss) to avoid
|
|
180
229
|
// conflicts with multi-touch trackpad right-click
|
|
@@ -299,6 +348,7 @@ function initializeDropdownPlugin() {
|
|
|
299
348
|
// (client-reported empty menu) — hydrate the x-defer stash ourselves.
|
|
300
349
|
if (window.ManifestDefer?.isPending(menu)) window.ManifestDefer.render(menu);
|
|
301
350
|
|
|
351
|
+
ensureContextDismiss(menu, el);
|
|
302
352
|
if (!menu.matches(':popover-open')) menu.showPopover();
|
|
303
353
|
|
|
304
354
|
// Adjust if menu overflows viewport
|
|
@@ -384,20 +434,10 @@ function initializeDropdownPlugin() {
|
|
|
384
434
|
|
|
385
435
|
// Document-level dismiss listeners are global — bind once per
|
|
386
436
|
// menu via an AbortController so reprocessing can't leak them.
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
const { signal } = ctxAbort;
|
|
392
|
-
|
|
393
|
-
// Manual dismiss: click outside or Escape
|
|
394
|
-
document.addEventListener('pointerdown', (e) => {
|
|
395
|
-
if (menu.matches(':popover-open') && !menu.contains(e.target)) closeContext();
|
|
396
|
-
}, { signal });
|
|
397
|
-
document.addEventListener('keydown', (e) => {
|
|
398
|
-
if (e.key === 'Escape' && menu.matches(':popover-open')) { closeContext(); el.focus(); }
|
|
399
|
-
}, { signal });
|
|
400
|
-
}
|
|
437
|
+
// Bound once per menu, owned by one trigger and released in that
|
|
438
|
+
// trigger's cleanup (see top). Any other trigger of the same menu
|
|
439
|
+
// re-binds on its next open, so a shared menu never loses dismiss.
|
|
440
|
+
ensureContextDismiss(menu, el);
|
|
401
441
|
}
|
|
402
442
|
|
|
403
443
|
// Auto-close on selection: `close` per item, .close for every row
|
|
@@ -504,7 +544,7 @@ function initializeDropdownPlugin() {
|
|
|
504
544
|
(e.target.querySelector('a') || e.target).click();
|
|
505
545
|
}
|
|
506
546
|
}
|
|
507
|
-
});
|
|
547
|
+
}, { signal });
|
|
508
548
|
|
|
509
549
|
// Make li elements focusable when menu opens
|
|
510
550
|
menu.addEventListener('toggle', (e) => {
|
|
@@ -532,7 +572,7 @@ function initializeDropdownPlugin() {
|
|
|
532
572
|
}
|
|
533
573
|
}
|
|
534
574
|
}
|
|
535
|
-
});
|
|
575
|
+
}, { signal });
|
|
536
576
|
|
|
537
577
|
// Add hover functionality for menu
|
|
538
578
|
if (modifiers.includes('hover')) {
|
|
@@ -540,14 +580,14 @@ function initializeDropdownPlugin() {
|
|
|
540
580
|
menu.addEventListener('mouseenter', () => {
|
|
541
581
|
clearTimeout(autoCloseTimeout);
|
|
542
582
|
clearTimeout(hoverTimeout);
|
|
543
|
-
});
|
|
583
|
+
}, { signal });
|
|
544
584
|
|
|
545
585
|
menu.addEventListener('mouseleave', () => {
|
|
546
586
|
// Always start timer when leaving menu bounds
|
|
547
587
|
if (startAutoCloseTimer) {
|
|
548
588
|
startAutoCloseTimer();
|
|
549
589
|
}
|
|
550
|
-
});
|
|
590
|
+
}, { signal });
|
|
551
591
|
|
|
552
592
|
// Add event listeners to all interactive elements inside menu to cancel timers
|
|
553
593
|
const cancelCloseTimer = () => {
|
|
@@ -561,14 +601,14 @@ function initializeDropdownPlugin() {
|
|
|
561
601
|
menuItems.forEach(item => {
|
|
562
602
|
if (wiredItems.has(item)) return;
|
|
563
603
|
wiredItems.add(item);
|
|
564
|
-
item.addEventListener('mouseenter', cancelCloseTimer);
|
|
604
|
+
item.addEventListener('mouseenter', cancelCloseTimer, { signal });
|
|
565
605
|
});
|
|
566
606
|
};
|
|
567
607
|
|
|
568
608
|
// Setup listeners after a brief delay to ensure menu is rendered;
|
|
569
609
|
// again when a deferred menu renders its items
|
|
570
610
|
setTimeout(setupMenuItemListeners, 10);
|
|
571
|
-
menu.addEventListener('manifest:defer-render', setupMenuItemListeners);
|
|
611
|
+
menu.addEventListener('manifest:defer-render', setupMenuItemListeners, { signal });
|
|
572
612
|
}
|
|
573
613
|
} // End of setupDropdown function
|
|
574
614
|
});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifest.appwrite.auth.js": "sha384-9WNhIeSEzxxJm+yP7cV41kV2xyzyXgFCNpThqiREcNbb6tnIW6O7VRZPL2jwy9Nk",
|
|
3
|
-
"manifest.appwrite.data.js": "sha384-
|
|
3
|
+
"manifest.appwrite.data.js": "sha384-NrUgzRg0XIrS/BYh6iw9V/S5MH2EkMy7935n7UnT+nq9nUrPtVBRHlmfNuymT9R4",
|
|
4
4
|
"manifest.appwrite.presences.js": "sha384-/CagPsgWhO1sWEevCNGJmZ/ezRK9YCjLjvF7hxNSM4gVlJmEVtfSLfF7wnsRq441",
|
|
5
5
|
"manifest.bindings.js": "sha384-lPtMf8Ykaic9gNVZKq8Scia1881ZeMAyxer3WCIkUNwwrgzGBWto1OXADUwjvORF",
|
|
6
|
-
"manifest.charts.js": "sha384-
|
|
6
|
+
"manifest.charts.js": "sha384-lzcoovnPCKhcwigrwYvc5rPAZuZNHwWmNNuu7hxPsfJuKAu8ejla5F7agHZ2Xft9",
|
|
7
7
|
"manifest.chat.js": "sha384-88DfMfJLoi2oxclVD2iIMDkIGAExMXq5k47mekUredlicLaP3oZY5bwtwqs+TqDF",
|
|
8
8
|
"manifest.code.js": "sha384-WGPlZE5Sp9GygUzJSmCdpLyYQTgvmEKc9BQS9Hmq1VTQwkqYJzPSWibHvPekcres",
|
|
9
9
|
"manifest.color.js": "sha384-6Rv3LxyTcZNjrhtayQfqRdCx0uSZ4BiEbgEI98I62eTvp8Aw7LBIoNJ0Je1oktwL",
|
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
"manifest.combobox.js": "sha384-MILTkrgsTzsYUjGo4ZuADqV85Xs4GmfB4xexfe9vbJMIoQTZ42W4zs+DTaVSPEsx",
|
|
12
12
|
"manifest.components.js": "sha384-BUFA8h+G5Plr82sV7bKzO42pPoiRZwRQcKj1lt2ROFiKjjlkayU/vmkAFqEsdBA+",
|
|
13
13
|
"manifest.computed.js": "sha384-GYML/e81gQfN+iDbqhPUgny8bINCyL+SrbTofoGk4hlCnLLjv51mCv42JMqq+ku5",
|
|
14
|
-
"manifest.data.js": "sha384-
|
|
15
|
-
"manifest.datepicker.js": "sha384-
|
|
14
|
+
"manifest.data.js": "sha384-OXdlXbo1eKsq/47pj6A9qPTyxtvvjxycFzgZeE5tmLbIT/Nj+A1JdofNmoV9/iRa",
|
|
15
|
+
"manifest.datepicker.js": "sha384-JeDdzdwXdXmnvgv1N1N+7WIQlezew9YJcvui3uVEvqAOX0WEaJO7ofLRRuc4hFBS",
|
|
16
16
|
"manifest.defer.js": "sha384-GK9qJkYtchtyzSQ+3zmDQUJE3+au4qthT2M8JnFjXxgfwCH5IVKc2r3tackgMryU",
|
|
17
17
|
"manifest.device.js": "sha384-YeQaS56L8IILqrQNBSeAOLwIh5DuAOrE60cYLK1+46qJtUrXlAvqGe2j5mbV4Vq7",
|
|
18
|
-
"manifest.dropdowns.js": "sha384-
|
|
18
|
+
"manifest.dropdowns.js": "sha384-ORVhBVvqhx58sd7Ij8b+NOIkjWF2TGcz5a8BC+CIswsS8TDLtyIDqD3YM4HDsGzB",
|
|
19
19
|
"manifest.edit.js": "sha384-MOgQNdNLeHijhR0u2W6ntoOulKFglsATCFDqkinesOU15tHoILk/JNzHKkGi5dUG",
|
|
20
20
|
"manifest.export.js": "sha384-Rx6XvqBZc4apzP/FwcDr6yIln4/zNa08Q4ZqBZcEqUz1aNZQfl4h0+Ae7mqCQyuG",
|
|
21
21
|
"manifest.icons.js": "sha384-kKOINpX70YzNO3FvkV6umrmO3f0KIu0DNbwB+ej55a7y/lhU7v/myQtXL0bwCTbt",
|
|
@@ -26,9 +26,9 @@
|
|
|
26
26
|
"manifest.rich.text.js": "sha384-ZBV9jXmu2nmprEHicddRE/m7nR4RPZtVc969Jte0+EJYBcVph7itkjcgN/61PyeC",
|
|
27
27
|
"manifest.router.js": "sha384-9LMIkwrgnxmmFDv70TND2MRJF1z6Nl4yqG7fH5DbJ8oUIhdu/u4yUPSime1/EYhP",
|
|
28
28
|
"manifest.slides.js": "sha384-3uRTkyK9XPLmnxI2+igZlpi4EyPlU/7IHj5j3BZJJ2KN455vXyk99fiXV3feO/XY",
|
|
29
|
-
"manifest.status.js": "sha384-
|
|
29
|
+
"manifest.status.js": "sha384-Zf07q/5tRS2F0o128sINYrce8xP035FTV0Ot7V7/hh+cwFhVZg+EWkHZN5b42aBn",
|
|
30
30
|
"manifest.svg.js": "sha384-qr/8H9+2cIhSXNbRWRtIdrDlTOxKlNJqwEefHvCYoiBNW/kKhPTFa109Orv/EBnb",
|
|
31
|
-
"manifest.sw.js": "sha384-
|
|
31
|
+
"manifest.sw.js": "sha384-V4isxMDJOOMSqedY9JNCeVXhe4tJTA/GUBReX9dghYtNr68cUhsqur76nOmlO3iF",
|
|
32
32
|
"manifest.tabs.js": "sha384-otU09H7jnawVKQdLAYpMCd3jx00tgyPVr42D2hLIBzN5dG4se505YesavdnMqEi1",
|
|
33
33
|
"manifest.tailwind.js": "sha384-r/Jvqb+Piz21jUts10BbVAJoKkShOdJRVFpywyi4HPIi/OfOJq5CtPyWAPbdkMgt",
|
|
34
34
|
"manifest.toasts.js": "sha384-3zkWxzw693pxg3QDFsoYCA3CqYaLKmBaMArULXODD66Utolpewl0OAeTB92aWUVv",
|
package/lib/manifest.status.js
CHANGED
|
@@ -543,7 +543,7 @@
|
|
|
543
543
|
// Human label for a state, localized through `_ui`, else title-cased.
|
|
544
544
|
function formatStateLabel(state) {
|
|
545
545
|
// Dep on the data store version so labels re-resolve when a `_ui` source loads late.
|
|
546
|
-
try {
|
|
546
|
+
try { const ds = window.Alpine && Alpine.store('data'); if (ds) void ds._dataVersion; } catch (_) { }
|
|
547
547
|
const ui = window.ManifestUI ? window.ManifestUI.resolve('status', UI_FALLBACK) : UI_FALLBACK;
|
|
548
548
|
const labels = (ui && ui.label) || UI_FALLBACK.label;
|
|
549
549
|
if (labels[state]) return _resolveRefString(labels[state]);
|
package/lib/manifest.sw.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
// Build stamps the published version here; unstamped (dev) falls back to the
|
|
18
18
|
// registration URL's `v`, then 'dev'.
|
|
19
|
-
const BUILD_VERSION = '0.5.
|
|
19
|
+
const BUILD_VERSION = '0.5.260';
|
|
20
20
|
const CACHE_PREFIX = 'mnfst-sw:';
|
|
21
21
|
const META_CACHE = CACHE_PREFIX + 'meta';
|
|
22
22
|
// Sized to hold a full precache.json warm-up (PRECACHE_MAX_ENTRIES server-side)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mnfst",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.260",
|
|
4
4
|
"private": false,
|
|
5
5
|
"workspaces": [
|
|
6
6
|
"templates/starter",
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
"puppeteer": "^24.15.0",
|
|
66
66
|
"rimraf": "^5.0.0",
|
|
67
67
|
"rollup": "^4.24.2",
|
|
68
|
+
"terser": "^5.47.1",
|
|
68
69
|
"vitest": "^4.1.2"
|
|
69
70
|
},
|
|
70
71
|
"keywords": [
|