@adminide-stack/yantra-mobile 12.0.142-alpha.0 → 12.0.144

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 (118) hide show
  1. package/lib/features/attachments/displayUserMessageText.js +2 -2
  2. package/lib/features/attachments/displayUserMessageText.js.map +1 -1
  3. package/lib/features/devices/bodyComposition.js +116 -0
  4. package/lib/features/devices/bodyComposition.js.map +1 -0
  5. package/lib/features/devices/readings.js.map +1 -1
  6. package/lib/features/devices/session.js +22 -2
  7. package/lib/features/devices/session.js.map +1 -1
  8. package/lib/features/notion/NotionAgentPanel.js +987 -0
  9. package/lib/features/notion/NotionAgentPanel.js.map +1 -0
  10. package/lib/features/notion/NotionAskAiSheet.js +362 -0
  11. package/lib/features/notion/NotionAskAiSheet.js.map +1 -0
  12. package/lib/features/notion/NotionBlockView.js +4 -3
  13. package/lib/features/notion/NotionBlockView.js.map +1 -1
  14. package/lib/features/notion/NotionConnectionsSheet.js +47 -13
  15. package/lib/features/notion/NotionConnectionsSheet.js.map +1 -1
  16. package/lib/features/notion/NotionPageView.js +68 -8
  17. package/lib/features/notion/NotionPageView.js.map +1 -1
  18. package/lib/features/notion/NotionSidebarSections.js +1 -1
  19. package/lib/features/notion/NotionSidebarSections.js.map +1 -1
  20. package/lib/features/notion/NotionWorkspaceView.js +14 -9
  21. package/lib/features/notion/NotionWorkspaceView.js.map +1 -1
  22. package/lib/features/notion/database/DatabaseCells.js +3 -1
  23. package/lib/features/notion/database/DatabaseCells.js.map +1 -1
  24. package/lib/features/notion/database/DatabaseDateLayouts.js +1 -1
  25. package/lib/features/notion/database/DatabaseDateLayouts.js.map +1 -1
  26. package/lib/features/notion/database/NotionDatabaseView.js +1 -1
  27. package/lib/features/notion/database/NotionDatabaseView.js.map +1 -1
  28. package/lib/features/notion/notionAgentRunStatus.js +2 -2
  29. package/lib/features/notion/notionAgentRunStatus.js.map +1 -1
  30. package/lib/features/notion/notionAgentRuns.js +57 -0
  31. package/lib/features/notion/notionAgentRuns.js.map +1 -0
  32. package/lib/features/notion/notionAiContext.js +91 -0
  33. package/lib/features/notion/notionAiContext.js.map +1 -0
  34. package/lib/features/notion/notionConnections.js +42 -4
  35. package/lib/features/notion/notionConnections.js.map +1 -1
  36. package/lib/features/notion/notionDocuments.js +61 -1
  37. package/lib/features/notion/notionDocuments.js.map +1 -1
  38. package/lib/features/notion/notionNotesAgent.js +173 -3
  39. package/lib/features/notion/notionNotesAgent.js.map +1 -1
  40. package/lib/features/notion/notionPageKinds.js +1 -1
  41. package/lib/features/webbuilder/WebBuilderExperience.js +229 -97
  42. package/lib/features/webbuilder/WebBuilderExperience.js.map +1 -1
  43. package/lib/features/webbuilder/buildFragments.js +33 -7
  44. package/lib/features/webbuilder/buildFragments.js.map +1 -1
  45. package/lib/features/webbuilder/buildJob.js +2 -2
  46. package/lib/features/webbuilder/buildJob.js.map +1 -1
  47. package/lib/features/webbuilder/codeFiles.js +18 -1
  48. package/lib/features/webbuilder/codeFiles.js.map +1 -1
  49. package/lib/features/webbuilder/components/BottomTabs.js.map +1 -1
  50. package/lib/features/webbuilder/components/CodeView.js +134 -56
  51. package/lib/features/webbuilder/components/CodeView.js.map +1 -1
  52. package/lib/features/webbuilder/components/Composer.js +2 -2
  53. package/lib/features/webbuilder/components/Composer.js.map +1 -1
  54. package/lib/features/webbuilder/components/PreviewFrame.js +19 -3
  55. package/lib/features/webbuilder/components/PreviewFrame.js.map +1 -1
  56. package/lib/features/webbuilder/components/PreviewScreen.js +310 -46
  57. package/lib/features/webbuilder/components/PreviewScreen.js.map +1 -1
  58. package/lib/features/webbuilder/components/ProjectChat.js +141 -12
  59. package/lib/features/webbuilder/components/ProjectChat.js.map +1 -1
  60. package/lib/features/webbuilder/components/ProjectSheets.js +792 -0
  61. package/lib/features/webbuilder/components/ProjectSheets.js.map +1 -0
  62. package/lib/features/webbuilder/components/ProjectsScreen.js +14 -2
  63. package/lib/features/webbuilder/components/ProjectsScreen.js.map +1 -1
  64. package/lib/features/webbuilder/components/PublishSheet.js +914 -58
  65. package/lib/features/webbuilder/components/PublishSheet.js.map +1 -1
  66. package/lib/features/webbuilder/components/TemplateCard.js +9 -6
  67. package/lib/features/webbuilder/components/TemplateCard.js.map +1 -1
  68. package/lib/features/webbuilder/components/TemplatesSheet.js +5 -17
  69. package/lib/features/webbuilder/components/TemplatesSheet.js.map +1 -1
  70. package/lib/features/webbuilder/connectorTemplates.js +171 -0
  71. package/lib/features/webbuilder/connectorTemplates.js.map +1 -0
  72. package/lib/features/webbuilder/fileTree.js +163 -0
  73. package/lib/features/webbuilder/fileTree.js.map +1 -0
  74. package/lib/features/webbuilder/followUps.js +67 -0
  75. package/lib/features/webbuilder/followUps.js.map +1 -0
  76. package/lib/features/webbuilder/previewProbe.js +49 -0
  77. package/lib/features/webbuilder/previewProbe.js.map +1 -0
  78. package/lib/features/webbuilder/previewRoutes.js +156 -0
  79. package/lib/features/webbuilder/previewRoutes.js.map +1 -0
  80. package/lib/features/webbuilder/projectTools.js +341 -0
  81. package/lib/features/webbuilder/projectTools.js.map +1 -0
  82. package/lib/features/webbuilder/publishTools.js +475 -0
  83. package/lib/features/webbuilder/publishTools.js.map +1 -0
  84. package/lib/features/webbuilder/sleepNotice.js +13 -0
  85. package/lib/features/webbuilder/sleepNotice.js.map +1 -0
  86. package/lib/features/webbuilder/stepLabels.js +37 -7
  87. package/lib/features/webbuilder/stepLabels.js.map +1 -1
  88. package/lib/features/webbuilder/studioCatalog.js +5 -1
  89. package/lib/features/webbuilder/studioCatalog.js.map +1 -1
  90. package/lib/features/webbuilder/templateCatalog.js +140 -0
  91. package/lib/features/webbuilder/templateCatalog.js.map +1 -0
  92. package/lib/features/webbuilder/webbuilderPrompts.js +31 -5
  93. package/lib/features/webbuilder/webbuilderPrompts.js.map +1 -1
  94. package/lib/features/webbuilder/workflow.js +8 -4
  95. package/lib/features/webbuilder/workflow.js.map +1 -1
  96. package/lib/screens/Devices/index.js +205 -3
  97. package/lib/screens/Devices/index.js.map +1 -1
  98. package/lib/screens/WebBuilderNative/codeWorkspaceApi.js +9 -6
  99. package/lib/screens/WebBuilderNative/codeWorkspaceApi.js.map +1 -1
  100. package/lib/screens/WebBuilderNative/index.js +1 -1
  101. package/lib/screens/WebBuilderNative/index.js.map +1 -1
  102. package/lib/screens/WebBuilderNative/keepAlive.js +53 -3
  103. package/lib/screens/WebBuilderNative/keepAlive.js.map +1 -1
  104. package/lib/screens/WebBuilderNative/unreachableRetry.js +23 -0
  105. package/lib/screens/WebBuilderNative/unreachableRetry.js.map +1 -0
  106. package/lib/screens/WebBuilderNative/useConnectorTemplates.js +37 -0
  107. package/lib/screens/WebBuilderNative/useConnectorTemplates.js.map +1 -0
  108. package/lib/screens/WebBuilderNative/useSandboxKeepAlive.js +6 -0
  109. package/lib/screens/WebBuilderNative/useSandboxKeepAlive.js.map +1 -1
  110. package/lib/screens/WebBuilderNative/useWebBuilderHost.js +302 -40
  111. package/lib/screens/WebBuilderNative/useWebBuilderHost.js.map +1 -1
  112. package/lib/screens/WebBuilderNative/useWebBuilderJobs.js +2 -2
  113. package/lib/screens/WebBuilderNative/useWebBuilderJobs.js.map +1 -1
  114. package/lib/screens/WebBuilderNative/versionUndo.js +1 -1
  115. package/lib/screens/WebBuilderNative/versionUndo.js.map +1 -1
  116. package/lib/screens/WebBuilderNative/webbuilderTransport.js +147 -77
  117. package/lib/screens/WebBuilderNative/webbuilderTransport.js.map +1 -1
  118. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"codeWorkspaceApi.js","sources":["../../../src/screens/WebBuilderNative/codeWorkspaceApi.ts"],"sourcesContent":["/**\n * The Code view's sandbox calls (web `code/codeWorkspaceMachine` IO), over the site's\n * sandbox router (the guarded proxy, so the app never holds a sandbox key):\n *\n * - list: `WEBBUILDER_RUN_COMMAND` with the tree listing; when the sandbox is gone,\n * `WEBBUILDER_LIST_FILES` from the backup repo (read-only \"saved code\");\n * - read: `WEBBUILDER_READ_FILE` (live reads carry `fromRepo` too, so a gone sandbox\n * answers from the backup, which is then never saved against);\n * - save: read again, `decideSave`, then `WEBBUILDER_WRITE_FILES`; a file changed on\n * disk since it was opened comes back as a conflict (Overwrite or Reload);\n * - search: a capped `git grep`, else the files already open.\n * No React: the host hook binds it to the open site.\n */\nimport {\n READ_FILE_MAX_BYTES,\n buildListFilesCommand,\n buildSearchCommand,\n codeEditSummary,\n decideSave,\n isSandboxUnavailableError,\n isSavedCodeRead,\n openModeFor,\n parseListFilesOutput,\n parseListFilesResult,\n parseSearchOutput,\n searchDocs,\n type ContentSearchResult,\n type FileTree,\n type FromRepo,\n type OpenMode,\n} from '../../features/webbuilder/codeFiles';\nimport type { SandboxRun } from './webbuilderTransport';\n\nconst LIST_TIMEOUT_MS = 90_000;\nconst FILE_TIMEOUT_MS = 60_000;\n\n/** The connector's own output (its `data`, or `data.data`). */\nfunction dataOf(result: { data?: unknown } | null | undefined): Record<string, unknown> {\n const raw = result?.data;\n if (!raw || typeof raw !== 'object') return {};\n const rec = raw as Record<string, unknown>;\n return rec.data && typeof rec.data === 'object' && !Array.isArray(rec.data)\n ? (rec.data as Record<string, unknown>)\n : rec;\n}\n\n/** A command's printed output, wherever this connector version put it. */\nfunction stdoutOf(d: Record<string, unknown>): string {\n const nested = [d, d.data, d.result, d.output].filter(\n (v): v is Record<string, unknown> => Boolean(v) && typeof v === 'object',\n );\n for (const rec of nested) {\n if (typeof rec.stdout === 'string') return rec.stdout;\n if (typeof rec.output === 'string') return rec.output;\n }\n return '';\n}\n\nexport interface CodeTarget {\n sandboxId: string | null;\n /** The backup repo to read when the sandbox is gone; null when none is known. */\n savedSource: FromRepo | null;\n}\n\nexport interface TreeResult {\n ok: boolean;\n tree?: FileTree;\n /** Read from the backup repo: the whole view is read-only. */\n saved?: boolean;\n /** The sandbox is asleep or gone and there is no saved code: waking it brings the files. */\n asleep?: boolean;\n error?: string;\n}\n\nexport interface ReadResult {\n ok: boolean;\n content?: string;\n mode?: OpenMode;\n saved?: boolean;\n error?: string;\n}\n\nexport interface SaveResult {\n ok: boolean;\n /** The file changed on disk since it was opened: this is what is there now. */\n conflict?: boolean;\n disk?: string;\n /** Nothing to write (no change, or the disk already holds the draft). */\n unchanged?: boolean;\n summary?: string;\n error?: string;\n}\n\nexport function createCodeWorkspace(call: SandboxRun, onHandEdit: (edit: { file: string; summary: string }) => void) {\n const run = (action: string, params: Record<string, unknown>, timeoutMs: number) =>\n call(action, params, timeoutMs).catch((err: unknown) => ({\n successful: false,\n data: undefined as unknown,\n error: err instanceof Error ? err.message : String(err),\n }));\n\n const listSaved = async (target: CodeTarget): Promise<TreeResult> => {\n if (!target.savedSource) {\n return {\n ok: false,\n asleep: true,\n error: \"The site is asleep, so its files can't be read. Wake it to see them.\",\n };\n }\n const r = await run(\n 'WEBBUILDER_LIST_FILES',\n { ...(target.sandboxId ? { sandbox_id: target.sandboxId } : {}), fromRepo: target.savedSource },\n LIST_TIMEOUT_MS,\n );\n const tree = r.successful ? parseListFilesResult(dataOf(r)) : null;\n return tree\n ? { ok: true, tree, saved: true }\n : { ok: false, error: \"Couldn't load the saved code. Wake the site to see its files.\" };\n };\n\n const listFiles = async (target: CodeTarget): Promise<TreeResult> => {\n if (!target.sandboxId) return listSaved(target);\n // The project proxy's own listing: from the live sandbox, or - carrying `fromRepo` -\n // from the backup repo when the sandbox is gone (`source: 'repo'`, read-only).\n const listed = await run(\n 'WEBBUILDER_LIST_FILES',\n { sandbox_id: target.sandboxId, ...(target.savedSource ? { fromRepo: target.savedSource } : {}) },\n LIST_TIMEOUT_MS,\n );\n const listedData = dataOf(listed);\n const listedTree = listed.successful ? parseListFilesResult(listedData) : null;\n if (listedTree) {\n const fromRepo = listedData.source === 'repo' || isSavedCodeRead(listedData);\n return { ok: true, tree: listedTree, saved: fromRepo };\n }\n // An older connector without LIST_FILES on a live sandbox: the shell listing.\n const r = await run(\n 'WEBBUILDER_RUN_COMMAND',\n { sandbox_id: target.sandboxId, command: buildListFilesCommand() },\n LIST_TIMEOUT_MS,\n );\n const d = dataOf(r);\n const tree = r.successful ? parseListFilesOutput(stdoutOf(d), { truncated: d.truncated === true }) : null;\n if (tree) return { ok: true, tree, saved: false };\n if (typeof __DEV__ !== 'undefined' && __DEV__) {\n // eslint-disable-next-line no-console\n console.warn('[WebBuilderNative] code list', {\n sandboxId: target.sandboxId,\n listFiles: { error: listed.error, data: listedData },\n runCommand: { error: r.error, data: d },\n });\n }\n // Only a failed call's own error says the sandbox is gone (web `loadFileTree`); the\n // command's output is not read for it (its numbers and logs matched \"502\" / \"timed out\").\n if (!r.successful && (isSandboxUnavailableError(r.error) || isSandboxUnavailableError(listed.error))) {\n return listSaved(target);\n }\n if (r.successful) {\n const stderr = typeof d.stderr === 'string' ? d.stderr.trim().split('\\n')[0] : '';\n return { ok: false, error: `Couldn't read the file list${stderr ? `: ${stderr.slice(0, 160)}` : '.'}` };\n }\n return { ok: false, error: r.error || 'Could not list the project files.' };\n };\n\n const readFile = async (target: CodeTarget, path: string, saved: boolean): Promise<ReadResult> => {\n const params = {\n ...(target.sandboxId ? { sandbox_id: target.sandboxId } : {}),\n path,\n maxBytes: READ_FILE_MAX_BYTES,\n ...(target.savedSource ? { fromRepo: target.savedSource } : {}),\n };\n const r = await run('WEBBUILDER_READ_FILE', params, FILE_TIMEOUT_MS);\n if (!r.successful) return { ok: false, error: r.error || 'Could not read the file.' };\n const d = dataOf(r);\n const fromBackup = saved || isSavedCodeRead(d);\n return {\n ok: true,\n content: typeof d.content === 'string' ? d.content : undefined,\n mode: openModeFor(path, d),\n saved: fromBackup,\n };\n };\n\n /** Save `draft` over `base` (what was opened); `force` overwrites a file changed meanwhile. */\n const saveFile = async (\n target: CodeTarget,\n path: string,\n base: string,\n draft: string,\n force = false,\n ): Promise<SaveResult> => {\n if (!target.sandboxId) return { ok: false, error: 'Wake the site to save changes.' };\n if (!force) {\n const now = await readFile(target, path, false);\n if (now.ok && now.saved) return { ok: false, error: 'The site is asleep. Wake it to save changes.' };\n const disk = now.ok ? (now.content ?? null) : null;\n const decision = decideSave(base, disk, draft);\n if (decision === 'unchanged') return { ok: true, unchanged: true };\n if (decision === 'conflict') return { ok: false, conflict: true, disk: disk ?? '' };\n }\n const r = await run(\n 'WEBBUILDER_WRITE_FILES',\n { sandbox_id: target.sandboxId, files: [{ path, content: draft }] },\n FILE_TIMEOUT_MS,\n );\n if (!r.successful) return { ok: false, error: r.error || 'Could not save the file.' };\n const summary = codeEditSummary(base, draft);\n onHandEdit({ file: path, summary });\n return { ok: true, summary };\n };\n\n /** Project-wide search on a live sandbox, else the files already open (`openDocs`). */\n const search = async (\n target: CodeTarget,\n query: string,\n live: boolean,\n openDocs: Record<string, string>,\n ): Promise<{ result: ContentSearchResult; source: 'project' | 'open-files' }> => {\n const inMemory = () => ({ result: searchDocs(openDocs, query), source: 'open-files' as const });\n if (!live || !target.sandboxId) return inMemory();\n let command: string;\n try {\n command = buildSearchCommand(query);\n } catch {\n return inMemory();\n }\n const r = await run('WEBBUILDER_RUN_COMMAND', { sandbox_id: target.sandboxId, command }, LIST_TIMEOUT_MS);\n const d = dataOf(r);\n const parsed = r.successful\n ? parseSearchOutput(stdoutOf(d), query, {\n truncated: d.truncated === true,\n })\n : null;\n return parsed ? { result: parsed, source: 'project' } : inMemory();\n };\n\n return { listFiles, readFile, saveFile, search };\n}\n\nexport type CodeWorkspace = ReturnType<typeof createCodeWorkspace>;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"codeWorkspaceApi.js","sources":["../../../src/screens/WebBuilderNative/codeWorkspaceApi.ts"],"sourcesContent":["/**\n * The Code view's sandbox calls (web `code/codeWorkspaceMachine` IO), over the site's\n * sandbox router (the guarded proxy, so the app never holds a sandbox key):\n *\n * - list: `WEBBUILDER_RUN_COMMAND` with the tree listing; when the sandbox is gone,\n * `WEBBUILDER_LIST_FILES` from the backup repo (read-only \"saved code\");\n * - read: `WEBBUILDER_READ_FILE` (live reads carry `fromRepo` too, so a gone sandbox\n * answers from the backup, which is then never saved against);\n * - save: read again, `decideSave`, then `WEBBUILDER_WRITE_FILES`; a file changed on\n * disk since it was opened comes back as a conflict (Overwrite or Reload);\n * - search: a capped `git grep`, else the files already open.\n * No React: the host hook binds it to the open site.\n */\nimport { plainAgentError, retryUnreachable, UNREACHABLE_RETRY_DELAYS_MS } from './unreachableRetry';\nimport {\n READ_FILE_MAX_BYTES,\n buildListFilesCommand,\n buildSearchCommand,\n codeEditSummary,\n decideSave,\n isSandboxUnavailableError,\n isSavedCodeRead,\n openModeFor,\n parseListFilesOutput,\n parseListFilesResult,\n parseSearchOutput,\n searchDocs,\n type ContentSearchResult,\n type FileTree,\n type FromRepo,\n type OpenMode,\n} from '../../features/webbuilder/codeFiles';\nimport type { SandboxRun } from './webbuilderTransport';\n\nconst LIST_TIMEOUT_MS = 90_000;\nconst FILE_TIMEOUT_MS = 60_000;\n\n/** The connector's own output (its `data`, or `data.data`). */\nfunction dataOf(result: { data?: unknown } | null | undefined): Record<string, unknown> {\n const raw = result?.data;\n if (!raw || typeof raw !== 'object') return {};\n const rec = raw as Record<string, unknown>;\n return rec.data && typeof rec.data === 'object' && !Array.isArray(rec.data)\n ? (rec.data as Record<string, unknown>)\n : rec;\n}\n\n/** A command's printed output, wherever this connector version put it. */\nfunction stdoutOf(d: Record<string, unknown>): string {\n const nested = [d, d.data, d.result, d.output].filter(\n (v): v is Record<string, unknown> => Boolean(v) && typeof v === 'object',\n );\n for (const rec of nested) {\n if (typeof rec.stdout === 'string') return rec.stdout;\n if (typeof rec.output === 'string') return rec.output;\n }\n return '';\n}\n\nexport interface CodeTarget {\n sandboxId: string | null;\n /** The backup repo to read when the sandbox is gone; null when none is known. */\n savedSource: FromRepo | null;\n}\n\nexport interface TreeResult {\n ok: boolean;\n tree?: FileTree;\n /** Read from the backup repo: the whole view is read-only. */\n saved?: boolean;\n /** The sandbox is asleep or gone and there is no saved code: waking it brings the files. */\n asleep?: boolean;\n error?: string;\n}\n\nexport interface ReadResult {\n ok: boolean;\n content?: string;\n mode?: OpenMode;\n saved?: boolean;\n error?: string;\n}\n\nexport interface SaveResult {\n ok: boolean;\n /** The file changed on disk since it was opened: this is what is there now. */\n conflict?: boolean;\n disk?: string;\n /** Nothing to write (no change, or the disk already holds the draft). */\n unchanged?: boolean;\n summary?: string;\n error?: string;\n}\n\nexport function createCodeWorkspace(\n call: SandboxRun,\n onHandEdit: (edit: { file: string; summary: string }) => void,\n /** Waits before re-sending a listing that never reached the agent (tests pass `[]`). */\n retryDelaysMs: readonly number[] = UNREACHABLE_RETRY_DELAYS_MS,\n) {\n const run = (action: string, params: Record<string, unknown>, timeoutMs: number) =>\n call(action, params, timeoutMs)\n .catch((err: unknown) => ({\n successful: false,\n data: undefined as unknown,\n error: err instanceof Error ? err.message : String(err),\n }))\n .then((r) => (r.successful ? r : { ...r, error: plainAgentError(r.error) }));\n // The first read on a fresh build can find the agent restarting: sent again shortly (web #920f0bba).\n const list = (params: Record<string, unknown>) =>\n retryUnreachable(() => run('WEBBUILDER_LIST_FILES', params, LIST_TIMEOUT_MS), retryDelaysMs);\n\n const listSaved = async (target: CodeTarget): Promise<TreeResult> => {\n if (!target.savedSource) {\n return {\n ok: false,\n asleep: true,\n error: \"The site is asleep, so its files can't be read. Wake it to see them.\",\n };\n }\n const r = await list({\n ...(target.sandboxId ? { sandbox_id: target.sandboxId } : {}),\n fromRepo: target.savedSource,\n });\n const tree = r.successful ? parseListFilesResult(dataOf(r)) : null;\n return tree\n ? { ok: true, tree, saved: true }\n : { ok: false, error: \"Couldn't load the saved code. Wake the site to see its files.\" };\n };\n\n const listFiles = async (target: CodeTarget): Promise<TreeResult> => {\n if (!target.sandboxId) return listSaved(target);\n // The project proxy's own listing: from the live sandbox, or - carrying `fromRepo` -\n // from the backup repo when the sandbox is gone (`source: 'repo'`, read-only).\n const listed = await list({\n sandbox_id: target.sandboxId,\n ...(target.savedSource ? { fromRepo: target.savedSource } : {}),\n });\n const listedData = dataOf(listed);\n const listedTree = listed.successful ? parseListFilesResult(listedData) : null;\n if (listedTree) {\n const fromRepo = listedData.source === 'repo' || isSavedCodeRead(listedData);\n return { ok: true, tree: listedTree, saved: fromRepo };\n }\n // An older connector without LIST_FILES on a live sandbox: the shell listing.\n const r = await run(\n 'WEBBUILDER_RUN_COMMAND',\n { sandbox_id: target.sandboxId, command: buildListFilesCommand() },\n LIST_TIMEOUT_MS,\n );\n const d = dataOf(r);\n const tree = r.successful ? parseListFilesOutput(stdoutOf(d), { truncated: d.truncated === true }) : null;\n if (tree) return { ok: true, tree, saved: false };\n if (typeof __DEV__ !== 'undefined' && __DEV__) {\n // eslint-disable-next-line no-console\n console.warn('[WebBuilderNative] code list', {\n sandboxId: target.sandboxId,\n listFiles: { error: listed.error, data: listedData },\n runCommand: { error: r.error, data: d },\n });\n }\n // Only a failed call's own error says the sandbox is gone (web `loadFileTree`); the\n // command's output is not read for it (its numbers and logs matched \"502\" / \"timed out\").\n if (!r.successful && (isSandboxUnavailableError(r.error) || isSandboxUnavailableError(listed.error))) {\n return listSaved(target);\n }\n if (r.successful) {\n const stderr = typeof d.stderr === 'string' ? d.stderr.trim().split('\\n')[0] : '';\n return { ok: false, error: `Couldn't read the file list${stderr ? `: ${stderr.slice(0, 160)}` : '.'}` };\n }\n return { ok: false, error: r.error || 'Could not list the project files.' };\n };\n\n const readFile = async (target: CodeTarget, path: string, saved: boolean): Promise<ReadResult> => {\n const params = {\n ...(target.sandboxId ? { sandbox_id: target.sandboxId } : {}),\n path,\n maxBytes: READ_FILE_MAX_BYTES,\n ...(target.savedSource ? { fromRepo: target.savedSource } : {}),\n };\n const r = await run('WEBBUILDER_READ_FILE', params, FILE_TIMEOUT_MS);\n if (!r.successful) return { ok: false, error: r.error || 'Could not read the file.' };\n const d = dataOf(r);\n const fromBackup = saved || isSavedCodeRead(d);\n return {\n ok: true,\n content: typeof d.content === 'string' ? d.content : undefined,\n mode: openModeFor(path, d),\n saved: fromBackup,\n };\n };\n\n /** Save `draft` over `base` (what was opened); `force` overwrites a file changed meanwhile. */\n const saveFile = async (\n target: CodeTarget,\n path: string,\n base: string,\n draft: string,\n force = false,\n ): Promise<SaveResult> => {\n if (!target.sandboxId) return { ok: false, error: 'Wake the site to save changes.' };\n if (!force) {\n const now = await readFile(target, path, false);\n if (now.ok && now.saved) return { ok: false, error: 'The site is asleep. Wake it to save changes.' };\n const disk = now.ok ? (now.content ?? null) : null;\n const decision = decideSave(base, disk, draft);\n if (decision === 'unchanged') return { ok: true, unchanged: true };\n if (decision === 'conflict') return { ok: false, conflict: true, disk: disk ?? '' };\n }\n const r = await run(\n 'WEBBUILDER_WRITE_FILES',\n { sandbox_id: target.sandboxId, files: [{ path, content: draft }] },\n FILE_TIMEOUT_MS,\n );\n if (!r.successful) return { ok: false, error: r.error || 'Could not save the file.' };\n const summary = codeEditSummary(base, draft);\n onHandEdit({ file: path, summary });\n return { ok: true, summary };\n };\n\n /** Project-wide search on a live sandbox, else the files already open (`openDocs`). */\n const search = async (\n target: CodeTarget,\n query: string,\n live: boolean,\n openDocs: Record<string, string>,\n ): Promise<{ result: ContentSearchResult; source: 'project' | 'open-files' }> => {\n const inMemory = () => ({ result: searchDocs(openDocs, query), source: 'open-files' as const });\n if (!live || !target.sandboxId) return inMemory();\n let command: string;\n try {\n command = buildSearchCommand(query);\n } catch {\n return inMemory();\n }\n const r = await run('WEBBUILDER_RUN_COMMAND', { sandbox_id: target.sandboxId, command }, LIST_TIMEOUT_MS);\n const d = dataOf(r);\n const parsed = r.successful\n ? parseSearchOutput(stdoutOf(d), query, {\n truncated: d.truncated === true,\n })\n : null;\n return parsed ? { result: parsed, source: 'project' } : inMemory();\n };\n\n return { listFiles, readFile, saveFile, search };\n}\n\nexport type CodeWorkspace = ReturnType<typeof createCodeWorkspace>;\n"],"names":[],"mappings":"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"}
@@ -73,7 +73,7 @@ function WebBuilderNativeScreen() {
73
73
  /* @__PURE__ */ jsx(Text, { style: [styles.detail, isDark && styles.textMuted], children: "This build does not carry the federation host runtime." })
74
74
  ] }) });
75
75
  }
76
- return /* @__PURE__ */ jsx(SafeAreaView, { style: [styles.fill, isDark && styles.fillDark], edges: ["left", "right"], children: /* @__PURE__ */ jsx(Experience, { isDark, onExit, projects: host.projects, projectsLoading: host.projectsLoading, projectsError: host.projectsError, onRefreshProjects: host.refreshProjects, projectsHasMore: host.projectsHasMore, onLoadMoreProjects: host.loadMoreProjects, templates: host.templates, templatesLoading: host.templatesLoading, templatesError: host.templatesError, onReloadTemplates: host.reloadTemplates, startBlocked: host.startBlocked, startNotice: host.startNotice, activeChannelId: host.activeChannelId, onOpenProject: host.openProject, onCloseProject: host.closeProject, onStartProject: host.startProject, builds: host.builds, buildsLoading: host.buildsLoading, building: host.building, publishing: host.publishing, hostChat: host.hostChat, onPublish: host.publish, onResumePreview: host.resumePreview, onUndo: host.undo, onRedo: host.redo, onDownloadCode: host.downloadCode, code: host.code, onOpenCodezen, initialAgentSeed: seed }) });
76
+ return /* @__PURE__ */ jsx(SafeAreaView, { style: [styles.fill, isDark && styles.fillDark], edges: ["left", "right"], children: /* @__PURE__ */ jsx(Experience, { isDark, onExit, projects: host.projects, projectsLoading: host.projectsLoading, projectsError: host.projectsError, onRefreshProjects: host.refreshProjects, projectsHasMore: host.projectsHasMore, onLoadMoreProjects: host.loadMoreProjects, templates: host.templates, templatesLoading: host.templatesLoading, templatesError: host.templatesError, onReloadTemplates: host.reloadTemplates, startBlocked: host.startBlocked, startNotice: host.startNotice, activeChannelId: host.activeChannelId, onOpenProject: host.openProject, onCloseProject: host.closeProject, onStartProject: host.startProject, builds: host.builds, buildsLoading: host.buildsLoading, building: host.building, publishing: host.publishing, hostChat: host.hostChat, onPublish: host.publish, onResumePreview: host.resumePreview, onRestorePreview: host.restorePreview, goneSandboxIds: host.goneSandboxIds, onUndo: host.undo, onRedo: host.redo, onDownloadCode: host.downloadCode, publishTools: host.publishTools, projectTools: host.projectTools, code: host.code, onOpenCodezen, initialAgentSeed: seed }) });
77
77
  }
78
78
  const styles = StyleSheet.create({
79
79
  fill: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/screens/WebBuilderNative/index.tsx"],"sourcesContent":["/**\n * Native Web Builder screen - host route for the federated web builder experience.\n *\n * Same delivery contract as Expenses / Movies / Study: the App registers the\n * federated component; this screen reads the registry and hands over what\n * needs the app's data stack - the builds, the templates, the build workflow\n * (the web surface's connector lane), the publish mutation - plus\n * navigation for leaving. A brain-routed hand-off arrives as\n * `initialAgentQuery` and starts a new site with it; a task in the Tasks sheet\n * arrives as `openChannelId` and opens that site. Web Builder draws its own\n * header, so the stack header stays hidden.\n *\n * Not to be confused with `screens/WebBuilder`: that is the shared WebView\n * surface shell (historical name), which still opens the web Web Builder.\n */\nimport React, { useCallback, useEffect, useLayoutEffect, useMemo } from 'react';\nimport { StyleSheet, Text, View } from 'react-native';\nimport { SafeAreaView } from 'react-native-safe-area-context';\nimport {\n useNavigation,\n useRoute,\n type NavigationProp,\n type ParamListBase,\n type RouteProp,\n} from '@react-navigation/native';\nimport type { MessageAttachment } from '../../hooks/useChatStream';\nimport { getNativeWebBuilderExperience } from '../../features/webbuilder/nativeWebBuilderRegistry';\nimport { useAppTheme } from '../../theme/AppThemeProvider';\nimport { useWebBuilderHost } from './useWebBuilderHost';\nimport { config } from '../../config/env-config';\nimport { MOBILE_APP_CATALOG } from '../../features/apps/mobileAppCatalog';\nimport { resolveSurfaceUrl } from '../../features/apps/resolveSurfaceUrl';\nimport { CODEZEN_DEV_URL } from '../../features/webbuilder/codezenHandoff';\n\n/** What the launcher and the chat hand-offs may pass. */\ntype WebBuilderRouteParams = {\n orgName?: string | null;\n initialAgentQuery?: string;\n /** Photos or files the ask was typed with; they go to the agent with it. */\n initialAgentAttachments?: MessageAttachment[];\n /** A site to open (its chat), e.g. from its build's task in the Tasks sheet. */\n openChannelId?: string;\n hideNavigationHeader?: boolean;\n};\n\nexport default function WebBuilderNativeScreen() {\n // The in-app light/dark choice (the drawer's Appearance), not only the device setting.\n const { isDark } = useAppTheme();\n const navigation = useNavigation<NavigationProp<ParamListBase>>();\n const route = useRoute<RouteProp<Record<string, WebBuilderRouteParams | undefined>, string>>();\n const routeOrg = typeof route.params?.orgName === 'string' ? route.params.orgName.trim() : '';\n const Experience = getNativeWebBuilderExperience();\n const host = useWebBuilderHost(routeOrg || undefined);\n\n useLayoutEffect(() => {\n if (!route.params?.hideNavigationHeader) navigation.setParams({ hideNavigationHeader: true });\n }, [navigation, route.params?.hideNavigationHeader]);\n\n const seed = useMemo(() => {\n const query = typeof route.params?.initialAgentQuery === 'string' ? route.params.initialAgentQuery.trim() : '';\n const files = Array.isArray(route.params?.initialAgentAttachments)\n ? route.params.initialAgentAttachments\n : undefined;\n if (!query && !files?.length) return null;\n return { text: query, files };\n }, [route.params?.initialAgentQuery, route.params?.initialAgentAttachments]);\n\n // Opened once per hand-off: the param is cleared, so the same task can open it again later.\n const openChannelId = typeof route.params?.openChannelId === 'string' ? route.params.openChannelId.trim() : '';\n const { openProject } = host;\n useEffect(() => {\n if (!openChannelId) return;\n openProject(openChannelId);\n navigation.setParams({ openChannelId: undefined });\n }, [openChannelId, openProject, navigation]);\n\n const onExit = useCallback(() => {\n if (navigation.canGoBack?.()) navigation.goBack();\n else navigation.navigate('MainStack.Layout.Home');\n }, [navigation]);\n\n // \"Demo video\" (web 0.5.0): the Codezen surface, in the app's surface shell, with the handoff fragment.\n const onOpenCodezen = useCallback(\n (fragment: string) => {\n const tile = MOBILE_APP_CATALOG.find((app) => app.key === 'codezen');\n const base = (tile && resolveSurfaceUrl(tile, config)) || CODEZEN_DEV_URL;\n navigation.navigate('MainStack.WebBuilder', {\n url: `${base.split('#')[0]}#${fragment}`,\n appTitle: tile?.label ?? 'Codezen',\n ...(routeOrg ? { orgName: routeOrg } : {}),\n });\n },\n [navigation, routeOrg],\n );\n\n if (!Experience) {\n return (\n <SafeAreaView style={[styles.fill, isDark && styles.fillDark]}>\n <View style={styles.center}>\n <Text style={[styles.title, isDark && styles.textLight]}>Native web builder unavailable</Text>\n <Text style={[styles.detail, isDark && styles.textMuted]}>\n This build does not carry the federation host runtime.\n </Text>\n </View>\n </SafeAreaView>\n );\n }\n\n return (\n <SafeAreaView style={[styles.fill, isDark && styles.fillDark]} edges={['left', 'right']}>\n <Experience\n isDark={isDark}\n onExit={onExit}\n projects={host.projects}\n projectsLoading={host.projectsLoading}\n projectsError={host.projectsError}\n onRefreshProjects={host.refreshProjects}\n projectsHasMore={host.projectsHasMore}\n onLoadMoreProjects={host.loadMoreProjects}\n templates={host.templates}\n templatesLoading={host.templatesLoading}\n templatesError={host.templatesError}\n onReloadTemplates={host.reloadTemplates}\n startBlocked={host.startBlocked}\n startNotice={host.startNotice}\n activeChannelId={host.activeChannelId}\n onOpenProject={host.openProject}\n onCloseProject={host.closeProject}\n onStartProject={host.startProject}\n builds={host.builds}\n buildsLoading={host.buildsLoading}\n building={host.building}\n publishing={host.publishing}\n hostChat={host.hostChat}\n onPublish={host.publish}\n onResumePreview={host.resumePreview}\n onUndo={host.undo}\n onRedo={host.redo}\n onDownloadCode={host.downloadCode}\n code={host.code}\n onOpenCodezen={onOpenCodezen}\n initialAgentSeed={seed}\n />\n </SafeAreaView>\n );\n}\n\nconst styles = StyleSheet.create({\n fill: { flex: 1, backgroundColor: '#f5f6f8' },\n fillDark: { backgroundColor: '#0c0e14' },\n center: { flex: 1, alignItems: 'center', justifyContent: 'center', padding: 24 },\n title: { fontSize: 15, fontWeight: '600', color: '#111827', marginBottom: 6 },\n detail: { fontSize: 13, color: '#5d6575', textAlign: 'center' },\n textLight: { color: '#eceff6' },\n textMuted: { color: '#9ca4b6' },\n});\n"],"names":["_a","_b"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/screens/WebBuilderNative/index.tsx"],"sourcesContent":["/**\n * Native Web Builder screen - host route for the federated web builder experience.\n *\n * Same delivery contract as Expenses / Movies / Study: the App registers the\n * federated component; this screen reads the registry and hands over what\n * needs the app's data stack - the builds, the templates, the build workflow\n * (the web surface's connector lane), the publish mutation - plus\n * navigation for leaving. A brain-routed hand-off arrives as\n * `initialAgentQuery` and starts a new site with it; a task in the Tasks sheet\n * arrives as `openChannelId` and opens that site. Web Builder draws its own\n * header, so the stack header stays hidden.\n *\n * Not to be confused with `screens/WebBuilder`: that is the shared WebView\n * surface shell (historical name), which still opens the web Web Builder.\n */\nimport React, { useCallback, useEffect, useLayoutEffect, useMemo } from 'react';\nimport { StyleSheet, Text, View } from 'react-native';\nimport { SafeAreaView } from 'react-native-safe-area-context';\nimport {\n useNavigation,\n useRoute,\n type NavigationProp,\n type ParamListBase,\n type RouteProp,\n} from '@react-navigation/native';\nimport type { MessageAttachment } from '../../hooks/useChatStream';\nimport { getNativeWebBuilderExperience } from '../../features/webbuilder/nativeWebBuilderRegistry';\nimport { useAppTheme } from '../../theme/AppThemeProvider';\nimport { useWebBuilderHost } from './useWebBuilderHost';\nimport { config } from '../../config/env-config';\nimport { MOBILE_APP_CATALOG } from '../../features/apps/mobileAppCatalog';\nimport { resolveSurfaceUrl } from '../../features/apps/resolveSurfaceUrl';\nimport { CODEZEN_DEV_URL } from '../../features/webbuilder/codezenHandoff';\n\n/** What the launcher and the chat hand-offs may pass. */\ntype WebBuilderRouteParams = {\n orgName?: string | null;\n initialAgentQuery?: string;\n /** Photos or files the ask was typed with; they go to the agent with it. */\n initialAgentAttachments?: MessageAttachment[];\n /** A site to open (its chat), e.g. from its build's task in the Tasks sheet. */\n openChannelId?: string;\n hideNavigationHeader?: boolean;\n};\n\nexport default function WebBuilderNativeScreen() {\n // The in-app light/dark choice (the drawer's Appearance), not only the device setting.\n const { isDark } = useAppTheme();\n const navigation = useNavigation<NavigationProp<ParamListBase>>();\n const route = useRoute<RouteProp<Record<string, WebBuilderRouteParams | undefined>, string>>();\n const routeOrg = typeof route.params?.orgName === 'string' ? route.params.orgName.trim() : '';\n const Experience = getNativeWebBuilderExperience();\n const host = useWebBuilderHost(routeOrg || undefined);\n\n useLayoutEffect(() => {\n if (!route.params?.hideNavigationHeader) navigation.setParams({ hideNavigationHeader: true });\n }, [navigation, route.params?.hideNavigationHeader]);\n\n const seed = useMemo(() => {\n const query = typeof route.params?.initialAgentQuery === 'string' ? route.params.initialAgentQuery.trim() : '';\n const files = Array.isArray(route.params?.initialAgentAttachments)\n ? route.params.initialAgentAttachments\n : undefined;\n if (!query && !files?.length) return null;\n return { text: query, files };\n }, [route.params?.initialAgentQuery, route.params?.initialAgentAttachments]);\n\n // Opened once per hand-off: the param is cleared, so the same task can open it again later.\n const openChannelId = typeof route.params?.openChannelId === 'string' ? route.params.openChannelId.trim() : '';\n const { openProject } = host;\n useEffect(() => {\n if (!openChannelId) return;\n openProject(openChannelId);\n navigation.setParams({ openChannelId: undefined });\n }, [openChannelId, openProject, navigation]);\n\n const onExit = useCallback(() => {\n if (navigation.canGoBack?.()) navigation.goBack();\n else navigation.navigate('MainStack.Layout.Home');\n }, [navigation]);\n\n // \"Demo video\" (web 0.5.0): the Codezen surface, in the app's surface shell, with the handoff fragment.\n const onOpenCodezen = useCallback(\n (fragment: string) => {\n const tile = MOBILE_APP_CATALOG.find((app) => app.key === 'codezen');\n const base = (tile && resolveSurfaceUrl(tile, config)) || CODEZEN_DEV_URL;\n navigation.navigate('MainStack.WebBuilder', {\n url: `${base.split('#')[0]}#${fragment}`,\n appTitle: tile?.label ?? 'Codezen',\n ...(routeOrg ? { orgName: routeOrg } : {}),\n });\n },\n [navigation, routeOrg],\n );\n\n if (!Experience) {\n return (\n <SafeAreaView style={[styles.fill, isDark && styles.fillDark]}>\n <View style={styles.center}>\n <Text style={[styles.title, isDark && styles.textLight]}>Native web builder unavailable</Text>\n <Text style={[styles.detail, isDark && styles.textMuted]}>\n This build does not carry the federation host runtime.\n </Text>\n </View>\n </SafeAreaView>\n );\n }\n\n return (\n <SafeAreaView style={[styles.fill, isDark && styles.fillDark]} edges={['left', 'right']}>\n <Experience\n isDark={isDark}\n onExit={onExit}\n projects={host.projects}\n projectsLoading={host.projectsLoading}\n projectsError={host.projectsError}\n onRefreshProjects={host.refreshProjects}\n projectsHasMore={host.projectsHasMore}\n onLoadMoreProjects={host.loadMoreProjects}\n templates={host.templates}\n templatesLoading={host.templatesLoading}\n templatesError={host.templatesError}\n onReloadTemplates={host.reloadTemplates}\n startBlocked={host.startBlocked}\n startNotice={host.startNotice}\n activeChannelId={host.activeChannelId}\n onOpenProject={host.openProject}\n onCloseProject={host.closeProject}\n onStartProject={host.startProject}\n builds={host.builds}\n buildsLoading={host.buildsLoading}\n building={host.building}\n publishing={host.publishing}\n hostChat={host.hostChat}\n onPublish={host.publish}\n onResumePreview={host.resumePreview}\n onRestorePreview={host.restorePreview}\n goneSandboxIds={host.goneSandboxIds}\n onUndo={host.undo}\n onRedo={host.redo}\n onDownloadCode={host.downloadCode}\n publishTools={host.publishTools}\n projectTools={host.projectTools}\n code={host.code}\n onOpenCodezen={onOpenCodezen}\n initialAgentSeed={seed}\n />\n </SafeAreaView>\n );\n}\n\nconst styles = StyleSheet.create({\n fill: { flex: 1, backgroundColor: '#f5f6f8' },\n fillDark: { backgroundColor: '#0c0e14' },\n center: { flex: 1, alignItems: 'center', justifyContent: 'center', padding: 24 },\n title: { fontSize: 15, fontWeight: '600', color: '#111827', marginBottom: 6 },\n detail: { fontSize: 13, color: '#5d6575', textAlign: 'center' },\n textLight: { color: '#eceff6' },\n textMuted: { color: '#9ca4b6' },\n});\n"],"names":["_a","_b"],"mappings":"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"}
@@ -1,5 +1,22 @@
1
1
  var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
2
7
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
3
20
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
21
  const KEEPALIVE_INTERVAL_MS = 10 * 6e4;
5
22
  const KEEPALIVE_IDLE_MS = 15 * 6e4;
@@ -16,14 +33,47 @@ function keepAliveDecision(i) {
16
33
  function isUnsupportedActionError(message) {
17
34
  return /unknown (webbuilder |sandbox )?action|unsupported action|not (a )?(known|supported) action|no such action|not mocked|action .*not allowed|invalid action/i.test(String(message || ""));
18
35
  }
19
- const GONE_RE = /sandbox not found|not found \(404\)|no sandbox found|does not exist|sandbox.*expired|sandbox.*killed|not running anymore|cannot be resumed|was (?:killed|deleted|destroyed)/i;
36
+ const SANDBOX_GONE_RE = /\bSANDBOX_GONE\b|Sandbox Not Found|Paused sandbox .+ not found|sandbox \S+ not found|sandbox .*wasn'?t found|not found \(404\)|no sandbox found|does not exist|sandbox.*expired|sandbox.*killed|probably not running anymore|not running anymore|cannot be resumed|was (?:killed|deleted|destroyed)/i;
37
+ const rec = (v) => v && typeof v === "object" && !Array.isArray(v) ? v : {};
38
+ function answerData(r) {
39
+ const d = rec(r.data);
40
+ return Object.keys(rec(d.data)).length ? __spreadValues(__spreadValues({}, d), rec(d.data)) : d;
41
+ }
42
+ function isSandboxGoneResult(r) {
43
+ var _a, _b, _c, _d;
44
+ if (r.successful) return false;
45
+ const d = answerData(r);
46
+ const code = String((_d = (_c = (_b = (_a = d.errorCode) != null ? _a : d.code) != null ? _b : d.error_code) != null ? _c : rec(r).errorCode) != null ? _d : "").toUpperCase();
47
+ if (code === "FORBIDDEN" || /\bFORBIDDEN\b|sandbox is private/i.test(r.error || "")) return false;
48
+ return code === "SANDBOX_NOT_FOUND" || code === "SANDBOX_GONE" || d.gone === true || d.sandboxState === "gone" || SANDBOX_GONE_RE.test(r.error || "");
49
+ }
50
+ function savedCopyFrom(r) {
51
+ var _a, _b, _c, _d;
52
+ if (!isSandboxGoneResult(r)) return null;
53
+ const restore = rec(answerData(r).restore);
54
+ const str = (v) => typeof v === "string" && v.trim() ? v.trim() : void 0;
55
+ const text = r.error || "";
56
+ const snapshotId = (_b = str(restore.snapshotId)) != null ? _b : (_a = /\bsnapshot(?:Id)?\b[\s:=]+[`"']?([A-Za-z0-9][\w.:-]{3,199})/i.exec(text)) == null ? void 0 : _a[1];
57
+ const backupRepo = (_d = str(restore.backupRepo)) != null ? _d : (_c = /\b(?:backupRepo|backup repo|repo)\b[\s:=]+[`"']?([\w.-]+(?:\/[\w.-]+)?)/i.exec(text)) == null ? void 0 : _c[1];
58
+ let backupExists = backupRepo ? void 0 : false;
59
+ if (typeof restore.backupExists === "boolean") backupExists = restore.backupExists;
60
+ return __spreadValues(__spreadValues(__spreadValues({}, snapshotId ? {
61
+ snapshotId: snapshotId.replace(/[.,;)]+$/, "")
62
+ } : {}), backupRepo ? {
63
+ backupRepo: backupRepo.replace(/[.,;)]+$/, "")
64
+ } : {}), backupExists !== void 0 ? {
65
+ backupExists
66
+ } : {});
67
+ }
20
68
  function extendOutcome(r) {
21
69
  if (r.successful) {
22
70
  const d = r.data && typeof r.data === "object" ? r.data : {};
23
71
  return d.resumed === true ? "resumed" : "alive";
24
72
  }
25
73
  if (isUnsupportedActionError(r.error)) return "unsupported";
26
- if (GONE_RE.test(r.error || "")) return "gone";
74
+ if (isSandboxGoneResult(__spreadProps(__spreadValues({}, r), {
75
+ successful: false
76
+ }))) return "gone";
27
77
  return "failed";
28
78
  }
29
79
  class KeepAliveScheduler {
@@ -109,4 +159,4 @@ class KeepAliveScheduler {
109
159
  this.failures.delete(sandboxId);
110
160
  this.lastPingAt.delete(sandboxId);
111
161
  }
112
- }export{KEEPALIVE_EXTEND_MS,KEEPALIVE_IDLE_MS,KEEPALIVE_INTERVAL_MS,KEEPALIVE_MAX_FAILURES,KEEPALIVE_TICK_MS,KeepAliveScheduler,WEBBUILDER_EXTEND_ACTION,extendOutcome,isUnsupportedActionError,keepAliveDecision};//# sourceMappingURL=keepAlive.js.map
162
+ }export{KEEPALIVE_EXTEND_MS,KEEPALIVE_IDLE_MS,KEEPALIVE_INTERVAL_MS,KEEPALIVE_MAX_FAILURES,KEEPALIVE_TICK_MS,KeepAliveScheduler,SANDBOX_GONE_RE,WEBBUILDER_EXTEND_ACTION,extendOutcome,isSandboxGoneResult,isUnsupportedActionError,keepAliveDecision,savedCopyFrom};//# sourceMappingURL=keepAlive.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"keepAlive.js","sources":["../../../src/screens/WebBuilderNative/keepAlive.ts"],"sourcesContent":["/**\n * Keeps an open build's sandbox awake while the app is in front and in use; an idle\n * app lets it pause (web `sandbox/keepAlive.ts`, #438 C1 - ported as is). Pure.\n */\n\nexport const KEEPALIVE_INTERVAL_MS = 10 * 60_000;\nexport const KEEPALIVE_IDLE_MS = 15 * 60_000;\nexport const KEEPALIVE_EXTEND_MS = 1_800_000;\n/** How often the hook asks the scheduler (cheap; the scheduler decides). */\nexport const KEEPALIVE_TICK_MS = 60_000;\n/** Consecutive failures (sandbox gone, network) before pinging stops for that sandbox. */\nexport const KEEPALIVE_MAX_FAILURES = 2;\n\nexport const WEBBUILDER_EXTEND_ACTION = 'WEBBUILDER_EXTEND' as const;\n\nexport type KeepAliveDecision = 'ping' | 'wait' | 'idle';\n\nexport interface KeepAliveInput {\n visible: boolean;\n sandboxId: string;\n /** The build's preview is live (not asleep, not restoring). */\n live: boolean;\n now: number;\n lastActivityAt: number;\n /** When EXTEND last went out for this sandbox; null = never. */\n lastPingAt: number | null;\n}\n\n/** `idle`: nothing should run now (hidden, idle, no live sandbox); `wait`: not due yet. */\nexport function keepAliveDecision(i: KeepAliveInput): KeepAliveDecision {\n if (!i.visible || !i.sandboxId || !i.live) return 'idle';\n if (i.now - i.lastActivityAt > KEEPALIVE_IDLE_MS) return 'idle';\n if (i.lastPingAt !== null && i.now - i.lastPingAt < KEEPALIVE_INTERVAL_MS) return 'wait';\n return 'ping';\n}\n\n/** The connector (or the proxy) does not know the action: an older version, stop asking. */\nexport function isUnsupportedActionError(message: string | null | undefined): boolean {\n return /unknown (webbuilder |sandbox )?action|unsupported action|not (a )?(known|supported) action|no such action|not mocked|action .*not allowed|invalid action/i.test(\n String(message || ''),\n );\n}\n\nexport interface ExtendResult {\n successful: boolean;\n data?: unknown;\n error?: string;\n}\n\nexport type ExtendOutcome = 'resumed' | 'alive' | 'unsupported' | 'gone' | 'failed';\n\nconst GONE_RE =\n /sandbox not found|not found \\(404\\)|no sandbox found|does not exist|sandbox.*expired|sandbox.*killed|not running anymore|cannot be resumed|was (?:killed|deleted|destroyed)/i;\n\n/** What an EXTEND answer means (`{resumed, timeoutMs}` on success). */\nexport function extendOutcome(r: ExtendResult): ExtendOutcome {\n if (r.successful) {\n const d = r.data && typeof r.data === 'object' ? (r.data as Record<string, unknown>) : {};\n return d.resumed === true ? 'resumed' : 'alive';\n }\n if (isUnsupportedActionError(r.error)) return 'unsupported';\n if (GONE_RE.test(r.error || '')) return 'gone';\n return 'failed';\n}\n\nexport interface KeepAliveDeps {\n now: () => number;\n extend: (sandboxId: string) => Promise<ExtendResult>;\n /** EXTEND says the sandbox is gone: the host runs its wake flow. */\n onGone?: (sandboxId: string) => void;\n /** EXTEND woke a paused sandbox: the host reloads the preview. */\n onResumed?: (sandboxId: string) => void;\n}\n\n/** One scheduler per open build; `tick()` runs EXTEND when due, one at a time. */\nexport class KeepAliveScheduler {\n private visible = true;\n\n private sandboxId = '';\n\n private live = false;\n\n private lastActivityAt: number;\n\n private lastPingAt = new Map<string, number>();\n\n private failures = new Map<string, number>();\n\n private off = new Set<string>();\n\n private inflight = false;\n\n private deps: KeepAliveDeps;\n\n constructor(deps: KeepAliveDeps) {\n this.deps = deps;\n this.lastActivityAt = deps.now();\n }\n\n noteActivity(): void {\n this.lastActivityAt = this.deps.now();\n }\n\n setVisible(visible: boolean): void {\n this.visible = visible;\n }\n\n setTarget(sandboxId: string | null | undefined, live: boolean): void {\n this.sandboxId = String(sandboxId || '').trim();\n this.live = live;\n }\n\n /** Pinging is off for this sandbox (no EXTEND on this connector, or it kept failing). */\n isOff(sandboxId = this.sandboxId): boolean {\n return this.off.has(sandboxId);\n }\n\n decision(): KeepAliveDecision {\n if (!this.sandboxId || this.off.has(this.sandboxId) || this.inflight) return 'idle';\n return keepAliveDecision({\n visible: this.visible,\n sandboxId: this.sandboxId,\n live: this.live,\n now: this.deps.now(),\n lastActivityAt: this.lastActivityAt,\n lastPingAt: this.lastPingAt.get(this.sandboxId) ?? null,\n });\n }\n\n async tick(): Promise<KeepAliveDecision | ExtendOutcome> {\n const d = this.decision();\n if (d !== 'ping') return d;\n const id = this.sandboxId;\n this.inflight = true;\n this.lastPingAt.set(id, this.deps.now());\n let outcome: ExtendOutcome;\n try {\n outcome = extendOutcome(await this.deps.extend(id));\n } catch (e) {\n outcome = extendOutcome({ successful: false, error: e instanceof Error ? e.message : String(e) });\n } finally {\n this.inflight = false;\n }\n if (outcome === 'resumed' || outcome === 'alive') {\n this.failures.delete(id);\n if (outcome === 'resumed') this.deps.onResumed?.(id);\n return outcome;\n }\n if (outcome === 'unsupported') {\n this.off.add(id);\n return outcome;\n }\n const n = (this.failures.get(id) ?? 0) + 1;\n this.failures.set(id, n);\n if (outcome === 'gone') {\n this.off.add(id);\n this.deps.onGone?.(id);\n } else if (n >= KEEPALIVE_MAX_FAILURES) {\n this.off.add(id);\n }\n return outcome;\n }\n\n /** A new sandbox came up for this build (wake, restore): try again from scratch. */\n reset(sandboxId: string): void {\n this.off.delete(sandboxId);\n this.failures.delete(sandboxId);\n this.lastPingAt.delete(sandboxId);\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"keepAlive.js","sources":["../../../src/screens/WebBuilderNative/keepAlive.ts"],"sourcesContent":["/**\n * Keeps an open build's sandbox awake while the app is in front and in use; an idle\n * app lets it pause (web `sandbox/keepAlive.ts`, #438 C1 - ported as is). Pure.\n */\n\nexport const KEEPALIVE_INTERVAL_MS = 10 * 60_000;\nexport const KEEPALIVE_IDLE_MS = 15 * 60_000;\nexport const KEEPALIVE_EXTEND_MS = 1_800_000;\n/** How often the hook asks the scheduler (cheap; the scheduler decides). */\nexport const KEEPALIVE_TICK_MS = 60_000;\n/** Consecutive failures (sandbox gone, network) before pinging stops for that sandbox. */\nexport const KEEPALIVE_MAX_FAILURES = 2;\n\nexport const WEBBUILDER_EXTEND_ACTION = 'WEBBUILDER_EXTEND' as const;\n\nexport type KeepAliveDecision = 'ping' | 'wait' | 'idle';\n\nexport interface KeepAliveInput {\n visible: boolean;\n sandboxId: string;\n /** The build's preview is live (not asleep, not restoring). */\n live: boolean;\n now: number;\n lastActivityAt: number;\n /** When EXTEND last went out for this sandbox; null = never. */\n lastPingAt: number | null;\n}\n\n/** `idle`: nothing should run now (hidden, idle, no live sandbox); `wait`: not due yet. */\nexport function keepAliveDecision(i: KeepAliveInput): KeepAliveDecision {\n if (!i.visible || !i.sandboxId || !i.live) return 'idle';\n if (i.now - i.lastActivityAt > KEEPALIVE_IDLE_MS) return 'idle';\n if (i.lastPingAt !== null && i.now - i.lastPingAt < KEEPALIVE_INTERVAL_MS) return 'wait';\n return 'ping';\n}\n\n/** The connector (or the proxy) does not know the action: an older version, stop asking. */\nexport function isUnsupportedActionError(message: string | null | undefined): boolean {\n return /unknown (webbuilder |sandbox )?action|unsupported action|not (a )?(known|supported) action|no such action|not mocked|action .*not allowed|invalid action/i.test(\n String(message || ''),\n );\n}\n\nexport interface ExtendResult {\n successful: boolean;\n data?: unknown;\n error?: string;\n}\n\nexport type ExtendOutcome = 'resumed' | 'alive' | 'unsupported' | 'gone' | 'failed';\n\n/** The sandbox was reclaimed, not paused (web `SANDBOX_GONE_RE`). */\nexport const SANDBOX_GONE_RE =\n /\\bSANDBOX_GONE\\b|Sandbox Not Found|Paused sandbox .+ not found|sandbox \\S+ not found|sandbox .*wasn'?t found|not found \\(404\\)|no sandbox found|does not exist|sandbox.*expired|sandbox.*killed|probably not running anymore|not running anymore|cannot be resumed|was (?:killed|deleted|destroyed)/i;\n\ntype ConnectorAnswer = { successful?: boolean; data?: unknown; error?: string | null };\n\nconst rec = (v: unknown): Record<string, unknown> =>\n v && typeof v === 'object' && !Array.isArray(v) ? (v as Record<string, unknown>) : {};\n\n/** The connector's `data` (the proxy may wrap it once more in `data`). */\nfunction answerData(r: ConnectorAnswer): Record<string, unknown> {\n const d = rec(r.data);\n return Object.keys(rec(d.data)).length ? { ...d, ...rec(d.data) } : d;\n}\n\n/**\n * A connector answer that says the sandbox no longer exists (web `isSandboxGoneResult`):\n * `errorCode: SANDBOX_NOT_FOUND` / `SANDBOX_GONE`, `data.gone` / `sandboxState: \"gone\"`, or the\n * old wording. A private sandbox refused (FORBIDDEN) is not gone.\n */\nexport function isSandboxGoneResult(r: ConnectorAnswer): boolean {\n if (r.successful) return false;\n const d = answerData(r);\n const code = String(d.errorCode ?? d.code ?? d.error_code ?? rec(r).errorCode ?? '').toUpperCase();\n if (code === 'FORBIDDEN' || /\\bFORBIDDEN\\b|sandbox is private/i.test(r.error || '')) return false;\n return (\n code === 'SANDBOX_NOT_FOUND' ||\n code === 'SANDBOX_GONE' ||\n d.gone === true ||\n d.sandboxState === 'gone' ||\n SANDBOX_GONE_RE.test(r.error || '')\n );\n}\n\n/** Where a gone sandbox can be restored from, as the connector reports it (`data.restore`, else its error text). */\nexport interface SavedCopy {\n snapshotId?: string;\n backupRepo?: string;\n backupExists?: boolean;\n}\n\nexport function savedCopyFrom(r: ConnectorAnswer): SavedCopy | null {\n if (!isSandboxGoneResult(r)) return null;\n const restore = rec(answerData(r).restore);\n const str = (v: unknown) => (typeof v === 'string' && v.trim() ? v.trim() : undefined);\n // cdecli drops `data` on a failed direct call; its message still names the snapshot and the repo.\n const text = r.error || '';\n const snapshotId =\n str(restore.snapshotId) ?? /\\bsnapshot(?:Id)?\\b[\\s:=]+[`\"']?([A-Za-z0-9][\\w.:-]{3,199})/i.exec(text)?.[1];\n const backupRepo =\n str(restore.backupRepo) ??\n /\\b(?:backupRepo|backup repo|repo)\\b[\\s:=]+[`\"']?([\\w.-]+(?:\\/[\\w.-]+)?)/i.exec(text)?.[1];\n let backupExists: boolean | undefined = backupRepo ? undefined : false;\n if (typeof restore.backupExists === 'boolean') backupExists = restore.backupExists;\n return {\n ...(snapshotId ? { snapshotId: snapshotId.replace(/[.,;)]+$/, '') } : {}),\n ...(backupRepo ? { backupRepo: backupRepo.replace(/[.,;)]+$/, '') } : {}),\n ...(backupExists !== undefined ? { backupExists } : {}),\n };\n}\n\n/** What an EXTEND answer means (`{resumed, timeoutMs}` on success). */\nexport function extendOutcome(r: ExtendResult): ExtendOutcome {\n if (r.successful) {\n const d = r.data && typeof r.data === 'object' ? (r.data as Record<string, unknown>) : {};\n return d.resumed === true ? 'resumed' : 'alive';\n }\n if (isUnsupportedActionError(r.error)) return 'unsupported';\n if (isSandboxGoneResult({ ...r, successful: false })) return 'gone';\n return 'failed';\n}\n\nexport interface KeepAliveDeps {\n now: () => number;\n extend: (sandboxId: string) => Promise<ExtendResult>;\n /** EXTEND says the sandbox is gone: the host runs its wake flow. */\n onGone?: (sandboxId: string) => void;\n /** EXTEND woke a paused sandbox: the host reloads the preview. */\n onResumed?: (sandboxId: string) => void;\n}\n\n/** One scheduler per open build; `tick()` runs EXTEND when due, one at a time. */\nexport class KeepAliveScheduler {\n private visible = true;\n\n private sandboxId = '';\n\n private live = false;\n\n private lastActivityAt: number;\n\n private lastPingAt = new Map<string, number>();\n\n private failures = new Map<string, number>();\n\n private off = new Set<string>();\n\n private inflight = false;\n\n private deps: KeepAliveDeps;\n\n constructor(deps: KeepAliveDeps) {\n this.deps = deps;\n this.lastActivityAt = deps.now();\n }\n\n noteActivity(): void {\n this.lastActivityAt = this.deps.now();\n }\n\n setVisible(visible: boolean): void {\n this.visible = visible;\n }\n\n setTarget(sandboxId: string | null | undefined, live: boolean): void {\n this.sandboxId = String(sandboxId || '').trim();\n this.live = live;\n }\n\n /** Pinging is off for this sandbox (no EXTEND on this connector, or it kept failing). */\n isOff(sandboxId = this.sandboxId): boolean {\n return this.off.has(sandboxId);\n }\n\n decision(): KeepAliveDecision {\n if (!this.sandboxId || this.off.has(this.sandboxId) || this.inflight) return 'idle';\n return keepAliveDecision({\n visible: this.visible,\n sandboxId: this.sandboxId,\n live: this.live,\n now: this.deps.now(),\n lastActivityAt: this.lastActivityAt,\n lastPingAt: this.lastPingAt.get(this.sandboxId) ?? null,\n });\n }\n\n async tick(): Promise<KeepAliveDecision | ExtendOutcome> {\n const d = this.decision();\n if (d !== 'ping') return d;\n const id = this.sandboxId;\n this.inflight = true;\n this.lastPingAt.set(id, this.deps.now());\n let outcome: ExtendOutcome;\n try {\n outcome = extendOutcome(await this.deps.extend(id));\n } catch (e) {\n outcome = extendOutcome({ successful: false, error: e instanceof Error ? e.message : String(e) });\n } finally {\n this.inflight = false;\n }\n if (outcome === 'resumed' || outcome === 'alive') {\n this.failures.delete(id);\n if (outcome === 'resumed') this.deps.onResumed?.(id);\n return outcome;\n }\n if (outcome === 'unsupported') {\n this.off.add(id);\n return outcome;\n }\n const n = (this.failures.get(id) ?? 0) + 1;\n this.failures.set(id, n);\n if (outcome === 'gone') {\n this.off.add(id);\n this.deps.onGone?.(id);\n } else if (n >= KEEPALIVE_MAX_FAILURES) {\n this.off.add(id);\n }\n return outcome;\n }\n\n /** A new sandbox came up for this build (wake, restore): try again from scratch. */\n reset(sandboxId: string): void {\n this.off.delete(sandboxId);\n this.failures.delete(sandboxId);\n this.lastPingAt.delete(sandboxId);\n }\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ const UNREACHABLE_COPY = "Couldn't reach the server. Check your connection, then try again.";
2
+ const UNREACHABLE_RETRY_DELAYS_MS = [800, 2e3, 4e3];
3
+ function isAgentUnreachable(raw) {
4
+ const s = String(raw != null ? raw : "").trim();
5
+ return s === UNREACHABLE_COPY || /cdecli-agent unreachable|failed to fetch|fetch failed|networkerror|network request failed|load failed|cdecli-agent HTTP 50[234]\b/i.test(s);
6
+ }
7
+ function plainAgentError(raw) {
8
+ const s = String(raw != null ? raw : "").trim();
9
+ if (isAgentUnreachable(s)) return UNREACHABLE_COPY;
10
+ return /^cdecli-agent\b/i.test(s) ? "Something went wrong on our side. Try again in a moment." : s;
11
+ }
12
+ const wait = (ms) => new Promise((resolve) => {
13
+ setTimeout(resolve, ms);
14
+ });
15
+ async function retryUnreachable(run, delays = UNREACHABLE_RETRY_DELAYS_MS) {
16
+ let r = await run();
17
+ for (const delay of delays) {
18
+ if (r.successful || !isAgentUnreachable(r.error)) return r;
19
+ await wait(delay);
20
+ r = await run();
21
+ }
22
+ return r;
23
+ }export{UNREACHABLE_COPY,UNREACHABLE_RETRY_DELAYS_MS,isAgentUnreachable,plainAgentError,retryUnreachable};//# sourceMappingURL=unreachableRetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unreachableRetry.js","sources":["../../../src/screens/WebBuilderNative/unreachableRetry.ts"],"sourcesContent":["/**\n * Sandbox calls that never reached the agent (an offline blip, a gateway restart) are\n * sent again (web `sandbox/unreachableRetry.ts`, #920f0bba). Pure.\n */\n\nexport const UNREACHABLE_COPY = \"Couldn't reach the server. Check your connection, then try again.\";\n\n/** Waits before each new attempt. */\nexport const UNREACHABLE_RETRY_DELAYS_MS = [800, 2_000, 4_000];\n\n/** The agent (or its gateway) was never reached: nothing ran, so the same call can simply be sent again. */\nexport function isAgentUnreachable(raw: string | null | undefined): boolean {\n const s = String(raw ?? '').trim();\n return (\n s === UNREACHABLE_COPY ||\n /cdecli-agent unreachable|failed to fetch|fetch failed|networkerror|network request failed|load failed|cdecli-agent HTTP 50[234]\\b/i.test(\n s,\n )\n );\n}\n\n/** A connector call's error as people see it: the agent client's own errors (its URL, HTTP bodies) never show. */\nexport function plainAgentError(raw: string | null | undefined): string {\n const s = String(raw ?? '').trim();\n if (isAgentUnreachable(s)) return UNREACHABLE_COPY;\n return /^cdecli-agent\\b/i.test(s) ? 'Something went wrong on our side. Try again in a moment.' : s;\n}\n\nconst wait = (ms: number) =>\n new Promise<void>((resolve) => {\n setTimeout(resolve, ms);\n });\n\n/** `run` again, after each delay, while its result says the agent was unreachable. */\nexport async function retryUnreachable<T extends { successful: boolean; error?: string | null }>(\n run: () => Promise<T>,\n delays: readonly number[] = UNREACHABLE_RETRY_DELAYS_MS,\n): Promise<T> {\n let r = await run();\n for (const delay of delays) {\n if (r.successful || !isAgentUnreachable(r.error)) return r;\n await wait(delay);\n r = await run();\n }\n return r;\n}\n"],"names":[],"mappings":"AAKO,MAAM,gBAAmB,GAAA;AAGzB,MAAM,2BAA8B,GAAA,CAAC,GAAK,EAAA,GAAA,EAAO,GAAK;AAGtD,SAAS,mBAAmB,GAAyC,EAAA;AAC1E,EAAA,MAAM,CAAI,GAAA,MAAA,CAAO,GAAO,IAAA,IAAA,GAAA,GAAA,GAAA,EAAE,EAAE,IAAK,EAAA;AACjC,EAAA,OAAO,CAAM,KAAA,gBAAA,IAAoB,oIAAqI,CAAA,IAAA,CAAK,CAAC,CAAA;AAC9K;AAGO,SAAS,gBAAgB,GAAwC,EAAA;AACtE,EAAA,MAAM,CAAI,GAAA,MAAA,CAAO,GAAO,IAAA,IAAA,GAAA,GAAA,GAAA,EAAE,EAAE,IAAK,EAAA;AACjC,EAAI,IAAA,kBAAA,CAAmB,CAAC,CAAA,EAAU,OAAA,gBAAA;AAClC,EAAA,OAAO,kBAAmB,CAAA,IAAA,CAAK,CAAC,CAAA,GAAI,0DAA6D,GAAA,CAAA;AACnG;AACA,MAAM,IAAO,GAAA,CAAC,EAAe,KAAA,IAAI,QAAc,CAAW,OAAA,KAAA;AACxD,EAAA,UAAA,CAAW,SAAS,EAAE,CAAA;AACxB,CAAC,CAAA;AAGqB,eAAA,gBAAA,CAGnB,GAAuB,EAAA,MAAA,GAA4B,2BAAyC,EAAA;AAC7F,EAAI,IAAA,CAAA,GAAI,MAAM,GAAI,EAAA;AAClB,EAAA,KAAA,MAAW,SAAS,MAAQ,EAAA;AAC1B,IAAA,IAAI,EAAE,UAAc,IAAA,CAAC,mBAAmB,CAAE,CAAA,KAAK,GAAU,OAAA,CAAA;AACzD,IAAA,MAAM,KAAK,KAAK,CAAA;AAChB,IAAA,CAAA,GAAI,MAAM,GAAI,EAAA;AAAA;AAEhB,EAAO,OAAA,CAAA;AACT"}
@@ -0,0 +1,37 @@
1
+ import {useState,useEffect,useMemo}from'react';import {createRemoteConnectorExec}from'../../features/canvas/videoEditor/remoteMediaClient.js';import {WEBBUILDER_CONNECTOR_ID}from'../../features/webbuilder/workflow.js';import {galleryTemplates,WEBBUILDER_LIST_TEMPLATES_ACTION}from'../../features/webbuilder/connectorTemplates.js';const LIST_TEMPLATES_TIMEOUT_MS = 2e4;
2
+ const TEMPLATE_CACHE_MS = 5 * 6e4;
3
+ let cached = null;
4
+ function connectorCatalog(token, indexUrl) {
5
+ if (cached && cached.token === token && Date.now() - cached.at < TEMPLATE_CACHE_MS) return cached.data;
6
+ const data = createRemoteConnectorExec(token, indexUrl)(WEBBUILDER_CONNECTOR_ID, WEBBUILDER_LIST_TEMPLATES_ACTION, {}, {
7
+ timeoutMs: LIST_TEMPLATES_TIMEOUT_MS
8
+ }).then((result) => result.successful === false ? null : result.data).catch((err) => {
9
+ console.warn("[WebBuilderNative] template catalog read failed", err);
10
+ return null;
11
+ });
12
+ const entry = {
13
+ token,
14
+ at: Date.now(),
15
+ data
16
+ };
17
+ cached = entry;
18
+ data.then((d) => {
19
+ if (!d && cached === entry) cached = null;
20
+ });
21
+ return data;
22
+ }
23
+ function useConnectorTemplates(token, indexUrl, fromSettings, reloadKey = 0) {
24
+ const [catalog, setCatalog] = useState(null);
25
+ useEffect(() => {
26
+ if (!token || !indexUrl) return void 0;
27
+ if (reloadKey && (cached == null ? void 0 : cached.token) === token) cached = null;
28
+ let live = true;
29
+ connectorCatalog(token, indexUrl).then((data) => {
30
+ if (live) setCatalog(data);
31
+ });
32
+ return () => {
33
+ live = false;
34
+ };
35
+ }, [token, indexUrl, reloadKey]);
36
+ return useMemo(() => galleryTemplates(catalog, fromSettings), [catalog, fromSettings]);
37
+ }export{useConnectorTemplates};//# sourceMappingURL=useConnectorTemplates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useConnectorTemplates.js","sources":["../../../src/screens/WebBuilderNative/useConnectorTemplates.ts"],"sourcesContent":["/**\n * The template gallery from the yantra-webbuilder catalog (`WEBBUILDER_LIST_TEMPLATES`, the one\n * the agent picks from), merged with the workspace's pageSettings cards for what a pick still\n * needs from them - the web `listGalleryTemplates`. Read once per sign-in for a few minutes;\n * the workspace cards alone while it loads or when the connector read fails.\n */\nimport { useEffect, useMemo, useState } from 'react';\nimport { createRemoteConnectorExec } from '../../features/canvas/videoEditor/remoteMediaClient';\nimport { WEBBUILDER_CONNECTOR_ID, type WebBuilderTemplate } from '../../features/webbuilder/workflow';\nimport { WEBBUILDER_LIST_TEMPLATES_ACTION, galleryTemplates } from '../../features/webbuilder/connectorTemplates';\n\nconst LIST_TEMPLATES_TIMEOUT_MS = 20_000;\nconst TEMPLATE_CACHE_MS = 5 * 60_000;\n\nlet cached: { token: string; at: number; data: Promise<unknown> } | null = null;\n\n/** The connector's catalog `data` for this sign-in (null when the read failed); one read per few minutes. */\nfunction connectorCatalog(token: string, indexUrl: string): Promise<unknown> {\n if (cached && cached.token === token && Date.now() - cached.at < TEMPLATE_CACHE_MS) return cached.data;\n const data = createRemoteConnectorExec(token, indexUrl)(\n WEBBUILDER_CONNECTOR_ID,\n WEBBUILDER_LIST_TEMPLATES_ACTION,\n {},\n { timeoutMs: LIST_TEMPLATES_TIMEOUT_MS },\n )\n .then((result) => (result.successful === false ? null : result.data))\n .catch((err: unknown) => {\n console.warn('[WebBuilderNative] template catalog read failed', err);\n return null;\n });\n const entry = { token, at: Date.now(), data };\n cached = entry;\n // A failed or empty read is not kept: the next open asks again.\n data.then((d) => {\n if (!d && cached === entry) cached = null;\n });\n return data;\n}\n\nexport function useConnectorTemplates(\n token: string | null | undefined,\n indexUrl: string | null | undefined,\n fromSettings: WebBuilderTemplate[],\n reloadKey = 0,\n): WebBuilderTemplate[] {\n const [catalog, setCatalog] = useState<unknown>(null);\n useEffect(() => {\n if (!token || !indexUrl) return undefined;\n if (reloadKey && cached?.token === token) cached = null;\n let live = true;\n connectorCatalog(token, indexUrl).then((data) => {\n if (live) setCatalog(data);\n });\n return () => {\n live = false;\n };\n }, [token, indexUrl, reloadKey]);\n return useMemo(() => galleryTemplates(catalog, fromSettings), [catalog, fromSettings]);\n}\n"],"names":[],"mappings":"0UAUA,MAAM,yBAA4B,GAAA,GAAA;AAClC,MAAM,oBAAoB,CAAI,GAAA,GAAA;AAC9B,IAAI,MAIO,GAAA,IAAA;AAGX,SAAS,gBAAA,CAAiB,OAAe,QAAoC,EAAA;AAC3E,EAAI,IAAA,MAAA,IAAU,MAAO,CAAA,KAAA,KAAU,KAAS,IAAA,IAAA,CAAK,GAAI,EAAA,GAAI,MAAO,CAAA,EAAA,GAAK,iBAAmB,EAAA,OAAO,MAAO,CAAA,IAAA;AAClG,EAAM,MAAA,IAAA,GAAO,0BAA0B,KAAO,EAAA,QAAQ,EAAE,uBAAyB,EAAA,gCAAA,EAAkC,EAAI,EAAA;AAAA,IACrH,SAAW,EAAA;AAAA,GACZ,CAAA,CAAE,IAAK,CAAA,CAAA,MAAA,KAAU,MAAO,CAAA,UAAA,KAAe,KAAQ,GAAA,IAAA,GAAO,MAAO,CAAA,IAAI,CAAE,CAAA,KAAA,CAAM,CAAC,GAAiB,KAAA;AAC1F,IAAQ,OAAA,CAAA,IAAA,CAAK,mDAAmD,GAAG,CAAA;AACnE,IAAO,OAAA,IAAA;AAAA,GACR,CAAA;AACD,EAAA,MAAM,KAAQ,GAAA;AAAA,IACZ,KAAA;AAAA,IACA,EAAA,EAAI,KAAK,GAAI,EAAA;AAAA,IACb;AAAA,GACF;AACA,EAAS,MAAA,GAAA,KAAA;AAET,EAAA,IAAA,CAAK,KAAK,CAAK,CAAA,KAAA;AACb,IAAA,IAAI,CAAC,CAAA,IAAK,MAAW,KAAA,KAAA,EAAgB,MAAA,GAAA,IAAA;AAAA,GACtC,CAAA;AACD,EAAO,OAAA,IAAA;AACT;AACO,SAAS,qBAAsB,CAAA,KAAA,EAAkC,QAAqC,EAAA,YAAA,EAAoC,YAAY,CAAyB,EAAA;AACpL,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAkB,IAAI,CAAA;AACpD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,KAAA,IAAS,CAAC,QAAA,EAAiB,OAAA,MAAA;AAChC,IAAA,IAAI,SAAa,IAAA,CAAA,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ,KAAU,MAAA,KAAA,EAAgB,MAAA,GAAA,IAAA;AACnD,IAAA,IAAI,IAAO,GAAA,IAAA;AACX,IAAA,gBAAA,CAAiB,KAAO,EAAA,QAAQ,CAAE,CAAA,IAAA,CAAK,CAAQ,IAAA,KAAA;AAC7C,MAAI,IAAA,IAAA,aAAiB,IAAI,CAAA;AAAA,KAC1B,CAAA;AACD,IAAA,OAAO,MAAM;AACX,MAAO,IAAA,GAAA,KAAA;AAAA,KACT;AAAA,GACC,EAAA,CAAC,KAAO,EAAA,QAAA,EAAU,SAAS,CAAC,CAAA;AAC/B,EAAO,OAAA,OAAA,CAAQ,MAAM,gBAAiB,CAAA,OAAA,EAAS,YAAY,CAAG,EAAA,CAAC,OAAS,EAAA,YAAY,CAAC,CAAA;AACvF"}
@@ -1,4 +1,6 @@
1
1
  import {useRef,useEffect,useCallback}from'react';import {AppState}from'react-native';import {KeepAliveScheduler,WEBBUILDER_EXTEND_ACTION,KEEPALIVE_EXTEND_MS,KEEPALIVE_TICK_MS}from'./keepAlive.js';function useSandboxKeepAlive(opts) {
2
+ const onGoneRef = useRef(opts.onGone);
3
+ onGoneRef.current = opts.onGone;
2
4
  const runRef = useRef(opts.run);
3
5
  runRef.current = opts.run;
4
6
  const schedulerRef = useRef(null);
@@ -16,6 +18,10 @@ import {useRef,useEffect,useCallback}from'react';import {AppState}from'react-nat
16
18
  sandbox_id: sandboxId2,
17
19
  timeoutMs: KEEPALIVE_EXTEND_MS
18
20
  }, 9e4);
21
+ },
22
+ onGone: (sandboxId2) => {
23
+ var _a;
24
+ return (_a = onGoneRef.current) == null ? void 0 : _a.call(onGoneRef, sandboxId2);
19
25
  }
20
26
  });
21
27
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useSandboxKeepAlive.js","sources":["../../../src/screens/WebBuilderNative/useSandboxKeepAlive.ts"],"sourcesContent":["/**\n * Feeds the keep-alive scheduler (keepAlive.ts) the app's foreground state and the\n * person's activity (web `sandbox/useSandboxKeepAlive.ts`): `WEBBUILDER_EXTEND`\n * every 10 minutes while a build is open, the app is in front and the person did\n * something in the last 15 minutes. Opening a project, sending a turn and\n * returning to the app count as activity (`noteActivity`).\n */\nimport { useCallback, useEffect, useRef } from 'react';\nimport { AppState } from 'react-native';\nimport {\n KEEPALIVE_EXTEND_MS,\n KEEPALIVE_TICK_MS,\n KeepAliveScheduler,\n WEBBUILDER_EXTEND_ACTION,\n type ExtendResult,\n} from './keepAlive';\n\nexport function useSandboxKeepAlive(opts: {\n run: ((action: string, params: Record<string, unknown>, timeoutMs: number) => Promise<ExtendResult>) | null;\n sandboxId?: string | null;\n /** A build is open (its preview may be on screen). */\n live: boolean;\n}): { noteActivity: () => void } {\n const runRef = useRef(opts.run);\n runRef.current = opts.run;\n const schedulerRef = useRef<KeepAliveScheduler | null>(null);\n if (!schedulerRef.current) {\n schedulerRef.current = new KeepAliveScheduler({\n now: () => Date.now(),\n extend: async (sandboxId) => {\n const run = runRef.current;\n if (!run) return { successful: false, data: {}, error: 'no sandbox access' };\n return run(WEBBUILDER_EXTEND_ACTION, { sandbox_id: sandboxId, timeoutMs: KEEPALIVE_EXTEND_MS }, 90_000);\n },\n });\n }\n\n const sandboxId = String(opts.sandboxId || '').trim();\n const enabled = Boolean(opts.run) && opts.live;\n\n useEffect(() => {\n const s = schedulerRef.current!;\n s.setTarget(sandboxId, enabled);\n if (enabled) {\n s.noteActivity();\n s.tick().catch(() => undefined);\n }\n }, [sandboxId, enabled]);\n\n useEffect(() => {\n const s = schedulerRef.current!;\n s.setVisible(AppState.currentState === 'active');\n const sub = AppState.addEventListener('change', (state) => {\n s.setVisible(state === 'active');\n if (state === 'active') {\n s.noteActivity();\n s.tick().catch(() => undefined);\n }\n });\n const timer = setInterval(() => {\n s.tick().catch(() => undefined);\n }, KEEPALIVE_TICK_MS);\n return () => {\n sub.remove();\n clearInterval(timer);\n };\n }, []);\n\n const noteActivity = useCallback(() => schedulerRef.current?.noteActivity(), []);\n return { noteActivity };\n}\n"],"names":["sandboxId"],"mappings":"oMAUO,SAAS,oBAAoB,IAOlC,EAAA;AACA,EAAM,MAAA,MAAA,GAAS,MAAO,CAAA,IAAA,CAAK,GAAG,CAAA;AAC9B,EAAA,MAAA,CAAO,UAAU,IAAK,CAAA,GAAA;AACtB,EAAM,MAAA,YAAA,GAAe,OAAkC,IAAI,CAAA;AAC3D,EAAI,IAAA,CAAC,aAAa,OAAS,EAAA;AACzB,IAAa,YAAA,CAAA,OAAA,GAAU,IAAI,kBAAmB,CAAA;AAAA,MAC5C,GAAA,EAAK,MAAM,IAAA,CAAK,GAAI,EAAA;AAAA,MACpB,MAAA,EAAQ,OAAMA,UAAa,KAAA;AACzB,QAAA,MAAM,MAAM,MAAO,CAAA,OAAA;AACnB,QAAI,IAAA,CAAC,KAAY,OAAA;AAAA,UACf,UAAY,EAAA,KAAA;AAAA,UACZ,MAAM,EAAC;AAAA,UACP,KAAO,EAAA;AAAA,SACT;AACA,QAAA,OAAO,IAAI,wBAA0B,EAAA;AAAA,UACnC,UAAYA,EAAAA,UAAAA;AAAA,UACZ,SAAW,EAAA;AAAA,WACV,GAAM,CAAA;AAAA;AACX,KACD,CAAA;AAAA;AAEH,EAAA,MAAM,YAAY,MAAO,CAAA,IAAA,CAAK,SAAa,IAAA,EAAE,EAAE,IAAK,EAAA;AACpD,EAAA,MAAM,OAAU,GAAA,OAAA,CAAQ,IAAK,CAAA,GAAG,KAAK,IAAK,CAAA,IAAA;AAC1C,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,IAAI,YAAa,CAAA,OAAA;AACvB,IAAE,CAAA,CAAA,SAAA,CAAU,WAAW,OAAO,CAAA;AAC9B,IAAA,IAAI,OAAS,EAAA;AACX,MAAA,CAAA,CAAE,YAAa,EAAA;AACf,MAAA,CAAA,CAAE,IAAK,EAAA,CAAE,KAAM,CAAA,MAAM,MAAS,CAAA;AAAA;AAChC,GACC,EAAA,CAAC,SAAW,EAAA,OAAO,CAAC,CAAA;AACvB,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,IAAI,YAAa,CAAA,OAAA;AACvB,IAAE,CAAA,CAAA,UAAA,CAAW,QAAS,CAAA,YAAA,KAAiB,QAAQ,CAAA;AAC/C,IAAA,MAAM,GAAM,GAAA,QAAA,CAAS,gBAAiB,CAAA,QAAA,EAAU,CAAS,KAAA,KAAA;AACvD,MAAE,CAAA,CAAA,UAAA,CAAW,UAAU,QAAQ,CAAA;AAC/B,MAAA,IAAI,UAAU,QAAU,EAAA;AACtB,QAAA,CAAA,CAAE,YAAa,EAAA;AACf,QAAA,CAAA,CAAE,IAAK,EAAA,CAAE,KAAM,CAAA,MAAM,MAAS,CAAA;AAAA;AAChC,KACD,CAAA;AACD,IAAM,MAAA,KAAA,GAAQ,YAAY,MAAM;AAC9B,MAAA,CAAA,CAAE,IAAK,EAAA,CAAE,KAAM,CAAA,MAAM,MAAS,CAAA;AAAA,OAC7B,iBAAiB,CAAA;AACpB,IAAA,OAAO,MAAM;AACX,MAAA,GAAA,CAAI,MAAO,EAAA;AACX,MAAA,aAAA,CAAc,KAAK,CAAA;AAAA,KACrB;AAAA,GACF,EAAG,EAAE,CAAA;AACL,EAAM,MAAA,YAAA,GAAe,YAAY,MAAG;AAlEtC,IAAA,IAAA,EAAA;AAkEyC,IAAA,OAAA,CAAA,EAAA,GAAA,YAAA,CAAa,YAAb,IAAsB,GAAA,MAAA,GAAA,EAAA,CAAA,YAAA,EAAA;AAAA,GAAA,EAAgB,EAAE,CAAA;AAC/E,EAAO,OAAA;AAAA,IACL;AAAA,GACF;AACF"}
1
+ {"version":3,"file":"useSandboxKeepAlive.js","sources":["../../../src/screens/WebBuilderNative/useSandboxKeepAlive.ts"],"sourcesContent":["/**\n * Feeds the keep-alive scheduler (keepAlive.ts) the app's foreground state and the\n * person's activity (web `sandbox/useSandboxKeepAlive.ts`): `WEBBUILDER_EXTEND`\n * every 10 minutes while a build is open, the app is in front and the person did\n * something in the last 15 minutes. Opening a project, sending a turn and\n * returning to the app count as activity (`noteActivity`).\n */\nimport { useCallback, useEffect, useRef } from 'react';\nimport { AppState } from 'react-native';\nimport {\n KEEPALIVE_EXTEND_MS,\n KEEPALIVE_TICK_MS,\n KeepAliveScheduler,\n WEBBUILDER_EXTEND_ACTION,\n type ExtendResult,\n} from './keepAlive';\n\nexport function useSandboxKeepAlive(opts: {\n run: ((action: string, params: Record<string, unknown>, timeoutMs: number) => Promise<ExtendResult>) | null;\n sandboxId?: string | null;\n /** A build is open (its preview may be on screen). */\n live: boolean;\n /** EXTEND found the sandbox gone: the preview shows it cleaned up, with Restore (not a wake that can only fail). */\n onGone?: (sandboxId: string) => void;\n}): { noteActivity: () => void } {\n const onGoneRef = useRef(opts.onGone);\n onGoneRef.current = opts.onGone;\n const runRef = useRef(opts.run);\n runRef.current = opts.run;\n const schedulerRef = useRef<KeepAliveScheduler | null>(null);\n if (!schedulerRef.current) {\n schedulerRef.current = new KeepAliveScheduler({\n now: () => Date.now(),\n extend: async (sandboxId) => {\n const run = runRef.current;\n if (!run) return { successful: false, data: {}, error: 'no sandbox access' };\n return run(WEBBUILDER_EXTEND_ACTION, { sandbox_id: sandboxId, timeoutMs: KEEPALIVE_EXTEND_MS }, 90_000);\n },\n onGone: (sandboxId) => onGoneRef.current?.(sandboxId),\n });\n }\n\n const sandboxId = String(opts.sandboxId || '').trim();\n const enabled = Boolean(opts.run) && opts.live;\n\n useEffect(() => {\n const s = schedulerRef.current!;\n s.setTarget(sandboxId, enabled);\n if (enabled) {\n s.noteActivity();\n s.tick().catch(() => undefined);\n }\n }, [sandboxId, enabled]);\n\n useEffect(() => {\n const s = schedulerRef.current!;\n s.setVisible(AppState.currentState === 'active');\n const sub = AppState.addEventListener('change', (state) => {\n s.setVisible(state === 'active');\n if (state === 'active') {\n s.noteActivity();\n s.tick().catch(() => undefined);\n }\n });\n const timer = setInterval(() => {\n s.tick().catch(() => undefined);\n }, KEEPALIVE_TICK_MS);\n return () => {\n sub.remove();\n clearInterval(timer);\n };\n }, []);\n\n const noteActivity = useCallback(() => schedulerRef.current?.noteActivity(), []);\n return { noteActivity };\n}\n"],"names":["sandboxId"],"mappings":"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"}