@powerhousedao/connect 6.2.2-dev.2 → 6.2.2-dev.20
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/assets/document-icon-192x192.png +0 -0
- package/assets/document-icon-512x512.png +0 -0
- package/assets/pwa-192x192.png +0 -0
- package/assets/pwa-512x512-maskable.png +0 -0
- package/assets/pwa-512x512.png +0 -0
- package/dist/{AddDriveModal-MMHlkJBJ.js → AddDriveModal-Cy4_b0wO.js} +4 -4
- package/dist/{AddDriveModal-MMHlkJBJ.js.map → AddDriveModal-Cy4_b0wO.js.map} +1 -1
- package/dist/{ClearStorageModal-CFBQ3g2W.js → ClearStorageModal-DzbBamBg.js} +4 -4
- package/dist/{ClearStorageModal-CFBQ3g2W.js.map → ClearStorageModal-DzbBamBg.js.map} +1 -1
- package/dist/{CookiesPolicyModal-CkcUKPLb.js → CookiesPolicyModal-Dpx-2TgP.js} +3 -3
- package/dist/{CookiesPolicyModal-CkcUKPLb.js.map → CookiesPolicyModal-Dpx-2TgP.js.map} +1 -1
- package/dist/{CreateDocumentModal-CvsTh0HM.js → CreateDocumentModal-u-IaJUQ0.js} +3 -3
- package/dist/{CreateDocumentModal-CvsTh0HM.js.map → CreateDocumentModal-u-IaJUQ0.js.map} +1 -1
- package/dist/{DebugSettingsModal-Rbn2aHS5.js → DebugSettingsModal-B64Dd6MI.js} +6 -6
- package/dist/{DebugSettingsModal-Rbn2aHS5.js.map → DebugSettingsModal-B64Dd6MI.js.map} +1 -1
- package/dist/{DeleteDriveModal-DSTK8FYk.js → DeleteDriveModal-CJKhWtli.js} +4 -4
- package/dist/{DeleteDriveModal-DSTK8FYk.js.map → DeleteDriveModal-CJKhWtli.js.map} +1 -1
- package/dist/{DeleteItemModal-B2nJmjsP.js → DeleteItemModal-DiieJw_o.js} +4 -4
- package/dist/{DeleteItemModal-B2nJmjsP.js.map → DeleteItemModal-DiieJw_o.js.map} +1 -1
- package/dist/{DisclaimerModal-D5FO34u9.js → DisclaimerModal-DAvYIF9-.js} +3 -3
- package/dist/{DisclaimerModal-D5FO34u9.js.map → DisclaimerModal-DAvYIF9-.js.map} +1 -1
- package/dist/{DownloadDocumentWithErrorsModal-tEr3bbtN.js → DownloadDocumentWithErrorsModal-CE4fa1k5.js} +3 -3
- package/dist/{DownloadDocumentWithErrorsModal-tEr3bbtN.js.map → DownloadDocumentWithErrorsModal-CE4fa1k5.js.map} +1 -1
- package/dist/DriveAuthRequiredModal-DSM6uNlb.js +36 -0
- package/dist/DriveAuthRequiredModal-DSM6uNlb.js.map +1 -0
- package/dist/{DriveSettingsModal-kR3hQnh4.js → DriveSettingsModal-CqFeWu4r.js} +3 -3
- package/dist/{DriveSettingsModal-kR3hQnh4.js.map → DriveSettingsModal-CqFeWu4r.js.map} +1 -1
- package/dist/{InspectorModal-D2BipxVV.js → InspectorModal-B9EdY0kb.js} +6 -6
- package/dist/{InspectorModal-D2BipxVV.js.map → InspectorModal-B9EdY0kb.js.map} +1 -1
- package/dist/LoginModal-BGTKLJx0.js +75 -0
- package/dist/LoginModal-BGTKLJx0.js.map +1 -0
- package/dist/{MissingPackageModal-BQcCQbOn.js → MissingPackageModal-C3acJ9r0.js} +18 -6
- package/dist/MissingPackageModal-C3acJ9r0.js.map +1 -0
- package/dist/OpenFileDocumentsModal-V2KByPpZ.js +293 -0
- package/dist/OpenFileDocumentsModal-V2KByPpZ.js.map +1 -0
- package/dist/{SettingsModal-C3gueGaR.js → SettingsModal-Cqb-1c4T.js} +26 -13
- package/dist/SettingsModal-Cqb-1c4T.js.map +1 -0
- package/dist/{UpgradeDriveModal-BZGSE9_r.js → UpgradeDriveModal-rUHyJTc7.js} +3 -3
- package/dist/{UpgradeDriveModal-BZGSE9_r.js.map → UpgradeDriveModal-rUHyJTc7.js.map} +1 -1
- package/dist/{app-loader-CuI4Pvun.js → app-loader-C4GMxAYB.js} +288 -39
- package/dist/app-loader-C4GMxAYB.js.map +1 -0
- package/dist/app-loader-gXQFs-oQ.js +4 -0
- package/dist/{build-info-DRFIgMZ5.js → build-info-D48uD8Uk.js} +5 -5
- package/dist/{build-info-DRFIgMZ5.js.map → build-info-D48uD8Uk.js.map} +1 -1
- package/dist/components-BjuHdG8Q.js +5 -0
- package/dist/{connect.config-vgUeFoNp.js → connect.config-C-b_Yhd6.js} +9 -4
- package/dist/connect.config-C-b_Yhd6.js.map +1 -0
- package/dist/{connection-state-DO_2lAEJ.js → connection-state-KCa1yljA.js} +4 -4
- package/dist/{connection-state-DO_2lAEJ.js.map → connection-state-KCa1yljA.js.map} +1 -1
- package/dist/{load-D7Bd6r8L.js → load-C1TQWaRI.js} +10 -10
- package/dist/{load-D7Bd6r8L.js.map → load-C1TQWaRI.js.map} +1 -1
- package/dist/main.js +1 -1
- package/dist/{package-nOMk-HnW.js → package-BosGa7CE.js} +8 -4
- package/dist/package-BosGa7CE.js.map +1 -0
- package/dist/{pglite-seed-z3B1JA38.js → pglite-seed-DRXPe7p-.js} +4 -4
- package/dist/{pglite-seed-z3B1JA38.js.map → pglite-seed-DRXPe7p-.js.map} +1 -1
- package/dist/pwa-manifest-link-CG8UajMz.js +34 -0
- package/dist/pwa-manifest-link-CG8UajMz.js.map +1 -0
- package/dist/{reactor-DNtlhToA.js → reactor-DEFv5EuZ.js} +145 -14
- package/dist/reactor-DEFv5EuZ.js.map +1 -0
- package/dist/reactor.worker.js +9 -5
- package/dist/reactor.worker.js.map +1 -1
- package/dist/{registerServiceWorker-nJIc0yEY.js → registerServiceWorker-Bn1KWmk0.js} +6 -4
- package/dist/registerServiceWorker-Bn1KWmk0.js.map +1 -0
- package/dist/{reload-connect-toast-D1Iqw9E_.js → reload-connect-toast-BkgP9i6_.js} +19 -3
- package/dist/{reload-connect-toast-D1Iqw9E_.js.map → reload-connect-toast-BkgP9i6_.js.map} +1 -1
- package/dist/start-connect.js +1 -1
- package/dist/style.css +64 -3
- package/dist/{toast-4t-VimvD.js → toast-BLv8rjmy.js} +3 -3
- package/dist/{toast-4t-VimvD.js.map → toast-BLv8rjmy.js.map} +1 -1
- package/dist/use-renown-login-DBujbqs8.js +55 -0
- package/dist/use-renown-login-DBujbqs8.js.map +1 -0
- package/dist/useRegistryPackages-DMhCvTWq.js +314 -0
- package/dist/useRegistryPackages-DMhCvTWq.js.map +1 -0
- package/package.json +15 -11
- package/dist/DriveAuthRequiredModal-BA2vS3oF.js +0 -40
- package/dist/DriveAuthRequiredModal-BA2vS3oF.js.map +0 -1
- package/dist/MissingPackageModal-BQcCQbOn.js.map +0 -1
- package/dist/SettingsModal-C3gueGaR.js.map +0 -1
- package/dist/app-loader-CuI4Pvun.js.map +0 -1
- package/dist/app-loader-DGIZ2168.js +0 -4
- package/dist/components-L890idPs.js +0 -5
- package/dist/connect.config-vgUeFoNp.js.map +0 -1
- package/dist/package-nOMk-HnW.js.map +0 -1
- package/dist/reactor-DNtlhToA.js.map +0 -1
- package/dist/registerServiceWorker-nJIc0yEY.js.map +0 -1
- package/dist/useRegistryPackages-BaYtekjQ.js +0 -179
- package/dist/useRegistryPackages-BaYtekjQ.js.map +0 -1
package/dist/style.css
CHANGED
|
@@ -78,6 +78,7 @@
|
|
|
78
78
|
--font-weight-bold: 700;
|
|
79
79
|
--tracking-normal: 0em;
|
|
80
80
|
--tracking-wide: 0.025em;
|
|
81
|
+
--tracking-wider: 0.05em;
|
|
81
82
|
--leading-tight: 1.25;
|
|
82
83
|
--leading-normal: 1.5;
|
|
83
84
|
--leading-relaxed: 1.625;
|
|
@@ -372,6 +373,9 @@
|
|
|
372
373
|
.end {
|
|
373
374
|
inset-inline-end: var(--spacing);
|
|
374
375
|
}
|
|
376
|
+
.-top-2 {
|
|
377
|
+
top: calc(var(--spacing) * -2);
|
|
378
|
+
}
|
|
375
379
|
.top-0 {
|
|
376
380
|
top: calc(var(--spacing) * 0);
|
|
377
381
|
}
|
|
@@ -474,6 +478,9 @@
|
|
|
474
478
|
.z-50 {
|
|
475
479
|
z-index: 50;
|
|
476
480
|
}
|
|
481
|
+
.z-200 {
|
|
482
|
+
z-index: 200;
|
|
483
|
+
}
|
|
477
484
|
.z-1000 {
|
|
478
485
|
z-index: 1000;
|
|
479
486
|
}
|
|
@@ -858,9 +865,6 @@
|
|
|
858
865
|
.h-\[420px\] {
|
|
859
866
|
height: 420px;
|
|
860
867
|
}
|
|
861
|
-
.h-\[500px\] {
|
|
862
|
-
height: 500px;
|
|
863
|
-
}
|
|
864
868
|
.h-\[600px\] {
|
|
865
869
|
height: 600px;
|
|
866
870
|
}
|
|
@@ -909,6 +913,9 @@
|
|
|
909
913
|
.max-h-\[404px\] {
|
|
910
914
|
max-height: 404px;
|
|
911
915
|
}
|
|
916
|
+
.max-h-\[calc\(100dvh-14rem\)\] {
|
|
917
|
+
max-height: calc(100dvh - 14rem);
|
|
918
|
+
}
|
|
912
919
|
.max-h-full {
|
|
913
920
|
max-height: 100%;
|
|
914
921
|
}
|
|
@@ -1149,6 +1156,9 @@
|
|
|
1149
1156
|
.max-w-\[calc\(100\%-2rem\)\] {
|
|
1150
1157
|
max-width: calc(100% - 2rem);
|
|
1151
1158
|
}
|
|
1159
|
+
.max-w-\[calc\(100vw-2rem\)\] {
|
|
1160
|
+
max-width: calc(100vw - 2rem);
|
|
1161
|
+
}
|
|
1152
1162
|
.max-w-fit {
|
|
1153
1163
|
max-width: fit-content;
|
|
1154
1164
|
}
|
|
@@ -1638,6 +1648,9 @@
|
|
|
1638
1648
|
.border-b-border {
|
|
1639
1649
|
border-bottom-color: var(--border);
|
|
1640
1650
|
}
|
|
1651
|
+
.bg-accent {
|
|
1652
|
+
background-color: var(--accent);
|
|
1653
|
+
}
|
|
1641
1654
|
.bg-background {
|
|
1642
1655
|
background-color: var(--background);
|
|
1643
1656
|
}
|
|
@@ -1647,6 +1660,9 @@
|
|
|
1647
1660
|
background-color: color-mix(in oklab, var(--background) 50%, transparent);
|
|
1648
1661
|
}
|
|
1649
1662
|
}
|
|
1663
|
+
.bg-border {
|
|
1664
|
+
background-color: var(--border);
|
|
1665
|
+
}
|
|
1650
1666
|
.bg-card {
|
|
1651
1667
|
background-color: var(--card);
|
|
1652
1668
|
}
|
|
@@ -1665,6 +1681,9 @@
|
|
|
1665
1681
|
background-color: color-mix(in oklab, var(--destructive) 10%, transparent);
|
|
1666
1682
|
}
|
|
1667
1683
|
}
|
|
1684
|
+
.bg-foreground {
|
|
1685
|
+
background-color: var(--foreground);
|
|
1686
|
+
}
|
|
1668
1687
|
.bg-info {
|
|
1669
1688
|
background-color: var(--info);
|
|
1670
1689
|
}
|
|
@@ -2041,6 +2060,9 @@
|
|
|
2041
2060
|
font-size: var(--text-xs);
|
|
2042
2061
|
line-height: calc(var(--spacing) * 5);
|
|
2043
2062
|
}
|
|
2063
|
+
.text-\[10px\] {
|
|
2064
|
+
font-size: 10px;
|
|
2065
|
+
}
|
|
2044
2066
|
.leading-4 {
|
|
2045
2067
|
--tw-leading: calc(var(--spacing) * 4);
|
|
2046
2068
|
line-height: calc(var(--spacing) * 4);
|
|
@@ -2093,6 +2115,10 @@
|
|
|
2093
2115
|
--tw-tracking: var(--tracking-wide);
|
|
2094
2116
|
letter-spacing: var(--tracking-wide);
|
|
2095
2117
|
}
|
|
2118
|
+
.tracking-wider {
|
|
2119
|
+
--tw-tracking: var(--tracking-wider);
|
|
2120
|
+
letter-spacing: var(--tracking-wider);
|
|
2121
|
+
}
|
|
2096
2122
|
.wrap-anywhere {
|
|
2097
2123
|
overflow-wrap: anywhere;
|
|
2098
2124
|
}
|
|
@@ -2109,6 +2135,9 @@
|
|
|
2109
2135
|
.whitespace-nowrap {
|
|
2110
2136
|
white-space: nowrap;
|
|
2111
2137
|
}
|
|
2138
|
+
.text-background {
|
|
2139
|
+
color: var(--background);
|
|
2140
|
+
}
|
|
2112
2141
|
.text-current {
|
|
2113
2142
|
color: currentcolor;
|
|
2114
2143
|
}
|
|
@@ -2920,6 +2949,13 @@
|
|
|
2920
2949
|
}
|
|
2921
2950
|
}
|
|
2922
2951
|
}
|
|
2952
|
+
.hover\:bg-accent {
|
|
2953
|
+
&:hover {
|
|
2954
|
+
@media (hover: hover) {
|
|
2955
|
+
background-color: var(--accent);
|
|
2956
|
+
}
|
|
2957
|
+
}
|
|
2958
|
+
}
|
|
2923
2959
|
.hover\:bg-muted {
|
|
2924
2960
|
&:hover {
|
|
2925
2961
|
@media (hover: hover) {
|
|
@@ -2927,6 +2963,16 @@
|
|
|
2927
2963
|
}
|
|
2928
2964
|
}
|
|
2929
2965
|
}
|
|
2966
|
+
.hover\:bg-primary\/85 {
|
|
2967
|
+
&:hover {
|
|
2968
|
+
@media (hover: hover) {
|
|
2969
|
+
background-color: var(--primary);
|
|
2970
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
2971
|
+
background-color: color-mix(in oklab, var(--primary) 85%, transparent);
|
|
2972
|
+
}
|
|
2973
|
+
}
|
|
2974
|
+
}
|
|
2975
|
+
}
|
|
2930
2976
|
.hover\:pr-6 {
|
|
2931
2977
|
&:hover {
|
|
2932
2978
|
@media (hover: hover) {
|
|
@@ -3089,6 +3135,11 @@
|
|
|
3089
3135
|
transition: filter 0.1s ease-in-out;
|
|
3090
3136
|
}
|
|
3091
3137
|
}
|
|
3138
|
+
.disabled\:pointer-events-none {
|
|
3139
|
+
&:disabled {
|
|
3140
|
+
pointer-events: none;
|
|
3141
|
+
}
|
|
3142
|
+
}
|
|
3092
3143
|
.disabled\:disabled-effect {
|
|
3093
3144
|
&:disabled {
|
|
3094
3145
|
cursor: not-allowed;
|
|
@@ -3116,6 +3167,16 @@
|
|
|
3116
3167
|
box-shadow: none;
|
|
3117
3168
|
}
|
|
3118
3169
|
}
|
|
3170
|
+
.disabled\:cursor-wait {
|
|
3171
|
+
&:disabled {
|
|
3172
|
+
cursor: wait;
|
|
3173
|
+
}
|
|
3174
|
+
}
|
|
3175
|
+
.disabled\:opacity-60 {
|
|
3176
|
+
&:disabled {
|
|
3177
|
+
opacity: 60%;
|
|
3178
|
+
}
|
|
3179
|
+
}
|
|
3119
3180
|
.disabled\:opacity-100 {
|
|
3120
3181
|
&:disabled {
|
|
3121
3182
|
opacity: 100%;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="70c9da16-68cb-54a4-9662-dd9a799742d5")}catch(e){}}();
|
|
3
3
|
import { createElement } from "react";
|
|
4
4
|
import { ToastContainer, toast } from "@powerhousedao/design-system/connect/toast";
|
|
5
5
|
//#region src/services/toast.ts
|
|
@@ -19,5 +19,5 @@ function toast$1(content, options) {
|
|
|
19
19
|
//#endregion
|
|
20
20
|
export { toast$1 as n, ToastContainer$1 as t };
|
|
21
21
|
|
|
22
|
-
//# sourceMappingURL=toast-
|
|
23
|
-
//# debugId=
|
|
22
|
+
//# sourceMappingURL=toast-BLv8rjmy.js.map
|
|
23
|
+
//# debugId=70c9da16-68cb-54a4-9662-dd9a799742d5
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toast-
|
|
1
|
+
{"version":3,"file":"toast-BLv8rjmy.js","sources":["../src/services/toast.ts"],"sourcesContent":["import type { ConnectToastOptions } from \"@powerhousedao/design-system/connect/toast\";\nimport {\n ToastContainer as BaseToastContainer,\n toast as baseToast,\n} from \"@powerhousedao/design-system/connect/toast\";\nimport { createElement, type ComponentProps } from \"react\";\n\nexport const CONNECT_TOAST_CONTAINER_ID = \"connect\";\n\ntype BaseToastContainerProps = ComponentProps<typeof BaseToastContainer>;\n\nexport const ToastContainer = (\n props: Omit<BaseToastContainerProps, \"containerId\"> = {},\n) =>\n createElement(BaseToastContainer, {\n containerId: CONNECT_TOAST_CONTAINER_ID,\n ...props,\n });\n\ntype ToastArgs = Parameters<typeof baseToast>;\nexport function toast(content: ToastArgs[0], options?: ConnectToastOptions) {\n const {\n type = \"default\",\n containerId = CONNECT_TOAST_CONTAINER_ID,\n ...restOptions\n } = options || {};\n return baseToast(content, { type, containerId, ...restOptions });\n}\n"],"names":["ToastContainer","BaseToastContainer","toast","baseToast"],"mappings":";;;;;AAOA,MAAa,6BAA6B;AAI1C,MAAaA,oBACX,QAAsD,EAAE,KAExD,cAAcC,gBAAoB;CAChC,aAAa;CACb,GAAG;CACJ,CAAC;AAGJ,SAAgBC,QAAM,SAAuB,SAA+B;CAC1E,MAAM,EACJ,OAAO,WACP,cAAc,4BACd,GAAG,gBACD,WAAW,EAAE;AACjB,QAAOC,MAAU,SAAS;EAAE;EAAM;EAAa,GAAG;EAAa,CAAC","debug_id":"70c9da16-68cb-54a4-9662-dd9a799742d5"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="bbb5e35d-c252-50af-bc16-46e7ceedd324")}catch(e){}}();
|
|
3
|
+
import { n as getRuntimeConfig } from "./runtime-config-DL3QjcfM.js";
|
|
4
|
+
import { useCallback, useMemo } from "react";
|
|
5
|
+
import { openRenown, showPHModal, useRenownAuth, useRenownLoginMethods } from "@powerhousedao/reactor-browser";
|
|
6
|
+
//#region src/hooks/use-renown-login.ts
|
|
7
|
+
function useOpenRenownLogin() {
|
|
8
|
+
const adapters = getRuntimeConfig().connect.renown?.adapters;
|
|
9
|
+
const methods = useRenownLoginMethods(adapters);
|
|
10
|
+
return useCallback(() => {
|
|
11
|
+
if (methods.length > 0) showPHModal({ type: "login" });
|
|
12
|
+
else openRenown();
|
|
13
|
+
}, [methods]);
|
|
14
|
+
}
|
|
15
|
+
const LAST_METHOD_KEY = "renown:last-login-method";
|
|
16
|
+
function getLastLoginMethod() {
|
|
17
|
+
try {
|
|
18
|
+
return localStorage.getItem(LAST_METHOD_KEY);
|
|
19
|
+
} catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function setLastLoginMethod(method) {
|
|
24
|
+
try {
|
|
25
|
+
localStorage.setItem(LAST_METHOD_KEY, method);
|
|
26
|
+
} catch {}
|
|
27
|
+
}
|
|
28
|
+
function useRenownLoginProps() {
|
|
29
|
+
const { login, pending, error } = useRenownAuth();
|
|
30
|
+
const onLogin = useCallback(() => login(), [login]);
|
|
31
|
+
const adapters = getRuntimeConfig().connect.renown?.adapters;
|
|
32
|
+
const baseMethods = useRenownLoginMethods(adapters);
|
|
33
|
+
return {
|
|
34
|
+
onLogin,
|
|
35
|
+
methods: useMemo(() => {
|
|
36
|
+
const lastUsed = getLastLoginMethod();
|
|
37
|
+
return baseMethods.map((method) => ({
|
|
38
|
+
id: method.id,
|
|
39
|
+
label: method.label,
|
|
40
|
+
lastUsed: lastUsed === method.id,
|
|
41
|
+
onSelect: () => {
|
|
42
|
+
setLastLoginMethod(method.id);
|
|
43
|
+
login(void 0, method.id);
|
|
44
|
+
}
|
|
45
|
+
}));
|
|
46
|
+
}, [baseMethods, login]),
|
|
47
|
+
loading: pending,
|
|
48
|
+
error: error?.message ?? null
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
export { useRenownLoginProps as n, useOpenRenownLogin as t };
|
|
53
|
+
|
|
54
|
+
//# sourceMappingURL=use-renown-login-DBujbqs8.js.map
|
|
55
|
+
//# debugId=bbb5e35d-c252-50af-bc16-46e7ceedd324
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-renown-login-DBujbqs8.js","sources":["../src/hooks/use-renown-login.ts"],"sourcesContent":["import type { RenownLoginOption } from \"@powerhousedao/design-system/connect\";\nimport {\n openRenown,\n showPHModal,\n useRenownAuth,\n useRenownLoginMethods,\n} from \"@powerhousedao/reactor-browser\";\nimport type { WalletAdaptersConfig } from \"@renown/sdk/wallet\";\nimport { useCallback, useMemo } from \"react\";\nimport { getRuntimeConfig } from \"../runtime-config.js\";\n\n// Opens the in-page login modal when wallet adapters are configured; otherwise\n// redirects straight to the Renown portal (no modal with only a redirect button).\nexport function useOpenRenownLogin(): () => void {\n const adapters = getRuntimeConfig().connect.renown?.adapters as\n | WalletAdaptersConfig\n | undefined;\n const methods = useRenownLoginMethods(adapters);\n return useCallback(() => {\n if (methods.length > 0) {\n showPHModal({ type: \"login\" });\n } else {\n openRenown();\n }\n }, [methods]);\n}\n\nexport interface RenownLoginProps {\n onLogin: () => void;\n // One option per configured login method (wallet, Google, email, …). Empty\n // only when no adapters are configured (the redirect Connect button is used).\n methods: RenownLoginOption[];\n loading: boolean;\n error: string | null;\n}\n\nconst LAST_METHOD_KEY = \"renown:last-login-method\";\n\nfunction getLastLoginMethod(): string | null {\n try {\n return localStorage.getItem(LAST_METHOD_KEY);\n } catch {\n return null;\n }\n}\n\nfunction setLastLoginMethod(method: string): void {\n try {\n localStorage.setItem(LAST_METHOD_KEY, method);\n } catch {\n // localStorage unavailable (private mode / SSR) — the badge is optional.\n }\n}\n\n// Single source of the login wiring shared by every Connect CTA: in-page\n// sign-in (with redirect fallback) plus pending/error feedback.\nexport function useRenownLoginProps(): RenownLoginProps {\n const { login, pending, error } = useRenownAuth();\n const onLogin = useCallback(() => login(), [login]);\n\n const adapters = getRuntimeConfig().connect.renown?.adapters as\n | WalletAdaptersConfig\n | undefined;\n // Method list (labels) comes from the shared primitive; Connect adds the\n // last-used badge + the onSelect wiring for its design-system card.\n const baseMethods = useRenownLoginMethods(adapters);\n\n const methods = useMemo<RenownLoginOption[]>(() => {\n const lastUsed = getLastLoginMethod();\n return baseMethods.map((method) => ({\n id: method.id,\n label: method.label,\n lastUsed: lastUsed === method.id,\n onSelect: () => {\n setLastLoginMethod(method.id);\n login(undefined, method.id);\n },\n }));\n }, [baseMethods, login]);\n\n return { onLogin, methods, loading: pending, error: error?.message ?? null };\n}\n"],"names":[],"mappings":";;;;;;AAaA,SAAgB,qBAAiC;CAC/C,MAAM,WAAW,kBAAkB,CAAC,QAAQ,QAAQ;CAGpD,MAAM,UAAU,sBAAsB,SAAS;AAC/C,QAAO,kBAAkB;AACvB,MAAI,QAAQ,SAAS,EACnB,aAAY,EAAE,MAAM,SAAS,CAAC;MAE9B,aAAY;IAEb,CAAC,QAAQ,CAAC;;AAYf,MAAM,kBAAkB;AAExB,SAAS,qBAAoC;AAC3C,KAAI;AACF,SAAO,aAAa,QAAQ,gBAAgB;SACtC;AACN,SAAO;;;AAIX,SAAS,mBAAmB,QAAsB;AAChD,KAAI;AACF,eAAa,QAAQ,iBAAiB,OAAO;SACvC;;AAOV,SAAgB,sBAAwC;CACtD,MAAM,EAAE,OAAO,SAAS,UAAU,eAAe;CACjD,MAAM,UAAU,kBAAkB,OAAO,EAAE,CAAC,MAAM,CAAC;CAEnD,MAAM,WAAW,kBAAkB,CAAC,QAAQ,QAAQ;CAKpD,MAAM,cAAc,sBAAsB,SAAS;AAenD,QAAO;EAAE;EAAS,SAbF,cAAmC;GACjD,MAAM,WAAW,oBAAoB;AACrC,UAAO,YAAY,KAAK,YAAY;IAClC,IAAI,OAAO;IACX,OAAO,OAAO;IACd,UAAU,aAAa,OAAO;IAC9B,gBAAgB;AACd,wBAAmB,OAAO,GAAG;AAC7B,WAAM,KAAA,GAAW,OAAO,GAAG;;IAE9B,EAAE;KACF,CAAC,aAAa,MAAM,CAAC;EAEG,SAAS;EAAS,OAAO,OAAO,WAAW;EAAM","debug_id":"bbb5e35d-c252-50af-bc16-46e7ceedd324"}
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a2bca0ce-adce-512d-a646-5adf41d1dd3f")}catch(e){}}();
|
|
3
|
+
import { n as getRuntimeConfig } from "./runtime-config-DL3QjcfM.js";
|
|
4
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
5
|
+
import { getPackagePage, getPackagesForDocumentType, trimTrailingSlash, useVetraPackageManager } from "@powerhousedao/reactor-browser";
|
|
6
|
+
import { slimManifest } from "@powerhousedao/shared/registry/manifest-slim";
|
|
7
|
+
//#region src/hooks/useRegistryPackages.ts
|
|
8
|
+
/** Page size for the paginated Available-packages listing. */
|
|
9
|
+
const AVAILABLE_PAGE_SIZE = 30;
|
|
10
|
+
function useRegistryPackages() {
|
|
11
|
+
const packageManager = useVetraPackageManager();
|
|
12
|
+
const packageManagerPackages = packageManager?.packages;
|
|
13
|
+
const registryUrl = getRuntimeConfig().packageRegistryUrl ?? null;
|
|
14
|
+
const [registryPackagesMap, setRegistryPackagesMap] = useBestEffortLocalStorage(`REGISTRY_PACKAGES:${registryUrl === null ? null : trimTrailingSlash(registryUrl)}`, {});
|
|
15
|
+
const registryPackageList = useMemo(() => {
|
|
16
|
+
return Array.from(Object.values(registryPackagesMap)).filter((p) => p !== void 0);
|
|
17
|
+
}, [registryPackagesMap]);
|
|
18
|
+
const installedPackages = useMemo(() => registryPackageList.filter((p) => p.status === "local-install" || p.status === "registry-install"), [registryPackageList]);
|
|
19
|
+
const [availableOrder, setAvailableOrder] = useState([]);
|
|
20
|
+
const [availableTotal, setAvailableTotal] = useState(null);
|
|
21
|
+
const [availableHasMore, setAvailableHasMore] = useState(false);
|
|
22
|
+
const [isLoadingAvailable, setIsLoadingAvailable] = useState(false);
|
|
23
|
+
const [isLoadingMoreAvailable, setIsLoadingMoreAvailable] = useState(false);
|
|
24
|
+
const [availableError, setAvailableError] = useState(false);
|
|
25
|
+
const availableQueryRef = useRef("");
|
|
26
|
+
const nextOffsetRef = useRef(0);
|
|
27
|
+
const requestGenerationRef = useRef(0);
|
|
28
|
+
const debounceRef = useRef(null);
|
|
29
|
+
const availablePackages = useMemo(() => availableOrder.map((name) => registryPackagesMap[name]).filter((p) => p !== void 0 && (p.status === "available" || p.status === "dismissed")), [availableOrder, registryPackagesMap]);
|
|
30
|
+
const fetchAvailablePage = useCallback(async ({ reset }) => {
|
|
31
|
+
if (registryUrl === null || !packageManager) return;
|
|
32
|
+
const generation = ++requestGenerationRef.current;
|
|
33
|
+
const offset = reset ? 0 : nextOffsetRef.current;
|
|
34
|
+
const search = availableQueryRef.current;
|
|
35
|
+
if (reset) setIsLoadingAvailable(true);
|
|
36
|
+
else setIsLoadingMoreAvailable(true);
|
|
37
|
+
setAvailableError(false);
|
|
38
|
+
try {
|
|
39
|
+
const page = await getPackagePage(registryUrl, {
|
|
40
|
+
limit: AVAILABLE_PAGE_SIZE,
|
|
41
|
+
offset,
|
|
42
|
+
search: search || void 0
|
|
43
|
+
});
|
|
44
|
+
if (generation !== requestGenerationRef.current) return;
|
|
45
|
+
setRegistryPackagesMap((oldPackages) => {
|
|
46
|
+
const next = { ...oldPackages };
|
|
47
|
+
for (const item of page.items) {
|
|
48
|
+
const existing = next[item.name];
|
|
49
|
+
if (!existing) {
|
|
50
|
+
const status = getPackageStatusFromPackageSource(packageManager.getPackageSource(item.name));
|
|
51
|
+
next[item.name] = makeRegistryPackageFromListItem(item, status);
|
|
52
|
+
} else next[item.name] = {
|
|
53
|
+
...existing,
|
|
54
|
+
version: packageManager.getPackageVersion(item.name) ?? item.version ?? existing.version,
|
|
55
|
+
status: promoteStatus(existing.status, packageManager.getPackageSource(item.name))
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
return next;
|
|
59
|
+
});
|
|
60
|
+
setAvailableOrder((prev) => {
|
|
61
|
+
const base = reset ? [] : prev;
|
|
62
|
+
const seen = new Set(base);
|
|
63
|
+
const merged = [...base];
|
|
64
|
+
for (const item of page.items) if (!seen.has(item.name)) {
|
|
65
|
+
seen.add(item.name);
|
|
66
|
+
merged.push(item.name);
|
|
67
|
+
}
|
|
68
|
+
return merged;
|
|
69
|
+
});
|
|
70
|
+
nextOffsetRef.current = offset + page.items.length;
|
|
71
|
+
setAvailableTotal(page.total);
|
|
72
|
+
setAvailableHasMore(page.hasMore);
|
|
73
|
+
} catch (error) {
|
|
74
|
+
if (generation !== requestGenerationRef.current) return;
|
|
75
|
+
console.error(error);
|
|
76
|
+
setAvailableError(true);
|
|
77
|
+
} finally {
|
|
78
|
+
if (generation === requestGenerationRef.current) {
|
|
79
|
+
setIsLoadingAvailable(false);
|
|
80
|
+
setIsLoadingMoreAvailable(false);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}, [
|
|
84
|
+
registryUrl,
|
|
85
|
+
packageManager,
|
|
86
|
+
setRegistryPackagesMap
|
|
87
|
+
]);
|
|
88
|
+
/** Debounced server search — resets to page 1 for the new query. */
|
|
89
|
+
const setAvailableSearch = useCallback((query) => {
|
|
90
|
+
availableQueryRef.current = query;
|
|
91
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
92
|
+
debounceRef.current = setTimeout(() => {
|
|
93
|
+
fetchAvailablePage({ reset: true });
|
|
94
|
+
}, 300);
|
|
95
|
+
}, [fetchAvailablePage]);
|
|
96
|
+
/** Load the next page (infinite scroll). No-op when exhausted/busy. */
|
|
97
|
+
const loadMoreAvailable = useCallback(() => {
|
|
98
|
+
if (!availableHasMore || isLoadingAvailable || isLoadingMoreAvailable) return;
|
|
99
|
+
fetchAvailablePage({ reset: false });
|
|
100
|
+
}, [
|
|
101
|
+
availableHasMore,
|
|
102
|
+
isLoadingAvailable,
|
|
103
|
+
isLoadingMoreAvailable,
|
|
104
|
+
fetchAvailablePage
|
|
105
|
+
]);
|
|
106
|
+
/**
|
|
107
|
+
* Load page 1 the first time the Available tab is opened. Re-opening keeps
|
|
108
|
+
* the accumulated pages; a fetch error leaves the panel's Retry to re-fetch
|
|
109
|
+
* (this guard avoids auto-retry loops on tab re-open).
|
|
110
|
+
*/
|
|
111
|
+
function ensureAvailableLoaded() {
|
|
112
|
+
if (availableOrder.length > 0 || isLoadingAvailable || availableError) return;
|
|
113
|
+
fetchAvailablePage({ reset: true });
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Fetch full package info for a document type (via the legacy
|
|
117
|
+
* `?documentType=` filter) and merge into the map. Lets MissingPackageModal
|
|
118
|
+
* offer installs without loading the whole paginated listing.
|
|
119
|
+
*/
|
|
120
|
+
const fetchPackagesByDocumentType = useCallback(async (documentType) => {
|
|
121
|
+
if (registryUrl === null || !packageManager) return [];
|
|
122
|
+
try {
|
|
123
|
+
const infos = await getPackagesForDocumentType(registryUrl, documentType);
|
|
124
|
+
setRegistryPackagesMap((oldPackages) => {
|
|
125
|
+
const next = { ...oldPackages };
|
|
126
|
+
for (const info of infos) {
|
|
127
|
+
const existing = next[info.name];
|
|
128
|
+
const status = getPackageStatusFromPackageSource(packageManager.getPackageSource(info.name));
|
|
129
|
+
next[info.name] = existing ? {
|
|
130
|
+
...existing,
|
|
131
|
+
status: promoteStatus(existing.status, packageManager.getPackageSource(info.name))
|
|
132
|
+
} : makeRegistryPackageFromPackageInfo(info, status);
|
|
133
|
+
}
|
|
134
|
+
return next;
|
|
135
|
+
});
|
|
136
|
+
return infos.map((info) => makeRegistryPackageFromPackageInfo(info, getPackageStatusFromPackageSource(packageManager.getPackageSource(info.name))));
|
|
137
|
+
} catch (error) {
|
|
138
|
+
console.error(error);
|
|
139
|
+
return [];
|
|
140
|
+
}
|
|
141
|
+
}, [
|
|
142
|
+
registryUrl,
|
|
143
|
+
packageManager,
|
|
144
|
+
setRegistryPackagesMap
|
|
145
|
+
]);
|
|
146
|
+
useEffect(() => () => {
|
|
147
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
148
|
+
}, []);
|
|
149
|
+
useEffect(() => {
|
|
150
|
+
if (!packageManager) return;
|
|
151
|
+
if (packageManagerPackages?.length) for (const packageManagerPackage of packageManagerPackages) setRegistryPackagesMap((existingRegistryPackages) => {
|
|
152
|
+
const packageName = packageManagerPackage.manifest.name;
|
|
153
|
+
const existingPackage = existingRegistryPackages[packageName];
|
|
154
|
+
const newRegistryPackages = { ...existingRegistryPackages };
|
|
155
|
+
const version = packageManager.getPackageVersion(packageName);
|
|
156
|
+
if (existingPackage) newRegistryPackages[packageName] = {
|
|
157
|
+
...existingPackage,
|
|
158
|
+
version: version ?? existingPackage.version,
|
|
159
|
+
status: promoteStatus(existingPackage.status, packageManager.getPackageSource(packageName))
|
|
160
|
+
};
|
|
161
|
+
else newRegistryPackages[packageName] = makeRegistryPackageFromDocumentModelLib(packageManagerPackage, getPackageStatusFromPackageSource(packageManager.getPackageSource(packageName)), version);
|
|
162
|
+
return newRegistryPackages;
|
|
163
|
+
});
|
|
164
|
+
}, [packageManagerPackages]);
|
|
165
|
+
function updateRegistryPackageStatus(packageName, newStatus) {
|
|
166
|
+
setRegistryPackagesMap((oldRegistryPackages) => {
|
|
167
|
+
const newRegistryPackages = { ...oldRegistryPackages };
|
|
168
|
+
const newRegistryPackage = newRegistryPackages[packageName];
|
|
169
|
+
if (!newRegistryPackage) {
|
|
170
|
+
console.error("Attempting to update status for package that does not exist.");
|
|
171
|
+
return newRegistryPackages;
|
|
172
|
+
}
|
|
173
|
+
newRegistryPackages[packageName] = {
|
|
174
|
+
...newRegistryPackage,
|
|
175
|
+
status: newStatus
|
|
176
|
+
};
|
|
177
|
+
return newRegistryPackages;
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Register a freshly-installed package that came in via the npm-uplink
|
|
182
|
+
* fallback — the user typed a bare name, our local `/packages` didn't know
|
|
183
|
+
* it, but the install succeeded because verdaccio proxy-fetched the tarball.
|
|
184
|
+
*
|
|
185
|
+
* This is the one legitimate case where the status update runs against a
|
|
186
|
+
* name that wasn't in the registry map. We treat it as an insert rather
|
|
187
|
+
* than logging the "does not exist" error. Data is pulled from the loaded
|
|
188
|
+
* module so the UI card shows the real manifest immediately; the next
|
|
189
|
+
* `/packages` refresh will add `versions`/`distTags`.
|
|
190
|
+
*/
|
|
191
|
+
function registerFallbackRegistryPackage(packageName, loadedPackage, version, status) {
|
|
192
|
+
setRegistryPackagesMap((oldRegistryPackages) => {
|
|
193
|
+
const newRegistryPackages = { ...oldRegistryPackages };
|
|
194
|
+
newRegistryPackages[packageName] = {
|
|
195
|
+
...makeRegistryPackageFromDocumentModelLib(loadedPackage, status, version),
|
|
196
|
+
name: packageName
|
|
197
|
+
};
|
|
198
|
+
return newRegistryPackages;
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
registryPackagesMap,
|
|
203
|
+
registryPackageList,
|
|
204
|
+
installedPackages,
|
|
205
|
+
availablePackages,
|
|
206
|
+
availableTotal,
|
|
207
|
+
availableHasMore,
|
|
208
|
+
isLoadingAvailable,
|
|
209
|
+
isLoadingMoreAvailable,
|
|
210
|
+
availableError,
|
|
211
|
+
ensureAvailableLoaded,
|
|
212
|
+
fetchAvailablePage,
|
|
213
|
+
loadMoreAvailable,
|
|
214
|
+
setAvailableSearch,
|
|
215
|
+
fetchPackagesByDocumentType,
|
|
216
|
+
updateRegistryPackageStatus,
|
|
217
|
+
registerFallbackRegistryPackage
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Build a RegistryPackage from a trimmed paginated list item. Version metadata
|
|
222
|
+
* (distTags/versions) and documentTypes are absent — the row lazy-loads them.
|
|
223
|
+
*/
|
|
224
|
+
function makeRegistryPackageFromListItem(item, status) {
|
|
225
|
+
return {
|
|
226
|
+
name: item.name,
|
|
227
|
+
path: item.path,
|
|
228
|
+
documentTypes: [],
|
|
229
|
+
version: item.version,
|
|
230
|
+
status,
|
|
231
|
+
manifest: {
|
|
232
|
+
name: item.name,
|
|
233
|
+
...item.description !== void 0 ? { description: item.description } : {},
|
|
234
|
+
...item.category !== void 0 ? { category: item.category } : {},
|
|
235
|
+
...item.publisher !== void 0 ? { publisher: item.publisher } : {}
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
function makeRegistryPackageFromDocumentModelLib(documentModelLib, status, version) {
|
|
240
|
+
return {
|
|
241
|
+
name: documentModelLib.manifest.name,
|
|
242
|
+
path: "stub-path",
|
|
243
|
+
documentTypes: documentModelLib.documentModels.map((d) => d.documentModel.global.id),
|
|
244
|
+
status,
|
|
245
|
+
manifest: slimManifest(documentModelLib.manifest),
|
|
246
|
+
version
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
function makeRegistryPackageFromPackageInfo(packageInfo, status) {
|
|
250
|
+
return {
|
|
251
|
+
...packageInfo,
|
|
252
|
+
manifest: slimManifest(packageInfo.manifest),
|
|
253
|
+
documentTypes: packageInfo.manifest?.documentModels?.map((d) => d.id) ?? [],
|
|
254
|
+
status
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Like usehooks-ts' useLocalStorage, but persistence is best-effort: a failed
|
|
259
|
+
* `setItem` (e.g. QuotaExceededError on an oversized payload) keeps the
|
|
260
|
+
* in-memory state so the package manager still works for the session.
|
|
261
|
+
* useLocalStorage couples the state update to the write — when the write
|
|
262
|
+
* threw, the freshly fetched package list was discarded and the registry UI
|
|
263
|
+
* rendered (and searched) an empty list.
|
|
264
|
+
*
|
|
265
|
+
* The key is derived from the boot-time runtime config and never changes
|
|
266
|
+
* within a session, so no key-change rehydration is needed.
|
|
267
|
+
*/
|
|
268
|
+
function useBestEffortLocalStorage(key, initialValue) {
|
|
269
|
+
const [value, setValue] = useState(() => readJsonFromStorage(key) ?? initialValue);
|
|
270
|
+
useEffect(() => {
|
|
271
|
+
try {
|
|
272
|
+
window.localStorage.setItem(key, JSON.stringify(value));
|
|
273
|
+
} catch (error) {
|
|
274
|
+
try {
|
|
275
|
+
window.localStorage.removeItem(key);
|
|
276
|
+
window.localStorage.setItem(key, JSON.stringify(value));
|
|
277
|
+
} catch {
|
|
278
|
+
console.warn(`Failed to persist "${key}" to localStorage; continuing with in-memory data.`, error);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}, [key, value]);
|
|
282
|
+
return [value, setValue];
|
|
283
|
+
}
|
|
284
|
+
function readJsonFromStorage(key) {
|
|
285
|
+
try {
|
|
286
|
+
const raw = window.localStorage.getItem(key);
|
|
287
|
+
return raw === null ? null : JSON.parse(raw);
|
|
288
|
+
} catch {
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* When refreshing a cached entry, promote `"available"` to whatever the
|
|
294
|
+
* packageManager now reports — the cached `"available"` was almost certainly
|
|
295
|
+
* recorded before `packageManager.addPackages()` finished on a prior session.
|
|
296
|
+
* Never downgrade an already-installed entry, and never overwrite a deliberate
|
|
297
|
+
* `"dismissed"` choice.
|
|
298
|
+
*/
|
|
299
|
+
function promoteStatus(cachedStatus, packageSource) {
|
|
300
|
+
if (cachedStatus !== "available") return cachedStatus;
|
|
301
|
+
if (packageSource === null) return cachedStatus;
|
|
302
|
+
return getPackageStatusFromPackageSource(packageSource);
|
|
303
|
+
}
|
|
304
|
+
function getPackageStatusFromPackageSource(packageSource) {
|
|
305
|
+
if (packageSource === null) return "available";
|
|
306
|
+
if (packageSource === "local-install" || packageSource === "common" || packageSource === "project") return "local-install";
|
|
307
|
+
if (packageSource === "registry-install") return "registry-install";
|
|
308
|
+
return "available";
|
|
309
|
+
}
|
|
310
|
+
//#endregion
|
|
311
|
+
export { useRegistryPackages as t };
|
|
312
|
+
|
|
313
|
+
//# sourceMappingURL=useRegistryPackages-DMhCvTWq.js.map
|
|
314
|
+
//# debugId=a2bca0ce-adce-512d-a646-5adf41d1dd3f
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRegistryPackages-DMhCvTWq.js","sources":["../src/hooks/useRegistryPackages.ts"],"sourcesContent":["import {\n getPackagePage,\n getPackagesForDocumentType,\n trimTrailingSlash,\n useVetraPackageManager,\n} from \"@powerhousedao/reactor-browser\";\nimport type {\n PackageInfo,\n PackageListItem,\n RegistryPackage,\n RegistryPackageList,\n RegistryPackageMap,\n RegistryPackageSource,\n RegistryPackageStatus,\n} from \"@powerhousedao/shared/registry\";\nimport { slimManifest } from \"@powerhousedao/shared/registry/manifest-slim\";\nimport type { DocumentModelLib } from \"document-model\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { getRuntimeConfig } from \"../runtime-config.js\";\n\n/** Page size for the paginated Available-packages listing. */\nconst AVAILABLE_PAGE_SIZE = 30;\n\nexport function useRegistryPackages() {\n const packageManager = useVetraPackageManager();\n const packageManagerPackages = packageManager?.packages;\n const registryUrl = getRuntimeConfig().packageRegistryUrl ?? null;\n // Normalize so `http://host` and `http://host/` don't produce two separate\n // localStorage maps where the install/status flow reads from one while the\n // registry fetch writes to the other.\n const registryPackagesKey = `REGISTRY_PACKAGES:${registryUrl === null ? null : trimTrailingSlash(registryUrl)}`;\n const [registryPackagesMap, setRegistryPackagesMap] =\n useBestEffortLocalStorage<RegistryPackageMap>(registryPackagesKey, {});\n const registryPackageList: RegistryPackageList = useMemo(() => {\n return Array.from(Object.values(registryPackagesMap)).filter(\n (p) => p !== undefined,\n );\n }, [registryPackagesMap]);\n // Split for the two Package Manager tabs: installed is derivable from local\n // state alone (no network), available/dismissed come from the registry\n // fetch (or its localStorage cache).\n const installedPackages: RegistryPackageList = useMemo(\n () =>\n registryPackageList.filter(\n (p) => p.status === \"local-install\" || p.status === \"registry-install\",\n ),\n [registryPackageList],\n );\n // --- Available tab: paginated + server-searched, layered on the map ---\n //\n // The map above stays the single source of truth for each package's status,\n // version metadata and install state. `availableOrder` is the ordering layer\n // for the current search: a page-accumulated list of names. The rendered\n // available list looks each name up in the map and drops anything that is\n // now installed (it moves to the Installed tab) — so installing a row needs\n // no extra bookkeeping.\n const [availableOrder, setAvailableOrder] = useState<string[]>([]);\n const [availableTotal, setAvailableTotal] = useState<number | null>(null);\n const [availableHasMore, setAvailableHasMore] = useState(false);\n const [isLoadingAvailable, setIsLoadingAvailable] = useState(false);\n const [isLoadingMoreAvailable, setIsLoadingMoreAvailable] = useState(false);\n const [availableError, setAvailableError] = useState(false);\n\n // Latest search string (updated synchronously so a debounced fetch reads the\n // freshest query), the server offset for the next page, and a monotonic\n // request generation so out-of-order responses never clobber a newer query.\n const availableQueryRef = useRef(\"\");\n const nextOffsetRef = useRef(0);\n const requestGenerationRef = useRef(0);\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const availablePackages: RegistryPackageList = useMemo(\n () =>\n availableOrder\n .map((name) => registryPackagesMap[name])\n .filter(\n (p): p is RegistryPackage =>\n p !== undefined &&\n (p.status === \"available\" || p.status === \"dismissed\"),\n ),\n [availableOrder, registryPackagesMap],\n );\n\n const fetchAvailablePage = useCallback(\n async ({ reset }: { reset: boolean }): Promise<void> => {\n if (registryUrl === null || !packageManager) return;\n const generation = ++requestGenerationRef.current;\n const offset = reset ? 0 : nextOffsetRef.current;\n const search = availableQueryRef.current;\n if (reset) setIsLoadingAvailable(true);\n else setIsLoadingMoreAvailable(true);\n setAvailableError(false);\n\n try {\n const page = await getPackagePage(registryUrl, {\n limit: AVAILABLE_PAGE_SIZE,\n offset,\n search: search || undefined,\n });\n // A newer search/reset superseded this request — drop its result.\n if (generation !== requestGenerationRef.current) return;\n\n setRegistryPackagesMap((oldPackages) => {\n const next: RegistryPackageMap = { ...oldPackages };\n for (const item of page.items) {\n const existing = next[item.name];\n if (!existing) {\n const status = getPackageStatusFromPackageSource(\n packageManager.getPackageSource(item.name),\n );\n next[item.name] = makeRegistryPackageFromListItem(item, status);\n } else {\n // Keep the existing (possibly fuller) entry; just refresh the\n // installed version and re-promote status. Never downgrade an\n // installed/dismissed row from a trimmed list item.\n next[item.name] = {\n ...existing,\n version:\n packageManager.getPackageVersion(item.name) ??\n item.version ??\n existing.version,\n status: promoteStatus(\n existing.status,\n packageManager.getPackageSource(item.name),\n ),\n };\n }\n }\n return next;\n });\n\n setAvailableOrder((prev) => {\n const base = reset ? [] : prev;\n const seen = new Set(base);\n const merged = [...base];\n for (const item of page.items) {\n if (!seen.has(item.name)) {\n seen.add(item.name);\n merged.push(item.name);\n }\n }\n return merged;\n });\n\n nextOffsetRef.current = offset + page.items.length;\n setAvailableTotal(page.total);\n setAvailableHasMore(page.hasMore);\n } catch (error: unknown) {\n if (generation !== requestGenerationRef.current) return;\n // Log the raw failure for debugging; the UI only gets a boolean so we\n // never surface generic API / network messages to the user.\n console.error(error);\n setAvailableError(true);\n } finally {\n // Only the newest request clears the spinners.\n if (generation === requestGenerationRef.current) {\n setIsLoadingAvailable(false);\n setIsLoadingMoreAvailable(false);\n }\n }\n },\n [registryUrl, packageManager, setRegistryPackagesMap],\n );\n\n /** Debounced server search — resets to page 1 for the new query. */\n const setAvailableSearch = useCallback(\n (query: string) => {\n availableQueryRef.current = query;\n if (debounceRef.current) clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(() => {\n void fetchAvailablePage({ reset: true });\n }, 300);\n },\n [fetchAvailablePage],\n );\n\n /** Load the next page (infinite scroll). No-op when exhausted/busy. */\n const loadMoreAvailable = useCallback(() => {\n if (!availableHasMore || isLoadingAvailable || isLoadingMoreAvailable) {\n return;\n }\n void fetchAvailablePage({ reset: false });\n }, [\n availableHasMore,\n isLoadingAvailable,\n isLoadingMoreAvailable,\n fetchAvailablePage,\n ]);\n\n /**\n * Load page 1 the first time the Available tab is opened. Re-opening keeps\n * the accumulated pages; a fetch error leaves the panel's Retry to re-fetch\n * (this guard avoids auto-retry loops on tab re-open).\n */\n function ensureAvailableLoaded() {\n if (availableOrder.length > 0 || isLoadingAvailable || availableError) {\n return;\n }\n void fetchAvailablePage({ reset: true });\n }\n\n /**\n * Fetch full package info for a document type (via the legacy\n * `?documentType=` filter) and merge into the map. Lets MissingPackageModal\n * offer installs without loading the whole paginated listing.\n */\n const fetchPackagesByDocumentType = useCallback(\n async (documentType: string): Promise<RegistryPackage[]> => {\n if (registryUrl === null || !packageManager) return [];\n try {\n const infos = await getPackagesForDocumentType(\n registryUrl,\n documentType,\n );\n setRegistryPackagesMap((oldPackages) => {\n const next: RegistryPackageMap = { ...oldPackages };\n for (const info of infos) {\n const existing = next[info.name];\n const status = getPackageStatusFromPackageSource(\n packageManager.getPackageSource(info.name),\n );\n next[info.name] = existing\n ? {\n ...existing,\n status: promoteStatus(\n existing.status,\n packageManager.getPackageSource(info.name),\n ),\n }\n : makeRegistryPackageFromPackageInfo(info, status);\n }\n return next;\n });\n return infos.map((info) =>\n makeRegistryPackageFromPackageInfo(\n info,\n getPackageStatusFromPackageSource(\n packageManager.getPackageSource(info.name),\n ),\n ),\n );\n } catch (error: unknown) {\n console.error(error);\n return [];\n }\n },\n [registryUrl, packageManager, setRegistryPackagesMap],\n );\n\n // Clear any pending debounce on unmount.\n useEffect(\n () => () => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n },\n [],\n );\n\n useEffect(() => {\n if (!packageManager) return;\n\n if (packageManagerPackages?.length) {\n for (const packageManagerPackage of packageManagerPackages) {\n setRegistryPackagesMap((existingRegistryPackages) => {\n const packageName = packageManagerPackage.manifest.name;\n const existingPackage = existingRegistryPackages[packageName];\n const newRegistryPackages = { ...existingRegistryPackages };\n const version = packageManager.getPackageVersion(packageName);\n if (existingPackage) {\n newRegistryPackages[packageName] = {\n ...existingPackage,\n version: version ?? existingPackage.version,\n status: promoteStatus(\n existingPackage.status,\n packageManager.getPackageSource(packageName),\n ),\n };\n } else {\n const packageSource = packageManager.getPackageSource(packageName);\n const status = getPackageStatusFromPackageSource(packageSource);\n const newRegistryPackage = makeRegistryPackageFromDocumentModelLib(\n packageManagerPackage,\n status,\n version,\n );\n newRegistryPackages[packageName] = newRegistryPackage;\n }\n return newRegistryPackages;\n });\n }\n }\n }, [packageManagerPackages]);\n\n function updateRegistryPackageStatus(\n packageName: string,\n newStatus: RegistryPackageStatus,\n ) {\n setRegistryPackagesMap((oldRegistryPackages) => {\n const newRegistryPackages = { ...oldRegistryPackages };\n const newRegistryPackage = newRegistryPackages[packageName];\n if (!newRegistryPackage) {\n console.error(\n \"Attempting to update status for package that does not exist.\",\n );\n return newRegistryPackages;\n }\n newRegistryPackages[packageName] = {\n ...newRegistryPackage,\n status: newStatus,\n };\n\n return newRegistryPackages;\n });\n }\n\n /**\n * Register a freshly-installed package that came in via the npm-uplink\n * fallback — the user typed a bare name, our local `/packages` didn't know\n * it, but the install succeeded because verdaccio proxy-fetched the tarball.\n *\n * This is the one legitimate case where the status update runs against a\n * name that wasn't in the registry map. We treat it as an insert rather\n * than logging the \"does not exist\" error. Data is pulled from the loaded\n * module so the UI card shows the real manifest immediately; the next\n * `/packages` refresh will add `versions`/`distTags`.\n */\n function registerFallbackRegistryPackage(\n packageName: string,\n loadedPackage: DocumentModelLib,\n version: string | undefined,\n status: RegistryPackageStatus,\n ) {\n setRegistryPackagesMap((oldRegistryPackages) => {\n const newRegistryPackages = { ...oldRegistryPackages };\n newRegistryPackages[packageName] = {\n ...makeRegistryPackageFromDocumentModelLib(\n loadedPackage,\n status,\n version,\n ),\n name: packageName,\n };\n return newRegistryPackages;\n });\n }\n\n return {\n registryPackagesMap,\n registryPackageList,\n installedPackages,\n // Available tab (paginated + server search)\n availablePackages,\n availableTotal,\n availableHasMore,\n isLoadingAvailable,\n isLoadingMoreAvailable,\n availableError,\n ensureAvailableLoaded,\n fetchAvailablePage,\n loadMoreAvailable,\n setAvailableSearch,\n fetchPackagesByDocumentType,\n // Status mutations\n updateRegistryPackageStatus,\n registerFallbackRegistryPackage,\n };\n}\n\n/**\n * Build a RegistryPackage from a trimmed paginated list item. Version metadata\n * (distTags/versions) and documentTypes are absent — the row lazy-loads them.\n */\nfunction makeRegistryPackageFromListItem(\n item: PackageListItem,\n status: RegistryPackageStatus,\n): RegistryPackage {\n return {\n name: item.name,\n path: item.path,\n documentTypes: [],\n version: item.version,\n status,\n manifest: {\n name: item.name,\n ...(item.description !== undefined\n ? { description: item.description }\n : {}),\n ...(item.category !== undefined ? { category: item.category } : {}),\n ...(item.publisher !== undefined ? { publisher: item.publisher } : {}),\n },\n };\n}\n\nfunction makeRegistryPackageFromDocumentModelLib(\n documentModelLib: DocumentModelLib,\n status: RegistryPackageStatus,\n version?: string,\n): RegistryPackage {\n return {\n name: documentModelLib.manifest.name,\n path: \"stub-path\",\n documentTypes: documentModelLib.documentModels.map(\n (d) => d.documentModel.global.id,\n ),\n status,\n manifest: slimManifest(documentModelLib.manifest),\n version,\n };\n}\n\nfunction makeRegistryPackageFromPackageInfo(\n packageInfo: PackageInfo,\n status: RegistryPackageStatus,\n): RegistryPackage {\n return {\n ...packageInfo,\n // Slim before caching: registry manifests are unvalidated JSON and have\n // carried multi-megabyte junk fields that blew the localStorage quota\n // (and the UI only reads the summary fields anyway).\n manifest: slimManifest(packageInfo.manifest),\n documentTypes: packageInfo.manifest?.documentModels?.map((d) => d.id) ?? [],\n status,\n };\n}\n\n/**\n * Like usehooks-ts' useLocalStorage, but persistence is best-effort: a failed\n * `setItem` (e.g. QuotaExceededError on an oversized payload) keeps the\n * in-memory state so the package manager still works for the session.\n * useLocalStorage couples the state update to the write — when the write\n * threw, the freshly fetched package list was discarded and the registry UI\n * rendered (and searched) an empty list.\n *\n * The key is derived from the boot-time runtime config and never changes\n * within a session, so no key-change rehydration is needed.\n */\nfunction useBestEffortLocalStorage<T>(key: string, initialValue: T) {\n const [value, setValue] = useState<T>(\n () => readJsonFromStorage<T>(key) ?? initialValue,\n );\n\n useEffect(() => {\n try {\n window.localStorage.setItem(key, JSON.stringify(value));\n } catch (error) {\n // Free the key and retry once — a stale oversized entry from an older\n // session may be occupying the quota this write needs.\n try {\n window.localStorage.removeItem(key);\n window.localStorage.setItem(key, JSON.stringify(value));\n } catch {\n console.warn(\n `Failed to persist \"${key}\" to localStorage; continuing with in-memory data.`,\n error,\n );\n }\n }\n }, [key, value]);\n\n return [value, setValue] as const;\n}\n\nfunction readJsonFromStorage<T>(key: string): T | null {\n try {\n const raw = window.localStorage.getItem(key);\n return raw === null ? null : (JSON.parse(raw) as T);\n } catch {\n return null;\n }\n}\n\n/**\n * When refreshing a cached entry, promote `\"available\"` to whatever the\n * packageManager now reports — the cached `\"available\"` was almost certainly\n * recorded before `packageManager.addPackages()` finished on a prior session.\n * Never downgrade an already-installed entry, and never overwrite a deliberate\n * `\"dismissed\"` choice.\n */\nfunction promoteStatus(\n cachedStatus: RegistryPackageStatus,\n packageSource: RegistryPackageSource | null,\n): RegistryPackageStatus {\n if (cachedStatus !== \"available\") return cachedStatus;\n if (packageSource === null) return cachedStatus;\n return getPackageStatusFromPackageSource(packageSource);\n}\n\nfunction getPackageStatusFromPackageSource(\n packageSource: RegistryPackageSource | null,\n): RegistryPackageStatus {\n // if we check the package source for a package that came from the api and it doesn't exist yet,\n // then we know the package is available on the api but not installed\n if (packageSource === null) return \"available\";\n // show common package, local project package and locally installed packages as \"local-install\"\n if (\n packageSource === \"local-install\" ||\n packageSource === \"common\" ||\n packageSource === \"project\"\n )\n return \"local-install\";\n // show \"registry-install\" status for package source \"registry-install\"\n if (packageSource === \"registry-install\") return \"registry-install\";\n // fallback to available — we should probably do more checks here\n return \"available\";\n}\n"],"names":[],"mappings":"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","debug_id":"a2bca0ce-adce-512d-a646-5adf41d1dd3f"}
|