@stacksjs/stx 0.2.170 → 0.2.172
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/dist/cli.js +1263 -1168
- package/dist/client-script-bundler.js +2 -1
- package/dist/client-script.d.ts +1 -12
- package/dist/client-script.js +2 -149
- package/dist/codemod.d.ts +1 -24
- package/dist/codemod.js +61 -9
- package/dist/compression.d.ts +11 -4
- package/dist/compression.js +52 -13
- package/dist/craft.js +489 -415
- package/dist/expressions.d.ts +0 -21
- package/dist/expressions.js +12 -1
- package/dist/find-body-tag.js +29 -17
- package/dist/index.d.ts +8 -0
- package/dist/index.js +2 -0
- package/dist/page-action.d.ts +83 -0
- package/dist/page-action.js +64 -0
- package/dist/production-builder.js +1 -0
- package/dist/production-server.js +10 -3
- package/dist/pwa.js +398 -324
- package/dist/reactive-tracking.d.ts +81 -0
- package/dist/reactive-tracking.js +49 -0
- package/dist/reactivity.js +29 -23
- package/dist/render.js +5 -18
- package/dist/runtime-injection.js +25 -39
- package/dist/script-validation.d.ts +0 -7
- package/dist/script-validation.js +6 -4
- package/dist/signals-api.d.ts +18 -0
- package/dist/signals-api.js +26 -41
- package/dist/signals.js +93 -15
- package/dist/ssg.d.ts +8 -0
- package/dist/ssg.js +515 -441
- package/dist/state-management.js +2 -2
- package/dist/strip-literals.d.ts +40 -0
- package/dist/strip-literals.js +149 -0
- package/dist/stx-virtual-ts.d.ts +103 -1
- package/dist/stx-virtual-ts.js +124 -7
- package/dist/template-compiler.js +4 -2
- package/dist/template-hydrator.d.ts +1 -1
- package/dist/template-hydrator.js +13 -1
- package/dist/typecheck.d.ts +2 -14
- package/dist/typecheck.js +133 -11
- package/dist/types/config-types.d.ts +10 -3
- package/dist/variable-extractor.js +1 -1
- package/package.json +5 -5
package/dist/signals.js
CHANGED
|
@@ -5637,6 +5637,36 @@ catch (e) {} }
|
|
|
5637
5637
|
}, 300);
|
|
5638
5638
|
}
|
|
5639
5639
|
|
|
5640
|
+
/*
|
|
5641
|
+
* Is the APP in dark mode, not just the OS?
|
|
5642
|
+
*
|
|
5643
|
+
* stx's own color-mode boot writes a class (default 'dark') and/or an
|
|
5644
|
+
* attribute (data-theme / data-color-mode) onto <html>, so an app pinned to
|
|
5645
|
+
* light on a dark OS must not get a dark overlay over a light page. An
|
|
5646
|
+
* explicit override wins over both, and the media query is the last resort.
|
|
5647
|
+
*
|
|
5648
|
+
* One function rather than the resolution inlined per surface. #1875 fixed
|
|
5649
|
+
* this at the two dialog call sites, and toast kept the OS-only version and
|
|
5650
|
+
* shipped the exact bug #1875 describes; that is what a per-call-site fix
|
|
5651
|
+
* costs. See #1912.
|
|
5652
|
+
*/
|
|
5653
|
+
function _resolveDark(override) {
|
|
5654
|
+
if (override != null)
|
|
5655
|
+
return !!override;
|
|
5656
|
+
|
|
5657
|
+
var root = document.documentElement;
|
|
5658
|
+
if (root.classList.contains('dark'))
|
|
5659
|
+
return true;
|
|
5660
|
+
|
|
5661
|
+
var attr = root.getAttribute('data-theme') || root.getAttribute('data-color-mode');
|
|
5662
|
+
if (attr === 'dark')
|
|
5663
|
+
return true;
|
|
5664
|
+
if (attr === 'light')
|
|
5665
|
+
return false;
|
|
5666
|
+
|
|
5667
|
+
return !!(window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches);
|
|
5668
|
+
}
|
|
5669
|
+
|
|
5640
5670
|
function addToast(type, message, options) {
|
|
5641
5671
|
var container = _getToastContainer();
|
|
5642
5672
|
if (!container) {
|
|
@@ -5648,6 +5678,26 @@ catch (e) {} }
|
|
|
5648
5678
|
var id = ++_toastId;
|
|
5649
5679
|
var maxToasts = parseInt(container.getAttribute('data-stx-toast-max') || '5', 10);
|
|
5650
5680
|
|
|
5681
|
+
/*
|
|
5682
|
+
* A semantic id replaces its own toast in place (stacksjs/stx#1913).
|
|
5683
|
+
*
|
|
5684
|
+
* Without it, a persistent 'Publishing...' toast and the call that clears
|
|
5685
|
+
* it on completion have to thread the numeric return value between two
|
|
5686
|
+
* different functions by hand, which is the state management the primitive
|
|
5687
|
+
* exists to remove. With an id of 'publish' the second call simply replaces
|
|
5688
|
+
* the first, and toast.dismiss('publish') ends it.
|
|
5689
|
+
*/
|
|
5690
|
+
var key = opts.id != null ? String(opts.id) : '';
|
|
5691
|
+
if (key) {
|
|
5692
|
+
var prior = container.querySelector('[data-stx-toast-key="' + key.replace(/"/g, '') + '"]');
|
|
5693
|
+
// Removed outright rather than through removeToast, which animates for
|
|
5694
|
+
// 300ms first. This is a REPLACEMENT, not a dismissal: animating the old
|
|
5695
|
+
// one out while the new one animates in shows both at once, in the same
|
|
5696
|
+
// slot, which is exactly the flicker a keyed toast exists to avoid.
|
|
5697
|
+
if (prior && prior.parentNode)
|
|
5698
|
+
prior.parentNode.removeChild(prior);
|
|
5699
|
+
}
|
|
5700
|
+
|
|
5651
5701
|
// Enforce max toasts \u2014 remove oldest
|
|
5652
5702
|
var existing = container.querySelectorAll('[data-stx-toast]');
|
|
5653
5703
|
while (existing.length >= maxToasts && existing.length > 0) {
|
|
@@ -5659,7 +5709,7 @@ catch (e) {} }
|
|
|
5659
5709
|
var anims = _getToastAnimClass(container);
|
|
5660
5710
|
var borderColor = _toastColors[type] || _toastColors.info;
|
|
5661
5711
|
var icon = _toastIcons[type] || _toastIcons.info;
|
|
5662
|
-
var isDark =
|
|
5712
|
+
var isDark = _resolveDark(opts.dark);
|
|
5663
5713
|
var bg = isDark ? '#1f2937' : '#ffffff';
|
|
5664
5714
|
var textColor = isDark ? '#f3f4f6' : '#1f2937';
|
|
5665
5715
|
var shadow = isDark ? '0 4px 12px rgba(0,0,0,0.4)' : '0 4px 12px rgba(0,0,0,0.15)';
|
|
@@ -5667,6 +5717,8 @@ catch (e) {} }
|
|
|
5667
5717
|
var el = document.createElement('div');
|
|
5668
5718
|
el.id = 'stx-toast-' + id;
|
|
5669
5719
|
el.setAttribute('data-stx-toast', String(id));
|
|
5720
|
+
if (key)
|
|
5721
|
+
el.setAttribute('data-stx-toast-key', key);
|
|
5670
5722
|
el.setAttribute('role', 'alert');
|
|
5671
5723
|
el.setAttribute('aria-live', 'assertive');
|
|
5672
5724
|
el.style.cssText = 'pointer-events:auto;display:flex;align-items:flex-start;gap:0.75rem;padding:0.875rem 1rem;border-radius:0.5rem;border-left:4px solid ' + borderColor + ';background:' + bg + ';color:' + textColor + ';box-shadow:' + shadow + ';animation:' + anims.inAnim + ' 0.3s ease;font-family:system-ui,-apple-system,sans-serif;font-size:0.875rem;line-height:1.4;max-width:100%';
|
|
@@ -5675,9 +5727,32 @@ catch (e) {} }
|
|
|
5675
5727
|
iconSpan.style.cssText = 'flex-shrink:0;display:flex;align-items:center;margin-top:1px';
|
|
5676
5728
|
iconSpan.innerHTML = icon;
|
|
5677
5729
|
|
|
5678
|
-
|
|
5730
|
+
/*
|
|
5731
|
+
* Title above message, when one is given (#1913).
|
|
5732
|
+
*
|
|
5733
|
+
* Collapsing the two into one string loses the hierarchy that makes a toast
|
|
5734
|
+
* scannable, and every one of the 16 call sites in the reporting app passed
|
|
5735
|
+
* a title. A wrapper is used only when there IS a title, so the untitled
|
|
5736
|
+
* shape renders exactly as it did.
|
|
5737
|
+
*/
|
|
5738
|
+
var msgSpan = document.createElement(opts.title ? 'div' : 'span');
|
|
5679
5739
|
msgSpan.style.cssText = 'flex:1;word-wrap:break-word';
|
|
5680
|
-
|
|
5740
|
+
|
|
5741
|
+
if (opts.title) {
|
|
5742
|
+
var titleEl = document.createElement('div');
|
|
5743
|
+
titleEl.setAttribute('data-stx-toast-title', '');
|
|
5744
|
+
titleEl.style.cssText = 'font-weight:600;margin-bottom:0.125rem';
|
|
5745
|
+
titleEl.textContent = opts.title;
|
|
5746
|
+
msgSpan.appendChild(titleEl);
|
|
5747
|
+
|
|
5748
|
+
var bodyEl = document.createElement('div');
|
|
5749
|
+
bodyEl.style.cssText = 'opacity:0.9';
|
|
5750
|
+
bodyEl.textContent = message;
|
|
5751
|
+
msgSpan.appendChild(bodyEl);
|
|
5752
|
+
}
|
|
5753
|
+
else {
|
|
5754
|
+
msgSpan.textContent = message;
|
|
5755
|
+
}
|
|
5681
5756
|
|
|
5682
5757
|
var closeBtn = document.createElement('button');
|
|
5683
5758
|
closeBtn.type = 'button';
|
|
@@ -5704,7 +5779,20 @@ catch (e) {} }
|
|
|
5704
5779
|
info: function(message, options) { return addToast('info', message, options); },
|
|
5705
5780
|
warning: function(message, options) { return addToast('warning', message, options); },
|
|
5706
5781
|
dismiss: function(id) {
|
|
5707
|
-
if (id !== undefined) {
|
|
5782
|
+
if (id !== undefined) {
|
|
5783
|
+
// A string id is the semantic key the caller passed; a number is the
|
|
5784
|
+
// handle addToast returned. Both dismiss, so a caller does not have to
|
|
5785
|
+
// know which kind it is holding (#1913).
|
|
5786
|
+
if (typeof id === 'string') {
|
|
5787
|
+
var c = _getToastContainer();
|
|
5788
|
+
var match = c && c.querySelector('[data-stx-toast-key="' + id.replace(/"/g, '') + '"]');
|
|
5789
|
+
if (match)
|
|
5790
|
+
removeToast(match.getAttribute('data-stx-toast'));
|
|
5791
|
+
return;
|
|
5792
|
+
}
|
|
5793
|
+
removeToast(id);
|
|
5794
|
+
return;
|
|
5795
|
+
}
|
|
5708
5796
|
var container = _getToastContainer();
|
|
5709
5797
|
if (!container) return;
|
|
5710
5798
|
var all = container.querySelectorAll('[data-stx-toast]');
|
|
@@ -5782,17 +5870,7 @@ catch (e) {} }
|
|
|
5782
5870
|
// (e.g. data-theme) onto <html>, so an app pinned to light on a dark OS used
|
|
5783
5871
|
// to get a dark dialog over a light page. An explicit opts.dark wins over
|
|
5784
5872
|
// both, and the media query stays as the last resort. See #1875.
|
|
5785
|
-
var
|
|
5786
|
-
var _attrTheme = _root.getAttribute('data-theme') || _root.getAttribute('data-color-mode');
|
|
5787
|
-
var isDark = opts.dark != null
|
|
5788
|
-
? !!opts.dark
|
|
5789
|
-
: _root.classList.contains('dark')
|
|
5790
|
-
? true
|
|
5791
|
-
: _attrTheme === 'dark'
|
|
5792
|
-
? true
|
|
5793
|
-
: _attrTheme === 'light'
|
|
5794
|
-
? false
|
|
5795
|
-
: !!(window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches);
|
|
5873
|
+
var isDark = _resolveDark(opts.dark);
|
|
5796
5874
|
var bg = isDark ? '#1f2937' : '#ffffff';
|
|
5797
5875
|
var textColor = isDark ? '#f3f4f6' : '#1f2937';
|
|
5798
5876
|
var subColor = isDark ? '#9ca3af' : '#6b7280';
|
package/dist/ssg.d.ts
CHANGED
|
@@ -257,6 +257,14 @@ export interface CachedPage {
|
|
|
257
257
|
etag: string;
|
|
258
258
|
headers?: Record<string, string>;
|
|
259
259
|
}
|
|
260
|
+
/**
|
|
261
|
+
* Whether a page declares an `action` — the export that receives its own POST.
|
|
262
|
+
*
|
|
263
|
+
* Exported so the rule is testable without running a build. A page action
|
|
264
|
+
* cannot run in a static build: `action` receives a POST, and a static build
|
|
265
|
+
* produces files, so there is no server left to receive one (stacksjs/stx#1847).
|
|
266
|
+
*/
|
|
267
|
+
export declare function declaresPageAction(source: string): boolean;
|
|
260
268
|
/**
|
|
261
269
|
* Generate sitemap.xml
|
|
262
270
|
*/
|