mnfst 0.5.257 → 0.5.259

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.
@@ -2,7 +2,7 @@
2
2
 
3
3
  (function () {
4
4
 
5
- const MANIFEST_BUILD_VERSION = '0.5.257';
5
+ const MANIFEST_BUILD_VERSION = '0.5.259';
6
6
 
7
7
  /* Manifest Data Sources - Appwrite Integration */
8
8
 
@@ -298,8 +298,7 @@ if (!window.ManifestRealtimeHub) {
298
298
  status: 'online',
299
299
  metadata: null,
300
300
  scope: 'auto', // 'auto'/'team' = current team, 'global', or an explicit team id
301
- teamsEnabled: false, // manifest.appwrite.auth.teams (read at start)
302
- settleTimer: null, // bounded wait for teams to settle
301
+ teamsEnabled: false, // manifest.appwrite.auth.teams (read in ensureServices)
303
302
  auto: true, // focus/blur auto-flip
304
303
  heartbeatMs: 25000, // TTL refresh cadence
305
304
  onFocus: null,
@@ -363,6 +362,12 @@ if (!window.ManifestRealtimeHub) {
363
362
  if (!A || !A.Presences || !A.Realtime || !window.ManifestRealtimeHub) return false;
364
363
  const services = await window.ManifestAppwriteAuthConfig?.getAppwriteClient?.();
365
364
  if (!services?.client) return false;
365
+ // teamsEnabled gates the scoped (never-users()) grant: resolve it here
366
+ // so pre-start set() writes are covered, not only start()
367
+ try {
368
+ const authCfg = await window.ManifestAppwriteAuthConfig?.getAppwriteConfig?.();
369
+ ctx.teamsEnabled = !!authCfg?.teams;
370
+ } catch (e) { ctx.teamsEnabled = false; }
366
371
  ctx.client = services.client;
367
372
  ctx.presences = new A.Presences(services.client);
368
373
  return true;
@@ -370,23 +375,6 @@ if (!window.ManifestRealtimeHub) {
370
375
 
371
376
  /* Scope */
372
377
 
373
- // Teams load in the background after auth init; until they settle, a scoped
374
- // write must not fall back to read(users()) — that is the cross-tenant
375
- // broadcast window. Settles on the auth event, or after a bounded wait for
376
- // sessions the background load never covers (e.g. guests without guestTeams).
377
- let teamsSettled = false;
378
- window.addEventListener('manifest:auth:teams-loaded', () => { settleTeams(); });
379
- ['manifest:auth:logout', 'manifest:auth:session-cleared', 'manifest:auth:login', 'manifest:auth:anonymous'].forEach(type =>
380
- window.addEventListener(type, () => { teamsSettled = false; }));
381
- function settleTeams() {
382
- if (teamsSettled) return;
383
- teamsSettled = true;
384
- if (ctx.settleTimer) { clearTimeout(ctx.settleTimer); ctx.settleTimer = null; }
385
- // Settled with a team: the team-switch effect rescopes. Settled with
386
- // none: rewrite here, from self-only to the global users() grant.
387
- if (ctx.started && !scopeTeamId()) { hydrate(); rescope(); }
388
- }
389
-
390
378
  // Roster scope as a team id: explicit id > current team ('auto'/'team') > none ('global')
391
379
  function scopeTeamId() {
392
380
  const s = ctx.scope;
@@ -491,13 +479,13 @@ if (!window.ManifestRealtimeHub) {
491
479
  ctx.metadata = metadata !== undefined ? metadata : ctx.metadata;
492
480
 
493
481
  // Read-scope + owner write (owner update/delete required, else updates 401).
494
- // Reads follow the roster scope: team role when scoped, all users when
495
- // global. Scoped with teams NOT yet settled: self-only — never the
496
- // users() broadcast (the leak window); settle/team-switch rewrites it.
482
+ // Scoped (teams enabled, scope not global): team grant when resolved,
483
+ // self-only until then — however long teams take — never the users()
484
+ // broadcast. users() is only for global scope or teams-disabled projects.
485
+ // The team-switch effect rescopes reactively when a team resolves/changes.
497
486
  const teamId = scopeTeamId();
498
- const pending = !teamId && ctx.teamsEnabled && !teamsSettled
499
- && ctx.scope !== 'global' && ctx.scope !== false;
500
- const readRole = teamId ? A.Role.team(teamId) : (pending ? A.Role.user(user.$id) : A.Role.users());
487
+ const scoped = ctx.teamsEnabled && ctx.scope !== 'global' && ctx.scope !== false && ctx.scope != null;
488
+ const readRole = teamId ? A.Role.team(teamId) : (scoped ? A.Role.user(user.$id) : A.Role.users());
501
489
  const permissions = [
502
490
  A.Permission.read(readRole),
503
491
  A.Permission.update(A.Role.user(user.$id)),
@@ -566,18 +554,6 @@ if (!window.ManifestRealtimeHub) {
566
554
  if (!(await ensureServices())) { if (s) s.error = 'Appwrite Presences unavailable'; return false; }
567
555
  if (ctx.started) return true;
568
556
 
569
- // Teams settle via the auth plugin's background load; disabled teams or
570
- // an already-active team settle now, and a bounded wait covers sessions
571
- // the load never fires for (e.g. guests without guestTeams)
572
- try {
573
- const authCfg = await window.ManifestAppwriteAuthConfig?.getAppwriteConfig?.();
574
- ctx.teamsEnabled = !!authCfg?.teams;
575
- } catch (e) { ctx.teamsEnabled = false; }
576
- if (!ctx.teamsEnabled || currentTeamId()) settleTeams();
577
- else if (!teamsSettled && !ctx.settleTimer) {
578
- ctx.settleTimer = setTimeout(() => { ctx.settleTimer = null; settleTeams(); }, 8000);
579
- }
580
-
581
557
  ctx.started = true;
582
558
 
583
559
  await hydrate();
@@ -600,7 +576,6 @@ if (!window.ManifestRealtimeHub) {
600
576
  }
601
577
 
602
578
  function stop() {
603
- if (ctx.settleTimer) { clearTimeout(ctx.settleTimer); ctx.settleTimer = null; }
604
579
  if (ctx.heartbeat) { clearInterval(ctx.heartbeat); ctx.heartbeat = null; }
605
580
  if (ctx.onBlur) { window.removeEventListener('blur', ctx.onBlur); ctx.onBlur = null; }
606
581
  if (ctx.onFocus) { window.removeEventListener('focus', ctx.onFocus); ctx.onFocus = null; }
@@ -336,16 +336,19 @@
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
353
  try { void Alpine.store('data')?._dataVersion; } catch (_) { }
351
354
  // Every effect fire re-evaluates the expression (it may read live reactive
@@ -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
- this._t = setTimeout(() => { this._t = null; this.draw(); }, 0);
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);
@@ -2,7 +2,7 @@
2
2
 
3
3
  (function () {
4
4
 
5
- const MANIFEST_BUILD_VERSION = '0.5.257';
5
+ const MANIFEST_BUILD_VERSION = '0.5.259';
6
6
 
7
7
  /* Manifest Data Sources - Configuration */
8
8
 
@@ -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
- if (!menu.__mnfstContextDismissBound) {
388
- menu.__mnfstContextDismissBound = true;
389
- const ctxAbort = new AbortController();
390
- menu.__mnfstContextAbort = ctxAbort;
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-SE2I2UOfch9mzTeH8mN4eahFheT+k/nVTRLjHxFYqxPctgdw6x0c1Mq3Vm29JqZK",
4
- "manifest.appwrite.presences.js": "sha384-qsRtzFCtW7pS+I95EQuZQoPAeZvBsNDSMFwDFBJriyCWcNv2Jo2KFvOweClJhowJ",
3
+ "manifest.appwrite.data.js": "sha384-lTISi6IIxO+bW130kKO7a9/EHyjGT0lUru8qtPElMs238L+/gxvHg/A3P9NefCST",
4
+ "manifest.appwrite.presences.js": "sha384-/CagPsgWhO1sWEevCNGJmZ/ezRK9YCjLjvF7hxNSM4gVlJmEVtfSLfF7wnsRq441",
5
5
  "manifest.bindings.js": "sha384-lPtMf8Ykaic9gNVZKq8Scia1881ZeMAyxer3WCIkUNwwrgzGBWto1OXADUwjvORF",
6
- "manifest.charts.js": "sha384-G+huD7UvjF9zDovdVVlh4I5X1Mq4oNnJfoFg4NnGdP3R/4Skq9hy5cGuHNYLxDYm",
6
+ "manifest.charts.js": "sha384-H76xPNgPqvpOg1AIyvlZEqQo9V8AYASd/bWNRBMjY2hg+GbznTcH2LVXG2I89XAv",
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-qUo88WvgBU6QXgCD63d5/LGA5AtJx/qRvi88RUoW+CsOLELxOPNHOV1PimyRBsD6",
14
+ "manifest.data.js": "sha384-gIOTxlWIUF3LnJiLNKMZ42qB6BwLozfRDAy4kdHgD7WiDvoSibuv9jgFRARCDTL2",
15
15
  "manifest.datepicker.js": "sha384-2XwFFnS4Bg5FDvG/v8x6KUvrjcBQEOYyTxynX2K/D/Qb3PI6+Y04lEwCnVDJLzwL",
16
16
  "manifest.defer.js": "sha384-GK9qJkYtchtyzSQ+3zmDQUJE3+au4qthT2M8JnFjXxgfwCH5IVKc2r3tackgMryU",
17
17
  "manifest.device.js": "sha384-YeQaS56L8IILqrQNBSeAOLwIh5DuAOrE60cYLK1+46qJtUrXlAvqGe2j5mbV4Vq7",
18
- "manifest.dropdowns.js": "sha384-acufUps7R9WjqB4XXW5JLACqniuHJGM4CNTb2rF4B2Q/jv7ZRmsAwfr2McanOz3s",
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",
@@ -28,7 +28,7 @@
28
28
  "manifest.slides.js": "sha384-3uRTkyK9XPLmnxI2+igZlpi4EyPlU/7IHj5j3BZJJ2KN455vXyk99fiXV3feO/XY",
29
29
  "manifest.status.js": "sha384-MBO345ab7H6Uq1X2dZLt4Ge1Gcra+Z2qYApvlAeIV8CJhDDJrz2FPXpp+Kcp8zcM",
30
30
  "manifest.svg.js": "sha384-qr/8H9+2cIhSXNbRWRtIdrDlTOxKlNJqwEefHvCYoiBNW/kKhPTFa109Orv/EBnb",
31
- "manifest.sw.js": "sha384-KcWPCZS3JjopTS6bWZ+LarK4khKcWOL8q2ez+0OCj2XwjhcIN33IkLhdboAxoksP",
31
+ "manifest.sw.js": "sha384-yW9G0DKmr2DLNeT8w36vHnl/hRIuzlgMFGlWoDdykU8MNirE5+TyYUZuBzZ59F+/",
32
32
  "manifest.tabs.js": "sha384-otU09H7jnawVKQdLAYpMCd3jx00tgyPVr42D2hLIBzN5dG4se505YesavdnMqEi1",
33
33
  "manifest.tailwind.js": "sha384-r/Jvqb+Piz21jUts10BbVAJoKkShOdJRVFpywyi4HPIi/OfOJq5CtPyWAPbdkMgt",
34
34
  "manifest.toasts.js": "sha384-3zkWxzw693pxg3QDFsoYCA3CqYaLKmBaMArULXODD66Utolpewl0OAeTB92aWUVv",
@@ -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.257';
19
+ const BUILD_VERSION = '0.5.259';
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.257",
3
+ "version": "0.5.259",
4
4
  "private": false,
5
5
  "workspaces": [
6
6
  "templates/starter",