@powerhousedao/connect 6.2.2-dev.11 → 6.2.2-dev.13

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 (66) hide show
  1. package/dist/{AddDriveModal-B_Oft9Cv.js → AddDriveModal-Cy4_b0wO.js} +3 -3
  2. package/dist/{AddDriveModal-B_Oft9Cv.js.map → AddDriveModal-Cy4_b0wO.js.map} +1 -1
  3. package/dist/{ClearStorageModal-DKxn1Qxa.js → ClearStorageModal-D8TkbUFu.js} +4 -4
  4. package/dist/{ClearStorageModal-DKxn1Qxa.js.map → ClearStorageModal-D8TkbUFu.js.map} +1 -1
  5. package/dist/{CookiesPolicyModal-CYFTfkEN.js → CookiesPolicyModal-Dpx-2TgP.js} +3 -3
  6. package/dist/{CookiesPolicyModal-CYFTfkEN.js.map → CookiesPolicyModal-Dpx-2TgP.js.map} +1 -1
  7. package/dist/{CreateDocumentModal-Dmg3R-Vh.js → CreateDocumentModal-u-IaJUQ0.js} +3 -3
  8. package/dist/{CreateDocumentModal-Dmg3R-Vh.js.map → CreateDocumentModal-u-IaJUQ0.js.map} +1 -1
  9. package/dist/{DebugSettingsModal-DUNPkZoc.js → DebugSettingsModal-Dzvgz9f_.js} +6 -6
  10. package/dist/{DebugSettingsModal-DUNPkZoc.js.map → DebugSettingsModal-Dzvgz9f_.js.map} +1 -1
  11. package/dist/{DeleteDriveModal-CzRPqyMf.js → DeleteDriveModal-CJKhWtli.js} +3 -3
  12. package/dist/{DeleteDriveModal-CzRPqyMf.js.map → DeleteDriveModal-CJKhWtli.js.map} +1 -1
  13. package/dist/{DeleteItemModal-CaCrmQOG.js → DeleteItemModal-DiieJw_o.js} +3 -3
  14. package/dist/{DeleteItemModal-CaCrmQOG.js.map → DeleteItemModal-DiieJw_o.js.map} +1 -1
  15. package/dist/{DisclaimerModal-D5Jhefcc.js → DisclaimerModal-DAvYIF9-.js} +3 -3
  16. package/dist/{DisclaimerModal-D5Jhefcc.js.map → DisclaimerModal-DAvYIF9-.js.map} +1 -1
  17. package/dist/{DownloadDocumentWithErrorsModal-ZuX8WDCC.js → DownloadDocumentWithErrorsModal-CE4fa1k5.js} +3 -3
  18. package/dist/{DownloadDocumentWithErrorsModal-ZuX8WDCC.js.map → DownloadDocumentWithErrorsModal-CE4fa1k5.js.map} +1 -1
  19. package/dist/DriveAuthRequiredModal-DSM6uNlb.js +36 -0
  20. package/dist/DriveAuthRequiredModal-DSM6uNlb.js.map +1 -0
  21. package/dist/{DriveSettingsModal-VNpuhty1.js → DriveSettingsModal-CqFeWu4r.js} +3 -3
  22. package/dist/{DriveSettingsModal-VNpuhty1.js.map → DriveSettingsModal-CqFeWu4r.js.map} +1 -1
  23. package/dist/{InspectorModal-B7wmgMfE.js → InspectorModal-BR0x5ZLQ.js} +6 -6
  24. package/dist/{InspectorModal-B7wmgMfE.js.map → InspectorModal-BR0x5ZLQ.js.map} +1 -1
  25. package/dist/LoginModal-BGTKLJx0.js +75 -0
  26. package/dist/LoginModal-BGTKLJx0.js.map +1 -0
  27. package/dist/{MissingPackageModal-D4V6oYzy.js → MissingPackageModal-C3acJ9r0.js} +3 -3
  28. package/dist/{MissingPackageModal-D4V6oYzy.js.map → MissingPackageModal-C3acJ9r0.js.map} +1 -1
  29. package/dist/{OpenFileDocumentsModal-DCrZnA6c.js → OpenFileDocumentsModal-BhSWuzik.js} +4 -4
  30. package/dist/{OpenFileDocumentsModal-DCrZnA6c.js.map → OpenFileDocumentsModal-BhSWuzik.js.map} +1 -1
  31. package/dist/{SettingsModal-BsYFJB2W.js → SettingsModal-CeSSSHVv.js} +6 -6
  32. package/dist/{SettingsModal-BsYFJB2W.js.map → SettingsModal-CeSSSHVv.js.map} +1 -1
  33. package/dist/{UpgradeDriveModal-Ul4tyz-Q.js → UpgradeDriveModal-rUHyJTc7.js} +3 -3
  34. package/dist/{UpgradeDriveModal-Ul4tyz-Q.js.map → UpgradeDriveModal-rUHyJTc7.js.map} +1 -1
  35. package/dist/{app-loader-DG_ohYMb.js → app-loader-Bjt8BAsA.js} +60 -28
  36. package/dist/app-loader-Bjt8BAsA.js.map +1 -0
  37. package/dist/app-loader-DQIfi-9s.js +4 -0
  38. package/dist/{build-info-Do0SMo9O.js → build-info-BcBkHhsx.js} +5 -5
  39. package/dist/{build-info-Do0SMo9O.js.map → build-info-BcBkHhsx.js.map} +1 -1
  40. package/dist/{components-BDpsXnOO.js → components-CpA7UNBZ.js} +3 -3
  41. package/dist/{connect.config-vgUeFoNp.js → connect.config-C-b_Yhd6.js} +9 -4
  42. package/dist/connect.config-C-b_Yhd6.js.map +1 -0
  43. package/dist/{connection-state-xPSbZ_4J.js → connection-state-KCa1yljA.js} +4 -4
  44. package/dist/{connection-state-xPSbZ_4J.js.map → connection-state-KCa1yljA.js.map} +1 -1
  45. package/dist/{load-y7fD2Bfj.js → load-BfbcYZLT.js} +8 -8
  46. package/dist/{load-y7fD2Bfj.js.map → load-BfbcYZLT.js.map} +1 -1
  47. package/dist/main.js +1 -1
  48. package/dist/{package-Bc_Nktb7.js → package-B1sniFBZ.js} +8 -4
  49. package/dist/package-B1sniFBZ.js.map +1 -0
  50. package/dist/{pglite-seed-DRYYEWUq.js → pglite-seed-DRXPe7p-.js} +4 -4
  51. package/dist/{pglite-seed-DRYYEWUq.js.map → pglite-seed-DRXPe7p-.js.map} +1 -1
  52. package/dist/{reactor-BzjtiHGa.js → reactor-h5C3JTSU.js} +8 -7
  53. package/dist/{reactor-BzjtiHGa.js.map → reactor-h5C3JTSU.js.map} +1 -1
  54. package/dist/{registerServiceWorker-uI4Gj6fl.js → registerServiceWorker-Bn1KWmk0.js} +4 -4
  55. package/dist/{registerServiceWorker-uI4Gj6fl.js.map → registerServiceWorker-Bn1KWmk0.js.map} +1 -1
  56. package/dist/start-connect.js +1 -1
  57. package/dist/style.css +48 -0
  58. package/dist/use-renown-login-DBujbqs8.js +55 -0
  59. package/dist/use-renown-login-DBujbqs8.js.map +1 -0
  60. package/package.json +15 -11
  61. package/dist/DriveAuthRequiredModal-CPV5uXnf.js +0 -40
  62. package/dist/DriveAuthRequiredModal-CPV5uXnf.js.map +0 -1
  63. package/dist/app-loader-DG_ohYMb.js.map +0 -1
  64. package/dist/app-loader-aQ0Wk8uH.js +0 -4
  65. package/dist/connect.config-vgUeFoNp.js.map +0 -1
  66. package/dist/package-Bc_Nktb7.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"InspectorModal-B7wmgMfE.js","sources":["../src/components/modal/modals/InspectorModal/useDbExplorer.ts","../src/components/modal/modals/InspectorModal/useDebugInspector.ts","../src/components/modal/modals/InspectorModal/useIntegrityInspector.ts","../src/components/modal/modals/InspectorModal/useProcessorsInspector.ts","../src/components/modal/modals/InspectorModal/useQueueInspector.ts","../src/components/modal/modals/InspectorModal/useRemotesInspector.ts","../src/components/modal/modals/InspectorModal/useWorkerInspector.ts","../src/components/modal/modals/InspectorModal/InspectorModal.tsx"],"sourcesContent":["import type { PGlite } from \"@electric-sql/pglite\";\nimport {\n getCachedReactorPgMajor,\n loadPgDump,\n resolvePgMajorForRuntime,\n} from \"@powerhousedao/connect/utils\";\nimport type {\n FilterGroup,\n SortOptions,\n} from \"@powerhousedao/design-system/connect\";\nimport type { Database } from \"@powerhousedao/reactor\";\nimport {\n REACTOR_SCHEMA,\n useDatabase,\n usePGlite,\n useReactorClientModule,\n type IQueue,\n} from \"@powerhousedao/reactor-browser\";\nimport type { IInspectorProxy } from \"@powerhousedao/reactor-browser/rpc\";\nimport { Kysely, sql } from \"kysely\";\nimport { PGliteDialect } from \"kysely-pglite-dialect\";\nimport { useCallback, useMemo } from \"react\";\n\nasync function quiesceQueue(queue: IQueue): Promise<void> {\n await new Promise<void>((resolve) => queue.block(() => resolve()));\n}\n\n// The reactor runs with `relaxedDurability: true`, which makes PGlite's\n// `syncToFs()` fire the IDBFS→IndexedDB write and return without awaiting\n// Emscripten's syncfs callback. `close()` also doesn't flush. Calling\n// `FS.syncfs(false, cb)` directly gives us a callback that fires from the\n// IDBFS transaction's `oncomplete` — i.e. after IDB has actually committed.\nasync function syncPgliteToIdb(pglite: {\n readonly Module: {\n readonly FS: {\n syncfs(populate: boolean, cb: (err: Error | null) => void): void;\n };\n };\n}): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n pglite.Module.FS.syncfs(false, (err) => (err ? reject(err) : resolve()));\n });\n}\n\ntype ColumnInfo = {\n readonly name: string;\n readonly dataType: string;\n readonly isNullable: boolean;\n};\n\ntype TableInfo = {\n readonly name: string;\n readonly columns: ColumnInfo[];\n};\n\ntype ColumnRow = {\n table_name: string;\n column_name: string;\n data_type: string;\n is_nullable: string;\n};\n\ntype GetTableRowsOptions = {\n readonly schema?: string;\n readonly limit: number;\n readonly offset: number;\n readonly sort?: SortOptions;\n readonly filters?: FilterGroup;\n};\n\ntype TablePage = {\n readonly columns: string[];\n readonly rows: Record<string, unknown>[];\n readonly total: number | null;\n};\n\nconst PRIORITY_COLUMNS = [\n \"documentType\",\n \"documentId\",\n \"scope\",\n \"branch\",\n \"index\",\n \"skip\",\n] as const;\n\ntype ReactorPgliteAdapter = {\n query: (\n sql: string,\n params?: unknown[],\n ) => Promise<{ rows: unknown[]; affectedRows?: number }>;\n};\n\nfunction createWorkerReactorDatabase(\n inspector: IInspectorProxy,\n): Kysely<Database> {\n const adapter: ReactorPgliteAdapter = {\n query: async (statement, params) => ({\n rows: (await inspector.queryReactorDb(statement, params)) as unknown[],\n }),\n };\n return new Kysely<Database>({\n dialect: new PGliteDialect(adapter as unknown as PGlite),\n });\n}\n\nexport function useDbExplorer() {\n const browserDatabase = useDatabase();\n const pglite = usePGlite();\n const module = useReactorClientModule();\n const reactorClientModule = module?.kind === \"browser\" ? module : undefined;\n const reactor = reactorClientModule?.reactorModule?.reactor;\n const queue = reactorClientModule?.reactorModule?.queue;\n const workerModule = module?.kind === \"worker\" ? module : undefined;\n const workerDatabase = useMemo(\n () =>\n workerModule\n ? createWorkerReactorDatabase(workerModule.inspector)\n : undefined,\n [workerModule],\n );\n const database = browserDatabase ?? workerDatabase;\n\n const getTables = useCallback(async (): Promise<TableInfo[]> => {\n if (!database) return [];\n\n const result = await sql<ColumnRow>`\n SELECT\n c.table_name,\n c.column_name,\n c.data_type,\n c.is_nullable\n FROM information_schema.columns c\n INNER JOIN information_schema.tables t\n ON c.table_name = t.table_name\n AND c.table_schema = t.table_schema\n WHERE c.table_schema = ${REACTOR_SCHEMA}\n AND t.table_type = 'BASE TABLE'\n ORDER BY c.table_name, c.ordinal_position\n `.execute(database);\n\n const tableMap = new Map<string, ColumnInfo[]>();\n for (const row of result.rows) {\n if (!tableMap.has(row.table_name)) {\n tableMap.set(row.table_name, []);\n }\n tableMap.get(row.table_name)!.push({\n name: row.column_name,\n dataType: row.data_type,\n isNullable: row.is_nullable === \"YES\",\n });\n }\n\n return Array.from(tableMap).map(([name, columns]) => {\n const columnNames = columns.map((col) => col.name);\n const orderedColumns = [\n ...PRIORITY_COLUMNS.filter((col) => columnNames.includes(col)).map(\n (col) => columns.find((c) => c.name === col)!,\n ),\n ...columns.filter(\n (col) =>\n !PRIORITY_COLUMNS.includes(\n col.name as (typeof PRIORITY_COLUMNS)[number],\n ),\n ),\n ];\n return {\n name,\n columns: orderedColumns,\n };\n });\n }, [database]);\n\n const getTableRows = useCallback(\n async (table: string, options: GetTableRowsOptions): Promise<TablePage> => {\n if (!database) {\n return { columns: [], rows: [], total: null };\n }\n\n const limit = options.limit;\n const offset = options.offset;\n const sort = options.sort;\n const filters = options.filters;\n const tableRef = sql.raw(`${REACTOR_SCHEMA}.\"${table}\"`);\n\n // Build WHERE clause from filters\n let whereClause = sql``;\n if (filters?.clauses && filters.clauses.length > 0) {\n const conditions: ReturnType<typeof sql>[] = [];\n\n for (let i = 0; i < filters.clauses.length; i++) {\n const clause = filters.clauses[i];\n if (!clause) continue;\n\n const columnRef = sql.raw(`\"${clause.column}\"`);\n\n let condition: ReturnType<typeof sql>;\n\n if (clause.operator === \"IS NULL\") {\n condition = sql`${columnRef} IS NULL`;\n } else if (clause.operator === \"IS NOT NULL\") {\n condition = sql`${columnRef} IS NOT NULL`;\n } else if (\n clause.operator === \"LIKE\" ||\n clause.operator === \"ILIKE\"\n ) {\n const value = clause.value;\n const operator =\n clause.operator === \"LIKE\" ? sql`LIKE` : sql`ILIKE`;\n condition = sql`${columnRef} ${operator} ${value}`;\n } else {\n // For =, !=, >, <, >=, <=\n const operator = sql.raw(clause.operator);\n const value = clause.value;\n\n // Try to parse as number if it looks like a number\n let parsedValue: string | number = value;\n if (value !== \"\" && !isNaN(Number(value)) && value.trim() !== \"\") {\n parsedValue = Number(value);\n }\n\n condition = sql`${columnRef} ${operator} ${parsedValue}`;\n }\n\n conditions.push(condition);\n\n // Add connector if not the last clause\n if (i < filters.clauses.length - 1) {\n const connector = filters.connectors?.[i] ?? \"AND\";\n conditions.push(sql.raw(connector));\n }\n }\n\n // Combine all conditions\n if (conditions.length > 0) {\n whereClause = sql`WHERE ${sql.join(conditions, sql` `)}`;\n }\n }\n\n // Build main query\n let query;\n if (sort) {\n const columnRef = sql.raw(`\"${sort.column}\"`);\n const direction = sort.direction === \"desc\" ? sql`DESC` : sql`ASC`;\n query = sql<Record<string, unknown>>`\n SELECT * FROM ${tableRef}\n ${whereClause}\n ORDER BY ${columnRef} ${direction}\n LIMIT ${limit} OFFSET ${offset}\n `;\n } else {\n query = sql<Record<string, unknown>>`\n SELECT * FROM ${tableRef}\n ${whereClause}\n LIMIT ${limit} OFFSET ${offset}\n `;\n }\n\n const result = await query.execute(database);\n\n // Build count query with same filters\n const countQuery = sql<{ count: string }>`\n SELECT COUNT(*) as count FROM ${tableRef}\n ${whereClause}\n `;\n const countResult = await countQuery.execute(database);\n const total = countResult.rows[0]\n ? parseInt(countResult.rows[0].count, 10)\n : null;\n\n const rawColumns =\n result.rows.length > 0 ? Object.keys(result.rows[0]) : [];\n const columns = [\n ...PRIORITY_COLUMNS.filter((col) => rawColumns.includes(col)),\n ...rawColumns.filter(\n (col) =>\n !PRIORITY_COLUMNS.includes(\n col as (typeof PRIORITY_COLUMNS)[number],\n ),\n ),\n ];\n\n return {\n columns,\n rows: result.rows,\n total,\n };\n },\n [database],\n );\n\n const onExportDb = useCallback(async () => {\n if (!pglite) return;\n\n if (queue) await quiesceQueue(queue);\n\n try {\n const major = resolvePgMajorForRuntime(getCachedReactorPgMajor() ?? null);\n const pgDump = await loadPgDump(major);\n const dump = await pgDump({ pg: pglite });\n const sqlContent = await dump.text();\n\n const blob = new Blob([sqlContent], { type: \"text/sql\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = `database-export-${Date.now()}.sql`;\n a.click();\n URL.revokeObjectURL(url);\n } finally {\n queue?.unblock();\n }\n }, [pglite, queue]);\n\n const onImportDb = useCallback(\n async (sqlContent: string) => {\n if (!pglite) return;\n\n if (queue) await quiesceQueue(queue);\n\n if (reactor) {\n const status = reactor.kill();\n await status.completed;\n }\n\n // drop every user-created schema before restoring\n await pglite.transaction(async (tx) => {\n const schemas = await tx.query<{ nspname: string }>(\n `SELECT nspname FROM pg_namespace\n WHERE nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema', 'public')\n AND nspname NOT LIKE 'pg_temp_%'\n AND nspname NOT LIKE 'pg_toast_temp_%'`,\n );\n for (const { nspname } of schemas.rows) {\n await tx.exec(`DROP SCHEMA IF EXISTS \"${nspname}\" CASCADE`);\n }\n try {\n await tx.exec(\"SET standard_conforming_strings = off;\");\n } catch {\n // PG17 still accepts this but log if it ever fails.\n }\n await tx.exec(sqlContent);\n await tx.exec(`SET search_path TO ${REACTOR_SCHEMA}`);\n });\n\n // flush IDBFS → IndexedDB synchronously\n await syncPgliteToIdb(pglite);\n\n window.location.reload();\n\n // reload() is asynchronous; without blocking here the DBExplorer caller\n // would continue and call loadTables() against an in-flight shutdown.\n await new Promise(() => {});\n },\n [pglite, queue, reactor],\n );\n\n const getDefaultSort = useCallback(\n (table: string): SortOptions | undefined => {\n if (table === \"Operation\") {\n return { column: \"timestampUtcMs\", direction: \"desc\" };\n }\n return undefined;\n },\n [],\n );\n\n const canModifyDb = !!pglite;\n\n return {\n getTables,\n getTableRows,\n getDefaultSort,\n onExportDb: canModifyDb ? onExportDb : undefined,\n onImportDb: canModifyDb ? onImportDb : undefined,\n };\n}\n","import { clearReactorStorage } from \"@powerhousedao/connect/store\";\nimport {\n getCachedReactorPgMajor,\n PENDING_PG_SEED_KEY,\n subscribeReactorPgMajor,\n} from \"@powerhousedao/connect/utils\";\nimport { useCallback, useSyncExternalStore } from \"react\";\n\nconst SUPPORTED_PG_VERSIONS = [16, 17] as const;\n\nexport function useDebugInspector() {\n const currentPgVersion = useSyncExternalStore(\n subscribeReactorPgMajor,\n getCachedReactorPgMajor,\n () => undefined,\n );\n\n const onResetToPgVersion = useCallback(async (major: number) => {\n console.info(`[debug-inspector] Reset requested: PG${major}`);\n try {\n localStorage.setItem(PENDING_PG_SEED_KEY, String(major));\n console.info(`[debug-inspector] Clearing reactor storage...`);\n await clearReactorStorage();\n console.info(`[debug-inspector] Storage cleared. Reloading...`);\n window.location.reload();\n } catch (err) {\n console.error(\"[debug-inspector] Reset failed:\", err);\n localStorage.removeItem(PENDING_PG_SEED_KEY);\n throw err;\n }\n }, []);\n\n return {\n supportedPgVersions: SUPPORTED_PG_VERSIONS,\n currentPgVersion: currentPgVersion ?? null,\n onResetToPgVersion,\n };\n}\n","import type { IntegrityInspectorProps } from \"@powerhousedao/design-system/connect\";\nimport {\n DocumentIntegrityService,\n useReactorClientModule,\n type RebuildResult,\n type ValidationResult,\n} from \"@powerhousedao/reactor-browser\";\nimport { useCallback, useMemo } from \"react\";\n\nexport function useIntegrityInspector(): IntegrityInspectorProps | undefined {\n const module = useReactorClientModule();\n const reactorModule =\n module?.kind === \"browser\" ? module.reactorModule : undefined;\n const inspector = module?.kind === \"worker\" ? module.inspector : undefined;\n\n const service = useMemo(() => {\n if (!reactorModule) return undefined;\n\n return new DocumentIntegrityService(\n reactorModule.keyframeStore,\n reactorModule.operationStore,\n reactorModule.writeCache,\n reactorModule.documentView,\n reactorModule.documentModelRegistry,\n );\n }, [reactorModule]);\n\n const onValidate = useCallback(\n async (documentId: string, branch?: string): Promise<ValidationResult> => {\n if (inspector) {\n return (await inspector.validateDocument(\n documentId,\n branch,\n )) as ValidationResult;\n }\n if (!service) {\n throw new Error(\"Reactor module not available\");\n }\n return service.validateDocument(documentId, branch);\n },\n [service, inspector],\n );\n\n const onRebuildKeyframes = useCallback(\n async (documentId: string, branch?: string): Promise<RebuildResult> => {\n if (inspector) {\n return (await inspector.rebuildKeyframes(\n documentId,\n branch,\n )) as RebuildResult;\n }\n if (!service) {\n throw new Error(\"Reactor module not available\");\n }\n return service.rebuildKeyframes(documentId, branch);\n },\n [service, inspector],\n );\n\n const onRebuildSnapshots = useCallback(\n async (documentId: string, branch?: string): Promise<RebuildResult> => {\n if (inspector) {\n return (await inspector.rebuildSnapshots(\n documentId,\n branch,\n )) as RebuildResult;\n }\n if (!service) {\n throw new Error(\"Reactor module not available\");\n }\n return service.rebuildSnapshots(documentId, branch);\n },\n [service, inspector],\n );\n\n if (!service && !inspector) {\n return undefined;\n }\n\n return {\n onValidate,\n onRebuildKeyframes,\n onRebuildSnapshots,\n };\n}\n","import type {\n ProcessorInfo,\n ProcessorsInspectorProps,\n} from \"@powerhousedao/design-system/connect\";\nimport { useReactorClientModule } from \"@powerhousedao/reactor-browser\";\nimport { useCallback, useMemo } from \"react\";\n\nexport function useProcessorsInspector(): ProcessorsInspectorProps | undefined {\n const module = useReactorClientModule();\n const processorManager =\n module?.kind === \"browser\"\n ? module.reactorModule?.processorManager\n : undefined;\n const inspector = module?.kind === \"worker\" ? module.inspector : undefined;\n\n const available = useMemo(\n () => processorManager != null || inspector != null,\n [processorManager, inspector],\n );\n\n const getProcessors = useCallback((): Promise<ProcessorInfo[]> => {\n if (inspector) {\n return inspector.getProcessors() as Promise<ProcessorInfo[]>;\n }\n if (!processorManager) {\n return Promise.resolve([]);\n }\n return Promise.resolve(\n processorManager.getAll().map((tracked) => ({\n processorId: tracked.processorId,\n factoryId: tracked.factoryId,\n driveId: tracked.driveId,\n processorIndex: tracked.processorIndex,\n lastOrdinal: tracked.lastOrdinal,\n status: tracked.status,\n lastError: tracked.lastError,\n lastErrorTimestamp: tracked.lastErrorTimestamp,\n })),\n );\n }, [processorManager, inspector]);\n\n const onRetry = useCallback(\n async (processorId: string) => {\n if (inspector) {\n await inspector.retryProcessor(processorId);\n return;\n }\n if (!processorManager) return;\n const tracked = processorManager.get(processorId);\n if (tracked) {\n await tracked.retry();\n }\n },\n [processorManager, inspector],\n );\n\n if (!available) {\n return undefined;\n }\n\n return {\n getProcessors,\n onRetry,\n };\n}\n","import type {\n QueueInspectorProps,\n QueueState,\n} from \"@powerhousedao/design-system/connect\";\nimport {\n InMemoryQueue,\n useReactorClientModule,\n type Job,\n} from \"@powerhousedao/reactor-browser\";\nimport { useCallback, useMemo } from \"react\";\n\nexport function useQueueInspector(): QueueInspectorProps | undefined {\n const module = useReactorClientModule();\n const reactorClientModule = module?.kind === \"browser\" ? module : undefined;\n const inspector = module?.kind === \"worker\" ? module.inspector : undefined;\n const queue = reactorClientModule?.reactorModule?.queue;\n\n const inMemoryQueue = useMemo(() => {\n if (queue instanceof InMemoryQueue) {\n return queue;\n }\n return undefined;\n }, [queue]);\n\n const getQueueState = useCallback((): Promise<QueueState> => {\n if (inspector) {\n return inspector.getQueueState() as Promise<QueueState>;\n }\n if (!inMemoryQueue) {\n return Promise.resolve({\n isPaused: false,\n pendingJobs: [],\n executingJobs: [],\n totalPending: 0,\n totalExecuting: 0,\n });\n }\n\n const pendingJobs = inMemoryQueue.getPendingJobs();\n const executingJobIds = inMemoryQueue.getExecutingJobIds();\n\n const executingJobs: Job[] = [];\n for (const jobIdSet of executingJobIds.values()) {\n for (const jobId of jobIdSet) {\n const job = inMemoryQueue.getJob(jobId);\n if (job) {\n executingJobs.push(job);\n }\n }\n }\n\n return Promise.resolve({\n isPaused: inMemoryQueue.paused,\n pendingJobs,\n executingJobs,\n totalPending: pendingJobs.length,\n totalExecuting: executingJobs.length,\n });\n }, [inMemoryQueue, inspector]);\n\n const onPause = useCallback(async (): Promise<void> => {\n if (inspector) {\n await inspector.pauseQueue();\n return;\n }\n if (inMemoryQueue) {\n inMemoryQueue.pause();\n }\n }, [inMemoryQueue, inspector]);\n\n const onResume = useCallback(async (): Promise<void> => {\n if (inspector) {\n await inspector.resumeQueue();\n return;\n }\n if (inMemoryQueue) {\n await inMemoryQueue.resume();\n }\n }, [inMemoryQueue, inspector]);\n\n if (!inMemoryQueue && !inspector) {\n return undefined;\n }\n\n return {\n getQueueState,\n onPause,\n onResume,\n };\n}\n","import type {\n ConnectionStateSnapshot,\n Remote,\n} from \"@powerhousedao/reactor-browser\";\nimport {\n addRemoteDrive,\n PollBehavior,\n useConnectionStates,\n useSync,\n} from \"@powerhousedao/reactor-browser\";\nimport { useCallback } from \"react\";\n\nexport function useRemotesInspector(): {\n getRemotes: () => Promise<Remote[]>;\n removeRemote: (name: string) => Promise<void>;\n addRemoteManual: (url: string) => Promise<void>;\n triggerPull: (name: string) => void;\n connectionStates: ReadonlyMap<string, ConnectionStateSnapshot>;\n} {\n const syncManager = useSync();\n if (!syncManager) {\n throw new Error(\"Sync manager not found\");\n }\n\n const connectionStates = useConnectionStates();\n\n const getRemotes = useCallback(() => {\n return Promise.resolve(syncManager.list());\n }, [syncManager]);\n\n const removeRemote = useCallback(\n (name: string) => syncManager.remove(name),\n [syncManager],\n );\n\n const addRemoteManual = useCallback(async (url: string) => {\n await addRemoteDrive(url, undefined, {\n pollBehavior: PollBehavior.Manual,\n });\n }, []);\n\n const triggerPull = useCallback(\n (name: string) => syncManager.triggerPull(name),\n [syncManager],\n );\n\n return {\n getRemotes,\n removeRemote,\n addRemoteManual,\n triggerPull,\n connectionStates,\n };\n}\n","import type { WorkerInspectorProps } from \"@powerhousedao/design-system/connect\";\nimport { useReactorClientModule } from \"@powerhousedao/reactor-browser\";\nimport { useMemo } from \"react\";\n\nexport function useWorkerInspector(): WorkerInspectorProps | undefined {\n const module = useReactorClientModule();\n const adminClient =\n module?.kind === \"worker\" ? module.adminClient : undefined;\n\n return useMemo(() => {\n if (!adminClient) {\n return undefined;\n }\n return {\n getInfo: () => adminClient.info(),\n onRestart: () => adminClient.restart(),\n };\n }, [adminClient]);\n}\n","import { InspectorModal as ConnectInspectorModal } from \"@powerhousedao/design-system/connect\";\nimport {\n closePHModal,\n REACTOR_SCHEMA,\n usePHModal,\n} from \"@powerhousedao/reactor-browser\";\nimport { useDbExplorer } from \"./useDbExplorer.js\";\nimport { useDebugInspector } from \"./useDebugInspector.js\";\nimport { useIntegrityInspector } from \"./useIntegrityInspector.js\";\nimport { useProcessorsInspector } from \"./useProcessorsInspector.js\";\nimport { useQueueInspector } from \"./useQueueInspector.js\";\nimport { useRemotesInspector } from \"./useRemotesInspector.js\";\nimport { useWorkerInspector } from \"./useWorkerInspector.js\";\n\nconst DEFAULT_PAGE_SIZE = 25;\n\nexport const InspectorModal: React.FC = () => {\n const phModal = usePHModal();\n const open = phModal?.type === \"inspector\";\n\n const { getTables, getTableRows, getDefaultSort, onExportDb, onImportDb } =\n useDbExplorer();\n const {\n getRemotes,\n removeRemote,\n addRemoteManual,\n triggerPull,\n connectionStates,\n } = useRemotesInspector();\n const queueInspectorProps = useQueueInspector();\n const processorsInspectorProps = useProcessorsInspector();\n const integrityInspectorProps = useIntegrityInspector();\n const workerInspectorProps = useWorkerInspector();\n const { currentPgVersion, supportedPgVersions, onResetToPgVersion } =\n useDebugInspector();\n\n return (\n <ConnectInspectorModal\n open={open}\n onOpenChange={(status) => {\n if (!status) closePHModal();\n }}\n dbExplorerProps={{\n schema: REACTOR_SCHEMA,\n getTables,\n getTableRows,\n getDefaultSort,\n pageSize: DEFAULT_PAGE_SIZE,\n onExportDb,\n onImportDb,\n pgVersionControl: {\n currentPgVersion,\n supportedPgVersions,\n onResetToPgVersion,\n },\n }}\n remotesInspectorProps={{\n getRemotes,\n removeRemote,\n addRemoteManual,\n triggerPull,\n connectionStates,\n }}\n queueInspectorProps={queueInspectorProps}\n processorsInspectorProps={processorsInspectorProps}\n integrityInspectorProps={integrityInspectorProps}\n workerInspectorProps={workerInspectorProps}\n />\n );\n};\n"],"names":["ConnectInspectorModal"],"mappings":"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","debug_id":"f7f161d8-9d9b-57f0-adb3-ea909f7d423c"}
1
+ {"version":3,"file":"InspectorModal-BR0x5ZLQ.js","sources":["../src/components/modal/modals/InspectorModal/useDbExplorer.ts","../src/components/modal/modals/InspectorModal/useDebugInspector.ts","../src/components/modal/modals/InspectorModal/useIntegrityInspector.ts","../src/components/modal/modals/InspectorModal/useProcessorsInspector.ts","../src/components/modal/modals/InspectorModal/useQueueInspector.ts","../src/components/modal/modals/InspectorModal/useRemotesInspector.ts","../src/components/modal/modals/InspectorModal/useWorkerInspector.ts","../src/components/modal/modals/InspectorModal/InspectorModal.tsx"],"sourcesContent":["import type { PGlite } from \"@electric-sql/pglite\";\nimport {\n getCachedReactorPgMajor,\n loadPgDump,\n resolvePgMajorForRuntime,\n} from \"@powerhousedao/connect/utils\";\nimport type {\n FilterGroup,\n SortOptions,\n} from \"@powerhousedao/design-system/connect\";\nimport type { Database } from \"@powerhousedao/reactor\";\nimport {\n REACTOR_SCHEMA,\n useDatabase,\n usePGlite,\n useReactorClientModule,\n type IQueue,\n} from \"@powerhousedao/reactor-browser\";\nimport type { IInspectorProxy } from \"@powerhousedao/reactor-browser/rpc\";\nimport { Kysely, sql } from \"kysely\";\nimport { PGliteDialect } from \"kysely-pglite-dialect\";\nimport { useCallback, useMemo } from \"react\";\n\nasync function quiesceQueue(queue: IQueue): Promise<void> {\n await new Promise<void>((resolve) => queue.block(() => resolve()));\n}\n\n// The reactor runs with `relaxedDurability: true`, which makes PGlite's\n// `syncToFs()` fire the IDBFS→IndexedDB write and return without awaiting\n// Emscripten's syncfs callback. `close()` also doesn't flush. Calling\n// `FS.syncfs(false, cb)` directly gives us a callback that fires from the\n// IDBFS transaction's `oncomplete` — i.e. after IDB has actually committed.\nasync function syncPgliteToIdb(pglite: {\n readonly Module: {\n readonly FS: {\n syncfs(populate: boolean, cb: (err: Error | null) => void): void;\n };\n };\n}): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n pglite.Module.FS.syncfs(false, (err) => (err ? reject(err) : resolve()));\n });\n}\n\ntype ColumnInfo = {\n readonly name: string;\n readonly dataType: string;\n readonly isNullable: boolean;\n};\n\ntype TableInfo = {\n readonly name: string;\n readonly columns: ColumnInfo[];\n};\n\ntype ColumnRow = {\n table_name: string;\n column_name: string;\n data_type: string;\n is_nullable: string;\n};\n\ntype GetTableRowsOptions = {\n readonly schema?: string;\n readonly limit: number;\n readonly offset: number;\n readonly sort?: SortOptions;\n readonly filters?: FilterGroup;\n};\n\ntype TablePage = {\n readonly columns: string[];\n readonly rows: Record<string, unknown>[];\n readonly total: number | null;\n};\n\nconst PRIORITY_COLUMNS = [\n \"documentType\",\n \"documentId\",\n \"scope\",\n \"branch\",\n \"index\",\n \"skip\",\n] as const;\n\ntype ReactorPgliteAdapter = {\n query: (\n sql: string,\n params?: unknown[],\n ) => Promise<{ rows: unknown[]; affectedRows?: number }>;\n};\n\nfunction createWorkerReactorDatabase(\n inspector: IInspectorProxy,\n): Kysely<Database> {\n const adapter: ReactorPgliteAdapter = {\n query: async (statement, params) => ({\n rows: (await inspector.queryReactorDb(statement, params)) as unknown[],\n }),\n };\n return new Kysely<Database>({\n dialect: new PGliteDialect(adapter as unknown as PGlite),\n });\n}\n\nexport function useDbExplorer() {\n const browserDatabase = useDatabase();\n const pglite = usePGlite();\n const module = useReactorClientModule();\n const reactorClientModule = module?.kind === \"browser\" ? module : undefined;\n const reactor = reactorClientModule?.reactorModule?.reactor;\n const queue = reactorClientModule?.reactorModule?.queue;\n const workerModule = module?.kind === \"worker\" ? module : undefined;\n const workerDatabase = useMemo(\n () =>\n workerModule\n ? createWorkerReactorDatabase(workerModule.inspector)\n : undefined,\n [workerModule],\n );\n const database = browserDatabase ?? workerDatabase;\n\n const getTables = useCallback(async (): Promise<TableInfo[]> => {\n if (!database) return [];\n\n const result = await sql<ColumnRow>`\n SELECT\n c.table_name,\n c.column_name,\n c.data_type,\n c.is_nullable\n FROM information_schema.columns c\n INNER JOIN information_schema.tables t\n ON c.table_name = t.table_name\n AND c.table_schema = t.table_schema\n WHERE c.table_schema = ${REACTOR_SCHEMA}\n AND t.table_type = 'BASE TABLE'\n ORDER BY c.table_name, c.ordinal_position\n `.execute(database);\n\n const tableMap = new Map<string, ColumnInfo[]>();\n for (const row of result.rows) {\n if (!tableMap.has(row.table_name)) {\n tableMap.set(row.table_name, []);\n }\n tableMap.get(row.table_name)!.push({\n name: row.column_name,\n dataType: row.data_type,\n isNullable: row.is_nullable === \"YES\",\n });\n }\n\n return Array.from(tableMap).map(([name, columns]) => {\n const columnNames = columns.map((col) => col.name);\n const orderedColumns = [\n ...PRIORITY_COLUMNS.filter((col) => columnNames.includes(col)).map(\n (col) => columns.find((c) => c.name === col)!,\n ),\n ...columns.filter(\n (col) =>\n !PRIORITY_COLUMNS.includes(\n col.name as (typeof PRIORITY_COLUMNS)[number],\n ),\n ),\n ];\n return {\n name,\n columns: orderedColumns,\n };\n });\n }, [database]);\n\n const getTableRows = useCallback(\n async (table: string, options: GetTableRowsOptions): Promise<TablePage> => {\n if (!database) {\n return { columns: [], rows: [], total: null };\n }\n\n const limit = options.limit;\n const offset = options.offset;\n const sort = options.sort;\n const filters = options.filters;\n const tableRef = sql.raw(`${REACTOR_SCHEMA}.\"${table}\"`);\n\n // Build WHERE clause from filters\n let whereClause = sql``;\n if (filters?.clauses && filters.clauses.length > 0) {\n const conditions: ReturnType<typeof sql>[] = [];\n\n for (let i = 0; i < filters.clauses.length; i++) {\n const clause = filters.clauses[i];\n if (!clause) continue;\n\n const columnRef = sql.raw(`\"${clause.column}\"`);\n\n let condition: ReturnType<typeof sql>;\n\n if (clause.operator === \"IS NULL\") {\n condition = sql`${columnRef} IS NULL`;\n } else if (clause.operator === \"IS NOT NULL\") {\n condition = sql`${columnRef} IS NOT NULL`;\n } else if (\n clause.operator === \"LIKE\" ||\n clause.operator === \"ILIKE\"\n ) {\n const value = clause.value;\n const operator =\n clause.operator === \"LIKE\" ? sql`LIKE` : sql`ILIKE`;\n condition = sql`${columnRef} ${operator} ${value}`;\n } else {\n // For =, !=, >, <, >=, <=\n const operator = sql.raw(clause.operator);\n const value = clause.value;\n\n // Try to parse as number if it looks like a number\n let parsedValue: string | number = value;\n if (value !== \"\" && !isNaN(Number(value)) && value.trim() !== \"\") {\n parsedValue = Number(value);\n }\n\n condition = sql`${columnRef} ${operator} ${parsedValue}`;\n }\n\n conditions.push(condition);\n\n // Add connector if not the last clause\n if (i < filters.clauses.length - 1) {\n const connector = filters.connectors?.[i] ?? \"AND\";\n conditions.push(sql.raw(connector));\n }\n }\n\n // Combine all conditions\n if (conditions.length > 0) {\n whereClause = sql`WHERE ${sql.join(conditions, sql` `)}`;\n }\n }\n\n // Build main query\n let query;\n if (sort) {\n const columnRef = sql.raw(`\"${sort.column}\"`);\n const direction = sort.direction === \"desc\" ? sql`DESC` : sql`ASC`;\n query = sql<Record<string, unknown>>`\n SELECT * FROM ${tableRef}\n ${whereClause}\n ORDER BY ${columnRef} ${direction}\n LIMIT ${limit} OFFSET ${offset}\n `;\n } else {\n query = sql<Record<string, unknown>>`\n SELECT * FROM ${tableRef}\n ${whereClause}\n LIMIT ${limit} OFFSET ${offset}\n `;\n }\n\n const result = await query.execute(database);\n\n // Build count query with same filters\n const countQuery = sql<{ count: string }>`\n SELECT COUNT(*) as count FROM ${tableRef}\n ${whereClause}\n `;\n const countResult = await countQuery.execute(database);\n const total = countResult.rows[0]\n ? parseInt(countResult.rows[0].count, 10)\n : null;\n\n const rawColumns =\n result.rows.length > 0 ? Object.keys(result.rows[0]) : [];\n const columns = [\n ...PRIORITY_COLUMNS.filter((col) => rawColumns.includes(col)),\n ...rawColumns.filter(\n (col) =>\n !PRIORITY_COLUMNS.includes(\n col as (typeof PRIORITY_COLUMNS)[number],\n ),\n ),\n ];\n\n return {\n columns,\n rows: result.rows,\n total,\n };\n },\n [database],\n );\n\n const onExportDb = useCallback(async () => {\n if (!pglite) return;\n\n if (queue) await quiesceQueue(queue);\n\n try {\n const major = resolvePgMajorForRuntime(getCachedReactorPgMajor() ?? null);\n const pgDump = await loadPgDump(major);\n const dump = await pgDump({ pg: pglite });\n const sqlContent = await dump.text();\n\n const blob = new Blob([sqlContent], { type: \"text/sql\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = `database-export-${Date.now()}.sql`;\n a.click();\n URL.revokeObjectURL(url);\n } finally {\n queue?.unblock();\n }\n }, [pglite, queue]);\n\n const onImportDb = useCallback(\n async (sqlContent: string) => {\n if (!pglite) return;\n\n if (queue) await quiesceQueue(queue);\n\n if (reactor) {\n const status = reactor.kill();\n await status.completed;\n }\n\n // drop every user-created schema before restoring\n await pglite.transaction(async (tx) => {\n const schemas = await tx.query<{ nspname: string }>(\n `SELECT nspname FROM pg_namespace\n WHERE nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema', 'public')\n AND nspname NOT LIKE 'pg_temp_%'\n AND nspname NOT LIKE 'pg_toast_temp_%'`,\n );\n for (const { nspname } of schemas.rows) {\n await tx.exec(`DROP SCHEMA IF EXISTS \"${nspname}\" CASCADE`);\n }\n try {\n await tx.exec(\"SET standard_conforming_strings = off;\");\n } catch {\n // PG17 still accepts this but log if it ever fails.\n }\n await tx.exec(sqlContent);\n await tx.exec(`SET search_path TO ${REACTOR_SCHEMA}`);\n });\n\n // flush IDBFS → IndexedDB synchronously\n await syncPgliteToIdb(pglite);\n\n window.location.reload();\n\n // reload() is asynchronous; without blocking here the DBExplorer caller\n // would continue and call loadTables() against an in-flight shutdown.\n await new Promise(() => {});\n },\n [pglite, queue, reactor],\n );\n\n const getDefaultSort = useCallback(\n (table: string): SortOptions | undefined => {\n if (table === \"Operation\") {\n return { column: \"timestampUtcMs\", direction: \"desc\" };\n }\n return undefined;\n },\n [],\n );\n\n const canModifyDb = !!pglite;\n\n return {\n getTables,\n getTableRows,\n getDefaultSort,\n onExportDb: canModifyDb ? onExportDb : undefined,\n onImportDb: canModifyDb ? onImportDb : undefined,\n };\n}\n","import { clearReactorStorage } from \"@powerhousedao/connect/store\";\nimport {\n getCachedReactorPgMajor,\n PENDING_PG_SEED_KEY,\n subscribeReactorPgMajor,\n} from \"@powerhousedao/connect/utils\";\nimport { useCallback, useSyncExternalStore } from \"react\";\n\nconst SUPPORTED_PG_VERSIONS = [16, 17] as const;\n\nexport function useDebugInspector() {\n const currentPgVersion = useSyncExternalStore(\n subscribeReactorPgMajor,\n getCachedReactorPgMajor,\n () => undefined,\n );\n\n const onResetToPgVersion = useCallback(async (major: number) => {\n console.info(`[debug-inspector] Reset requested: PG${major}`);\n try {\n localStorage.setItem(PENDING_PG_SEED_KEY, String(major));\n console.info(`[debug-inspector] Clearing reactor storage...`);\n await clearReactorStorage();\n console.info(`[debug-inspector] Storage cleared. Reloading...`);\n window.location.reload();\n } catch (err) {\n console.error(\"[debug-inspector] Reset failed:\", err);\n localStorage.removeItem(PENDING_PG_SEED_KEY);\n throw err;\n }\n }, []);\n\n return {\n supportedPgVersions: SUPPORTED_PG_VERSIONS,\n currentPgVersion: currentPgVersion ?? null,\n onResetToPgVersion,\n };\n}\n","import type { IntegrityInspectorProps } from \"@powerhousedao/design-system/connect\";\nimport {\n DocumentIntegrityService,\n useReactorClientModule,\n type RebuildResult,\n type ValidationResult,\n} from \"@powerhousedao/reactor-browser\";\nimport { useCallback, useMemo } from \"react\";\n\nexport function useIntegrityInspector(): IntegrityInspectorProps | undefined {\n const module = useReactorClientModule();\n const reactorModule =\n module?.kind === \"browser\" ? module.reactorModule : undefined;\n const inspector = module?.kind === \"worker\" ? module.inspector : undefined;\n\n const service = useMemo(() => {\n if (!reactorModule) return undefined;\n\n return new DocumentIntegrityService(\n reactorModule.keyframeStore,\n reactorModule.operationStore,\n reactorModule.writeCache,\n reactorModule.documentView,\n reactorModule.documentModelRegistry,\n );\n }, [reactorModule]);\n\n const onValidate = useCallback(\n async (documentId: string, branch?: string): Promise<ValidationResult> => {\n if (inspector) {\n return (await inspector.validateDocument(\n documentId,\n branch,\n )) as ValidationResult;\n }\n if (!service) {\n throw new Error(\"Reactor module not available\");\n }\n return service.validateDocument(documentId, branch);\n },\n [service, inspector],\n );\n\n const onRebuildKeyframes = useCallback(\n async (documentId: string, branch?: string): Promise<RebuildResult> => {\n if (inspector) {\n return (await inspector.rebuildKeyframes(\n documentId,\n branch,\n )) as RebuildResult;\n }\n if (!service) {\n throw new Error(\"Reactor module not available\");\n }\n return service.rebuildKeyframes(documentId, branch);\n },\n [service, inspector],\n );\n\n const onRebuildSnapshots = useCallback(\n async (documentId: string, branch?: string): Promise<RebuildResult> => {\n if (inspector) {\n return (await inspector.rebuildSnapshots(\n documentId,\n branch,\n )) as RebuildResult;\n }\n if (!service) {\n throw new Error(\"Reactor module not available\");\n }\n return service.rebuildSnapshots(documentId, branch);\n },\n [service, inspector],\n );\n\n if (!service && !inspector) {\n return undefined;\n }\n\n return {\n onValidate,\n onRebuildKeyframes,\n onRebuildSnapshots,\n };\n}\n","import type {\n ProcessorInfo,\n ProcessorsInspectorProps,\n} from \"@powerhousedao/design-system/connect\";\nimport { useReactorClientModule } from \"@powerhousedao/reactor-browser\";\nimport { useCallback, useMemo } from \"react\";\n\nexport function useProcessorsInspector(): ProcessorsInspectorProps | undefined {\n const module = useReactorClientModule();\n const processorManager =\n module?.kind === \"browser\"\n ? module.reactorModule?.processorManager\n : undefined;\n const inspector = module?.kind === \"worker\" ? module.inspector : undefined;\n\n const available = useMemo(\n () => processorManager != null || inspector != null,\n [processorManager, inspector],\n );\n\n const getProcessors = useCallback((): Promise<ProcessorInfo[]> => {\n if (inspector) {\n return inspector.getProcessors() as Promise<ProcessorInfo[]>;\n }\n if (!processorManager) {\n return Promise.resolve([]);\n }\n return Promise.resolve(\n processorManager.getAll().map((tracked) => ({\n processorId: tracked.processorId,\n factoryId: tracked.factoryId,\n driveId: tracked.driveId,\n processorIndex: tracked.processorIndex,\n lastOrdinal: tracked.lastOrdinal,\n status: tracked.status,\n lastError: tracked.lastError,\n lastErrorTimestamp: tracked.lastErrorTimestamp,\n })),\n );\n }, [processorManager, inspector]);\n\n const onRetry = useCallback(\n async (processorId: string) => {\n if (inspector) {\n await inspector.retryProcessor(processorId);\n return;\n }\n if (!processorManager) return;\n const tracked = processorManager.get(processorId);\n if (tracked) {\n await tracked.retry();\n }\n },\n [processorManager, inspector],\n );\n\n if (!available) {\n return undefined;\n }\n\n return {\n getProcessors,\n onRetry,\n };\n}\n","import type {\n QueueInspectorProps,\n QueueState,\n} from \"@powerhousedao/design-system/connect\";\nimport {\n InMemoryQueue,\n useReactorClientModule,\n type Job,\n} from \"@powerhousedao/reactor-browser\";\nimport { useCallback, useMemo } from \"react\";\n\nexport function useQueueInspector(): QueueInspectorProps | undefined {\n const module = useReactorClientModule();\n const reactorClientModule = module?.kind === \"browser\" ? module : undefined;\n const inspector = module?.kind === \"worker\" ? module.inspector : undefined;\n const queue = reactorClientModule?.reactorModule?.queue;\n\n const inMemoryQueue = useMemo(() => {\n if (queue instanceof InMemoryQueue) {\n return queue;\n }\n return undefined;\n }, [queue]);\n\n const getQueueState = useCallback((): Promise<QueueState> => {\n if (inspector) {\n return inspector.getQueueState() as Promise<QueueState>;\n }\n if (!inMemoryQueue) {\n return Promise.resolve({\n isPaused: false,\n pendingJobs: [],\n executingJobs: [],\n totalPending: 0,\n totalExecuting: 0,\n });\n }\n\n const pendingJobs = inMemoryQueue.getPendingJobs();\n const executingJobIds = inMemoryQueue.getExecutingJobIds();\n\n const executingJobs: Job[] = [];\n for (const jobIdSet of executingJobIds.values()) {\n for (const jobId of jobIdSet) {\n const job = inMemoryQueue.getJob(jobId);\n if (job) {\n executingJobs.push(job);\n }\n }\n }\n\n return Promise.resolve({\n isPaused: inMemoryQueue.paused,\n pendingJobs,\n executingJobs,\n totalPending: pendingJobs.length,\n totalExecuting: executingJobs.length,\n });\n }, [inMemoryQueue, inspector]);\n\n const onPause = useCallback(async (): Promise<void> => {\n if (inspector) {\n await inspector.pauseQueue();\n return;\n }\n if (inMemoryQueue) {\n inMemoryQueue.pause();\n }\n }, [inMemoryQueue, inspector]);\n\n const onResume = useCallback(async (): Promise<void> => {\n if (inspector) {\n await inspector.resumeQueue();\n return;\n }\n if (inMemoryQueue) {\n await inMemoryQueue.resume();\n }\n }, [inMemoryQueue, inspector]);\n\n if (!inMemoryQueue && !inspector) {\n return undefined;\n }\n\n return {\n getQueueState,\n onPause,\n onResume,\n };\n}\n","import type {\n ConnectionStateSnapshot,\n Remote,\n} from \"@powerhousedao/reactor-browser\";\nimport {\n addRemoteDrive,\n PollBehavior,\n useConnectionStates,\n useSync,\n} from \"@powerhousedao/reactor-browser\";\nimport { useCallback } from \"react\";\n\nexport function useRemotesInspector(): {\n getRemotes: () => Promise<Remote[]>;\n removeRemote: (name: string) => Promise<void>;\n addRemoteManual: (url: string) => Promise<void>;\n triggerPull: (name: string) => void;\n connectionStates: ReadonlyMap<string, ConnectionStateSnapshot>;\n} {\n const syncManager = useSync();\n if (!syncManager) {\n throw new Error(\"Sync manager not found\");\n }\n\n const connectionStates = useConnectionStates();\n\n const getRemotes = useCallback(() => {\n return Promise.resolve(syncManager.list());\n }, [syncManager]);\n\n const removeRemote = useCallback(\n (name: string) => syncManager.remove(name),\n [syncManager],\n );\n\n const addRemoteManual = useCallback(async (url: string) => {\n await addRemoteDrive(url, undefined, {\n pollBehavior: PollBehavior.Manual,\n });\n }, []);\n\n const triggerPull = useCallback(\n (name: string) => syncManager.triggerPull(name),\n [syncManager],\n );\n\n return {\n getRemotes,\n removeRemote,\n addRemoteManual,\n triggerPull,\n connectionStates,\n };\n}\n","import type { WorkerInspectorProps } from \"@powerhousedao/design-system/connect\";\nimport { useReactorClientModule } from \"@powerhousedao/reactor-browser\";\nimport { useMemo } from \"react\";\n\nexport function useWorkerInspector(): WorkerInspectorProps | undefined {\n const module = useReactorClientModule();\n const adminClient =\n module?.kind === \"worker\" ? module.adminClient : undefined;\n\n return useMemo(() => {\n if (!adminClient) {\n return undefined;\n }\n return {\n getInfo: () => adminClient.info(),\n onRestart: () => adminClient.restart(),\n };\n }, [adminClient]);\n}\n","import { InspectorModal as ConnectInspectorModal } from \"@powerhousedao/design-system/connect\";\nimport {\n closePHModal,\n REACTOR_SCHEMA,\n usePHModal,\n} from \"@powerhousedao/reactor-browser\";\nimport { useDbExplorer } from \"./useDbExplorer.js\";\nimport { useDebugInspector } from \"./useDebugInspector.js\";\nimport { useIntegrityInspector } from \"./useIntegrityInspector.js\";\nimport { useProcessorsInspector } from \"./useProcessorsInspector.js\";\nimport { useQueueInspector } from \"./useQueueInspector.js\";\nimport { useRemotesInspector } from \"./useRemotesInspector.js\";\nimport { useWorkerInspector } from \"./useWorkerInspector.js\";\n\nconst DEFAULT_PAGE_SIZE = 25;\n\nexport const InspectorModal: React.FC = () => {\n const phModal = usePHModal();\n const open = phModal?.type === \"inspector\";\n\n const { getTables, getTableRows, getDefaultSort, onExportDb, onImportDb } =\n useDbExplorer();\n const {\n getRemotes,\n removeRemote,\n addRemoteManual,\n triggerPull,\n connectionStates,\n } = useRemotesInspector();\n const queueInspectorProps = useQueueInspector();\n const processorsInspectorProps = useProcessorsInspector();\n const integrityInspectorProps = useIntegrityInspector();\n const workerInspectorProps = useWorkerInspector();\n const { currentPgVersion, supportedPgVersions, onResetToPgVersion } =\n useDebugInspector();\n\n return (\n <ConnectInspectorModal\n open={open}\n onOpenChange={(status) => {\n if (!status) closePHModal();\n }}\n dbExplorerProps={{\n schema: REACTOR_SCHEMA,\n getTables,\n getTableRows,\n getDefaultSort,\n pageSize: DEFAULT_PAGE_SIZE,\n onExportDb,\n onImportDb,\n pgVersionControl: {\n currentPgVersion,\n supportedPgVersions,\n onResetToPgVersion,\n },\n }}\n remotesInspectorProps={{\n getRemotes,\n removeRemote,\n addRemoteManual,\n triggerPull,\n connectionStates,\n }}\n queueInspectorProps={queueInspectorProps}\n processorsInspectorProps={processorsInspectorProps}\n integrityInspectorProps={integrityInspectorProps}\n workerInspectorProps={workerInspectorProps}\n />\n );\n};\n"],"names":["ConnectInspectorModal"],"mappings":"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","debug_id":"243325c2-a665-504d-ae71-90e2d1259b60"}
@@ -0,0 +1,75 @@
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]="034b2e40-178c-58ac-a670-b3581c6d75b8")}catch(e){}}();
3
+ import { n as useRenownLoginProps } from "./use-renown-login-DBujbqs8.js";
4
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
+ import { useLayoutEffect, useMemo } from "react";
6
+ import { closePHModal, usePHModal, useUser } from "@powerhousedao/reactor-browser";
7
+ import { RenownLoginMethods } from "@powerhousedao/design-system/connect";
8
+ import { Icon, Modal } from "@powerhousedao/design-system";
9
+ //#region src/components/modal/modals/LoginModal.tsx
10
+ const LoginModal = () => {
11
+ const phModal = usePHModal();
12
+ const user = useUser();
13
+ const { methods: baseMethods, onLogin, loading, error } = useRenownLoginProps();
14
+ const open = phModal?.type === "login";
15
+ const methods = useMemo(() => baseMethods?.map((method) => ({
16
+ ...method,
17
+ onSelect: () => {
18
+ closePHModal();
19
+ method.onSelect();
20
+ }
21
+ })), [baseMethods]);
22
+ useLayoutEffect(() => {
23
+ if (open && user) closePHModal();
24
+ }, [open, user]);
25
+ const hasMethods = !!methods && methods.length > 0;
26
+ return /* @__PURE__ */ jsx(Modal, {
27
+ open,
28
+ onOpenChange: (next) => {
29
+ if (!next) closePHModal();
30
+ },
31
+ title: "Log in",
32
+ contentProps: { className: "rounded-2xl" },
33
+ children: /* @__PURE__ */ jsxs("div", {
34
+ className: "w-96 max-w-[calc(100vw-2rem)] rounded-2xl bg-background p-6 text-foreground",
35
+ children: [/* @__PURE__ */ jsxs("div", {
36
+ className: "mb-6 flex items-center justify-between",
37
+ children: [/* @__PURE__ */ jsx("h1", {
38
+ className: "text-xl font-bold text-foreground",
39
+ children: "Log in"
40
+ }), /* @__PURE__ */ jsx("button", {
41
+ type: "button",
42
+ "aria-label": "Close",
43
+ onClick: () => closePHModal(),
44
+ className: "flex size-8 items-center justify-center rounded-md bg-muted text-muted-foreground outline-none hover:hover-effect",
45
+ children: /* @__PURE__ */ jsx(Icon, {
46
+ name: "Xmark",
47
+ size: 20
48
+ })
49
+ })]
50
+ }), hasMethods ? /* @__PURE__ */ jsx(RenownLoginMethods, {
51
+ methods,
52
+ loading,
53
+ error
54
+ }) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("button", {
55
+ type: "button",
56
+ onClick: onLogin,
57
+ disabled: loading,
58
+ className: "flex h-10 w-full items-center justify-center rounded-lg bg-primary text-sm font-semibold text-primary-foreground transition-colors hover:bg-primary/85 active:active-effect disabled:cursor-wait disabled:opacity-60",
59
+ children: loading ? /* @__PURE__ */ jsx(Icon, {
60
+ name: "Reload",
61
+ size: 14,
62
+ className: "animate-spin"
63
+ }) : /* @__PURE__ */ jsx("span", { children: "Connect" })
64
+ }), error ? /* @__PURE__ */ jsx("p", {
65
+ className: "mt-2 text-center text-xs text-destructive",
66
+ children: error
67
+ }) : null] })]
68
+ })
69
+ });
70
+ };
71
+ //#endregion
72
+ export { LoginModal };
73
+
74
+ //# sourceMappingURL=LoginModal-BGTKLJx0.js.map
75
+ //# debugId=034b2e40-178c-58ac-a670-b3581c6d75b8
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoginModal-BGTKLJx0.js","sources":["../src/components/modal/modals/LoginModal.tsx"],"sourcesContent":["import { Icon } from \"@powerhousedao/design-system\";\nimport { Modal } from \"@powerhousedao/design-system\";\nimport { RenownLoginMethods } from \"@powerhousedao/design-system/connect\";\nimport {\n closePHModal,\n usePHModal,\n useUser,\n} from \"@powerhousedao/reactor-browser\";\nimport React, { useLayoutEffect, useMemo } from \"react\";\nimport { useRenownLoginProps } from \"../../../hooks/use-renown-login.js\";\n\n// The single login surface, opened via showPHModal({ type: \"login\" }). Matches\n// the other modals' chrome (title + close, rounded-2xl, p-6).\nexport const LoginModal: React.FC = () => {\n const phModal = usePHModal();\n const user = useUser();\n const {\n methods: baseMethods,\n onLogin,\n loading,\n error,\n } = useRenownLoginProps();\n const open = phModal?.type === \"login\";\n\n // A method that opens its own modal (wallet/Privy) closes this one first, so\n // the two surfaces never overlap.\n const methods = useMemo(\n () =>\n baseMethods?.map((method) => ({\n ...method,\n onSelect: () => {\n closePHModal();\n method.onSelect();\n },\n })),\n [baseMethods],\n );\n\n useLayoutEffect(() => {\n if (open && user) closePHModal();\n }, [open, user]);\n\n const hasMethods = !!methods && methods.length > 0;\n\n return (\n <Modal\n open={open}\n onOpenChange={(next) => {\n if (!next) closePHModal();\n }}\n title=\"Log in\"\n contentProps={{ className: \"rounded-2xl\" }}\n >\n <div className=\"w-96 max-w-[calc(100vw-2rem)] rounded-2xl bg-background p-6 text-foreground\">\n <div className=\"mb-6 flex items-center justify-between\">\n <h1 className=\"text-xl font-bold text-foreground\">Log in</h1>\n <button\n type=\"button\"\n aria-label=\"Close\"\n onClick={() => closePHModal()}\n className=\"flex size-8 items-center justify-center rounded-md bg-muted text-muted-foreground outline-none hover:hover-effect\"\n >\n <Icon name=\"Xmark\" size={20} />\n </button>\n </div>\n {hasMethods ? (\n <RenownLoginMethods\n methods={methods}\n loading={loading}\n error={error}\n />\n ) : (\n <>\n <button\n type=\"button\"\n onClick={onLogin}\n disabled={loading}\n className=\"flex h-10 w-full items-center justify-center rounded-lg bg-primary text-sm font-semibold text-primary-foreground transition-colors hover:bg-primary/85 active:active-effect disabled:cursor-wait disabled:opacity-60\"\n >\n {loading ? (\n <Icon name=\"Reload\" size={14} className=\"animate-spin\" />\n ) : (\n <span>Connect</span>\n )}\n </button>\n {error ? (\n <p className=\"mt-2 text-center text-xs text-destructive\">\n {error}\n </p>\n ) : null}\n </>\n )}\n </div>\n </Modal>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;AAaA,MAAa,mBAA6B;CACxC,MAAM,UAAU,YAAY;CAC5B,MAAM,OAAO,SAAS;CACtB,MAAM,EACJ,SAAS,aACT,SACA,SACA,UACE,qBAAqB;CACzB,MAAM,OAAO,SAAS,SAAS;CAI/B,MAAM,UAAU,cAEZ,aAAa,KAAK,YAAY;EAC5B,GAAG;EACH,gBAAgB;AACd,iBAAc;AACd,UAAO,UAAU;;EAEpB,EAAE,EACL,CAAC,YAAY,CACd;AAED,uBAAsB;AACpB,MAAI,QAAQ,KAAM,eAAc;IAC/B,CAAC,MAAM,KAAK,CAAC;CAEhB,MAAM,aAAa,CAAC,CAAC,WAAW,QAAQ,SAAS;AAEjD,QACE,oBAAC,OAAD;EACQ;EACN,eAAe,SAAS;AACtB,OAAI,CAAC,KAAM,eAAc;;EAE3B,OAAM;EACN,cAAc,EAAE,WAAW,eAAe;YAE1C,qBAAC,OAAD;GAAK,WAAU;aAAf,CACE,qBAAC,OAAD;IAAK,WAAU;cAAf,CACE,oBAAC,MAAD;KAAI,WAAU;eAAoC;KAAW,CAAA,EAC7D,oBAAC,UAAD;KACE,MAAK;KACL,cAAW;KACX,eAAe,cAAc;KAC7B,WAAU;eAEV,oBAAC,MAAD;MAAM,MAAK;MAAQ,MAAM;MAAM,CAAA;KACxB,CAAA,CACL;OACL,aACC,oBAAC,oBAAD;IACW;IACA;IACF;IACP,CAAA,GAEF,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,UAAD;IACE,MAAK;IACL,SAAS;IACT,UAAU;IACV,WAAU;cAET,UACC,oBAAC,MAAD;KAAM,MAAK;KAAS,MAAM;KAAI,WAAU;KAAiB,CAAA,GAEzD,oBAAC,QAAD,EAAA,UAAM,WAAc,CAAA;IAEf,CAAA,EACR,QACC,oBAAC,KAAD;IAAG,WAAU;cACV;IACC,CAAA,GACF,KACH,EAAA,CAAA,CAED;;EACA,CAAA","debug_id":"034b2e40-178c-58ac-a670-b3581c6d75b8"}
@@ -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]="60fd96c2-f34b-5c54-a471-a817c573fc6e")}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]="81fed4d0-2942-5b6b-9222-b4614362cba3")}catch(e){}}();
3
3
  import { t as useRegistryPackages } from "./useRegistryPackages-DMhCvTWq.js";
4
4
  import { jsx } from "react/jsx-runtime";
5
5
  import { useEffect, useState } from "react";
@@ -45,5 +45,5 @@ function ConnectMissingPackageModal() {
45
45
  //#endregion
46
46
  export { ConnectMissingPackageModal };
47
47
 
48
- //# sourceMappingURL=MissingPackageModal-D4V6oYzy.js.map
49
- //# debugId=60fd96c2-f34b-5c54-a471-a817c573fc6e
48
+ //# sourceMappingURL=MissingPackageModal-C3acJ9r0.js.map
49
+ //# debugId=81fed4d0-2942-5b6b-9222-b4614362cba3
@@ -1 +1 @@
1
- {"version":3,"file":"MissingPackageModal-D4V6oYzy.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\";\nimport type { RegistryPackage } from \"@powerhousedao/shared/registry\";\nimport { useEffect, useState } from \"react\";\n\nexport function ConnectMissingPackageModal() {\n const phModal = usePHModal();\n const { updateRegistryPackageStatus, fetchPackagesByDocumentType } =\n useRegistryPackages();\n const packageManager = useVetraPackageManager();\n const open = phModal?.type === \"missingPackage\";\n\n const documentType = open ? phModal.documentType : undefined;\n\n const [matches, setMatches] = useState<RegistryPackage[]>([]);\n\n // The full registry listing is paginated and not loaded up front, so this\n // modal fetches just the packages that provide the missing document type\n // (targeted `?documentType=` query). The callback's identity changes when\n // the package manager arrives, re-running until the fetch can proceed.\n useEffect(() => {\n if (!documentType) return;\n let cancelled = false;\n void fetchPackagesByDocumentType(documentType).then((pkgs) => {\n if (!cancelled) setMatches(pkgs);\n });\n return () => {\n cancelled = true;\n };\n }, [documentType, fetchPackagesByDocumentType]);\n\n if (!packageManager || !documentType) return null;\n\n // Filter to the current document type: guards against a stale result set\n // from a previous open while the new fetch is in flight.\n const pendingInstallations: PendingPackageInstallation[] = matches\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":";;;;;;;;AAaA,SAAgB,6BAA6B;CAC3C,MAAM,UAAU,YAAY;CAC5B,MAAM,EAAE,6BAA6B,gCACnC,qBAAqB;CACvB,MAAM,iBAAiB,wBAAwB;CAG/C,MAAM,eAFO,SAAS,SAAS,mBAEH,QAAQ,eAAe,KAAA;CAEnD,MAAM,CAAC,SAAS,cAAc,SAA4B,EAAE,CAAC;AAM7D,iBAAgB;AACd,MAAI,CAAC,aAAc;EACnB,IAAI,YAAY;AACX,8BAA4B,aAAa,CAAC,MAAM,SAAS;AAC5D,OAAI,CAAC,UAAW,YAAW,KAAK;IAChC;AACF,eAAa;AACX,eAAY;;IAEb,CAAC,cAAc,4BAA4B,CAAC;AAE/C,KAAI,CAAC,kBAAkB,CAAC,aAAc,QAAO;CAI7C,MAAM,uBAAqD,QACxD,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":"60fd96c2-f34b-5c54-a471-a817c573fc6e"}
1
+ {"version":3,"file":"MissingPackageModal-C3acJ9r0.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\";\nimport type { RegistryPackage } from \"@powerhousedao/shared/registry\";\nimport { useEffect, useState } from \"react\";\n\nexport function ConnectMissingPackageModal() {\n const phModal = usePHModal();\n const { updateRegistryPackageStatus, fetchPackagesByDocumentType } =\n useRegistryPackages();\n const packageManager = useVetraPackageManager();\n const open = phModal?.type === \"missingPackage\";\n\n const documentType = open ? phModal.documentType : undefined;\n\n const [matches, setMatches] = useState<RegistryPackage[]>([]);\n\n // The full registry listing is paginated and not loaded up front, so this\n // modal fetches just the packages that provide the missing document type\n // (targeted `?documentType=` query). The callback's identity changes when\n // the package manager arrives, re-running until the fetch can proceed.\n useEffect(() => {\n if (!documentType) return;\n let cancelled = false;\n void fetchPackagesByDocumentType(documentType).then((pkgs) => {\n if (!cancelled) setMatches(pkgs);\n });\n return () => {\n cancelled = true;\n };\n }, [documentType, fetchPackagesByDocumentType]);\n\n if (!packageManager || !documentType) return null;\n\n // Filter to the current document type: guards against a stale result set\n // from a previous open while the new fetch is in flight.\n const pendingInstallations: PendingPackageInstallation[] = matches\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":";;;;;;;;AAaA,SAAgB,6BAA6B;CAC3C,MAAM,UAAU,YAAY;CAC5B,MAAM,EAAE,6BAA6B,gCACnC,qBAAqB;CACvB,MAAM,iBAAiB,wBAAwB;CAG/C,MAAM,eAFO,SAAS,SAAS,mBAEH,QAAQ,eAAe,KAAA;CAEnD,MAAM,CAAC,SAAS,cAAc,SAA4B,EAAE,CAAC;AAM7D,iBAAgB;AACd,MAAI,CAAC,aAAc;EACnB,IAAI,YAAY;AACX,8BAA4B,aAAa,CAAC,MAAM,SAAS;AAC5D,OAAI,CAAC,UAAW,YAAW,KAAK;IAChC;AACF,eAAa;AACX,eAAY;;IAEb,CAAC,cAAc,4BAA4B,CAAC;AAE/C,KAAI,CAAC,kBAAkB,CAAC,aAAc,QAAO;CAI7C,MAAM,uBAAqD,QACxD,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":"81fed4d0-2942-5b6b-9222-b4614362cba3"}
@@ -1,6 +1,6 @@
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]="d82043cd-8807-560f-b39b-4261a300066e")}catch(e){}}();
3
- import { _ as getPendingImportFiles, g as clearPendingImportFiles, h as runOpenFileImports, o as DriveIcon, v as pendingFileKey, y as subscribePendingImportFiles } from "./app-loader-DG_ohYMb.js";
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]="11a73724-d073-5b5a-8a5c-c166b7848241")}catch(e){}}();
3
+ import { _ as getPendingImportFiles, g as clearPendingImportFiles, h as runOpenFileImports, o as DriveIcon, v as pendingFileKey, y as subscribePendingImportFiles } from "./app-loader-Bjt8BAsA.js";
4
4
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
5
  import { useTranslation } from "react-i18next";
6
6
  import { useEffect, useState, useSyncExternalStore } from "react";
@@ -289,5 +289,5 @@ function OpenFileDocumentsModal() {
289
289
  //#endregion
290
290
  export { OpenFileDocumentsModal };
291
291
 
292
- //# sourceMappingURL=OpenFileDocumentsModal-DCrZnA6c.js.map
293
- //# debugId=d82043cd-8807-560f-b39b-4261a300066e
292
+ //# sourceMappingURL=OpenFileDocumentsModal-BhSWuzik.js.map
293
+ //# debugId=11a73724-d073-5b5a-8a5c-c166b7848241
@@ -1 +1 @@
1
- {"version":3,"file":"OpenFileDocumentsModal-DCrZnA6c.js","sources":["../src/utils/open-file-plan.ts","../src/components/modal/modals/OpenFileDocumentsModal.tsx"],"sourcesContent":["import { isDocumentTypeSupported } from \"@powerhousedao/reactor-browser\";\nimport type { Node } from \"@powerhousedao/shared/document-drive\";\nimport {\n getNextCopyNumber,\n isFileNode,\n} from \"@powerhousedao/shared/document-drive\";\n\n// Pure pre-flight planning for the open-file picker: given the pending files,\n// their parse results and the selected drive's nodes, decide per file whether\n// it can be imported, whether it collides with an existing document, and what\n// name it should be stored under. No reactor access — everything here derives\n// synchronously so the picker can recompute on every drive switch.\n\n/** What the one-time parse of a pending file yielded. */\nexport type ParsedFileInfo =\n | { state: \"parsed\"; id: string; documentType: string; headerName: string }\n // The document model isn't installed: the import path's package\n // auto-discovery may still resolve it, so the file stays importable —\n // but its header is unknown, so no duplicate check is possible.\n | { state: \"model-missing\" }\n // Corrupt zip / not a Powerhouse document.\n | { state: \"invalid\" };\n\nexport type PlannedRow =\n | { kind: \"checking\" }\n | { kind: \"invalid\" }\n | { kind: \"unsupported\" }\n | {\n kind: \"ready\";\n finalName: string;\n duplicate?: \"id\" | \"name\";\n renamed: boolean;\n };\n\nexport type PlanEntry = {\n /** Stable identity of the pending file (see pendingFileKey). */\n key: string;\n file: File;\n /** undefined while the parse is still in flight. */\n parsed: ParsedFileInfo | undefined;\n};\n\n/** Same name normalization the import stores (use-on-drop-file convention). */\nexport function storedFileName(file: File): string {\n return file.name.replace(/\\..+/gim, \"\");\n}\n\n/**\n * Duplicate semantics mirror the import path's isDocumentInLocation, scoped\n * to the drive ROOT: an id match, or a file node with the same name AND the\n * same document type. Renames follow the drive-tree copy convention\n * (\"name (copy) N\" via getNextCopyNumber). Names assigned within the batch\n * accumulate into the collision set, so two pending files that would store\n * the same name never end up identical either.\n */\nexport function planOpenFileImports(args: {\n entries: PlanEntry[];\n nodes: Node[];\n documentTypes: string[] | undefined;\n}): Map<string, PlannedRow> {\n const { entries, nodes, documentTypes } = args;\n const rootNodes = nodes.filter(\n (node) => (node.parentFolder ?? null) === null,\n );\n const rows = new Map<string, PlannedRow>();\n const assignedNames = new Set<string>();\n\n function uniqueName(base: string, driveNames: string[]): string {\n const collides = driveNames.includes(base) || assignedNames.has(base);\n if (!collides) return base;\n const candidates = [...driveNames, ...assignedNames];\n return `${base} (copy) ${getNextCopyNumber(candidates, base)}`;\n }\n\n for (const { key, file, parsed } of entries) {\n if (!parsed) {\n rows.set(key, { kind: \"checking\" });\n continue;\n }\n if (parsed.state === \"invalid\") {\n rows.set(key, { kind: \"invalid\" });\n continue;\n }\n\n if (parsed.state === \"model-missing\") {\n const base = storedFileName(file) || file.name;\n const finalName = uniqueName(base, []);\n assignedNames.add(finalName);\n rows.set(key, {\n kind: \"ready\",\n finalName,\n renamed: finalName !== base,\n });\n continue;\n }\n\n if (!isDocumentTypeSupported(parsed.documentType, documentTypes)) {\n rows.set(key, { kind: \"unsupported\" });\n continue;\n }\n\n // The stored name falls back to the document's own header name when the\n // file name is extension-only (\".phd\" normalizes to \"\").\n const base = storedFileName(file) || parsed.headerName;\n const sameTypeNames = rootNodes\n .filter(\n (node) => isFileNode(node) && node.documentType === parsed.documentType,\n )\n .map((node) => node.name);\n const idDuplicate = rootNodes.some((node) => node.id === parsed.id);\n const nameDuplicate = sameTypeNames.includes(base);\n\n const finalName = uniqueName(base, sameTypeNames);\n assignedNames.add(finalName);\n rows.set(key, {\n kind: \"ready\",\n finalName,\n duplicate: nameDuplicate ? \"name\" : idDuplicate ? \"id\" : undefined,\n renamed: finalName !== base,\n });\n }\n\n return rows;\n}\n","import { DriveIcon } from \"@powerhousedao/connect/components\";\nimport {\n clearPendingImportFiles,\n getPendingImportFiles,\n pendingFileKey,\n planOpenFileImports,\n runOpenFileImports,\n subscribePendingImportFiles,\n type ParsedFileInfo,\n type PlanEntry,\n type PlannedOpenFileImport,\n} from \"@powerhousedao/connect/utils\";\nimport { Modal } from \"@powerhousedao/design-system\";\nimport {\n Combobox,\n formatFileSize,\n ModalButton,\n} from \"@powerhousedao/design-system/connect\";\nimport {\n closePHModal,\n DocumentModelNotFoundError,\n loadFile,\n setSelectedDrive,\n showPHModal,\n useDocumentTypes,\n useDrives,\n usePHModal,\n useUserPermissions,\n} from \"@powerhousedao/reactor-browser\";\nimport { useEffect, useState, useSyncExternalStore } from \"react\";\nimport { useTranslation } from \"react-i18next\";\n\n// Drive picker for documents opened through the OS file association (PWA\n// File Handling). This is the flow's ONLY dialog state: validity and\n// duplicate checks run up-front against the selected drive (inline errors,\n// automatic \"(copy) N\" renames surfaced as \"Rename and import\"), and on\n// confirmation the dialog closes — progress is shown by the floating upload\n// panel (OpenFileUploadList) driven from utils/open-file-uploads.ts, the same\n// UI drag-and-drop uses.\n//\n// The component only mounts while the modal is shown (ModalsContainer keys on\n// the modal type), so picker state starts fresh on every open.\n\n// Parse results are cached at module level so they survive the create-drive\n// detour (which unmounts this component) and are computed once per pending\n// file — loadFile replays the file's full operation history. Only header\n// fields are retained, never the parsed document. In-flight promises are\n// cached too, deduplicating StrictMode double-effects.\nconst parseCache = new Map<string, ParsedFileInfo | Promise<ParsedFileInfo>>();\n\nasync function parsePendingFile(file: File): Promise<ParsedFileInfo> {\n try {\n const document = await loadFile(file);\n return {\n state: \"parsed\",\n id: document.header.id,\n documentType: document.header.documentType,\n headerName: document.header.name,\n };\n } catch (error) {\n // Missing document model ≠ invalid: the import path's package\n // auto-discovery may still resolve it.\n if (DocumentModelNotFoundError.isError(error)) {\n return { state: \"model-missing\" };\n }\n return { state: \"invalid\" };\n }\n}\n\nexport function OpenFileDocumentsModal() {\n const phModal = usePHModal();\n const open = phModal?.type === \"openFileDocuments\";\n const { t } = useTranslation();\n const drives = useDrives();\n const documentTypes = useDocumentTypes();\n const { isAllowedToCreateDocuments } = useUserPermissions();\n const pendingFiles = useSyncExternalStore(\n subscribePendingImportFiles,\n getPendingImportFiles,\n );\n\n const [pickedDriveId, setPickedDriveId] = useState<string>();\n const [, setParseVersion] = useState(0);\n\n // Kick off (and cache) the one-time parse of each pending file. Gated on\n // the reactor being ready — never cache \"reactor not initialized\" as a\n // parse result; the effect re-runs when files change and drives arriving\n // re-render the modal anyway.\n useEffect(() => {\n if (!window.ph?.reactorClient) return;\n let cancelled = false;\n const pendingKeys = new Set(pendingFiles.map(pendingFileKey));\n for (const key of parseCache.keys()) {\n if (!pendingKeys.has(key)) parseCache.delete(key);\n }\n for (const file of pendingFiles) {\n const key = pendingFileKey(file);\n if (parseCache.has(key)) continue;\n const promise = parsePendingFile(file).then((info) => {\n parseCache.set(key, info);\n return info;\n });\n parseCache.set(key, promise);\n void promise.then(() => {\n if (!cancelled) setParseVersion((version) => version + 1);\n });\n }\n return () => {\n cancelled = true;\n };\n }, [pendingFiles]);\n\n // The first drive is preselected so opening a file is a single\n // confirmation; the select lets the user switch destination.\n const selectedDriveId = pickedDriveId ?? drives?.[0]?.header.id;\n const selectedDrive = drives?.find(\n (drive) => drive.header.id === selectedDriveId,\n );\n\n const driveOptions = (drives ?? []).map((drive) => ({\n // New local drives carry their name only in the global state until the\n // header syncs.\n label: drive.header.name || drive.state.global.name,\n value: drive.header.id,\n drive,\n }));\n type DriveOption = (typeof driveOptions)[number];\n\n // Pure derivations — recomputed on drive switch, on files arriving, and on\n // parses settling.\n const entries: PlanEntry[] = pendingFiles.map((file) => {\n const cached = parseCache.get(pendingFileKey(file));\n return {\n key: pendingFileKey(file),\n file,\n parsed: cached instanceof Promise ? undefined : cached,\n };\n });\n const plan = selectedDrive\n ? planOpenFileImports({\n entries,\n nodes: selectedDrive.state.global.nodes,\n documentTypes,\n })\n : new Map<string, never>();\n\n const planRows = [...plan.values()];\n const readyCount = planRows.filter((row) => row.kind === \"ready\").length;\n const anyChecking = planRows.some((row) => row.kind === \"checking\");\n const anyRenamed = planRows.some(\n (row) => row.kind === \"ready\" && row.renamed,\n );\n\n function onImport() {\n const drive = selectedDrive;\n if (!drive) return;\n const imports: PlannedOpenFileImport[] = [];\n for (const { key, file } of entries) {\n const row = plan.get(key);\n if (row?.kind === \"ready\") imports.push({ file, name: row.finalName });\n }\n if (imports.length === 0) return;\n // Ordering matters: the pending store must be cleared BEFORE the modal\n // closes — the launch-queue listener reopens this picker whenever the\n // modal clears while files are still pending.\n clearPendingImportFiles();\n closePHModal();\n setSelectedDrive(drive);\n void runOpenFileImports({\n driveId: drive.header.id,\n imports,\n documentTypes,\n });\n }\n\n function onCancel() {\n clearPendingImportFiles();\n closePHModal();\n }\n\n if (!open) return null;\n\n const hasDrives = (drives?.length ?? 0) > 0;\n\n function rowAnnotation(key: string) {\n const row = plan.get(key);\n if (!row) return null;\n switch (row.kind) {\n case \"checking\":\n return (\n <span className=\"text-xs text-muted-foreground\">\n {t(\"modals.openFileDocuments.checking\")}\n </span>\n );\n case \"invalid\":\n return (\n <span className=\"text-xs text-destructive\">\n {t(\"modals.openFileDocuments.invalidFile\")}\n </span>\n );\n case \"unsupported\":\n return (\n <span className=\"text-xs text-destructive\">\n {t(\"modals.openFileDocuments.unsupportedType\")}\n </span>\n );\n case \"ready\":\n // \"name\": same name + type already in the drive, so the file is\n // renamed to a copy. \"id\": same document id, imported as a fresh copy\n // under its original name. A row that only got renamed to avoid\n // clashing with another file in THIS batch is NOT in the drive, so it\n // must not claim to be — it gets the neutral rename hint instead.\n if (row.duplicate === \"name\") {\n return (\n <span className=\"text-xs text-muted-foreground\">\n {t(\"modals.openFileDocuments.duplicateHint\", {\n name: row.finalName,\n })}\n </span>\n );\n }\n if (row.duplicate === \"id\") {\n return (\n <span className=\"text-xs text-muted-foreground\">\n {t(\"modals.openFileDocuments.duplicateCopyHint\")}\n </span>\n );\n }\n if (row.renamed) {\n return (\n <span className=\"text-xs text-muted-foreground\">\n {t(\"modals.openFileDocuments.renamedHint\", {\n name: row.finalName,\n })}\n </span>\n );\n }\n return null;\n }\n }\n\n return (\n <Modal\n open={open}\n onOpenChange={(status) => {\n if (!status) onCancel();\n }}\n // The drive select's dropdown must be able to spill past the dialog\n // bounds instead of being clipped (the menu cannot portal to <body>:\n // Radix's modal pointer-events lock would make it unclickable there).\n contentProps={{ className: \"overflow-visible\" }}\n >\n <div className=\"w-[520px] p-6\">\n <div className=\"pb-2 text-2xl font-bold text-foreground\">\n {t(\"modals.openFileDocuments.title\", {\n count: pendingFiles.length,\n })}\n </div>\n\n {!isAllowedToCreateDocuments ? (\n <>\n <div className=\"my-6 rounded-md bg-background p-4 text-center text-foreground\">\n {t(\"modals.openFileDocuments.notAllowed\")}\n </div>\n <div className=\"mt-8 flex\">\n <ModalButton variant=\"cancel\" onClick={onCancel}>\n {t(\"common.cancel\")}\n </ModalButton>\n </div>\n </>\n ) : (\n <>\n <div className=\"my-4 flex flex-col gap-1 text-sm text-foreground\">\n {pendingFiles.map((file, index) => {\n const key = pendingFileKey(file);\n const annotation = rowAnnotation(key);\n return (\n <div\n key={`${index}-${key}`}\n className=\"flex flex-col gap-0.5 rounded-md bg-background px-3 py-2\"\n >\n <div className=\"flex justify-between gap-2\">\n <span className=\"truncate\">{file.name}</span>\n <span className=\"shrink-0 text-muted-foreground\">\n {formatFileSize(file.size)}\n </span>\n </div>\n {annotation}\n </div>\n );\n })}\n </div>\n\n {hasDrives ? (\n <>\n <div className=\"mb-2 text-sm text-muted-foreground\">\n {t(\"modals.openFileDocuments.body\")}\n </div>\n <Combobox\n id=\"open-file-documents-drive\"\n isSearchable={false}\n options={driveOptions}\n value={\n driveOptions.find(\n (option) => option.value === selectedDriveId,\n ) ?? null\n }\n onChange={(option) =>\n setPickedDriveId((option as DriveOption).value)\n }\n formatOptionLabel={(option) => {\n const { label, drive } = option as DriveOption;\n return (\n <span className=\"flex items-center gap-2\">\n <DriveIcon drive={drive} />\n <span className=\"truncate\">{label}</span>\n </span>\n );\n }}\n maxMenuHeight={200}\n />\n </>\n ) : (\n <div className=\"my-6 rounded-md bg-background p-4 text-center text-foreground\">\n {t(\"modals.openFileDocuments.noDrives\")}\n </div>\n )}\n\n <div className=\"mt-8 flex justify-between gap-3\">\n <ModalButton variant=\"cancel\" onClick={onCancel}>\n {t(\"common.cancel\")}\n </ModalButton>\n {hasDrives ? (\n <ModalButton\n variant=\"confirm\"\n disabled={!selectedDriveId || readyCount === 0 || anyChecking}\n onClick={onImport}\n >\n {anyRenamed\n ? t(\"modals.openFileDocuments.renameAndImport\")\n : t(\"modals.openFileDocuments.import\")}\n </ModalButton>\n ) : (\n <ModalButton\n variant=\"confirm\"\n onClick={() => showPHModal({ type: \"addDrive\" })}\n >\n {t(\"modals.openFileDocuments.createDrive\")}\n </ModalButton>\n )}\n </div>\n </>\n )}\n </div>\n </Modal>\n );\n}\n"],"names":[],"mappings":"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","debug_id":"d82043cd-8807-560f-b39b-4261a300066e"}
1
+ {"version":3,"file":"OpenFileDocumentsModal-BhSWuzik.js","sources":["../src/utils/open-file-plan.ts","../src/components/modal/modals/OpenFileDocumentsModal.tsx"],"sourcesContent":["import { isDocumentTypeSupported } from \"@powerhousedao/reactor-browser\";\nimport type { Node } from \"@powerhousedao/shared/document-drive\";\nimport {\n getNextCopyNumber,\n isFileNode,\n} from \"@powerhousedao/shared/document-drive\";\n\n// Pure pre-flight planning for the open-file picker: given the pending files,\n// their parse results and the selected drive's nodes, decide per file whether\n// it can be imported, whether it collides with an existing document, and what\n// name it should be stored under. No reactor access — everything here derives\n// synchronously so the picker can recompute on every drive switch.\n\n/** What the one-time parse of a pending file yielded. */\nexport type ParsedFileInfo =\n | { state: \"parsed\"; id: string; documentType: string; headerName: string }\n // The document model isn't installed: the import path's package\n // auto-discovery may still resolve it, so the file stays importable —\n // but its header is unknown, so no duplicate check is possible.\n | { state: \"model-missing\" }\n // Corrupt zip / not a Powerhouse document.\n | { state: \"invalid\" };\n\nexport type PlannedRow =\n | { kind: \"checking\" }\n | { kind: \"invalid\" }\n | { kind: \"unsupported\" }\n | {\n kind: \"ready\";\n finalName: string;\n duplicate?: \"id\" | \"name\";\n renamed: boolean;\n };\n\nexport type PlanEntry = {\n /** Stable identity of the pending file (see pendingFileKey). */\n key: string;\n file: File;\n /** undefined while the parse is still in flight. */\n parsed: ParsedFileInfo | undefined;\n};\n\n/** Same name normalization the import stores (use-on-drop-file convention). */\nexport function storedFileName(file: File): string {\n return file.name.replace(/\\..+/gim, \"\");\n}\n\n/**\n * Duplicate semantics mirror the import path's isDocumentInLocation, scoped\n * to the drive ROOT: an id match, or a file node with the same name AND the\n * same document type. Renames follow the drive-tree copy convention\n * (\"name (copy) N\" via getNextCopyNumber). Names assigned within the batch\n * accumulate into the collision set, so two pending files that would store\n * the same name never end up identical either.\n */\nexport function planOpenFileImports(args: {\n entries: PlanEntry[];\n nodes: Node[];\n documentTypes: string[] | undefined;\n}): Map<string, PlannedRow> {\n const { entries, nodes, documentTypes } = args;\n const rootNodes = nodes.filter(\n (node) => (node.parentFolder ?? null) === null,\n );\n const rows = new Map<string, PlannedRow>();\n const assignedNames = new Set<string>();\n\n function uniqueName(base: string, driveNames: string[]): string {\n const collides = driveNames.includes(base) || assignedNames.has(base);\n if (!collides) return base;\n const candidates = [...driveNames, ...assignedNames];\n return `${base} (copy) ${getNextCopyNumber(candidates, base)}`;\n }\n\n for (const { key, file, parsed } of entries) {\n if (!parsed) {\n rows.set(key, { kind: \"checking\" });\n continue;\n }\n if (parsed.state === \"invalid\") {\n rows.set(key, { kind: \"invalid\" });\n continue;\n }\n\n if (parsed.state === \"model-missing\") {\n const base = storedFileName(file) || file.name;\n const finalName = uniqueName(base, []);\n assignedNames.add(finalName);\n rows.set(key, {\n kind: \"ready\",\n finalName,\n renamed: finalName !== base,\n });\n continue;\n }\n\n if (!isDocumentTypeSupported(parsed.documentType, documentTypes)) {\n rows.set(key, { kind: \"unsupported\" });\n continue;\n }\n\n // The stored name falls back to the document's own header name when the\n // file name is extension-only (\".phd\" normalizes to \"\").\n const base = storedFileName(file) || parsed.headerName;\n const sameTypeNames = rootNodes\n .filter(\n (node) => isFileNode(node) && node.documentType === parsed.documentType,\n )\n .map((node) => node.name);\n const idDuplicate = rootNodes.some((node) => node.id === parsed.id);\n const nameDuplicate = sameTypeNames.includes(base);\n\n const finalName = uniqueName(base, sameTypeNames);\n assignedNames.add(finalName);\n rows.set(key, {\n kind: \"ready\",\n finalName,\n duplicate: nameDuplicate ? \"name\" : idDuplicate ? \"id\" : undefined,\n renamed: finalName !== base,\n });\n }\n\n return rows;\n}\n","import { DriveIcon } from \"@powerhousedao/connect/components\";\nimport {\n clearPendingImportFiles,\n getPendingImportFiles,\n pendingFileKey,\n planOpenFileImports,\n runOpenFileImports,\n subscribePendingImportFiles,\n type ParsedFileInfo,\n type PlanEntry,\n type PlannedOpenFileImport,\n} from \"@powerhousedao/connect/utils\";\nimport { Modal } from \"@powerhousedao/design-system\";\nimport {\n Combobox,\n formatFileSize,\n ModalButton,\n} from \"@powerhousedao/design-system/connect\";\nimport {\n closePHModal,\n DocumentModelNotFoundError,\n loadFile,\n setSelectedDrive,\n showPHModal,\n useDocumentTypes,\n useDrives,\n usePHModal,\n useUserPermissions,\n} from \"@powerhousedao/reactor-browser\";\nimport { useEffect, useState, useSyncExternalStore } from \"react\";\nimport { useTranslation } from \"react-i18next\";\n\n// Drive picker for documents opened through the OS file association (PWA\n// File Handling). This is the flow's ONLY dialog state: validity and\n// duplicate checks run up-front against the selected drive (inline errors,\n// automatic \"(copy) N\" renames surfaced as \"Rename and import\"), and on\n// confirmation the dialog closes — progress is shown by the floating upload\n// panel (OpenFileUploadList) driven from utils/open-file-uploads.ts, the same\n// UI drag-and-drop uses.\n//\n// The component only mounts while the modal is shown (ModalsContainer keys on\n// the modal type), so picker state starts fresh on every open.\n\n// Parse results are cached at module level so they survive the create-drive\n// detour (which unmounts this component) and are computed once per pending\n// file — loadFile replays the file's full operation history. Only header\n// fields are retained, never the parsed document. In-flight promises are\n// cached too, deduplicating StrictMode double-effects.\nconst parseCache = new Map<string, ParsedFileInfo | Promise<ParsedFileInfo>>();\n\nasync function parsePendingFile(file: File): Promise<ParsedFileInfo> {\n try {\n const document = await loadFile(file);\n return {\n state: \"parsed\",\n id: document.header.id,\n documentType: document.header.documentType,\n headerName: document.header.name,\n };\n } catch (error) {\n // Missing document model ≠ invalid: the import path's package\n // auto-discovery may still resolve it.\n if (DocumentModelNotFoundError.isError(error)) {\n return { state: \"model-missing\" };\n }\n return { state: \"invalid\" };\n }\n}\n\nexport function OpenFileDocumentsModal() {\n const phModal = usePHModal();\n const open = phModal?.type === \"openFileDocuments\";\n const { t } = useTranslation();\n const drives = useDrives();\n const documentTypes = useDocumentTypes();\n const { isAllowedToCreateDocuments } = useUserPermissions();\n const pendingFiles = useSyncExternalStore(\n subscribePendingImportFiles,\n getPendingImportFiles,\n );\n\n const [pickedDriveId, setPickedDriveId] = useState<string>();\n const [, setParseVersion] = useState(0);\n\n // Kick off (and cache) the one-time parse of each pending file. Gated on\n // the reactor being ready — never cache \"reactor not initialized\" as a\n // parse result; the effect re-runs when files change and drives arriving\n // re-render the modal anyway.\n useEffect(() => {\n if (!window.ph?.reactorClient) return;\n let cancelled = false;\n const pendingKeys = new Set(pendingFiles.map(pendingFileKey));\n for (const key of parseCache.keys()) {\n if (!pendingKeys.has(key)) parseCache.delete(key);\n }\n for (const file of pendingFiles) {\n const key = pendingFileKey(file);\n if (parseCache.has(key)) continue;\n const promise = parsePendingFile(file).then((info) => {\n parseCache.set(key, info);\n return info;\n });\n parseCache.set(key, promise);\n void promise.then(() => {\n if (!cancelled) setParseVersion((version) => version + 1);\n });\n }\n return () => {\n cancelled = true;\n };\n }, [pendingFiles]);\n\n // The first drive is preselected so opening a file is a single\n // confirmation; the select lets the user switch destination.\n const selectedDriveId = pickedDriveId ?? drives?.[0]?.header.id;\n const selectedDrive = drives?.find(\n (drive) => drive.header.id === selectedDriveId,\n );\n\n const driveOptions = (drives ?? []).map((drive) => ({\n // New local drives carry their name only in the global state until the\n // header syncs.\n label: drive.header.name || drive.state.global.name,\n value: drive.header.id,\n drive,\n }));\n type DriveOption = (typeof driveOptions)[number];\n\n // Pure derivations — recomputed on drive switch, on files arriving, and on\n // parses settling.\n const entries: PlanEntry[] = pendingFiles.map((file) => {\n const cached = parseCache.get(pendingFileKey(file));\n return {\n key: pendingFileKey(file),\n file,\n parsed: cached instanceof Promise ? undefined : cached,\n };\n });\n const plan = selectedDrive\n ? planOpenFileImports({\n entries,\n nodes: selectedDrive.state.global.nodes,\n documentTypes,\n })\n : new Map<string, never>();\n\n const planRows = [...plan.values()];\n const readyCount = planRows.filter((row) => row.kind === \"ready\").length;\n const anyChecking = planRows.some((row) => row.kind === \"checking\");\n const anyRenamed = planRows.some(\n (row) => row.kind === \"ready\" && row.renamed,\n );\n\n function onImport() {\n const drive = selectedDrive;\n if (!drive) return;\n const imports: PlannedOpenFileImport[] = [];\n for (const { key, file } of entries) {\n const row = plan.get(key);\n if (row?.kind === \"ready\") imports.push({ file, name: row.finalName });\n }\n if (imports.length === 0) return;\n // Ordering matters: the pending store must be cleared BEFORE the modal\n // closes — the launch-queue listener reopens this picker whenever the\n // modal clears while files are still pending.\n clearPendingImportFiles();\n closePHModal();\n setSelectedDrive(drive);\n void runOpenFileImports({\n driveId: drive.header.id,\n imports,\n documentTypes,\n });\n }\n\n function onCancel() {\n clearPendingImportFiles();\n closePHModal();\n }\n\n if (!open) return null;\n\n const hasDrives = (drives?.length ?? 0) > 0;\n\n function rowAnnotation(key: string) {\n const row = plan.get(key);\n if (!row) return null;\n switch (row.kind) {\n case \"checking\":\n return (\n <span className=\"text-xs text-muted-foreground\">\n {t(\"modals.openFileDocuments.checking\")}\n </span>\n );\n case \"invalid\":\n return (\n <span className=\"text-xs text-destructive\">\n {t(\"modals.openFileDocuments.invalidFile\")}\n </span>\n );\n case \"unsupported\":\n return (\n <span className=\"text-xs text-destructive\">\n {t(\"modals.openFileDocuments.unsupportedType\")}\n </span>\n );\n case \"ready\":\n // \"name\": same name + type already in the drive, so the file is\n // renamed to a copy. \"id\": same document id, imported as a fresh copy\n // under its original name. A row that only got renamed to avoid\n // clashing with another file in THIS batch is NOT in the drive, so it\n // must not claim to be — it gets the neutral rename hint instead.\n if (row.duplicate === \"name\") {\n return (\n <span className=\"text-xs text-muted-foreground\">\n {t(\"modals.openFileDocuments.duplicateHint\", {\n name: row.finalName,\n })}\n </span>\n );\n }\n if (row.duplicate === \"id\") {\n return (\n <span className=\"text-xs text-muted-foreground\">\n {t(\"modals.openFileDocuments.duplicateCopyHint\")}\n </span>\n );\n }\n if (row.renamed) {\n return (\n <span className=\"text-xs text-muted-foreground\">\n {t(\"modals.openFileDocuments.renamedHint\", {\n name: row.finalName,\n })}\n </span>\n );\n }\n return null;\n }\n }\n\n return (\n <Modal\n open={open}\n onOpenChange={(status) => {\n if (!status) onCancel();\n }}\n // The drive select's dropdown must be able to spill past the dialog\n // bounds instead of being clipped (the menu cannot portal to <body>:\n // Radix's modal pointer-events lock would make it unclickable there).\n contentProps={{ className: \"overflow-visible\" }}\n >\n <div className=\"w-[520px] p-6\">\n <div className=\"pb-2 text-2xl font-bold text-foreground\">\n {t(\"modals.openFileDocuments.title\", {\n count: pendingFiles.length,\n })}\n </div>\n\n {!isAllowedToCreateDocuments ? (\n <>\n <div className=\"my-6 rounded-md bg-background p-4 text-center text-foreground\">\n {t(\"modals.openFileDocuments.notAllowed\")}\n </div>\n <div className=\"mt-8 flex\">\n <ModalButton variant=\"cancel\" onClick={onCancel}>\n {t(\"common.cancel\")}\n </ModalButton>\n </div>\n </>\n ) : (\n <>\n <div className=\"my-4 flex flex-col gap-1 text-sm text-foreground\">\n {pendingFiles.map((file, index) => {\n const key = pendingFileKey(file);\n const annotation = rowAnnotation(key);\n return (\n <div\n key={`${index}-${key}`}\n className=\"flex flex-col gap-0.5 rounded-md bg-background px-3 py-2\"\n >\n <div className=\"flex justify-between gap-2\">\n <span className=\"truncate\">{file.name}</span>\n <span className=\"shrink-0 text-muted-foreground\">\n {formatFileSize(file.size)}\n </span>\n </div>\n {annotation}\n </div>\n );\n })}\n </div>\n\n {hasDrives ? (\n <>\n <div className=\"mb-2 text-sm text-muted-foreground\">\n {t(\"modals.openFileDocuments.body\")}\n </div>\n <Combobox\n id=\"open-file-documents-drive\"\n isSearchable={false}\n options={driveOptions}\n value={\n driveOptions.find(\n (option) => option.value === selectedDriveId,\n ) ?? null\n }\n onChange={(option) =>\n setPickedDriveId((option as DriveOption).value)\n }\n formatOptionLabel={(option) => {\n const { label, drive } = option as DriveOption;\n return (\n <span className=\"flex items-center gap-2\">\n <DriveIcon drive={drive} />\n <span className=\"truncate\">{label}</span>\n </span>\n );\n }}\n maxMenuHeight={200}\n />\n </>\n ) : (\n <div className=\"my-6 rounded-md bg-background p-4 text-center text-foreground\">\n {t(\"modals.openFileDocuments.noDrives\")}\n </div>\n )}\n\n <div className=\"mt-8 flex justify-between gap-3\">\n <ModalButton variant=\"cancel\" onClick={onCancel}>\n {t(\"common.cancel\")}\n </ModalButton>\n {hasDrives ? (\n <ModalButton\n variant=\"confirm\"\n disabled={!selectedDriveId || readyCount === 0 || anyChecking}\n onClick={onImport}\n >\n {anyRenamed\n ? t(\"modals.openFileDocuments.renameAndImport\")\n : t(\"modals.openFileDocuments.import\")}\n </ModalButton>\n ) : (\n <ModalButton\n variant=\"confirm\"\n onClick={() => showPHModal({ type: \"addDrive\" })}\n >\n {t(\"modals.openFileDocuments.createDrive\")}\n </ModalButton>\n )}\n </div>\n </>\n )}\n </div>\n </Modal>\n );\n}\n"],"names":[],"mappings":"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","debug_id":"11a73724-d073-5b5a-8a5c-c166b7848241"}
@@ -1,8 +1,8 @@
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]="a1de242c-bdbe-5781-8009-4f46499b422a")}catch(e){}}();
3
- import { t as package_default } from "./package-Bc_Nktb7.js";
4
- import { i as shortGitSha, n as getGitUrl, t as getGitSha } from "./build-info-Do0SMo9O.js";
5
- import { r as connectConfig } from "./connect.config-vgUeFoNp.js";
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]="f2a64222-ae8b-5562-b3bf-6f4a73480d2c")}catch(e){}}();
3
+ import { t as package_default } from "./package-B1sniFBZ.js";
4
+ import { i as shortGitSha, n as getGitUrl, t as getGitSha } from "./build-info-BcBkHhsx.js";
5
+ import { r as connectConfig } from "./connect.config-C-b_Yhd6.js";
6
6
  import { n as toast } from "./toast-BLv8rjmy.js";
7
7
  import { t as useRegistryPackages } from "./useRegistryPackages-DMhCvTWq.js";
8
8
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -298,5 +298,5 @@ const SettingsModal = () => {
298
298
  //#endregion
299
299
  export { SettingsModal };
300
300
 
301
- //# sourceMappingURL=SettingsModal-BsYFJB2W.js.map
302
- //# debugId=a1de242c-bdbe-5781-8009-4f46499b422a
301
+ //# sourceMappingURL=SettingsModal-CeSSSHVv.js.map
302
+ //# debugId=f2a64222-ae8b-5562-b3bf-6f4a73480d2c
@@ -1 +1 @@
1
- {"version":3,"file":"SettingsModal-BsYFJB2W.js","sources":["../src/components/modal/modals/settings/about.tsx","../src/components/modal/modals/settings/danger-zone.tsx","../src/components/modal/modals/settings/default-editor.tsx","../src/components/modal/modals/settings/package-manager.tsx","../src/components/modal/modals/SettingsModal.tsx"],"sourcesContent":["import { connectConfig } from \"@powerhousedao/connect/config\";\nimport {\n getGitSha,\n getGitUrl,\n packageJson,\n shortGitSha,\n} from \"@powerhousedao/connect/utils\";\nimport { Icon } from \"@powerhousedao/design-system\";\nimport { About as BaseAbout } from \"@powerhousedao/design-system/connect\";\nimport {\n closePHModal,\n DriveCollectionId,\n showPHModal,\n useDrives,\n useDriveSystemInfo,\n useSyncList,\n} from \"@powerhousedao/reactor-browser\";\nimport type { DocumentDriveDocument } from \"@powerhousedao/shared/document-drive\";\nimport { useMemo } from \"react\";\n\nexport const About: React.FC = () => {\n const onOpenInspector = () => {\n closePHModal();\n showPHModal({ type: \"inspector\" });\n };\n\n return (\n <div>\n <BaseAbout\n packageJson={packageJson}\n phCliVersion={\n typeof connectConfig.phCliVersion === \"string\"\n ? connectConfig.phCliVersion\n : undefined\n }\n />\n <AppGitHash />\n <ConnectedDrives />\n <div className=\"bg-background p-3\">\n <h2 className=\"mb-2 font-semibold text-foreground\">Inspector</h2>\n <p className=\"mb-3 text-sm font-normal text-foreground\">\n Explore the local database and sync state for debugging.\n </p>\n <button\n className=\"flex items-center gap-x-2 rounded-md border border-border bg-transparent px-3 py-1 text-sm font-medium text-foreground transition-colors hover:hover-effect\"\n onClick={onOpenInspector}\n type=\"button\"\n >\n Open Inspector <Icon name=\"CircleInfo\" size={16} />\n </button>\n </div>\n </div>\n );\n};\n\nfunction AppGitHash() {\n const sha = getGitSha();\n if (sha === \"unknown\") return null;\n const url = getGitUrl();\n const label = shortGitSha(sha);\n return (\n <div className=\"bg-background p-3 text-sm\">\n <span className=\"font-semibold\">Git hash: </span>\n {url ? (\n <a\n className=\"font-mono underline\"\n href={url}\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n title={sha}\n >\n {label}\n </a>\n ) : (\n <span className=\"font-mono\" title={sha}>\n {label}\n </span>\n )}\n </div>\n );\n}\n\nfunction ConnectedDrives() {\n const drives = useDrives() ?? [];\n const remotes = useSyncList();\n\n const remoteDrives = useMemo(\n () =>\n drives.filter((d) =>\n remotes.some((r) =>\n r.meta.collectionId.equals(DriveCollectionId.forDrive(d.header.id)),\n ),\n ),\n [drives, remotes],\n );\n\n return (\n <div className=\"my-4 bg-background p-3\">\n <h2 className=\"mb-2 font-semibold text-foreground\">Connected drives</h2>\n {remoteDrives.length === 0 ? (\n <p className=\"text-sm font-normal text-foreground\">\n No connected remote drives.\n </p>\n ) : (\n <ul className=\"flex flex-col gap-3\">\n {remoteDrives.map((drive) => (\n <DriveAboutEntry key={drive.header.id} drive={drive} />\n ))}\n </ul>\n )}\n </div>\n );\n}\n\nfunction DriveAboutEntry({ drive }: { drive: DocumentDriveDocument }) {\n const info = useDriveSystemInfo(drive);\n const name = drive.state.global.name || drive.header.name;\n\n return (\n <li className=\"text-sm text-foreground\">\n <div className=\"flex items-baseline gap-2\">\n <span className=\"font-medium\">{name}</span>\n {info.status === \"ready\" && (\n <span className=\"text-xs text-muted-foreground\">{info.host}</span>\n )}\n </div>\n {info.status === \"loading\" && (\n <div className=\"mt-1 text-xs text-muted-foreground\">Loading…</div>\n )}\n {info.status === \"error\" && (\n <div className=\"mt-1 text-xs text-destructive\">\n Could not load system info\n </div>\n )}\n {info.status === \"ready\" && (\n <div className=\"mt-1 text-xs text-foreground\">\n <div>\n <span className=\"font-medium\">Version:</span> {info.version}\n </div>\n <div>\n <span className=\"font-medium\">Git hash: </span>\n {info.gitUrl ? (\n <a\n className=\"font-mono hover:underline\"\n href={info.gitUrl}\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n title={info.gitHash}\n >\n {shortGitSha(info.gitHash)}\n </a>\n ) : (\n <span className=\"font-mono\" title={info.gitHash}>\n {shortGitSha(info.gitHash)}\n </span>\n )}\n </div>\n </div>\n )}\n {info.status === \"local\" && (\n <div className=\"mt-1 text-xs text-muted-foreground\">\n Local drive — N/A\n </div>\n )}\n </li>\n );\n}\n","import { DangerZone as BaseDangerZone } from \"@powerhousedao/design-system/connect\";\nimport {\n deleteDrive,\n setSelectedDrive,\n showPHModal,\n useDrives,\n} from \"@powerhousedao/reactor-browser\";\nimport type { DocumentDriveDocument } from \"@powerhousedao/shared/document-drive\";\n\nexport const DangerZone: React.FC = () => {\n const drives = useDrives();\n\n const handleDeleteDrive = async (drive: DocumentDriveDocument) => {\n await deleteDrive(drive.header.id);\n setSelectedDrive(undefined);\n };\n\n const handleClearStorage = () => {\n showPHModal({ type: \"clearStorage\" });\n };\n\n return (\n <BaseDangerZone\n drives={drives ?? []}\n onDeleteDrive={(drive) => {\n void handleDeleteDrive(drive);\n }}\n onClearStorage={handleClearStorage}\n />\n );\n};\n","import { DefaultEditor as BaseDefaultEditor } from \"@powerhousedao/design-system/connect\";\nimport { useCallback, useState } from \"react\";\n\nconst documentModelEditorOptions = [\n { label: \"V1\", value: \"document-model-editor\" },\n { label: \"V2\", value: \"document-model-editor-v2\" },\n] as const;\n\nexport const DefaultEditor: React.FC = () => {\n const [documentModelEditor, setDocumentModelEditor] = useState<\n (typeof documentModelEditorOptions)[number]\n >(documentModelEditorOptions[1]);\n\n const handleSetDocumentEditor = useCallback((value: string) => {\n const option = documentModelEditorOptions.find((dm) => dm.value == value);\n if (option) {\n setDocumentModelEditor(option);\n }\n }, []);\n\n return (\n <BaseDefaultEditor\n documentModelEditor={documentModelEditor.value}\n setDocumentModelEditor={handleSetDocumentEditor}\n documentModelEditorOptions={\n documentModelEditorOptions as unknown as {\n value: string;\n label: string;\n }[]\n }\n />\n );\n};\n","import { useRegistryPackages } from \"@powerhousedao/connect/hooks\";\nimport { toast } from \"@powerhousedao/connect/services\";\nimport { PackageManager } from \"@powerhousedao/design-system/connect\";\nimport { useVetraPackageManager } from \"@powerhousedao/reactor-browser\";\nimport React from \"react\";\n\n/**\n * Split a `name@tag` spec into its bare package name. Mirrors the design-system's\n * `parsePackageSpec` — duplicated here to avoid reaching into a deep subpath\n * export. Scoped names split on the LAST `@`, unscoped on the first.\n */\nfunction parseBareName(spec: string): string {\n const trimmed = spec.trim();\n const at = trimmed.startsWith(\"@\")\n ? trimmed.lastIndexOf(\"@\")\n : trimmed.indexOf(\"@\");\n return at > 0 ? trimmed.slice(0, at) : trimmed;\n}\n\nexport const ConnectPackageManager: React.FC = () => {\n const packageManager = useVetraPackageManager();\n const {\n registryPackageList,\n installedPackages,\n availablePackages,\n availableHasMore,\n isLoadingAvailable,\n isLoadingMoreAvailable,\n availableError,\n ensureAvailableLoaded,\n fetchAvailablePage,\n loadMoreAvailable,\n setAvailableSearch,\n updateRegistryPackageStatus,\n registerFallbackRegistryPackage,\n } = useRegistryPackages();\n\n async function handleInstall(packageSpec: string) {\n if (!packageManager) return;\n\n // The spec may include an explicit `@tag` / `@version` suffix from the\n // search input. Pass it through to the package manager as-is (the CDN\n // route already handles `name@tag` specs), but track status under the\n // bare name so the Settings list doesn't fragment.\n const bareName = parseBareName(packageSpec);\n // Packages that were in `/packages` when the user clicked Install go\n // through `updateRegistryPackageStatus` and hit an existing entry.\n // Packages that landed via the npm-uplink fallback weren't in the list,\n // so we register them explicitly rather than silently upserting a\n // placeholder — keeping the \"does not exist\" error as a signal for any\n // other code path that reaches update without a matching entry.\n const wasKnownToRegistry = registryPackageList.some(\n (p) => p.name === bareName,\n );\n const result = await packageManager.addPackage(packageSpec);\n if (result.type === \"success\") {\n if (wasKnownToRegistry) {\n updateRegistryPackageStatus(bareName, \"registry-install\");\n } else {\n registerFallbackRegistryPackage(\n bareName,\n result.package,\n packageManager.getPackageVersion(bareName) ??\n packageManager.getPackageVersion(packageSpec),\n \"registry-install\",\n );\n }\n toast(`Package \"${packageSpec}\" installed successfully`, {\n type: \"connect-success\",\n });\n } else {\n const message = result.error.message;\n console.error(\n `[Connect][PackageManager] Install failed for \"${packageSpec}\":`,\n result.error,\n );\n // `BrowserPackageManager` raises a generic \"Failed to fetch dynamically\n // imported module\" when the registry CDN returns an error. That covers\n // both \"the name exists nowhere (not on this registry AND not on the\n // npmjs uplink)\" and \"the tarball is there but doesn't look like a\n // Powerhouse package\". Map to plain-language copy — never dump the raw\n // API / loader message into the toast.\n const isLikelyNotFound = /failed to fetch|404|not found/i.test(message);\n const userMessage = isLikelyNotFound\n ? `Couldn't install \"${packageSpec}\". It isn't available on this registry or via npm.`\n : `Couldn't install \"${packageSpec}\". Please try again.`;\n toast(userMessage, { type: \"error\" });\n }\n }\n\n function handleUninstall(packageName: string) {\n if (!packageManager) return;\n try {\n packageManager.removePackage(packageName);\n updateRegistryPackageStatus(packageName, \"available\");\n\n toast(`Package \"${packageName}\" uninstalled successfully`, {\n type: \"connect-success\",\n });\n } catch (error) {\n console.error(\n `[Connect][PackageManager] Uninstall failed for \"${packageName}\":`,\n error,\n );\n toast(`Couldn't uninstall \"${packageName}\". Please try again.`, {\n type: \"error\",\n });\n }\n }\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <PackageManager\n mutable={true}\n installedPackages={installedPackages}\n availablePackages={availablePackages}\n isAvailableLoading={isLoadingAvailable}\n isLoadingMoreAvailable={isLoadingMoreAvailable}\n hasMoreAvailable={availableHasMore}\n onLoadMoreAvailable={loadMoreAvailable}\n availableError={availableError}\n onAvailableRetry={() => {\n void fetchAvailablePage({ reset: true });\n }}\n onAvailableSearchChange={setAvailableSearch}\n onAvailableTabOpen={ensureAvailableLoaded}\n onInstall={handleInstall}\n onUninstall={handleUninstall}\n />\n </div>\n );\n};\n","import {\n SettingsModal as SettingsModalV2,\n ThemeSwitch,\n} from \"@powerhousedao/design-system/connect\";\nimport { closePHModal, usePHModal } from \"@powerhousedao/reactor-browser\";\nimport { t } from \"i18next\";\nimport { CircleHelp, Package, PenLine, TriangleAlert } from \"lucide-react\";\nimport React, { useMemo } from \"react\";\nimport { About } from \"./settings/about.js\";\nimport { DangerZone } from \"./settings/danger-zone.js\";\nimport { DefaultEditor } from \"./settings/default-editor.js\";\nimport { ConnectPackageManager } from \"./settings/package-manager.js\";\n\nconst iconProps = { size: 16 } as const;\n\nexport const SettingsModal: React.FC = () => {\n const phModal = usePHModal();\n const open = phModal?.type === \"settings\";\n\n const tabs = useMemo(\n () => [\n {\n id: \"package-manager\",\n icon: <Package {...iconProps} />,\n label: \"Package Manager\",\n content: ConnectPackageManager,\n },\n {\n id: \"default-editors\",\n icon: <PenLine {...iconProps} />,\n label: \"Default Editors\",\n content: DefaultEditor,\n },\n {\n id: \"danger-zone\",\n icon: <TriangleAlert {...iconProps} className=\"text-destructive\" />,\n label: <span className=\"text-destructive\">Danger Zone</span>,\n content: () => <DangerZone />,\n },\n {\n id: \"about\",\n icon: <CircleHelp {...iconProps} />,\n label: \"About\",\n content: About,\n },\n ],\n [],\n );\n\n return (\n <SettingsModalV2\n open={open}\n title={t(\"modals.connectSettings.title\")}\n onOpenChange={(status: boolean) => {\n if (!status) return closePHModal();\n }}\n tabs={tabs}\n navFooter={<ThemeSwitch horizontal />}\n />\n );\n};\n"],"names":["About","BaseAbout","packageJson","DangerZone","BaseDangerZone","DefaultEditor","BaseDefaultEditor","DefaultEditor","DangerZone","About","SettingsModalV2"],"mappings":"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","debug_id":"a1de242c-bdbe-5781-8009-4f46499b422a"}
1
+ {"version":3,"file":"SettingsModal-CeSSSHVv.js","sources":["../src/components/modal/modals/settings/about.tsx","../src/components/modal/modals/settings/danger-zone.tsx","../src/components/modal/modals/settings/default-editor.tsx","../src/components/modal/modals/settings/package-manager.tsx","../src/components/modal/modals/SettingsModal.tsx"],"sourcesContent":["import { connectConfig } from \"@powerhousedao/connect/config\";\nimport {\n getGitSha,\n getGitUrl,\n packageJson,\n shortGitSha,\n} from \"@powerhousedao/connect/utils\";\nimport { Icon } from \"@powerhousedao/design-system\";\nimport { About as BaseAbout } from \"@powerhousedao/design-system/connect\";\nimport {\n closePHModal,\n DriveCollectionId,\n showPHModal,\n useDrives,\n useDriveSystemInfo,\n useSyncList,\n} from \"@powerhousedao/reactor-browser\";\nimport type { DocumentDriveDocument } from \"@powerhousedao/shared/document-drive\";\nimport { useMemo } from \"react\";\n\nexport const About: React.FC = () => {\n const onOpenInspector = () => {\n closePHModal();\n showPHModal({ type: \"inspector\" });\n };\n\n return (\n <div>\n <BaseAbout\n packageJson={packageJson}\n phCliVersion={\n typeof connectConfig.phCliVersion === \"string\"\n ? connectConfig.phCliVersion\n : undefined\n }\n />\n <AppGitHash />\n <ConnectedDrives />\n <div className=\"bg-background p-3\">\n <h2 className=\"mb-2 font-semibold text-foreground\">Inspector</h2>\n <p className=\"mb-3 text-sm font-normal text-foreground\">\n Explore the local database and sync state for debugging.\n </p>\n <button\n className=\"flex items-center gap-x-2 rounded-md border border-border bg-transparent px-3 py-1 text-sm font-medium text-foreground transition-colors hover:hover-effect\"\n onClick={onOpenInspector}\n type=\"button\"\n >\n Open Inspector <Icon name=\"CircleInfo\" size={16} />\n </button>\n </div>\n </div>\n );\n};\n\nfunction AppGitHash() {\n const sha = getGitSha();\n if (sha === \"unknown\") return null;\n const url = getGitUrl();\n const label = shortGitSha(sha);\n return (\n <div className=\"bg-background p-3 text-sm\">\n <span className=\"font-semibold\">Git hash: </span>\n {url ? (\n <a\n className=\"font-mono underline\"\n href={url}\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n title={sha}\n >\n {label}\n </a>\n ) : (\n <span className=\"font-mono\" title={sha}>\n {label}\n </span>\n )}\n </div>\n );\n}\n\nfunction ConnectedDrives() {\n const drives = useDrives() ?? [];\n const remotes = useSyncList();\n\n const remoteDrives = useMemo(\n () =>\n drives.filter((d) =>\n remotes.some((r) =>\n r.meta.collectionId.equals(DriveCollectionId.forDrive(d.header.id)),\n ),\n ),\n [drives, remotes],\n );\n\n return (\n <div className=\"my-4 bg-background p-3\">\n <h2 className=\"mb-2 font-semibold text-foreground\">Connected drives</h2>\n {remoteDrives.length === 0 ? (\n <p className=\"text-sm font-normal text-foreground\">\n No connected remote drives.\n </p>\n ) : (\n <ul className=\"flex flex-col gap-3\">\n {remoteDrives.map((drive) => (\n <DriveAboutEntry key={drive.header.id} drive={drive} />\n ))}\n </ul>\n )}\n </div>\n );\n}\n\nfunction DriveAboutEntry({ drive }: { drive: DocumentDriveDocument }) {\n const info = useDriveSystemInfo(drive);\n const name = drive.state.global.name || drive.header.name;\n\n return (\n <li className=\"text-sm text-foreground\">\n <div className=\"flex items-baseline gap-2\">\n <span className=\"font-medium\">{name}</span>\n {info.status === \"ready\" && (\n <span className=\"text-xs text-muted-foreground\">{info.host}</span>\n )}\n </div>\n {info.status === \"loading\" && (\n <div className=\"mt-1 text-xs text-muted-foreground\">Loading…</div>\n )}\n {info.status === \"error\" && (\n <div className=\"mt-1 text-xs text-destructive\">\n Could not load system info\n </div>\n )}\n {info.status === \"ready\" && (\n <div className=\"mt-1 text-xs text-foreground\">\n <div>\n <span className=\"font-medium\">Version:</span> {info.version}\n </div>\n <div>\n <span className=\"font-medium\">Git hash: </span>\n {info.gitUrl ? (\n <a\n className=\"font-mono hover:underline\"\n href={info.gitUrl}\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n title={info.gitHash}\n >\n {shortGitSha(info.gitHash)}\n </a>\n ) : (\n <span className=\"font-mono\" title={info.gitHash}>\n {shortGitSha(info.gitHash)}\n </span>\n )}\n </div>\n </div>\n )}\n {info.status === \"local\" && (\n <div className=\"mt-1 text-xs text-muted-foreground\">\n Local drive — N/A\n </div>\n )}\n </li>\n );\n}\n","import { DangerZone as BaseDangerZone } from \"@powerhousedao/design-system/connect\";\nimport {\n deleteDrive,\n setSelectedDrive,\n showPHModal,\n useDrives,\n} from \"@powerhousedao/reactor-browser\";\nimport type { DocumentDriveDocument } from \"@powerhousedao/shared/document-drive\";\n\nexport const DangerZone: React.FC = () => {\n const drives = useDrives();\n\n const handleDeleteDrive = async (drive: DocumentDriveDocument) => {\n await deleteDrive(drive.header.id);\n setSelectedDrive(undefined);\n };\n\n const handleClearStorage = () => {\n showPHModal({ type: \"clearStorage\" });\n };\n\n return (\n <BaseDangerZone\n drives={drives ?? []}\n onDeleteDrive={(drive) => {\n void handleDeleteDrive(drive);\n }}\n onClearStorage={handleClearStorage}\n />\n );\n};\n","import { DefaultEditor as BaseDefaultEditor } from \"@powerhousedao/design-system/connect\";\nimport { useCallback, useState } from \"react\";\n\nconst documentModelEditorOptions = [\n { label: \"V1\", value: \"document-model-editor\" },\n { label: \"V2\", value: \"document-model-editor-v2\" },\n] as const;\n\nexport const DefaultEditor: React.FC = () => {\n const [documentModelEditor, setDocumentModelEditor] = useState<\n (typeof documentModelEditorOptions)[number]\n >(documentModelEditorOptions[1]);\n\n const handleSetDocumentEditor = useCallback((value: string) => {\n const option = documentModelEditorOptions.find((dm) => dm.value == value);\n if (option) {\n setDocumentModelEditor(option);\n }\n }, []);\n\n return (\n <BaseDefaultEditor\n documentModelEditor={documentModelEditor.value}\n setDocumentModelEditor={handleSetDocumentEditor}\n documentModelEditorOptions={\n documentModelEditorOptions as unknown as {\n value: string;\n label: string;\n }[]\n }\n />\n );\n};\n","import { useRegistryPackages } from \"@powerhousedao/connect/hooks\";\nimport { toast } from \"@powerhousedao/connect/services\";\nimport { PackageManager } from \"@powerhousedao/design-system/connect\";\nimport { useVetraPackageManager } from \"@powerhousedao/reactor-browser\";\nimport React from \"react\";\n\n/**\n * Split a `name@tag` spec into its bare package name. Mirrors the design-system's\n * `parsePackageSpec` — duplicated here to avoid reaching into a deep subpath\n * export. Scoped names split on the LAST `@`, unscoped on the first.\n */\nfunction parseBareName(spec: string): string {\n const trimmed = spec.trim();\n const at = trimmed.startsWith(\"@\")\n ? trimmed.lastIndexOf(\"@\")\n : trimmed.indexOf(\"@\");\n return at > 0 ? trimmed.slice(0, at) : trimmed;\n}\n\nexport const ConnectPackageManager: React.FC = () => {\n const packageManager = useVetraPackageManager();\n const {\n registryPackageList,\n installedPackages,\n availablePackages,\n availableHasMore,\n isLoadingAvailable,\n isLoadingMoreAvailable,\n availableError,\n ensureAvailableLoaded,\n fetchAvailablePage,\n loadMoreAvailable,\n setAvailableSearch,\n updateRegistryPackageStatus,\n registerFallbackRegistryPackage,\n } = useRegistryPackages();\n\n async function handleInstall(packageSpec: string) {\n if (!packageManager) return;\n\n // The spec may include an explicit `@tag` / `@version` suffix from the\n // search input. Pass it through to the package manager as-is (the CDN\n // route already handles `name@tag` specs), but track status under the\n // bare name so the Settings list doesn't fragment.\n const bareName = parseBareName(packageSpec);\n // Packages that were in `/packages` when the user clicked Install go\n // through `updateRegistryPackageStatus` and hit an existing entry.\n // Packages that landed via the npm-uplink fallback weren't in the list,\n // so we register them explicitly rather than silently upserting a\n // placeholder — keeping the \"does not exist\" error as a signal for any\n // other code path that reaches update without a matching entry.\n const wasKnownToRegistry = registryPackageList.some(\n (p) => p.name === bareName,\n );\n const result = await packageManager.addPackage(packageSpec);\n if (result.type === \"success\") {\n if (wasKnownToRegistry) {\n updateRegistryPackageStatus(bareName, \"registry-install\");\n } else {\n registerFallbackRegistryPackage(\n bareName,\n result.package,\n packageManager.getPackageVersion(bareName) ??\n packageManager.getPackageVersion(packageSpec),\n \"registry-install\",\n );\n }\n toast(`Package \"${packageSpec}\" installed successfully`, {\n type: \"connect-success\",\n });\n } else {\n const message = result.error.message;\n console.error(\n `[Connect][PackageManager] Install failed for \"${packageSpec}\":`,\n result.error,\n );\n // `BrowserPackageManager` raises a generic \"Failed to fetch dynamically\n // imported module\" when the registry CDN returns an error. That covers\n // both \"the name exists nowhere (not on this registry AND not on the\n // npmjs uplink)\" and \"the tarball is there but doesn't look like a\n // Powerhouse package\". Map to plain-language copy — never dump the raw\n // API / loader message into the toast.\n const isLikelyNotFound = /failed to fetch|404|not found/i.test(message);\n const userMessage = isLikelyNotFound\n ? `Couldn't install \"${packageSpec}\". It isn't available on this registry or via npm.`\n : `Couldn't install \"${packageSpec}\". Please try again.`;\n toast(userMessage, { type: \"error\" });\n }\n }\n\n function handleUninstall(packageName: string) {\n if (!packageManager) return;\n try {\n packageManager.removePackage(packageName);\n updateRegistryPackageStatus(packageName, \"available\");\n\n toast(`Package \"${packageName}\" uninstalled successfully`, {\n type: \"connect-success\",\n });\n } catch (error) {\n console.error(\n `[Connect][PackageManager] Uninstall failed for \"${packageName}\":`,\n error,\n );\n toast(`Couldn't uninstall \"${packageName}\". Please try again.`, {\n type: \"error\",\n });\n }\n }\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <PackageManager\n mutable={true}\n installedPackages={installedPackages}\n availablePackages={availablePackages}\n isAvailableLoading={isLoadingAvailable}\n isLoadingMoreAvailable={isLoadingMoreAvailable}\n hasMoreAvailable={availableHasMore}\n onLoadMoreAvailable={loadMoreAvailable}\n availableError={availableError}\n onAvailableRetry={() => {\n void fetchAvailablePage({ reset: true });\n }}\n onAvailableSearchChange={setAvailableSearch}\n onAvailableTabOpen={ensureAvailableLoaded}\n onInstall={handleInstall}\n onUninstall={handleUninstall}\n />\n </div>\n );\n};\n","import {\n SettingsModal as SettingsModalV2,\n ThemeSwitch,\n} from \"@powerhousedao/design-system/connect\";\nimport { closePHModal, usePHModal } from \"@powerhousedao/reactor-browser\";\nimport { t } from \"i18next\";\nimport { CircleHelp, Package, PenLine, TriangleAlert } from \"lucide-react\";\nimport React, { useMemo } from \"react\";\nimport { About } from \"./settings/about.js\";\nimport { DangerZone } from \"./settings/danger-zone.js\";\nimport { DefaultEditor } from \"./settings/default-editor.js\";\nimport { ConnectPackageManager } from \"./settings/package-manager.js\";\n\nconst iconProps = { size: 16 } as const;\n\nexport const SettingsModal: React.FC = () => {\n const phModal = usePHModal();\n const open = phModal?.type === \"settings\";\n\n const tabs = useMemo(\n () => [\n {\n id: \"package-manager\",\n icon: <Package {...iconProps} />,\n label: \"Package Manager\",\n content: ConnectPackageManager,\n },\n {\n id: \"default-editors\",\n icon: <PenLine {...iconProps} />,\n label: \"Default Editors\",\n content: DefaultEditor,\n },\n {\n id: \"danger-zone\",\n icon: <TriangleAlert {...iconProps} className=\"text-destructive\" />,\n label: <span className=\"text-destructive\">Danger Zone</span>,\n content: () => <DangerZone />,\n },\n {\n id: \"about\",\n icon: <CircleHelp {...iconProps} />,\n label: \"About\",\n content: About,\n },\n ],\n [],\n );\n\n return (\n <SettingsModalV2\n open={open}\n title={t(\"modals.connectSettings.title\")}\n onOpenChange={(status: boolean) => {\n if (!status) return closePHModal();\n }}\n tabs={tabs}\n navFooter={<ThemeSwitch horizontal />}\n />\n );\n};\n"],"names":["About","BaseAbout","packageJson","DangerZone","BaseDangerZone","DefaultEditor","BaseDefaultEditor","DefaultEditor","DangerZone","About","SettingsModalV2"],"mappings":"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","debug_id":"f2a64222-ae8b-5562-b3bf-6f4a73480d2c"}
@@ -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]="f3f737bf-a881-54cb-ae94-2c0265b6ac48")}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]="747d357b-8405-59e9-af1c-3c2155dedee8")}catch(e){}}();
3
3
  import { jsx } from "react/jsx-runtime";
4
4
  import { useTranslation } from "react-i18next";
5
5
  import "react";
@@ -30,5 +30,5 @@ const UpgradeDriveModal = () => {
30
30
  //#endregion
31
31
  export { UpgradeDriveModal };
32
32
 
33
- //# sourceMappingURL=UpgradeDriveModal-Ul4tyz-Q.js.map
34
- //# debugId=f3f737bf-a881-54cb-ae94-2c0265b6ac48
33
+ //# sourceMappingURL=UpgradeDriveModal-rUHyJTc7.js.map
34
+ //# debugId=747d357b-8405-59e9-af1c-3c2155dedee8
@@ -1 +1 @@
1
- {"version":3,"file":"UpgradeDriveModal-Ul4tyz-Q.js","sources":["../src/components/modal/modals/UpgradeDriveModal.tsx"],"sourcesContent":["import { ConnectUpgradeDriveModal } from \"@powerhousedao/design-system/connect\";\nimport { closePHModal, usePHModal } from \"@powerhousedao/reactor-browser\";\nimport React from \"react\";\nimport { useTranslation } from \"react-i18next\";\n\nexport const UpgradeDriveModal: React.FC = () => {\n const phModal = usePHModal();\n const open = phModal?.type === \"upgradeDrive\";\n const driveId = open ? phModal.driveId : undefined;\n\n const { t } = useTranslation();\n\n const onContinue = () => {\n // TODO: Implement upgrade drive\n console.log(\"Upgrade drive: \", driveId);\n closePHModal();\n };\n\n return (\n <ConnectUpgradeDriveModal\n open={open}\n onContinue={onContinue}\n header={t(\"modals.upgradeDrive.header\")}\n body={t(\"modals.upgradeDrive.body\")}\n cancelLabel={t(\"common.cancel\")}\n continueLabel={t(\"common.continue\")}\n onOpenChange={(status: boolean) => {\n if (!status) return closePHModal();\n }}\n />\n );\n};\n"],"names":[],"mappings":";;;;;;;;AAKA,MAAa,0BAAoC;CAC/C,MAAM,UAAU,YAAY;CAC5B,MAAM,OAAO,SAAS,SAAS;CAC/B,MAAM,UAAU,OAAO,QAAQ,UAAU,KAAA;CAEzC,MAAM,EAAE,MAAM,gBAAgB;CAE9B,MAAM,mBAAmB;AAEvB,UAAQ,IAAI,mBAAmB,QAAQ;AACvC,gBAAc;;AAGhB,QACE,oBAAC,0BAAD;EACQ;EACM;EACZ,QAAQ,EAAE,6BAA6B;EACvC,MAAM,EAAE,2BAA2B;EACnC,aAAa,EAAE,gBAAgB;EAC/B,eAAe,EAAE,kBAAkB;EACnC,eAAe,WAAoB;AACjC,OAAI,CAAC,OAAQ,QAAO,cAAc;;EAEpC,CAAA","debug_id":"f3f737bf-a881-54cb-ae94-2c0265b6ac48"}
1
+ {"version":3,"file":"UpgradeDriveModal-rUHyJTc7.js","sources":["../src/components/modal/modals/UpgradeDriveModal.tsx"],"sourcesContent":["import { ConnectUpgradeDriveModal } from \"@powerhousedao/design-system/connect\";\nimport { closePHModal, usePHModal } from \"@powerhousedao/reactor-browser\";\nimport React from \"react\";\nimport { useTranslation } from \"react-i18next\";\n\nexport const UpgradeDriveModal: React.FC = () => {\n const phModal = usePHModal();\n const open = phModal?.type === \"upgradeDrive\";\n const driveId = open ? phModal.driveId : undefined;\n\n const { t } = useTranslation();\n\n const onContinue = () => {\n // TODO: Implement upgrade drive\n console.log(\"Upgrade drive: \", driveId);\n closePHModal();\n };\n\n return (\n <ConnectUpgradeDriveModal\n open={open}\n onContinue={onContinue}\n header={t(\"modals.upgradeDrive.header\")}\n body={t(\"modals.upgradeDrive.body\")}\n cancelLabel={t(\"common.cancel\")}\n continueLabel={t(\"common.continue\")}\n onOpenChange={(status: boolean) => {\n if (!status) return closePHModal();\n }}\n />\n );\n};\n"],"names":[],"mappings":";;;;;;;;AAKA,MAAa,0BAAoC;CAC/C,MAAM,UAAU,YAAY;CAC5B,MAAM,OAAO,SAAS,SAAS;CAC/B,MAAM,UAAU,OAAO,QAAQ,UAAU,KAAA;CAEzC,MAAM,EAAE,MAAM,gBAAgB;CAE9B,MAAM,mBAAmB;AAEvB,UAAQ,IAAI,mBAAmB,QAAQ;AACvC,gBAAc;;AAGhB,QACE,oBAAC,0BAAD;EACQ;EACM;EACZ,QAAQ,EAAE,6BAA6B;EACvC,MAAM,EAAE,2BAA2B;EACnC,aAAa,EAAE,gBAAgB;EAC/B,eAAe,EAAE,kBAAkB;EACnC,eAAe,WAAoB;AACjC,OAAI,CAAC,OAAQ,QAAO,cAAc;;EAEpC,CAAA","debug_id":"747d357b-8405-59e9-af1c-3c2155dedee8"}