@powerhousedao/connect 6.2.2-dev.9 → 6.2.2-staging.0

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 (108) 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-Q-Ffh5XA.js} +5 -5
  7. package/dist/AddDriveModal-Q-Ffh5XA.js.map +1 -0
  8. package/dist/{ClearStorageModal-BrqS8I-J.js → ClearStorageModal-DXV7eveG.js} +4 -4
  9. package/dist/{ClearStorageModal-BrqS8I-J.js.map → ClearStorageModal-DXV7eveG.js.map} +1 -1
  10. package/dist/ConfirmDocumentUpgradeModal-FUOhZsk7.js +114 -0
  11. package/dist/ConfirmDocumentUpgradeModal-FUOhZsk7.js.map +1 -0
  12. package/dist/{CookiesPolicyModal-CkcUKPLb.js → CookiesPolicyModal-BpyPPyxS.js} +3 -3
  13. package/dist/{CookiesPolicyModal-CkcUKPLb.js.map → CookiesPolicyModal-BpyPPyxS.js.map} +1 -1
  14. package/dist/{CreateDocumentModal-CvsTh0HM.js → CreateDocumentModal-C45W8J0V.js} +7 -5
  15. package/dist/CreateDocumentModal-C45W8J0V.js.map +1 -0
  16. package/dist/{DebugSettingsModal-CCZi5Gmx.js → DebugSettingsModal-D-8XfrLE.js} +6 -6
  17. package/dist/{DebugSettingsModal-CCZi5Gmx.js.map → DebugSettingsModal-D-8XfrLE.js.map} +1 -1
  18. package/dist/{DeleteDriveModal-DSTK8FYk.js → DeleteDriveModal-Dug84t1j.js} +4 -4
  19. package/dist/{DeleteDriveModal-DSTK8FYk.js.map → DeleteDriveModal-Dug84t1j.js.map} +1 -1
  20. package/dist/{DeleteItemModal-B2nJmjsP.js → DeleteItemModal-mMzy3V8o.js} +4 -4
  21. package/dist/{DeleteItemModal-B2nJmjsP.js.map → DeleteItemModal-mMzy3V8o.js.map} +1 -1
  22. package/dist/{DisclaimerModal-D5FO34u9.js → DisclaimerModal-DvpD5dPM.js} +3 -3
  23. package/dist/{DisclaimerModal-D5FO34u9.js.map → DisclaimerModal-DvpD5dPM.js.map} +1 -1
  24. package/dist/DocumentVersionUnsupportedModal-C3Q0V75l.js +32 -0
  25. package/dist/DocumentVersionUnsupportedModal-C3Q0V75l.js.map +1 -0
  26. package/dist/{DownloadDocumentWithErrorsModal-tEr3bbtN.js → DownloadDocumentWithErrorsModal-IKl0ljQb.js} +3 -3
  27. package/dist/{DownloadDocumentWithErrorsModal-tEr3bbtN.js.map → DownloadDocumentWithErrorsModal-IKl0ljQb.js.map} +1 -1
  28. package/dist/DriveAuthRequiredModal-Cw9eCAQ_.js +36 -0
  29. package/dist/DriveAuthRequiredModal-Cw9eCAQ_.js.map +1 -0
  30. package/dist/{DriveSettingsModal-kR3hQnh4.js → DriveSettingsModal-C6-mRQiv.js} +3 -3
  31. package/dist/{DriveSettingsModal-kR3hQnh4.js.map → DriveSettingsModal-C6-mRQiv.js.map} +1 -1
  32. package/dist/{InspectorModal-BfwRytsl.js → InspectorModal-Fnp57gG_.js} +6 -6
  33. package/dist/{InspectorModal-BfwRytsl.js.map → InspectorModal-Fnp57gG_.js.map} +1 -1
  34. package/dist/LoginModal-CybbOm3N.js +75 -0
  35. package/dist/LoginModal-CybbOm3N.js.map +1 -0
  36. package/dist/{MissingPackageModal-BQcCQbOn.js → MissingPackageModal-C7usWVHQ.js} +18 -6
  37. package/dist/MissingPackageModal-C7usWVHQ.js.map +1 -0
  38. package/dist/OpenFileDocumentsModal-Bp2SFfGY.js +311 -0
  39. package/dist/OpenFileDocumentsModal-Bp2SFfGY.js.map +1 -0
  40. package/dist/SettingsModal-BKyrRL4W.js +568 -0
  41. package/dist/SettingsModal-BKyrRL4W.js.map +1 -0
  42. package/dist/{UpgradeDriveModal-BZGSE9_r.js → UpgradeDriveModal-_8t9slxQ.js} +3 -3
  43. package/dist/{UpgradeDriveModal-BZGSE9_r.js.map → UpgradeDriveModal-_8t9slxQ.js.map} +1 -1
  44. package/dist/app-loader-1ACi7O7G.js +4 -0
  45. package/dist/{app-loader-BqH5S4gP.js → app-loader-9oxJxBSC.js} +839 -560
  46. package/dist/app-loader-9oxJxBSC.js.map +1 -0
  47. package/dist/build-info-Ck0vFY36.js +28 -0
  48. package/dist/build-info-Ck0vFY36.js.map +1 -0
  49. package/dist/components-C5E86_ow.js +4 -0
  50. package/dist/{connect.config-vgUeFoNp.js → connect.config-DaHDEUrw.js} +13 -7
  51. package/dist/connect.config-DaHDEUrw.js.map +1 -0
  52. package/dist/{connection-state-DO_2lAEJ.js → connection-state-3w4liC1X.js} +4 -4
  53. package/dist/{connection-state-DO_2lAEJ.js.map → connection-state-3w4liC1X.js.map} +1 -1
  54. package/dist/cookie-banner-BH6bIq24.js +70 -0
  55. package/dist/cookie-banner-BH6bIq24.js.map +1 -0
  56. package/dist/{reload-connect-toast-D1Iqw9E_.js → i18n-CWO0vYVd.js} +23 -30
  57. package/dist/i18n-CWO0vYVd.js.map +1 -0
  58. package/dist/load-CvwtlhbX.js +131 -0
  59. package/dist/load-CvwtlhbX.js.map +1 -0
  60. package/dist/main.js +1 -1
  61. package/dist/{pglite-seed-z3B1JA38.js → pglite-seed-BqAUvNFw.js} +4 -4
  62. package/dist/{pglite-seed-z3B1JA38.js.map → pglite-seed-BqAUvNFw.js.map} +1 -1
  63. package/dist/preferences-store-_5Cw4_YV.js +104 -0
  64. package/dist/preferences-store-_5Cw4_YV.js.map +1 -0
  65. package/dist/pwa-manifest-link-DIgOSo2Q.js +34 -0
  66. package/dist/pwa-manifest-link-DIgOSo2Q.js.map +1 -0
  67. package/dist/{reactor-ynguOpe7.js → reactor-CrKlyk9q.js} +240 -67
  68. package/dist/reactor-CrKlyk9q.js.map +1 -0
  69. package/dist/reactor.worker.js +11 -6
  70. package/dist/reactor.worker.js.map +1 -1
  71. package/dist/{registerServiceWorker-nJIc0yEY.js → registerServiceWorker-BSzbNfvz.js} +6 -4
  72. package/dist/registerServiceWorker-BSzbNfvz.js.map +1 -0
  73. package/dist/sentry-QXKgQmr2.js +15 -0
  74. package/dist/sentry-QXKgQmr2.js.map +1 -0
  75. package/dist/start-connect.js +1 -1
  76. package/dist/style.css +243 -7
  77. package/dist/{toast-4t-VimvD.js → toast-BXIGd4Eb.js} +8 -5
  78. package/dist/toast-BXIGd4Eb.js.map +1 -0
  79. package/dist/use-renown-login-Cf3va6u_.js +52 -0
  80. package/dist/use-renown-login-Cf3va6u_.js.map +1 -0
  81. package/dist/useRegistryPackages-DMhCvTWq.js +314 -0
  82. package/dist/useRegistryPackages-DMhCvTWq.js.map +1 -0
  83. package/package.json +19 -13
  84. package/public/powerhouse.config.json +3 -0
  85. package/style.css +1 -0
  86. package/dist/AddDriveModal-MMHlkJBJ.js.map +0 -1
  87. package/dist/CreateDocumentModal-CvsTh0HM.js.map +0 -1
  88. package/dist/DriveAuthRequiredModal-BA2vS3oF.js +0 -40
  89. package/dist/DriveAuthRequiredModal-BA2vS3oF.js.map +0 -1
  90. package/dist/MissingPackageModal-BQcCQbOn.js.map +0 -1
  91. package/dist/SettingsModal-CdoFxyJJ.js +0 -289
  92. package/dist/SettingsModal-CdoFxyJJ.js.map +0 -1
  93. package/dist/app-loader-BqH5S4gP.js.map +0 -1
  94. package/dist/app-loader-J8Z4QAD5.js +0 -4
  95. package/dist/build-info-AUWI7jOw.js +0 -18
  96. package/dist/build-info-AUWI7jOw.js.map +0 -1
  97. package/dist/components-B6-PFL8z.js +0 -5
  98. package/dist/connect.config-vgUeFoNp.js.map +0 -1
  99. package/dist/load-BucYuvxH.js +0 -100
  100. package/dist/load-BucYuvxH.js.map +0 -1
  101. package/dist/package-BcKQ9BGX.js +0 -127
  102. package/dist/package-BcKQ9BGX.js.map +0 -1
  103. package/dist/reactor-ynguOpe7.js.map +0 -1
  104. package/dist/registerServiceWorker-nJIc0yEY.js.map +0 -1
  105. package/dist/reload-connect-toast-D1Iqw9E_.js.map +0 -1
  106. package/dist/toast-4t-VimvD.js.map +0 -1
  107. package/dist/useRegistryPackages-BaYtekjQ.js +0 -179
  108. package/dist/useRegistryPackages-BaYtekjQ.js.map +0 -1
@@ -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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@powerhousedao/connect",
3
3
  "productName": "Powerhouse-Connect",
4
- "version": "6.2.2-dev.9",
4
+ "version": "6.2.2-staging.0",
5
5
  "description": "Powerhouse Connect",
6
6
  "main": "dist/index.html",
7
7
  "type": "module",
@@ -55,8 +55,22 @@
55
55
  "@openfeature/core": "1.9.1",
56
56
  "@openfeature/web-sdk": "1.6.2",
57
57
  "@openpanel/web": "^1.4.1",
58
+ "@powerhousedao/config": "6.2.2-staging.0",
59
+ "@powerhousedao/design-system": "6.2.2-staging.0",
58
60
  "@powerhousedao/document-engineering": "1.40.5",
61
+ "@powerhousedao/powerhouse-vetra-packages": "6.2.2-staging.0",
62
+ "@powerhousedao/reactor": "6.2.2-staging.0",
63
+ "@powerhousedao/reactor-attachments": "6.2.2-staging.0",
64
+ "@powerhousedao/reactor-browser": "6.2.2-staging.0",
65
+ "@powerhousedao/reactor-mcp": "6.2.2-staging.0",
66
+ "@powerhousedao/shared": "6.2.2-staging.0",
67
+ "@powerhousedao/vetra": "6.2.2-staging.0",
68
+ "@privy-io/react-auth": "3.35.0",
69
+ "@rainbow-me/rainbowkit": "^2.2.11",
70
+ "@renown/sdk": "6.2.2-staging.0",
59
71
  "@sentry/react": "^10.17.0",
72
+ "@tanstack/react-query": "^5.90.2",
73
+ "document-model": "6.2.2-staging.0",
60
74
  "i18next": "^25.5.3",
61
75
  "kysely": "0.28.16",
62
76
  "kysely-pglite-dialect": "1.2.0",
@@ -69,19 +83,11 @@
69
83
  "react-router-dom": "^6.11.2",
70
84
  "tailwind-merge": "3.4.0",
71
85
  "usehooks-ts": "^3.1.1",
72
- "zod": "4.3.6",
73
- "@powerhousedao/config": "6.2.2-dev.9",
74
- "@powerhousedao/design-system": "6.2.2-dev.9",
75
- "@powerhousedao/powerhouse-vetra-packages": "6.2.2-dev.9",
76
- "@powerhousedao/reactor": "6.2.2-dev.9",
77
- "@powerhousedao/reactor-attachments": "6.2.2-dev.9",
78
- "@powerhousedao/reactor-browser": "6.2.2-dev.9",
79
- "@powerhousedao/shared": "6.2.2-dev.9",
80
- "@powerhousedao/vetra": "6.2.2-dev.9",
81
- "@renown/sdk": "6.2.2-dev.9",
82
- "document-model": "6.2.2-dev.9"
86
+ "wagmi": "2.19.5",
87
+ "zod": "4.3.6"
83
88
  },
84
89
  "devDependencies": {
90
+ "cross-env": "10.1.0",
85
91
  "@tailwindcss/cli": "4.2.2",
86
92
  "@tailwindcss/vite": "4.2.2",
87
93
  "@testing-library/dom": "^10.4.0",
@@ -114,7 +120,7 @@
114
120
  "build": "pnpm run build:bundle && pnpm run build:css",
115
121
  "build:bundle": "tsdown",
116
122
  "build:css": "pnpm exec tailwindcss -i style.css -o dist/style.css",
117
- "build:debug": "PH_DEBUG_BUILD=true vite build",
123
+ "build:debug": "cross-env PH_DEBUG_BUILD=true vite build",
118
124
  "preview": "vite preview",
119
125
  "cy:open": "cypress open",
120
126
  "docker:build": "docker build -f ./Dockerfile --tag connect-test-dev --build-arg TAG=dev .",
@@ -28,6 +28,9 @@
28
28
  "url": "https://www.renown.id",
29
29
  "networkId": "eip155",
30
30
  "chainId": 1
31
+ },
32
+ "ai": {
33
+ "assistantEnabled": true
31
34
  }
32
35
  }
33
36
  }
package/style.css CHANGED
@@ -16,6 +16,7 @@
16
16
  their classes are included in the compiled output. Tailwind does not scan
17
17
  node_modules by default, so each workspace package needs an explicit @source. */
18
18
  @source "../../packages/design-system/src/**/*.{tsx,ts}";
19
+ @source "../../packages/reactor-browser/src/ai/**/*.{tsx,ts}";
19
20
  @source "../../packages/powerhouse-vetra-packages/**/*.{tsx,ts}";
20
21
  @source "../../packages/vetra/**/*.{tsx,ts}";
21
22
 
@@ -1 +0,0 @@
1
- {"version":3,"file":"AddDriveModal-MMHlkJBJ.js","sources":["../src/utils/create-drive-app-options.ts","../src/components/modal/modals/AddDriveModal.tsx"],"sourcesContent":["import type { AppOptions } from \"@powerhousedao/design-system/connect\";\nimport type { EditorModule } from \"document-model\";\n\n// Create Drive picker order: installed/custom apps first (rank 0), then the\n// generic explorer, then the vetra drive app last.\nconst DRIVE_APP_RANK: Record<string, number> = {\n GenericDriveExplorer: 1,\n \"vetra-drive-app\": 2,\n};\n\nexport function getCreateDriveAppOptions(\n appModules: EditorModule[] | undefined,\n): AppOptions[] {\n if (!appModules?.length) {\n return [];\n }\n\n return appModules\n .map((pkg) => ({\n id: pkg.config.id,\n name: pkg.config.name,\n sharingType: \"LOCAL\" as const,\n availableOffline: false,\n }))\n .sort((a, b) => (DRIVE_APP_RANK[a.id] ?? 0) - (DRIVE_APP_RANK[b.id] ?? 0));\n}\n","import { toast } from \"@powerhousedao/connect/services\";\nimport type {\n AddRemoteDriveInput,\n AppOptions,\n} from \"@powerhousedao/design-system/connect\";\nimport { AddDriveModal as ConnectAddLocalDriveModal } from \"@powerhousedao/design-system/connect\";\nimport {\n addDrive,\n addRemoteDrive,\n closePHModal,\n extractDriveSlugFromPath,\n getDrives,\n setSelectedDrive,\n useAppModules,\n usePHModal,\n useRenown,\n useUser,\n waitForDocumentReady,\n} from \"@powerhousedao/reactor-browser\";\nimport { t } from \"i18next\";\nimport { getCreateDriveAppOptions } from \"../../../utils/create-drive-app-options.js\";\n\n// Max wait for a remote drive's initial sync before skipping navigation.\n// Safe to be generous: navigation only fires if the user is still on home.\nconst REMOTE_DRIVE_NAV_TIMEOUT_MS = 30_000;\n\nasync function requestPublicDriveFromReactor(\n url: string,\n headers?: Record<string, string>,\n): Promise<{ id: string; name: string }> {\n const response = await fetch(url, { headers: headers ?? {} });\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}`);\n }\n return (await response.json()) as { id: string; name: string };\n}\n\nexport function AddDriveModal() {\n const phModal = usePHModal();\n const open = phModal?.type === \"addDrive\";\n const user = useUser();\n const renown = useRenown();\n const appModules = useAppModules();\n const onAddLocalDrive = async (data: AppOptions) => {\n try {\n const app = appModules?.find((a) => a.config.id === data.id);\n const newDrive = await addDrive(\n {\n id: \"\",\n slug: \"\",\n global: {\n name: data.name,\n icon: null,\n },\n local: {\n availableOffline: data.availableOffline,\n sharingType: data.sharingType.toLowerCase(),\n listeners: [],\n triggers: [],\n },\n },\n app?.config.id,\n );\n\n toast(t(\"notifications.addDriveSuccess\"), {\n type: \"connect-success\",\n });\n\n if (!newDrive) {\n return;\n }\n\n setSelectedDrive(newDrive);\n } catch (e) {\n console.error(e);\n }\n };\n\n const onAddRemoteDrive = async (data: AddRemoteDriveInput) => {\n try {\n const driveId = await addRemoteDrive(data.url, data.id);\n\n toast(t(\"notifications.addDriveSuccess\"), {\n type: \"connect-success\",\n });\n\n // Navigate into the drive if its initial sync lands in time.\n // Not awaited so the modal closes immediately.\n const reactorClient = window.ph?.reactorClient;\n // Only a still unselected, un-pinned (home) view gets pulled into the\n // new drive — the user may have navigated elsewhere meanwhile.\n const stillOnHome = () =>\n !window.ph?.selectedDriveId &&\n !extractDriveSlugFromPath(window.location.pathname);\n void (async () => {\n try {\n if (!reactorClient) {\n return;\n }\n await waitForDocumentReady(reactorClient, driveId, {\n timeoutMs: REMOTE_DRIVE_NAV_TIMEOUT_MS,\n });\n const drives = await getDrives(reactorClient);\n const drive = drives.find((d) => d.header.id === driveId);\n if (drive && stillOnHome()) {\n setSelectedDrive(drive);\n }\n } catch {\n // sync still in flight — the drive shows up on home once it lands\n }\n })();\n } catch (e) {\n console.error(e);\n }\n };\n async function onAddLocalDriveSubmit(data: AppOptions) {\n await onAddLocalDrive(data);\n closePHModal();\n }\n\n async function onAddRemoteDriveSubmit(data: AddRemoteDriveInput) {\n await onAddRemoteDrive(data);\n closePHModal();\n }\n\n const ready = !!appModules?.length;\n\n return (\n <ConnectAddLocalDriveModal\n open={open && ready}\n onAddLocalDrive={(data) => {\n void onAddLocalDriveSubmit(data);\n }}\n onAddRemoteDrive={(data) => {\n void onAddRemoteDriveSubmit(data);\n }}\n requestPublicDrive={async (url: string) => {\n try {\n if (user) {\n // aud omitted: server verifies without an audience, so aud-bearing\n // tokens are rejected. Re-enable once both sides support it.\n const authToken = await renown?.getBearerToken?.({\n expiresIn: 10,\n });\n return requestPublicDriveFromReactor(url, {\n Authorization: `Bearer ${authToken}`,\n });\n }\n return requestPublicDriveFromReactor(url);\n } catch (error) {\n console.error(error);\n return requestPublicDriveFromReactor(url);\n }\n }}\n onOpenChange={(status) => {\n if (!status) return closePHModal();\n }}\n appOptions={getCreateDriveAppOptions(appModules)}\n />\n );\n}\n"],"names":["ConnectAddLocalDriveModal"],"mappings":"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","debug_id":"2617b9d1-eb4b-5a51-aaa8-28a0c8de951f"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"CreateDocumentModal-CvsTh0HM.js","sources":["../src/components/modal/modals/CreateDocumentModal.tsx"],"sourcesContent":["import { CreateDocumentModal as ConnectCreateDocumentModal } from \"@powerhousedao/design-system/connect\";\nimport {\n addDocument,\n closePHModal,\n setSelectedNode,\n useDocumentModelModuleById,\n useParentFolderForSelectedNode,\n usePHModal,\n useSelectedDriveSafe,\n useSelectedFolder,\n} from \"@powerhousedao/reactor-browser\";\n\nexport const CreateDocumentModal: React.FC = () => {\n const phModal = usePHModal();\n const open = phModal?.type === \"createDocument\";\n const documentType = open ? phModal.documentType : undefined;\n const documentModel = useDocumentModelModuleById(documentType);\n const [selectedDrive] = useSelectedDriveSafe();\n const selectedFolder = useSelectedFolder();\n const parentFolder = useParentFolderForSelectedNode();\n\n const onCreateDocument = async (documentName: string) => {\n closePHModal();\n if (!selectedDrive || !documentModel) return;\n\n const node = await addDocument(\n selectedDrive.header.id,\n documentName || `New ${documentModel.documentModel.global.name}`,\n documentModel.documentModel.global.id,\n selectedFolder?.id ?? parentFolder?.id,\n );\n setSelectedNode(node);\n };\n\n return (\n <ConnectCreateDocumentModal\n open={open}\n onContinue={(documentName) => {\n void onCreateDocument(documentName);\n }}\n onOpenChange={(status: boolean) => {\n if (!status) return closePHModal();\n }}\n />\n );\n};\n"],"names":["ConnectCreateDocumentModal"],"mappings":";;;;;;AAYA,MAAa,4BAAsC;CACjD,MAAM,UAAU,YAAY;CAC5B,MAAM,OAAO,SAAS,SAAS;CAE/B,MAAM,gBAAgB,2BADD,OAAO,QAAQ,eAAe,KAAA,EACW;CAC9D,MAAM,CAAC,iBAAiB,sBAAsB;CAC9C,MAAM,iBAAiB,mBAAmB;CAC1C,MAAM,eAAe,gCAAgC;CAErD,MAAM,mBAAmB,OAAO,iBAAyB;AACvD,gBAAc;AACd,MAAI,CAAC,iBAAiB,CAAC,cAAe;AAQtC,kBANa,MAAM,YACjB,cAAc,OAAO,IACrB,gBAAgB,OAAO,cAAc,cAAc,OAAO,QAC1D,cAAc,cAAc,OAAO,IACnC,gBAAgB,MAAM,cAAc,GACrC,CACoB;;AAGvB,QACE,oBAACA,uBAAD;EACQ;EACN,aAAa,iBAAiB;AACvB,oBAAiB,aAAa;;EAErC,eAAe,WAAoB;AACjC,OAAI,CAAC,OAAQ,QAAO,cAAc;;EAEpC,CAAA","debug_id":"548b8231-1690-5079-a2ae-e1750ed41a1f"}
@@ -1,40 +0,0 @@
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]="90682003-4d6a-5ec2-8433-28fdb17530a3")}catch(e){}}();
3
- import { jsx } from "react/jsx-runtime";
4
- import "react";
5
- import { logout, openRenown, usePHModal, useUser } from "@powerhousedao/reactor-browser";
6
- import { DriveAuthGate } from "@powerhousedao/design-system/connect";
7
- //#region src/components/modal/modals/DriveAuthRequiredModal.tsx
8
- /**
9
- * Shown when a protected drive can't be added because the user isn't logged in.
10
- *
11
- * Deliberately NOT a Radix modal dialog: a modal dialog blocks all outside
12
- * interaction, which would trap the cookie banner (rendered above at z-10000)
13
- * and prevent accepting/rejecting it. Instead this is a non-blocking overlay —
14
- * `pointer-events-none` on the backdrop (so the banner and page stay clickable)
15
- * with `pointer-events-auto` on the card — sitting below the cookie banner. The
16
- * card itself is the shared {@link DriveAuthGate}, identical to the full-page
17
- * gate. It stays up until login (the Renown CTA full-page-redirects).
18
- */
19
- const DriveAuthRequiredModal = () => {
20
- const phModal = usePHModal();
21
- const mode = useUser() ? "unauthorized" : "login";
22
- if (phModal?.type !== "driveAuthRequired") return null;
23
- return /* @__PURE__ */ jsx("div", {
24
- role: "dialog",
25
- "aria-modal": "false",
26
- "aria-label": mode === "unauthorized" ? "You don't have access to this drive" : "Log in to access this drive",
27
- className: "pointer-events-none fixed inset-0 z-50 grid place-items-center bg-primary/30",
28
- children: /* @__PURE__ */ jsx(DriveAuthGate, {
29
- mode,
30
- onLogin: () => openRenown(),
31
- onLogout: () => void logout(),
32
- className: "pointer-events-auto"
33
- })
34
- });
35
- };
36
- //#endregion
37
- export { DriveAuthRequiredModal };
38
-
39
- //# sourceMappingURL=DriveAuthRequiredModal-BA2vS3oF.js.map
40
- //# debugId=90682003-4d6a-5ec2-8433-28fdb17530a3
@@ -1 +0,0 @@
1
- {"version":3,"file":"DriveAuthRequiredModal-BA2vS3oF.js","sources":["../src/components/modal/modals/DriveAuthRequiredModal.tsx"],"sourcesContent":["import { DriveAuthGate } from \"@powerhousedao/design-system/connect\";\nimport {\n logout,\n openRenown,\n usePHModal,\n useUser,\n} from \"@powerhousedao/reactor-browser\";\nimport React from \"react\";\n\n/**\n * Shown when a protected drive can't be added because the user isn't logged in.\n *\n * Deliberately NOT a Radix modal dialog: a modal dialog blocks all outside\n * interaction, which would trap the cookie banner (rendered above at z-10000)\n * and prevent accepting/rejecting it. Instead this is a non-blocking overlay —\n * `pointer-events-none` on the backdrop (so the banner and page stay clickable)\n * with `pointer-events-auto` on the card — sitting below the cookie banner. The\n * card itself is the shared {@link DriveAuthGate}, identical to the full-page\n * gate. It stays up until login (the Renown CTA full-page-redirects).\n */\nexport const DriveAuthRequiredModal: React.FC = () => {\n const phModal = usePHModal();\n const user = useUser();\n const mode = user ? \"unauthorized\" : \"login\";\n if (phModal?.type !== \"driveAuthRequired\") return null;\n\n return (\n <div\n role=\"dialog\"\n aria-modal=\"false\"\n aria-label={\n mode === \"unauthorized\"\n ? \"You don't have access to this drive\"\n : \"Log in to access this drive\"\n }\n className=\"pointer-events-none fixed inset-0 z-50 grid place-items-center bg-primary/30\"\n >\n <DriveAuthGate\n mode={mode}\n onLogin={() => openRenown()}\n onLogout={() => void logout()}\n className=\"pointer-events-auto\"\n />\n </div>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAoBA,MAAa,+BAAyC;CACpD,MAAM,UAAU,YAAY;CAE5B,MAAM,OADO,SAAS,GACF,iBAAiB;AACrC,KAAI,SAAS,SAAS,oBAAqB,QAAO;AAElD,QACE,oBAAC,OAAD;EACE,MAAK;EACL,cAAW;EACX,cACE,SAAS,iBACL,wCACA;EAEN,WAAU;YAEV,oBAAC,eAAD;GACQ;GACN,eAAe,YAAY;GAC3B,gBAAgB,KAAK,QAAQ;GAC7B,WAAU;GACV,CAAA;EACE,CAAA","debug_id":"90682003-4d6a-5ec2-8433-28fdb17530a3"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"MissingPackageModal-BQcCQbOn.js","sources":["../src/components/modal/modals/MissingPackageModal.tsx"],"sourcesContent":["import { useRegistryPackages } from \"@powerhousedao/connect/hooks\";\nimport {\n PackageInstallModal,\n type PendingPackageInstallation,\n} from \"@powerhousedao/design-system/connect\";\nimport {\n closePHModal,\n usePHModal,\n useVetraPackageManager,\n} from \"@powerhousedao/reactor-browser\";\n\nexport function ConnectMissingPackageModal() {\n const phModal = usePHModal();\n const { registryPackageList, updateRegistryPackageStatus } =\n useRegistryPackages();\n const packageManager = useVetraPackageManager();\n const open = phModal?.type === \"missingPackage\";\n\n const documentType = open ? phModal.documentType : undefined;\n\n if (!packageManager || !documentType) return null;\n\n const pendingInstallations: PendingPackageInstallation[] = registryPackageList\n .filter((rp) => rp.documentTypes.includes(documentType))\n .map((rp) => ({\n documentType,\n packageName: rp.name,\n }));\n\n async function onInstall(packageName: string) {\n const result = await packageManager?.addPackage(packageName);\n if (result?.type === \"success\") {\n updateRegistryPackageStatus(packageName, \"registry-install\");\n }\n }\n\n function onDismiss(packageName: string) {\n updateRegistryPackageStatus(packageName, \"dismissed\");\n }\n\n return (\n <PackageInstallModal\n pendingInstallations={pendingInstallations}\n onInstall={onInstall}\n onDismiss={onDismiss}\n onOpenChange={(status: boolean) => {\n if (!status) return closePHModal();\n }}\n />\n );\n}\n"],"names":[],"mappings":";;;;;;;AAWA,SAAgB,6BAA6B;CAC3C,MAAM,UAAU,YAAY;CAC5B,MAAM,EAAE,qBAAqB,gCAC3B,qBAAqB;CACvB,MAAM,iBAAiB,wBAAwB;CAG/C,MAAM,eAFO,SAAS,SAAS,mBAEH,QAAQ,eAAe,KAAA;AAEnD,KAAI,CAAC,kBAAkB,CAAC,aAAc,QAAO;CAE7C,MAAM,uBAAqD,oBACxD,QAAQ,OAAO,GAAG,cAAc,SAAS,aAAa,CAAC,CACvD,KAAK,QAAQ;EACZ;EACA,aAAa,GAAG;EACjB,EAAE;CAEL,eAAe,UAAU,aAAqB;AAE5C,OADe,MAAM,gBAAgB,WAAW,YAAY,GAChD,SAAS,UACnB,6BAA4B,aAAa,mBAAmB;;CAIhE,SAAS,UAAU,aAAqB;AACtC,8BAA4B,aAAa,YAAY;;AAGvD,QACE,oBAAC,qBAAD;EACwB;EACX;EACA;EACX,eAAe,WAAoB;AACjC,OAAI,CAAC,OAAQ,QAAO,cAAc;;EAEpC,CAAA","debug_id":"bd7d533f-489c-56c6-b228-c4fb25a21177"}