@crvouga/mockingbird-service-fullscript 1.6.0 → 1.6.1
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/CHANGELOG.md +9 -1
- package/dist/{chunk-ZDHQHF3E.js → chunk-AJ6RYUHV.js} +2 -2
- package/dist/{chunk-OBQHBBFC.js → chunk-UZIN4H2O.js} +89 -10
- package/dist/chunk-UZIN4H2O.js.map +7 -0
- package/dist/cli.js +2 -2
- package/dist/index.js +1 -1
- package/dist/server.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-OBQHBBFC.js.map +0 -7
- /package/dist/{chunk-ZDHQHF3E.js.map → chunk-AJ6RYUHV.js.map} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# Changelog — @crvouga/mockingbird-service-fullscript
|
|
2
2
|
|
|
3
|
-
## 1.6.
|
|
3
|
+
## 1.6.1 (2026-09-30)
|
|
4
|
+
|
|
5
|
+
### Fixes and improvements
|
|
6
|
+
|
|
7
|
+
- keep admin buttons pressed until the action finishes ([0aabfcb](https://github.com/crvouga/mockingbird/commit/0aabfcb5f392aa51e193f9c3f817d5877d92bc6a))
|
|
8
|
+
- size admin select fields like the text inputs beside them ([0fb3ef2](https://github.com/crvouga/mockingbird/commit/0fb3ef2ddbf43376c93a2ae6d87c6c9bf890dafc))
|
|
9
|
+
- keep admin section tabs wired when boot is renamed ([4eda25e](https://github.com/crvouga/mockingbird/commit/4eda25eacd59da048d196f7cc8369d7a02b47bfc))
|
|
10
|
+
|
|
11
|
+
## 1.6.0 (2026-09-29)
|
|
4
12
|
|
|
5
13
|
### Features
|
|
6
14
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createRuntime
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-UZIN4H2O.js";
|
|
4
4
|
|
|
5
5
|
// ../../adapters/node/dist/cli.js
|
|
6
6
|
import { readFile } from "node:fs/promises";
|
|
@@ -381,4 +381,4 @@ export {
|
|
|
381
381
|
createServer2 as createServer,
|
|
382
382
|
serveTarget
|
|
383
383
|
};
|
|
384
|
-
//# sourceMappingURL=chunk-
|
|
384
|
+
//# sourceMappingURL=chunk-AJ6RYUHV.js.map
|
|
@@ -2327,6 +2327,50 @@ function bootAdmin(config) {
|
|
|
2327
2327
|
if (render)
|
|
2328
2328
|
await render();
|
|
2329
2329
|
}
|
|
2330
|
+
const delay = (ms) => new Promise((resolve) => {
|
|
2331
|
+
window.setTimeout(resolve, ms);
|
|
2332
|
+
});
|
|
2333
|
+
const confirmAction = async (button, pending, done, work) => {
|
|
2334
|
+
if (button.dataset.pending === "1")
|
|
2335
|
+
return;
|
|
2336
|
+
const label = button.textContent ?? "";
|
|
2337
|
+
const width = button.offsetWidth;
|
|
2338
|
+
button.dataset.pending = "1";
|
|
2339
|
+
button.classList.add("pressed");
|
|
2340
|
+
button.setAttribute("aria-busy", "true");
|
|
2341
|
+
button.style.minWidth = `${width}px`;
|
|
2342
|
+
button.textContent = pending;
|
|
2343
|
+
try {
|
|
2344
|
+
await work();
|
|
2345
|
+
button.textContent = done;
|
|
2346
|
+
await delay(1e3);
|
|
2347
|
+
} catch (error) {
|
|
2348
|
+
showError(error);
|
|
2349
|
+
} finally {
|
|
2350
|
+
button.textContent = label;
|
|
2351
|
+
button.style.minWidth = "";
|
|
2352
|
+
button.classList.remove("pressed");
|
|
2353
|
+
button.removeAttribute("aria-busy");
|
|
2354
|
+
delete button.dataset.pending;
|
|
2355
|
+
}
|
|
2356
|
+
};
|
|
2357
|
+
document.addEventListener("click", (event) => {
|
|
2358
|
+
const target = event.target;
|
|
2359
|
+
if (!(target instanceof Element))
|
|
2360
|
+
return;
|
|
2361
|
+
const button = target.closest("button");
|
|
2362
|
+
if (!(button instanceof HTMLButtonElement) || button.dataset.pending === "1")
|
|
2363
|
+
return;
|
|
2364
|
+
button.classList.add("pressed");
|
|
2365
|
+
const token = String(Date.now());
|
|
2366
|
+
button.dataset.press = token;
|
|
2367
|
+
window.setTimeout(() => {
|
|
2368
|
+
if (button.dataset.press !== token || button.dataset.pending === "1")
|
|
2369
|
+
return;
|
|
2370
|
+
button.classList.remove("pressed");
|
|
2371
|
+
delete button.dataset.press;
|
|
2372
|
+
}, 450);
|
|
2373
|
+
});
|
|
2330
2374
|
el("namespace", HTMLSelectElement).addEventListener("change", () => {
|
|
2331
2375
|
state.namespace = el("namespace", HTMLSelectElement).value;
|
|
2332
2376
|
refresh().catch(showError);
|
|
@@ -2337,7 +2381,7 @@ function bootAdmin(config) {
|
|
|
2337
2381
|
refresh().catch(showError);
|
|
2338
2382
|
});
|
|
2339
2383
|
el("refresh", HTMLButtonElement).addEventListener("click", () => {
|
|
2340
|
-
refresh().catch(showError);
|
|
2384
|
+
confirmAction(el("refresh", HTMLButtonElement), "Refreshing...", "Updated", () => refresh()).catch(showError);
|
|
2341
2385
|
});
|
|
2342
2386
|
el("collections", HTMLElement).addEventListener("click", (event) => {
|
|
2343
2387
|
const target = event.target;
|
|
@@ -2460,10 +2504,10 @@ function bootAdmin(config) {
|
|
|
2460
2504
|
}).then(() => renderFaults()).catch(showError);
|
|
2461
2505
|
});
|
|
2462
2506
|
el("fault-clear", HTMLButtonElement).addEventListener("click", () => {
|
|
2463
|
-
api("DELETE", "/faults").then(() => renderFaults()).catch(showError);
|
|
2507
|
+
confirmAction(el("fault-clear", HTMLButtonElement), "Clearing...", "Cleared", () => api("DELETE", "/faults").then(() => renderFaults())).catch(showError);
|
|
2464
2508
|
});
|
|
2465
2509
|
el("journal-clear", HTMLButtonElement).addEventListener("click", () => {
|
|
2466
|
-
api("DELETE", "/requests").then(() => renderJournal()).catch(showError);
|
|
2510
|
+
confirmAction(el("journal-clear", HTMLButtonElement), "Clearing...", "Cleared", () => api("DELETE", "/requests").then(() => renderJournal())).catch(showError);
|
|
2467
2511
|
});
|
|
2468
2512
|
el("route-list", HTMLElement).addEventListener("click", (event) => {
|
|
2469
2513
|
const target = event.target;
|
|
@@ -2578,9 +2622,13 @@ function bootAdmin(config) {
|
|
|
2578
2622
|
var clientPrelude = [isRecord2, mountAdminBrand, startAdminBrand, faultPresetList, bootAdmin].map((fn) => fn.toString()).join("\n");
|
|
2579
2623
|
var adminClientSource = (config) => {
|
|
2580
2624
|
const payload = JSON.stringify(config).replace(/</g, "\\u003c");
|
|
2625
|
+
const entry = bootAdmin.name;
|
|
2626
|
+
if (!/^[A-Za-z_$][\w$]*$/.test(entry)) {
|
|
2627
|
+
throw new Error("admin client cannot call its boot function");
|
|
2628
|
+
}
|
|
2581
2629
|
return `<script>
|
|
2582
2630
|
${clientPrelude}
|
|
2583
|
-
|
|
2631
|
+
${entry}(${payload});
|
|
2584
2632
|
</script>`;
|
|
2585
2633
|
};
|
|
2586
2634
|
|
|
@@ -2794,9 +2842,24 @@ var renderAdminDocument = (service) => {
|
|
|
2794
2842
|
.controls { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
|
|
2795
2843
|
label.field { display: flex; flex-direction: column; gap: 2px; font-size: 11px; color: var(--faint); }
|
|
2796
2844
|
label.field input, label.field select, .controls input[type="password"] {
|
|
2797
|
-
background: var(--bg-inset); border: 1px solid var(--line); border-radius: 8px;
|
|
2798
|
-
padding: 7px 8px; min-height: 36px;
|
|
2799
|
-
}
|
|
2845
|
+
background-color: var(--bg-inset); border: 1px solid var(--line); border-radius: 8px;
|
|
2846
|
+
padding: 7px 8px; min-height: 36px; line-height: 1.2;
|
|
2847
|
+
}
|
|
2848
|
+
/* A native menu ignores min-height, so Preset rendered about half as tall as
|
|
2849
|
+
the text fields in the same form. Paint it like those fields. */
|
|
2850
|
+
label.field select {
|
|
2851
|
+
-webkit-appearance: none; appearance: none;
|
|
2852
|
+
padding-right: 28px;
|
|
2853
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='none' stroke='%2371717a' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' d='M2.5 4.5 6 8l3.5-3.5'/%3E%3C/svg%3E");
|
|
2854
|
+
background-repeat: no-repeat; background-position: right 10px center; background-size: 12px 12px;
|
|
2855
|
+
}
|
|
2856
|
+
.stack > .field > input,
|
|
2857
|
+
.stack > .field > select,
|
|
2858
|
+
.stack > .field > textarea,
|
|
2859
|
+
dialog .field > input,
|
|
2860
|
+
dialog .field > select,
|
|
2861
|
+
dialog .field > textarea { width: 100%; }
|
|
2862
|
+
.icon-btn, .btn, .btn-primary, .btn-quiet, .btn-danger, nav.side button { cursor: pointer; }
|
|
2800
2863
|
.icon-btn, .btn, .btn-primary, .btn-quiet, .btn-danger {
|
|
2801
2864
|
border-radius: 9px; min-height: 36px; padding: 0 12px; border: 1px solid var(--line);
|
|
2802
2865
|
background: var(--bg-elev);
|
|
@@ -2804,6 +2867,14 @@ var renderAdminDocument = (service) => {
|
|
|
2804
2867
|
.btn-primary { background: var(--accent); color: var(--accent-ink); border-color: transparent; }
|
|
2805
2868
|
.btn-quiet { background: transparent; }
|
|
2806
2869
|
.btn-danger { color: var(--err); }
|
|
2870
|
+
/* Held after mouseup. Clearing an empty journal changes nothing on screen,
|
|
2871
|
+
so the press itself has to stay visible. */
|
|
2872
|
+
.icon-btn:active, .btn:active, .btn-quiet:active, .btn-danger:active, nav.side button:active,
|
|
2873
|
+
.icon-btn.pressed, .btn.pressed, .btn-quiet.pressed, .btn-danger.pressed, nav.side button.pressed {
|
|
2874
|
+
background: var(--bg-inset); border-color: var(--line-strong); color: var(--ink);
|
|
2875
|
+
}
|
|
2876
|
+
.btn-danger:active, .btn-danger.pressed { background: var(--err-soft); color: var(--err); }
|
|
2877
|
+
.btn-primary:active, .btn-primary.pressed { filter: brightness(0.88); color: var(--accent-ink); }
|
|
2807
2878
|
/* minmax(0, 1fr): a 1fr column will not shrink below its content, so a long
|
|
2808
2879
|
record or the full nav row would widen the page past the viewport. */
|
|
2809
2880
|
.layout {
|
|
@@ -2892,8 +2963,16 @@ var renderAdminDocument = (service) => {
|
|
|
2892
2963
|
input, select, textarea { font-size: 16px; }
|
|
2893
2964
|
.brand, .vendor, .controls { width: 100%; }
|
|
2894
2965
|
label.field, label.field select, label.field input { flex: 1; min-width: 0; }
|
|
2895
|
-
|
|
2966
|
+
/* The layout fills the screen. A single-column grid stretches every auto
|
|
2967
|
+
row, so the tab bar grew with the leftover height and the buttons floated
|
|
2968
|
+
in the middle of it. The bar stays one row; the page below takes the rest. */
|
|
2969
|
+
.layout {
|
|
2970
|
+
grid-template-columns: minmax(0, 1fr);
|
|
2971
|
+
grid-template-rows: auto minmax(0, 1fr);
|
|
2972
|
+
align-content: start;
|
|
2973
|
+
}
|
|
2896
2974
|
nav.side {
|
|
2975
|
+
align-self: start; height: auto;
|
|
2897
2976
|
flex-direction: row; align-items: center; overflow-x: auto; min-width: 0;
|
|
2898
2977
|
border-right: 0; border-bottom: 1px solid var(--line);
|
|
2899
2978
|
padding: 8px;
|
|
@@ -3761,7 +3840,7 @@ var stateAdminRoutes = (routes) => {
|
|
|
3761
3840
|
};
|
|
3762
3841
|
|
|
3763
3842
|
// ../core/dist/version.js
|
|
3764
|
-
var PACKAGE_VERSION = true ? "1.6.
|
|
3843
|
+
var PACKAGE_VERSION = true ? "1.6.1" : UNRELEASED_VERSION;
|
|
3765
3844
|
|
|
3766
3845
|
// ../core/dist/signing.js
|
|
3767
3846
|
var encoder = new TextEncoder();
|
|
@@ -5687,4 +5766,4 @@ export {
|
|
|
5687
5766
|
envelope,
|
|
5688
5767
|
FullscriptAPI
|
|
5689
5768
|
};
|
|
5690
|
-
//# sourceMappingURL=chunk-
|
|
5769
|
+
//# sourceMappingURL=chunk-UZIN4H2O.js.map
|