@powerhousedao/connect 6.2.2-dev.2 → 6.2.2-dev.21

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.
Files changed (88) hide show
  1. package/assets/document-icon-192x192.png +0 -0
  2. package/assets/document-icon-512x512.png +0 -0
  3. package/assets/pwa-192x192.png +0 -0
  4. package/assets/pwa-512x512-maskable.png +0 -0
  5. package/assets/pwa-512x512.png +0 -0
  6. package/dist/{AddDriveModal-MMHlkJBJ.js → AddDriveModal-Cy4_b0wO.js} +4 -4
  7. package/dist/{AddDriveModal-MMHlkJBJ.js.map → AddDriveModal-Cy4_b0wO.js.map} +1 -1
  8. package/dist/{ClearStorageModal-CFBQ3g2W.js → ClearStorageModal-ezYVwzfp.js} +4 -4
  9. package/dist/{ClearStorageModal-CFBQ3g2W.js.map → ClearStorageModal-ezYVwzfp.js.map} +1 -1
  10. package/dist/{CookiesPolicyModal-CkcUKPLb.js → CookiesPolicyModal-Dpx-2TgP.js} +3 -3
  11. package/dist/{CookiesPolicyModal-CkcUKPLb.js.map → CookiesPolicyModal-Dpx-2TgP.js.map} +1 -1
  12. package/dist/{CreateDocumentModal-CvsTh0HM.js → CreateDocumentModal-u-IaJUQ0.js} +3 -3
  13. package/dist/{CreateDocumentModal-CvsTh0HM.js.map → CreateDocumentModal-u-IaJUQ0.js.map} +1 -1
  14. package/dist/{DebugSettingsModal-Rbn2aHS5.js → DebugSettingsModal-CZd8DASY.js} +6 -6
  15. package/dist/{DebugSettingsModal-Rbn2aHS5.js.map → DebugSettingsModal-CZd8DASY.js.map} +1 -1
  16. package/dist/{DeleteDriveModal-DSTK8FYk.js → DeleteDriveModal-CJKhWtli.js} +4 -4
  17. package/dist/{DeleteDriveModal-DSTK8FYk.js.map → DeleteDriveModal-CJKhWtli.js.map} +1 -1
  18. package/dist/{DeleteItemModal-B2nJmjsP.js → DeleteItemModal-DiieJw_o.js} +4 -4
  19. package/dist/{DeleteItemModal-B2nJmjsP.js.map → DeleteItemModal-DiieJw_o.js.map} +1 -1
  20. package/dist/{DisclaimerModal-D5FO34u9.js → DisclaimerModal-DAvYIF9-.js} +3 -3
  21. package/dist/{DisclaimerModal-D5FO34u9.js.map → DisclaimerModal-DAvYIF9-.js.map} +1 -1
  22. package/dist/{DownloadDocumentWithErrorsModal-tEr3bbtN.js → DownloadDocumentWithErrorsModal-CE4fa1k5.js} +3 -3
  23. package/dist/{DownloadDocumentWithErrorsModal-tEr3bbtN.js.map → DownloadDocumentWithErrorsModal-CE4fa1k5.js.map} +1 -1
  24. package/dist/DriveAuthRequiredModal-DSM6uNlb.js +36 -0
  25. package/dist/DriveAuthRequiredModal-DSM6uNlb.js.map +1 -0
  26. package/dist/{DriveSettingsModal-kR3hQnh4.js → DriveSettingsModal-CqFeWu4r.js} +3 -3
  27. package/dist/{DriveSettingsModal-kR3hQnh4.js.map → DriveSettingsModal-CqFeWu4r.js.map} +1 -1
  28. package/dist/{InspectorModal-D2BipxVV.js → InspectorModal-9m_0PxRV.js} +6 -6
  29. package/dist/{InspectorModal-D2BipxVV.js.map → InspectorModal-9m_0PxRV.js.map} +1 -1
  30. package/dist/LoginModal-BGTKLJx0.js +75 -0
  31. package/dist/LoginModal-BGTKLJx0.js.map +1 -0
  32. package/dist/{MissingPackageModal-BQcCQbOn.js → MissingPackageModal-C3acJ9r0.js} +18 -6
  33. package/dist/MissingPackageModal-C3acJ9r0.js.map +1 -0
  34. package/dist/OpenFileDocumentsModal-fd8sCSEb.js +293 -0
  35. package/dist/OpenFileDocumentsModal-fd8sCSEb.js.map +1 -0
  36. package/dist/{SettingsModal-C3gueGaR.js → SettingsModal-CMBgwFxK.js} +26 -13
  37. package/dist/SettingsModal-CMBgwFxK.js.map +1 -0
  38. package/dist/{UpgradeDriveModal-BZGSE9_r.js → UpgradeDriveModal-rUHyJTc7.js} +3 -3
  39. package/dist/{UpgradeDriveModal-BZGSE9_r.js.map → UpgradeDriveModal-rUHyJTc7.js.map} +1 -1
  40. package/dist/app-loader-CaglOyak.js +4 -0
  41. package/dist/{app-loader-CuI4Pvun.js → app-loader-Dleb3fgm.js} +288 -39
  42. package/dist/app-loader-Dleb3fgm.js.map +1 -0
  43. package/dist/{build-info-DRFIgMZ5.js → build-info-BnqWB2AR.js} +5 -5
  44. package/dist/{build-info-DRFIgMZ5.js.map → build-info-BnqWB2AR.js.map} +1 -1
  45. package/dist/components-Dzfm4865.js +5 -0
  46. package/dist/{connect.config-vgUeFoNp.js → connect.config-C-b_Yhd6.js} +9 -4
  47. package/dist/connect.config-C-b_Yhd6.js.map +1 -0
  48. package/dist/{connection-state-DO_2lAEJ.js → connection-state-KCa1yljA.js} +4 -4
  49. package/dist/{connection-state-DO_2lAEJ.js.map → connection-state-KCa1yljA.js.map} +1 -1
  50. package/dist/{load-D7Bd6r8L.js → load-DqDzOWS1.js} +10 -10
  51. package/dist/{load-D7Bd6r8L.js.map → load-DqDzOWS1.js.map} +1 -1
  52. package/dist/main.js +1 -1
  53. package/dist/{package-nOMk-HnW.js → package-bJO2dGmF.js} +8 -4
  54. package/dist/package-bJO2dGmF.js.map +1 -0
  55. package/dist/{pglite-seed-z3B1JA38.js → pglite-seed-DRXPe7p-.js} +4 -4
  56. package/dist/{pglite-seed-z3B1JA38.js.map → pglite-seed-DRXPe7p-.js.map} +1 -1
  57. package/dist/pwa-manifest-link-CG8UajMz.js +34 -0
  58. package/dist/pwa-manifest-link-CG8UajMz.js.map +1 -0
  59. package/dist/{reactor-DNtlhToA.js → reactor-_STgkwbZ.js} +145 -14
  60. package/dist/reactor-_STgkwbZ.js.map +1 -0
  61. package/dist/reactor.worker.js +9 -5
  62. package/dist/reactor.worker.js.map +1 -1
  63. package/dist/{registerServiceWorker-nJIc0yEY.js → registerServiceWorker-Bn1KWmk0.js} +6 -4
  64. package/dist/registerServiceWorker-Bn1KWmk0.js.map +1 -0
  65. package/dist/{reload-connect-toast-D1Iqw9E_.js → reload-connect-toast-BkgP9i6_.js} +19 -3
  66. package/dist/{reload-connect-toast-D1Iqw9E_.js.map → reload-connect-toast-BkgP9i6_.js.map} +1 -1
  67. package/dist/start-connect.js +1 -1
  68. package/dist/style.css +64 -3
  69. package/dist/{toast-4t-VimvD.js → toast-BLv8rjmy.js} +3 -3
  70. package/dist/{toast-4t-VimvD.js.map → toast-BLv8rjmy.js.map} +1 -1
  71. package/dist/use-renown-login-DBujbqs8.js +55 -0
  72. package/dist/use-renown-login-DBujbqs8.js.map +1 -0
  73. package/dist/useRegistryPackages-DMhCvTWq.js +314 -0
  74. package/dist/useRegistryPackages-DMhCvTWq.js.map +1 -0
  75. package/package.json +15 -11
  76. package/dist/DriveAuthRequiredModal-BA2vS3oF.js +0 -40
  77. package/dist/DriveAuthRequiredModal-BA2vS3oF.js.map +0 -1
  78. package/dist/MissingPackageModal-BQcCQbOn.js.map +0 -1
  79. package/dist/SettingsModal-C3gueGaR.js.map +0 -1
  80. package/dist/app-loader-CuI4Pvun.js.map +0 -1
  81. package/dist/app-loader-DGIZ2168.js +0 -4
  82. package/dist/components-L890idPs.js +0 -5
  83. package/dist/connect.config-vgUeFoNp.js.map +0 -1
  84. package/dist/package-nOMk-HnW.js.map +0 -1
  85. package/dist/reactor-DNtlhToA.js.map +0 -1
  86. package/dist/registerServiceWorker-nJIc0yEY.js.map +0 -1
  87. package/dist/useRegistryPackages-BaYtekjQ.js +0 -179
  88. 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]="9ee5aa7b-b29e-5c77-bcea-8b57b1fbb493")}catch(e){}}();
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-4t-VimvD.js.map
23
- //# debugId=9ee5aa7b-b29e-5c77-bcea-8b57b1fbb493
22
+ //# sourceMappingURL=toast-BLv8rjmy.js.map
23
+ //# debugId=70c9da16-68cb-54a4-9662-dd9a799742d5
@@ -1 +1 @@
1
- {"version":3,"file":"toast-4t-VimvD.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":"9ee5aa7b-b29e-5c77-bcea-8b57b1fbb493"}
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"}