mnfst 0.5.229 → 0.5.230

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.229';
5
+ const MANIFEST_BUILD_VERSION = '0.5.230';
6
6
 
7
7
  /* Manifest Data Sources - Appwrite Integration */
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  (function () {
4
4
 
5
- const MANIFEST_BUILD_VERSION = '0.5.229';
5
+ const MANIFEST_BUILD_VERSION = '0.5.230';
6
6
 
7
7
  /* Manifest Data Sources - Configuration */
8
8
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "manifest.appwrite.auth.js": "sha384-dsIWnH0qCAGSzAXMGrd8fvOrVl4tOIE6j5tC35JPTrQXZ56qLD36ARyvhR7vi3Id",
3
- "manifest.appwrite.data.js": "sha384-dLaV5W1wDtVkrfE2k5BwFL3TCCybtkAjgi+lc9GaZ2OnTdC0pmXPYBOxX64TqG9I",
3
+ "manifest.appwrite.data.js": "sha384-Mpd1w3Weo2ioajbPvtsMQQtT/VhPJAGWCyjvN7IpSW2ZbGxsvWYj5FxxUxBOfITx",
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-Ry718yAA50wEXkWObL/41NDB7XFa2tMMxlwcrRnbK5ycYGApz2zD9/9SBPqRJY1R",
14
+ "manifest.data.js": "sha384-SjwWBJN06ct4ON/VFx3aVoZ141p1fn9oW8S8tMyzKz5fY2mx3/T5GWnwDids2qCx",
15
15
  "manifest.datepicker.js": "sha384-XnbeURni2X91ozVzatQcSjYYIS4MoW12dBRJnYAGBr0nCQ624heH5s+xtQSpLZX6",
16
16
  "manifest.defer.js": "sha384-WcCf8YQ1bKIXCLSZ24a0bJwepbYntYc8TzQM50hklo5VMIH8AtzDnwl6WU4prRv1",
17
17
  "manifest.device.js": "sha384-g+txmrEszYtuOvRelTp/c1wSNR2AtllVI9rx5NPPD7DzhVUnMNughonZykv2xlBW",
@@ -27,12 +27,12 @@
27
27
  "manifest.slides.js": "sha384-3uRTkyK9XPLmnxI2+igZlpi4EyPlU/7IHj5j3BZJJ2KN455vXyk99fiXV3feO/XY",
28
28
  "manifest.status.js": "sha384-MBO345ab7H6Uq1X2dZLt4Ge1Gcra+Z2qYApvlAeIV8CJhDDJrz2FPXpp+Kcp8zcM",
29
29
  "manifest.svg.js": "sha384-qr/8H9+2cIhSXNbRWRtIdrDlTOxKlNJqwEefHvCYoiBNW/kKhPTFa109Orv/EBnb",
30
- "manifest.sw.js": "sha384-FHy5ttfRVY2p/uI3dD8Pd2j/7YOOeTaHgKwdpR0UVJdBS2Tg2t9jzo8iHt7O8mTF",
30
+ "manifest.sw.js": "sha384-2+0QTucW8JqeS8aOImj9rehXkkQ6ZADpD4PAvt3k72woRiZIhYTJpQNgAm/Ra3/i",
31
31
  "manifest.tabs.js": "sha384-OIIcyaQnGS0eNYk4zgAFEDboNYect7THvUd9D0V6nqCeDOxQcoiqLrBEmmWVTTet",
32
32
  "manifest.tailwind.js": "sha384-r/Jvqb+Piz21jUts10BbVAJoKkShOdJRVFpywyi4HPIi/OfOJq5CtPyWAPbdkMgt",
33
33
  "manifest.text.edit.js": "sha384-RzOvLQE8GbmI6gntAwiotDewYT/08OHcd7sJ5hLon8e8u1Xbq1D7VfEGuaRVd2CE",
34
- "manifest.toasts.js": "sha384-/OV32LLMJl0Iw8NoNQJ+5lgntLxjIJq/YNj5JAKS/+nUhVx4MMB9h1FOqP7zuj2M",
35
- "manifest.tooltips.js": "sha384-sOWANzXAWeZYMJ+fVtx7dH5CpPMso10T+Oyau5wDCwYbAxI2n3adwCoq7PQp2RAE",
34
+ "manifest.toasts.js": "sha384-3zkWxzw693pxg3QDFsoYCA3CqYaLKmBaMArULXODD66Utolpewl0OAeTB92aWUVv",
35
+ "manifest.tooltips.js": "sha384-4b24PH5WsfFsewGea5SMWLwmrhC4kD6eDP/vvjNyjXYnQXXFGi4nLdojrIOwzG8M",
36
36
  "manifest.url.parameters.js": "sha384-J2aSVBOPsoqsbafHndrWLHEDpKb4AKJAoQnVmKA4gZh5P/8HHjFWHO/lkusmG84l",
37
37
  "manifest.utilities.js": "sha384-L5uXMLFBIF6LUM1haRjd4eGjHSWuqsCYSpPZRPYosNfJsMC5U5TnmjBxIhrZRe2d",
38
38
  "manifest.virtual.js": "sha384-ZDNoF9QVhVcVpkjIK6NH15S6I5c6OBshiJpXSOYjNsIB+298I0a7g3aFO+jyq4Vb",
@@ -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.229';
19
+ const BUILD_VERSION = '0.5.230';
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)
@@ -3,6 +3,57 @@
3
3
  (function () {
4
4
 
5
5
 
6
+ // mnfst:expressions:start — synced by the build from scripts/snippets/manifest.expressions.js; edit there
7
+ // Directive values: any JS expression evaluates; text that isn't one stays verbatim.
8
+
9
+ const EXPR_BARE_IDENTIFIER = /^[\p{ID_Start}$_][\p{ID_Continue}$]*$/u;
10
+ // No name, string or template: numbers, dates, ratios ("24/7", "2026-10-13") stay text
11
+ const EXPR_HAS_TOKEN = /[\p{L}$_'"`]/u;
12
+
13
+ function exprParses(src) {
14
+ try { new Function('return (' + src + '\n)'); return true; } catch { return false; }
15
+ }
16
+
17
+ function exprInScope(el, name) {
18
+ try { return name in Alpine.$data(el); } catch { return false; }
19
+ }
20
+
21
+ // Errors come back as values: unresolved names read as plain text
22
+ // ("Re-run", "Hello, world"); other errors warn against the authored expression
23
+ const exprGuarded = (src) =>
24
+ '(() => { try { return (' + src + '\n) } catch (e) { return { __exprError: e } } })()';
25
+
26
+ function exprUnwrap(v, el, src) {
27
+ const err = v && typeof v === 'object' && v.__exprError;
28
+ if (!(err instanceof Error)) return v;
29
+ if (err instanceof ReferenceError) return undefined;
30
+ console.warn(`Alpine Expression Error: ${err.message}\n\nExpression: "${src}"\n\n`, el);
31
+ return null;
32
+ }
33
+
34
+ // null for static text; else (cb) => cb(value, asText), asText meaning the
35
+ // authored text shows instead (unresolved name, undefined, NaN)
36
+ function expressionResolver(el, src, evaluateLater) {
37
+ if (src.startsWith('$x.')) {
38
+ const getValue = evaluateLater(src);
39
+ return (cb) => getValue(v => cb(v, false));
40
+ }
41
+ if (!EXPR_HAS_TOKEN.test(src) || !exprParses(src)) return null;
42
+ let getValue;
43
+ if (EXPR_BARE_IDENTIFIER.test(src)) {
44
+ // Single word: a scope value or magic, else text (never a global like Image or close)
45
+ const getWord = evaluateLater(exprGuarded(src));
46
+ getValue = (cb) => (src.startsWith('$') || exprInScope(el, src)) ? getWord(cb) : cb(undefined);
47
+ } else {
48
+ getValue = evaluateLater(exprGuarded(src));
49
+ }
50
+ return (cb) => getValue(raw => {
51
+ const v = exprUnwrap(raw, el, src);
52
+ cb(v, v === undefined || Number.isNaN(v));
53
+ });
54
+ }
55
+ // mnfst:expressions:end
56
+
6
57
  const TOAST_DURATION = 3000; // Default duration in ms
7
58
 
8
59
  function initializeToastPlugin() {
@@ -127,7 +178,7 @@ function initializeToastPlugin() {
127
178
  };
128
179
 
129
180
  // Add toast directive
130
- Alpine.directive('toast', (el, { modifiers, expression }, { evaluate }) => {
181
+ Alpine.directive('toast', (el, { modifiers, expression }, { evaluateLater }) => {
131
182
  // Parse options from modifiers
132
183
  const options = {
133
184
  type: modifiers.includes('brand') ? 'brand' :
@@ -146,32 +197,11 @@ function initializeToastPlugin() {
146
197
  options.duration = modifiers.includes('long') ? TOAST_DURATION * 2 : TOAST_DURATION;
147
198
  }
148
199
 
149
- // Handle both static and dynamic expressions
150
- let message;
151
- try {
152
- // Check if expression starts with $x (data sources)
153
- if (expression.startsWith('$x.')) {
154
- // Use evaluate for $x expressions to access collections
155
- message = evaluate(expression);
156
- } else if (expression.includes('<') && expression.includes('>')) {
157
- // Treat as literal HTML string - preserve spaces and formatting
158
- // Escape quotes to prevent syntax errors, but keep the HTML intact
159
- const escapedExpression = expression.replace(/'/g, "\\'");
160
- message = evaluate(`'${escapedExpression}'`);
161
- } else if (expression.includes('+') || expression.includes('`') || expression.includes('${')) {
162
- // Try to evaluate as a dynamic expression
163
- message = evaluate(expression);
164
- } else {
165
- // Use as static string
166
- message = expression;
167
- }
168
- } catch (e) {
169
- // If evaluation fails, use the expression as a static string
170
- message = expression;
171
- }
172
-
173
- // Store the toast options on the element
174
- el._toastOptions = { message, options };
200
+ // Static text (author HTML included) shows as written; expressions
201
+ // evaluate on every click. Empty results (null, false, '') show nothing.
202
+ const src = expression.trim();
203
+ const evaluate = expressionResolver(el, src, evaluateLater);
204
+ if (evaluate && src.startsWith('$x.')) evaluate(() => {}); // starts the source loading
175
205
 
176
206
  // Add click handler that works with other handlers
177
207
  const originalClick = el.onclick;
@@ -181,7 +211,13 @@ function initializeToastPlugin() {
181
211
  originalClick.call(el, e);
182
212
  }
183
213
  // Show toast after original handler
184
- showToast(message, options);
214
+ if (!evaluate) { showToast(expression, options); return; }
215
+ // After the element's other click listeners, so state they change shows
216
+ setTimeout(() => evaluate((v, asText) => {
217
+ if (asText) { showToast(expression, options); return; }
218
+ const message = v == null || v === false ? '' : String(v);
219
+ if (message !== '') showToast(message, options);
220
+ }));
185
221
  };
186
222
  });
187
223
 
@@ -3,6 +3,57 @@
3
3
  (function () {
4
4
 
5
5
 
6
+ // mnfst:expressions:start — synced by the build from scripts/snippets/manifest.expressions.js; edit there
7
+ // Directive values: any JS expression evaluates; text that isn't one stays verbatim.
8
+
9
+ const EXPR_BARE_IDENTIFIER = /^[\p{ID_Start}$_][\p{ID_Continue}$]*$/u;
10
+ // No name, string or template: numbers, dates, ratios ("24/7", "2026-10-13") stay text
11
+ const EXPR_HAS_TOKEN = /[\p{L}$_'"`]/u;
12
+
13
+ function exprParses(src) {
14
+ try { new Function('return (' + src + '\n)'); return true; } catch { return false; }
15
+ }
16
+
17
+ function exprInScope(el, name) {
18
+ try { return name in Alpine.$data(el); } catch { return false; }
19
+ }
20
+
21
+ // Errors come back as values: unresolved names read as plain text
22
+ // ("Re-run", "Hello, world"); other errors warn against the authored expression
23
+ const exprGuarded = (src) =>
24
+ '(() => { try { return (' + src + '\n) } catch (e) { return { __exprError: e } } })()';
25
+
26
+ function exprUnwrap(v, el, src) {
27
+ const err = v && typeof v === 'object' && v.__exprError;
28
+ if (!(err instanceof Error)) return v;
29
+ if (err instanceof ReferenceError) return undefined;
30
+ console.warn(`Alpine Expression Error: ${err.message}\n\nExpression: "${src}"\n\n`, el);
31
+ return null;
32
+ }
33
+
34
+ // null for static text; else (cb) => cb(value, asText), asText meaning the
35
+ // authored text shows instead (unresolved name, undefined, NaN)
36
+ function expressionResolver(el, src, evaluateLater) {
37
+ if (src.startsWith('$x.')) {
38
+ const getValue = evaluateLater(src);
39
+ return (cb) => getValue(v => cb(v, false));
40
+ }
41
+ if (!EXPR_HAS_TOKEN.test(src) || !exprParses(src)) return null;
42
+ let getValue;
43
+ if (EXPR_BARE_IDENTIFIER.test(src)) {
44
+ // Single word: a scope value or magic, else text (never a global like Image or close)
45
+ const getWord = evaluateLater(exprGuarded(src));
46
+ getValue = (cb) => (src.startsWith('$') || exprInScope(el, src)) ? getWord(cb) : cb(undefined);
47
+ } else {
48
+ getValue = evaluateLater(exprGuarded(src));
49
+ }
50
+ return (cb) => getValue(raw => {
51
+ const v = exprUnwrap(raw, el, src);
52
+ cb(v, v === undefined || Number.isNaN(v));
53
+ });
54
+ }
55
+ // mnfst:expressions:end
56
+
6
57
  // Hover delay from CSS var (with time-unit parsing). Defaults to 500ms.
7
58
  function getTooltipHoverDelay(element) {
8
59
  let computedStyle = getComputedStyle(element);
@@ -157,33 +208,8 @@ function initializeTooltipPlugin() {
157
208
  if (wasOpen) markTooltipHidden();
158
209
  }
159
210
 
160
- // ---- Content classification ----
161
- // Any JS expression evaluates; text that isn't one renders verbatim.
162
-
163
- const BARE_IDENTIFIER = /^[\p{ID_Start}$_][\p{ID_Continue}$]*$/u;
164
211
  const looksLikeHtml = (s) => s.includes('<') && s.includes('>');
165
212
 
166
- function parsesAsExpression(src) {
167
- try { new Function('return (' + src + '\n)'); return true; } catch { return false; }
168
- }
169
-
170
- function inScope(el, name) {
171
- try { return name in Alpine.$data(el); } catch { return false; }
172
- }
173
-
174
- // Errors come back as values: unresolved names read as plain text
175
- // ("Re-run", "Hello, world"); other errors warn against the authored expression
176
- const guarded = (src) =>
177
- '(() => { try { return (' + src + '\n) } catch (e) { return { __tooltipError: e } } })()';
178
-
179
- function unwrapError(v, el, src) {
180
- const err = v && typeof v === 'object' && v.__tooltipError;
181
- if (!(err instanceof Error)) return { value: v };
182
- if (err instanceof ReferenceError) return { value: undefined };
183
- console.warn(`Alpine Expression Error: ${err.message}\n\nExpression: "${src}"\n\n`, el);
184
- return { value: null };
185
- }
186
-
187
213
  // ---- Directive ----
188
214
 
189
215
  Alpine.directive('tooltip', (el, { modifiers, expression }, { effect, evaluateLater }) => {
@@ -193,25 +219,16 @@ function initializeTooltipPlugin() {
193
219
  const htmlOptIn = modifiers.includes('html') || modifiers.includes('safe');
194
220
  const literal = expression ? { text: expression, html: htmlOptIn || looksLikeHtml(expression) } : null;
195
221
  const src = expression.trim();
196
- let evaluate = null;
197
- let fallback = true;
222
+ const evaluate = expressionResolver(el, src, evaluateLater);
198
223
 
199
224
  if (src.startsWith('$x.')) {
200
225
  const [contentType] = src.substring(3).split('.');
201
- evaluate = evaluateLater(src);
202
- fallback = false;
203
226
  effect(() => {
204
227
  const store = Alpine.store('collections');
205
228
  if (store && typeof store.loadCollection === 'function' && !store[contentType]) {
206
229
  store.loadCollection(contentType);
207
230
  }
208
231
  });
209
- } else if (BARE_IDENTIFIER.test(src)) {
210
- // Single word: a scope value or magic, else text (never a global like Image or close)
211
- const getValue = evaluateLater(guarded(src));
212
- evaluate = (cb) => (src.startsWith('$') || inScope(el, src)) ? getValue(cb) : cb(undefined);
213
- } else if (parsesAsExpression(src)) {
214
- evaluate = evaluateLater(guarded(src));
215
232
  }
216
233
 
217
234
  // --- Positioning modifiers ---
@@ -222,11 +239,10 @@ function initializeTooltipPlugin() {
222
239
  // Empty results (null, false, '') show nothing.
223
240
  const resolveContent = (cb) => {
224
241
  if (!evaluate) { cb(literal); return; }
225
- evaluate(raw => {
226
- const v = fallback ? unwrapError(raw, el, src).value : raw;
227
- if (fallback && (v === undefined || Number.isNaN(v))) { cb(literal); return; }
228
- if (v == null || v === false || v === '') { cb(null); return; }
229
- cb({ text: String(v), html: htmlOptIn });
242
+ evaluate((v, asText) => {
243
+ if (asText) { cb(literal); return; }
244
+ const text = v == null || v === false ? '' : String(v);
245
+ cb(text === '' ? null : { text, html: htmlOptIn });
230
246
  });
231
247
  };
232
248
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mnfst",
3
- "version": "0.5.229",
3
+ "version": "0.5.230",
4
4
  "private": false,
5
5
  "workspaces": [
6
6
  "templates/starter",