mnfst 0.5.225 → 0.5.227

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.225';
5
+ const MANIFEST_BUILD_VERSION = '0.5.227';
6
6
 
7
7
  /* Manifest Data Sources - Configuration */
8
8
 
@@ -1593,6 +1593,7 @@ window.ManifestDataStore = {
1593
1593
  scope: '',
1594
1594
  generation: 0,
1595
1595
  pending: new Map(), // source -> time its debounced write is due
1596
+ landedIdentity: new Map(), // source -> identity its pending rows were read under
1596
1597
  writeTimer: null,
1597
1598
  hydrated: new Set(), // sources hydrated (or attempted) this generation
1598
1599
  hydratedIdentity: null, // identity auth-dependent hydration last ran under
@@ -1609,10 +1610,10 @@ window.ManifestDataStore = {
1609
1610
  const liveLocale = () => (typeof document !== 'undefined' && document.documentElement?.lang)
1610
1611
  || (typeof Alpine !== 'undefined' && Alpine.store?.('locale')?.current) || 'en';
1611
1612
 
1612
- // Auth-dependent sources (scope / $auth. queries) carry the identity they were read under
1613
+ // Auth-dependent sources (Appwrite tables/buckets, scope / $auth. queries) carry the identity they were read under
1613
1614
  function isAuthDependent(source) {
1614
1615
  if (!source || typeof source !== 'object') return false;
1615
- if (source.scope) return true;
1616
+ if (source.scope || source.appwriteTableId || source.appwriteBucketId) return true;
1616
1617
  try { return JSON.stringify(source.queries || '').includes('$auth.'); } catch { return false; }
1617
1618
  }
1618
1619
 
@@ -1629,6 +1630,19 @@ window.ManifestDataStore = {
1629
1630
  return auth?._sessionUnverified === true;
1630
1631
  }
1631
1632
 
1633
+ // Auth's last recorded identity (cross-tab mirror): '' signed out, null unknown
1634
+ function lastKnownIdentity() {
1635
+ try {
1636
+ const saved = JSON.parse((typeof window !== 'undefined' && window.localStorage?.getItem('manifest:auth:state')) || 'null');
1637
+ if (!saved || typeof saved !== 'object') return null;
1638
+ return saved.isAuthenticated ? (String(saved.user?.$id || saved.user?.id || '') || null) : '';
1639
+ } catch { return null; }
1640
+ }
1641
+
1642
+ // Unconfirmed (booting / offline): hydration trusts the last recorded identity; the data reset covers a mismatch
1643
+ function unconfirmed() { return authIdentity() === null || authUnverified(); }
1644
+ function hydrationIdentity() { return unconfirmed() ? lastKnownIdentity() : authIdentity(); }
1645
+
1632
1646
  function warnOnce(key, message, error) {
1633
1647
  if (state.warned.has(key)) return;
1634
1648
  state.warned.add(key);
@@ -1735,6 +1749,7 @@ window.ManifestDataStore = {
1735
1749
  function register(source, config) {
1736
1750
  const cfg = normalizeConfig(config === undefined ? true : config);
1737
1751
  if (!cfg) { state.sources.delete(source); return false; }
1752
+ cfg.authDependent = isAuthDependent(state.manifest?.data?.[source] || state.manifest?.appwrite?.[source]);
1738
1753
  state.sources.set(source, cfg);
1739
1754
  state.hydrated.delete(source);
1740
1755
  state.fetchKicked.delete(source);
@@ -1819,12 +1834,22 @@ window.ManifestDataStore = {
1819
1834
  if (next !== state.scope) changeScope(next);
1820
1835
  }
1821
1836
 
1837
+ // Pending saves of rows read under an identity that has since changed never land
1838
+ function dropStaleWrites() {
1839
+ if (unconfirmed()) return;
1840
+ const identity = authIdentity();
1841
+ for (const [source, landed] of [...state.landedIdentity]) {
1842
+ if (landed !== null && landed !== identity) cancelWrites(source);
1843
+ }
1844
+ }
1845
+
1822
1846
  function watchScope() {
1823
1847
  if (state.watching || typeof window === 'undefined') return;
1824
1848
  state.watching = true;
1825
1849
  for (const type of AUTH_EVENTS) {
1826
1850
  window.addEventListener(type, () => {
1827
1851
  if (!state.enabled) return;
1852
+ dropStaleWrites();
1828
1853
  if (WIPE_EVENTS.has(type)) deleteScope(state.scope);
1829
1854
  refreshScope();
1830
1855
  if (!state.scopePending) hydrate(bootSources()).catch(() => { /* disabled */ });
@@ -1998,14 +2023,18 @@ window.ManifestDataStore = {
1998
2023
  return null;
1999
2024
  }
2000
2025
 
2001
- function snapshotRecord(source) {
2026
+ function snapshotRecord(source, landed) {
2002
2027
  const cfg = state.sources.get(source);
2003
2028
  const ds = dataStore();
2004
2029
  if (!cfg || !ds) return null;
2005
2030
  const raw = ds.getRawData(source);
2006
2031
  if (raw === null || raw === undefined) return null;
2007
- const identity = cfg.authDependent ? authIdentity() : undefined;
2008
- if (identity === null) return null;
2032
+ let identity;
2033
+ if (cfg.authDependent) {
2034
+ // Stamped with the identity the rows were read under; skipped if it changed since or was never known
2035
+ identity = authUnverified() ? null : authIdentity();
2036
+ if (identity === null || landed === null || (landed !== undefined && landed !== identity)) return null;
2037
+ }
2009
2038
  try {
2010
2039
  const snapshot = snapshotOf(source, raw, cfg);
2011
2040
  if (snapshot === null) return null;
@@ -2028,9 +2057,10 @@ window.ManifestDataStore = {
2028
2057
 
2029
2058
  // Every source whose debounce has elapsed is written in ONE transaction
2030
2059
  function flush(sources) {
2031
- for (const source of sources) state.pending.delete(source);
2060
+ const landedIdentity = new Map(sources.map(source => [source, state.landedIdentity.get(source)]));
2061
+ for (const source of sources) { state.pending.delete(source); state.landedIdentity.delete(source); }
2032
2062
  if (!state.enabled || state.disabled) return Promise.resolve();
2033
- const records = sources.map(snapshotRecord).filter(Boolean);
2063
+ const records = sources.map(source => snapshotRecord(source, landedIdentity.get(source))).filter(Boolean);
2034
2064
  if (!records.length) return Promise.resolve();
2035
2065
  const generation = state.generation;
2036
2066
  return withStore('readwrite', (store) => { for (const record of records) store.put(record); }).then(() => {
@@ -2062,8 +2092,9 @@ window.ManifestDataStore = {
2062
2092
  }
2063
2093
 
2064
2094
  function cancelWrites(source) {
2065
- if (source !== undefined) { state.pending.delete(source); return; }
2095
+ if (source !== undefined) { state.pending.delete(source); state.landedIdentity.delete(source); return; }
2066
2096
  state.pending.clear();
2097
+ state.landedIdentity.clear();
2067
2098
  if (state.writeTimer !== null) { clearTimeout(state.writeTimer); state.writeTimer = null; }
2068
2099
  }
2069
2100
 
@@ -2071,7 +2102,12 @@ window.ManifestDataStore = {
2071
2102
  function onLanded(sources) {
2072
2103
  if (!state.enabled || state.disabled || state.scopePending) return; // nothing is keyed under an unresolved scope
2073
2104
  const at = Date.now() + WRITE_DEBOUNCE_MS;
2074
- for (const source of sources) if (state.sources.has(source)) state.pending.set(source, at);
2105
+ const identity = hydrationIdentity();
2106
+ for (const source of sources) {
2107
+ if (!state.sources.has(source)) continue;
2108
+ state.pending.set(source, at);
2109
+ if (state.sources.get(source).authDependent) state.landedIdentity.set(source, identity);
2110
+ }
2075
2111
  if (state.writeTimer !== null) { clearTimeout(state.writeTimer); state.writeTimer = null; }
2076
2112
  scheduleWrites();
2077
2113
  }
@@ -2085,8 +2121,11 @@ window.ManifestDataStore = {
2085
2121
  if (majorMinor(record.frameworkVersion) !== majorMinor(state.frameworkVersion)) return { ok: false, drop: true };
2086
2122
  if (record.locale && record.locale !== liveLocale()) return { ok: false };
2087
2123
  // Another identity's (or an unstamped) snapshot never hydrates: the scope alone may be '' for everyone
2088
- // An unverified (offline) signed-out boot keeps it for the session check to come back
2089
- if (cfg.authDependent && record.identity !== authIdentity()) return authUnverified() ? { ok: false } : { ok: false, drop: true };
2124
+ // Before the session is confirmed (booting / offline) a mismatch is kept for the check to come back
2125
+ if (cfg.authDependent) {
2126
+ const identity = hydrationIdentity();
2127
+ if (identity === null || record.identity !== identity) return unconfirmed() ? { ok: false } : { ok: false, drop: true };
2128
+ }
2090
2129
  return { ok: true };
2091
2130
  }
2092
2131
 
@@ -2095,7 +2134,7 @@ window.ManifestDataStore = {
2095
2134
  async function hydrate(sources) {
2096
2135
  const ds = dataStore();
2097
2136
  // Auth-dependent sources wait for a known identity (re-run on auth events), and retry when it changes
2098
- const identity = authIdentity();
2137
+ const identity = hydrationIdentity();
2099
2138
  const known = identity !== null;
2100
2139
  if (known && identity !== state.hydratedIdentity) {
2101
2140
  for (const [source, cfg] of state.sources) if (cfg.authDependent) state.hydrated.delete(source);
@@ -8666,10 +8705,8 @@ function createAppwriteMethodsHandler(dataSourceName, reloadDataSource) {
8666
8705
  }
8667
8706
  return null;
8668
8707
  } else if (method === '$remove') {
8669
- // Convenience method: delete file with automatic bucket reload and entry unlinking
8708
+ // Delete file(s), drop them from the source, unlink from table entries
8670
8709
  // Usage: $x.assets.$remove(fileId)
8671
- // Automatically reloads the entire assets bucket and unlinks from table entries
8672
- // This is an alias for $delete with the same auto-reload functionality
8673
8710
  const fileId = args[0];
8674
8711
  if (!fileId) {
8675
8712
  throw new Error('[Manifest Data] $remove requires file ID');
@@ -8687,20 +8724,15 @@ function createAppwriteMethodsHandler(dataSourceName, reloadDataSource) {
8687
8724
  // Continue with delete even if unlink fails
8688
8725
  }
8689
8726
 
8690
- // Delete file(s) and reload in parallel for speed
8691
- const deletePromise = Array.isArray(fileId)
8692
- ? Promise.all(fileId.map(id => window.ManifestDataAppwrite.deleteFile(bucketId, id.$id || id)))
8693
- : window.ManifestDataAppwrite.deleteFile(bucketId, actualFileId);
8694
-
8727
+ const deletedIds = (Array.isArray(fileId) ? fileId : [fileId]).map(id => id.$id || id);
8695
8728
  const generation = window.ManifestDataStore?.sourceGeneration?.(dataSourceName);
8696
- const reloadPromise = window.ManifestDataAppwrite.listBucketFiles(bucketId, []);
8697
-
8698
- // Do delete and reload in parallel
8699
- const [result, reloadedData] = await Promise.all([deletePromise, reloadPromise]);
8729
+ const result = Array.isArray(fileId)
8730
+ ? await Promise.all(deletedIds.map(id => window.ManifestDataAppwrite.deleteFile(bucketId, id)))
8731
+ : await window.ManifestDataAppwrite.deleteFile(bucketId, actualFileId);
8700
8732
 
8701
- // Network landing: reloaded bucket listing replaces the source (coalesced)
8702
- if (reloadedData && window.ManifestDataStore?.landRows) {
8703
- await window.ManifestDataStore.landRows(dataSourceName, reloadedData, { mode: 'replace', generation });
8733
+ // Drop the deleted file(s) locally: a relisting would bypass the source's queries and scope
8734
+ if (window.ManifestDataStore?.landRemove) {
8735
+ await window.ManifestDataStore.landRemove(dataSourceName, deletedIds, { generation });
8704
8736
  }
8705
8737
 
8706
8738
  // Reload affected table data sources so fileIds arrays and counters
@@ -11427,13 +11459,14 @@ function scheduleAuthRetry(dataSourceName, locale) {
11427
11459
  AUTH_RETRY_EVENTS.forEach(type => window.addEventListener(type, retry));
11428
11460
  }
11429
11461
 
11430
- // Teams known for this identity: login/anonymous dispatch after teams load, teams-loaded after the background load
11462
+ // Teams known for this identity: login/anonymous dispatch after teams load, teams-loaded after the background load.
11463
+ // A cross-tab login arrives before this tab's team load; its teams-loaded follows.
11431
11464
  let teamsSettledFor = null;
11432
11465
  // A sign-in deadline already answered by an auth event no longer holds sources
11433
11466
  let answeredDeadline = 0;
11434
11467
  if (typeof window !== 'undefined') {
11435
11468
  ['manifest:auth:teams-loaded', 'manifest:auth:login', 'manifest:auth:anonymous'].forEach(type =>
11436
- window.addEventListener(type, () => { teamsSettledFor = authUserId(currentAuth()); }));
11469
+ window.addEventListener(type, e => { if (!e?.detail?.crossTab) teamsSettledFor = authUserId(currentAuth()); }));
11437
11470
  // Kept only when logout restored the same (guest) identity whose teams already loaded
11438
11471
  ['manifest:auth:logout', 'manifest:auth:session-cleared', 'manifest:auth:initialized'].forEach(type =>
11439
11472
  window.addEventListener(type, () => { if (type === 'manifest:auth:initialized' || teamsSettledFor !== authUserId(currentAuth())) teamsSettledFor = null; }));
@@ -11449,10 +11482,11 @@ function authUserId(auth) {
11449
11482
  return auth?.user?.$id || auth?.user?.id || null;
11450
11483
  }
11451
11484
 
11452
- // Guest-auto or an auth callback is signing in after a signed-out init (bounded by the auth store)
11485
+ // Guest-auto or an auth callback is signing in after a signed-out init (bounded by the auth store).
11486
+ // Not while the session is unverified (no sign-in follows until Appwrite is reachable).
11453
11487
  // Prerender never waits on (or bakes) a guest's rows
11454
11488
  function signInWaitMs(auth) {
11455
- if (!auth || auth.isAuthenticated === true || window.__manifestRender) return 0;
11489
+ if (!auth || auth.isAuthenticated === true || auth._sessionUnverified === true || window.__manifestRender) return 0;
11456
11490
  const until = auth._signInPendingUntil || 0;
11457
11491
  if (until === answeredDeadline) return 0;
11458
11492
  return Math.max(0, until - Date.now());
@@ -11489,15 +11523,39 @@ function authSettledUnresolvable(manifest) {
11489
11523
  return auth._initialized === true && auth.isAuthenticated === true && teamsSettled(auth, manifest);
11490
11524
  }
11491
11525
 
11492
- function isAuthDependent(config) {
11526
+ // Rows depend on who reads them: scope / $auth. queries, or any Appwrite table/bucket (row/file permissions).
11527
+ // Reset on identity change only; whether a read needs an identity is buildAppwriteQueries' call (null = wait).
11528
+ function isIdentityBound(config) {
11493
11529
  if (!config || typeof config !== 'object') return false;
11530
+ if (window.ManifestDataConfig?.isAppwriteCollection?.(config)) return true;
11494
11531
  if (window.ManifestDataConfig?.getScope?.(config)) return true;
11495
11532
  try { return JSON.stringify(config.queries || '').includes('$auth.'); } catch { return false; }
11496
11533
  }
11497
11534
 
11498
- // Logout / session cleared: drop the previous identity's rows now, then settle for the new one
11535
+ // Auth's last recorded identity (cross-tab mirror): '' signed out, null unknown
11536
+ function lastKnownIdentity() {
11537
+ try {
11538
+ const saved = JSON.parse(window.localStorage?.getItem('manifest:auth:state') || 'null');
11539
+ if (!saved || typeof saved !== 'object') return null;
11540
+ return saved.isAuthenticated ? (String(saved.user?.$id || saved.user?.id || '') || null) : '';
11541
+ } catch { return null; }
11542
+ }
11543
+
11544
+ // Confirmed identity: '' signed out (or no auth plugin), null while booting or offline-unverified
11545
+ function confirmedIdentity() {
11546
+ const auth = currentAuth();
11547
+ if (!auth) return '';
11548
+ if (auth._initialized !== true || (auth._sessionUnverified === true && auth.isAuthenticated !== true)) return null;
11549
+ return auth.isAuthenticated === true ? (authUserId(auth) || '') : '';
11550
+ }
11551
+
11552
+ // Identity change (sign-in, sign-out, account switch): identity-bound sources reload for the new identity.
11553
+ // A previous user's rows drop at once; rows read signed out stay live until the reload lands.
11499
11554
  function setupAuthResetListener() {
11500
- const reset = async () => {
11555
+ let bound = (currentAuth() ? confirmedIdentity() : null) ?? lastKnownIdentity();
11556
+ // Reads under an unverified session failed or came from the snapshot: confirming the same identity still reloads
11557
+ let unverified = currentAuth()?._sessionUnverified === true;
11558
+ const reset = async (clear) => {
11501
11559
  const manifest = await window.ManifestDataConfig?.ensureManifest?.();
11502
11560
  const ds = window.ManifestDataStore;
11503
11561
  const store = typeof Alpine !== 'undefined' ? Alpine.store('data') : null;
@@ -11506,14 +11564,32 @@ function setupAuthResetListener() {
11506
11564
  const configs = { ...(manifest.appwrite || {}), ...(manifest.data || {}) };
11507
11565
  const locale = liveLocale();
11508
11566
  for (const [name, config] of Object.entries(configs)) {
11509
- if (!isAuthDependent(config) || raw[`_${name}_state`] === undefined) continue;
11510
- window.ManifestDataRealtime?.unsubscribeFromDataSource?.(name);
11511
- ds.resetSource(name);
11567
+ if (!isIdentityBound(config) || raw[`_${name}_state`] === undefined) continue;
11568
+ if (clear) {
11569
+ window.ManifestDataRealtime?.unsubscribeFromDataSource?.(name);
11570
+ ds.resetSource(name);
11571
+ }
11512
11572
  loadDataSource(name, locale, { reload: true });
11513
11573
  }
11514
11574
  };
11515
- window.addEventListener('manifest:auth:logout', reset);
11516
- window.addEventListener('manifest:auth:session-cleared', reset);
11575
+ const onAuth = (type) => {
11576
+ const ended = type === 'manifest:auth:logout' || type === 'manifest:auth:session-cleared';
11577
+ const next = confirmedIdentity() ?? (ended ? '' : null);
11578
+ if (next === null) { if (currentAuth()?._sessionUnverified === true) unverified = true; return; }
11579
+ const prev = bound;
11580
+ bound = next;
11581
+ const recovered = unverified;
11582
+ unverified = false;
11583
+ // Same identity, or unknown before (rows so far were read under this same session; a sign-out still drops them):
11584
+ // no reset, but an unverified boot's reads are redone with the rows kept live
11585
+ if (prev === next || (prev === null && !ended)) {
11586
+ if (recovered) reset(false);
11587
+ return;
11588
+ }
11589
+ reset(prev !== '');
11590
+ };
11591
+ ['manifest:auth:logout', 'manifest:auth:session-cleared', 'manifest:auth:login', 'manifest:auth:anonymous', 'manifest:auth:initialized']
11592
+ .forEach(type => window.addEventListener(type, () => onAuth(type)));
11517
11593
  }
11518
11594
 
11519
11595
  // Client-side scope filter: Appwrite returns all accessible files, so narrow to
@@ -1,6 +1,6 @@
1
1
  {
2
- "manifest.appwrite.auth.js": "sha384-eJ46LQV0lAoY48Zy1J8iecrK9azn/407FdeXz9+dwsuAJESUugOzlEBdTCw+i3m5",
3
- "manifest.appwrite.data.js": "sha384-uWy++AIY+DZbiEm+Qhkqxc6OJ3E0NSzx5Mq+8TCaAAI+cCV6PSbrS84JRjYV2jNF",
2
+ "manifest.appwrite.auth.js": "sha384-dsIWnH0qCAGSzAXMGrd8fvOrVl4tOIE6j5tC35JPTrQXZ56qLD36ARyvhR7vi3Id",
3
+ "manifest.appwrite.data.js": "sha384-gyEWaIe2Vk2k+OZL3d1YHsn2GUzso/3+L0z5a5hsRvc6yisJxCqBu+TCcJaq1qgT",
4
4
  "manifest.appwrite.presences.js": "sha384-JyVDWFT69b7Svq8J8p9tNWe2v9PZNQBY5UyhtOl1vnuHFAX0CRQ3MA9SiKq5wzNh",
5
5
  "manifest.bindings.js": "sha384-lPtMf8Ykaic9gNVZKq8Scia1881ZeMAyxer3WCIkUNwwrgzGBWto1OXADUwjvORF",
6
6
  "manifest.charts.js": "sha384-gEAv/98+29RbhvNkiNWTNyBPbLTFr2Ld15wLu29FLCL57j1cwGChRrL9Pfk7dBtT",
@@ -11,7 +11,7 @@
11
11
  "manifest.combobox.js": "sha384-MILTkrgsTzsYUjGo4ZuADqV85Xs4GmfB4xexfe9vbJMIoQTZ42W4zs+DTaVSPEsx",
12
12
  "manifest.components.js": "sha384-4bc3HgPvF9DHMiOG08w+nWXI7Hho01RuAPAUL9xyLxOiS2igeZpulCVcvr5aT9v6",
13
13
  "manifest.computed.js": "sha384-GYML/e81gQfN+iDbqhPUgny8bINCyL+SrbTofoGk4hlCnLLjv51mCv42JMqq+ku5",
14
- "manifest.data.js": "sha384-YljhDHjZ6BCU7qjoeecMvG1mgC7FwR7vw1EWBAyd6ZcMAlc3nmiztv3swRckN320",
14
+ "manifest.data.js": "sha384-nvTvY+1kswCEbVi8QZIpQHbWVUDipctUqRgv4yZCe2qbGmsGRGA4yK/UHVAEY3N8",
15
15
  "manifest.datepicker.js": "sha384-XnbeURni2X91ozVzatQcSjYYIS4MoW12dBRJnYAGBr0nCQ624heH5s+xtQSpLZX6",
16
16
  "manifest.defer.js": "sha384-WcCf8YQ1bKIXCLSZ24a0bJwepbYntYc8TzQM50hklo5VMIH8AtzDnwl6WU4prRv1",
17
17
  "manifest.device.js": "sha384-g+txmrEszYtuOvRelTp/c1wSNR2AtllVI9rx5NPPD7DzhVUnMNughonZykv2xlBW",
@@ -23,12 +23,11 @@
23
23
  "manifest.markdown.js": "sha384-JWUxlUZADxk1hZY7NpDX051UhtXt/ofpfsCDBRcweU6JhLbN8B832yPLgCatxFdl",
24
24
  "manifest.native.js": "sha384-g+txmrEszYtuOvRelTp/c1wSNR2AtllVI9rx5NPPD7DzhVUnMNughonZykv2xlBW",
25
25
  "manifest.payments.js": "sha384-8pofk2zhxtapPMpwnFyTelPMrYhShNhDCE722uQh/EYFvZFuPLmSdgunqsarVQjv",
26
- "manifest.resize.js": "sha384-+0IsyrGP/4gZmNbD6oU8dCgEyhpBsXMm74NIenYeUGuGRWyJDurcG27xE/CA0/aA",
27
26
  "manifest.router.js": "sha384-xkQaHO60lMQwtnqGPxPJJ646eyqBjINs4AFesrQbe2dWqPIoIcJ9RD5wsjqjak7w",
28
27
  "manifest.slides.js": "sha384-3uRTkyK9XPLmnxI2+igZlpi4EyPlU/7IHj5j3BZJJ2KN455vXyk99fiXV3feO/XY",
29
28
  "manifest.status.js": "sha384-MBO345ab7H6Uq1X2dZLt4Ge1Gcra+Z2qYApvlAeIV8CJhDDJrz2FPXpp+Kcp8zcM",
30
29
  "manifest.svg.js": "sha384-qr/8H9+2cIhSXNbRWRtIdrDlTOxKlNJqwEefHvCYoiBNW/kKhPTFa109Orv/EBnb",
31
- "manifest.sw.js": "sha384-hEYCjpYM1VHGJLc/RnSyUsmhBx/XrGhxCA31U6kW/TpFadcUZ0Uz96Rqm0uFbr+I",
30
+ "manifest.sw.js": "sha384-T29dPFWytpZW4ijBtvLGT4WZ0YPbF1whjHQbNVRw6RLYs5LMdO6LOcRlLPTC62CM",
32
31
  "manifest.tabs.js": "sha384-OIIcyaQnGS0eNYk4zgAFEDboNYect7THvUd9D0V6nqCeDOxQcoiqLrBEmmWVTTet",
33
32
  "manifest.tailwind.js": "sha384-r/Jvqb+Piz21jUts10BbVAJoKkShOdJRVFpywyi4HPIi/OfOJq5CtPyWAPbdkMgt",
34
33
  "manifest.text.edit.js": "sha384-RzOvLQE8GbmI6gntAwiotDewYT/08OHcd7sJ5hLon8e8u1Xbq1D7VfEGuaRVd2CE",
@@ -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.225';
19
+ const BUILD_VERSION = '0.5.227';
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.225",
3
+ "version": "0.5.227",
4
4
  "private": false,
5
5
  "workspaces": [
6
6
  "templates/starter",
@@ -47,7 +47,8 @@
47
47
  "test:e2e:sdk": "node tests/e2e/payments.sdk.e2e.mjs",
48
48
  "test:e2e:sw": "node tests/e2e/sw.e2e.mjs",
49
49
  "lint": "echo 'No linting configured'",
50
- "release:docs": "node scripts/release-bump.mjs packages/docs && cd packages/docs && npm publish --auth-type=web"
50
+ "release:docs": "node scripts/release-bump.mjs packages/docs && cd packages/docs && npm publish --auth-type=web",
51
+ "release:check": "node scripts/release-check.mjs"
51
52
  },
52
53
  "devDependencies": {
53
54
  "@rollup/plugin-commonjs": "^28.0.1",
@@ -1,194 +0,0 @@
1
- /* Manifest Resize Handles
2
-
3
- Superseded by x-edit.size (manifest.edit.css) — kept for existing projects.
4
- Self-contained: handle geometry lives here, not in a shared snippet. */
5
-
6
- @layer base, components, utilities;
7
-
8
- @layer utilities {
9
-
10
- :where([x-resize]) {
11
- position: relative;
12
-
13
- /* Resize handle area */
14
- .resize-handle {
15
- position: absolute;
16
- display: block;
17
- width: var(--h);
18
- height: var(--h);
19
- z-index: 100;
20
- background: transparent;
21
- border: none;
22
- outline: none;
23
- --h: var(--spacing-resize-handle, 1rem);
24
-
25
- /* Visible handle */
26
- &::before {
27
- content: '';
28
- position: absolute;
29
- top: 50%;
30
- left: 50%;
31
- transform: translate(-50%, -50%);
32
- width: 1px;
33
- height: 1px;
34
- background: transparent;
35
- transition: background-color 0.2s ease;
36
- pointer-events: none
37
- }
38
-
39
- &:hover::before,
40
- &:active::before {
41
- background-color: var(--color-line, color-mix(in oklch, oklch(20.5% 0 0) 10%, transparent));
42
- }
43
- }
44
-
45
- /* Handle geometry — edges span their axis, corners stay square */
46
- .resize-handle-top,
47
- .resize-handle-bottom {
48
- left: 0;
49
- width: 100%;
50
- height: var(--h);
51
- cursor: ns-resize;
52
-
53
- &::before {
54
- width: 100%
55
- }
56
- }
57
-
58
- .resize-handle-left,
59
- .resize-handle-right,
60
- .resize-handle-start,
61
- .resize-handle-end {
62
- top: 0;
63
- width: var(--h);
64
- height: 100%;
65
- cursor: ew-resize;
66
-
67
- &::before {
68
- height: 100%
69
- }
70
- }
71
-
72
- .resize-handle-top {
73
- top: calc(var(--h) * -0.5)
74
- }
75
-
76
- .resize-handle-bottom {
77
- bottom: calc(var(--h) * -0.5)
78
- }
79
-
80
- .resize-handle-left,
81
- .resize-handle-top-left,
82
- .resize-handle-bottom-left {
83
- left: calc(var(--h) * -0.5)
84
- }
85
-
86
- .resize-handle-right,
87
- .resize-handle-top-right,
88
- .resize-handle-bottom-right {
89
- right: calc(var(--h) * -0.5)
90
- }
91
-
92
- /* Logical edges — inset-inline-* auto-flips for RTL */
93
- .resize-handle-start,
94
- .resize-handle-top-start,
95
- .resize-handle-bottom-start {
96
- inset-inline-start: calc(var(--h) * -0.5)
97
- }
98
-
99
- .resize-handle-end,
100
- .resize-handle-top-end,
101
- .resize-handle-bottom-end {
102
- inset-inline-end: calc(var(--h) * -0.5)
103
- }
104
-
105
- .resize-handle-top-left,
106
- .resize-handle-top-right,
107
- .resize-handle-top-start,
108
- .resize-handle-top-end {
109
- top: calc(var(--h) * -0.5)
110
- }
111
-
112
- .resize-handle-bottom-left,
113
- .resize-handle-bottom-right,
114
- .resize-handle-bottom-start,
115
- .resize-handle-bottom-end {
116
- bottom: calc(var(--h) * -0.5)
117
- }
118
-
119
- /* Corner cursors */
120
- .resize-handle-top-left,
121
- .resize-handle-top-start {
122
- cursor: nw-resize;
123
- }
124
-
125
- .resize-handle-top-right,
126
- .resize-handle-top-end {
127
- cursor: ne-resize;
128
- }
129
-
130
- .resize-handle-bottom-left,
131
- .resize-handle-bottom-start {
132
- cursor: sw-resize;
133
- }
134
-
135
- .resize-handle-bottom-right,
136
- .resize-handle-bottom-end {
137
- cursor: se-resize;
138
- }
139
-
140
- /* Screen overlay to get mouse coordinates */
141
- .resize-overlay {
142
- position: fixed;
143
- top: 0;
144
- left: 0;
145
- width: 100vw;
146
- height: 100vh;
147
- z-index: 9999;
148
- display: none;
149
- background: transparent
150
- }
151
-
152
- /* Resize states */
153
- .resizable-closing {
154
- opacity: 0.5;
155
- transition: opacity 0.2s ease
156
- }
157
-
158
- .resizable-closed {
159
- display: none !important
160
- }
161
-
162
- /* Focus states for accessibility — framework ring (manifest.theme.css) */
163
- .resize-handle:focus {
164
- outline: none;
165
- box-shadow: 0 0 0 2px color-mix(in oklch, var(--color-content-stark) 30%, transparent)
166
- }
167
-
168
- /* Reduced motion support */
169
- @media (prefers-reduced-motion: reduce) {
170
-
171
- :where(.resizable-closing,
172
- .resize-handle) {
173
- transition: none
174
- }
175
- }
176
- }
177
-
178
- /* RTL cursor flips — placement follows the logical insets in the shared geometry */
179
- [dir=rtl] :where([x-resize]) .resize-handle-top-start {
180
- cursor: ne-resize;
181
- }
182
-
183
- [dir=rtl] :where([x-resize]) .resize-handle-top-end {
184
- cursor: nw-resize;
185
- }
186
-
187
- [dir=rtl] :where([x-resize]) .resize-handle-bottom-start {
188
- cursor: se-resize;
189
- }
190
-
191
- [dir=rtl] :where([x-resize]) .resize-handle-bottom-end {
192
- cursor: sw-resize;
193
- }
194
- }