@adminide-stack/yantra-mobile 12.0.142 → 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 (111) 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/notion/NotionAgentPanel.js +987 -0
  4. package/lib/features/notion/NotionAgentPanel.js.map +1 -0
  5. package/lib/features/notion/NotionAskAiSheet.js +362 -0
  6. package/lib/features/notion/NotionAskAiSheet.js.map +1 -0
  7. package/lib/features/notion/NotionBlockView.js +4 -3
  8. package/lib/features/notion/NotionBlockView.js.map +1 -1
  9. package/lib/features/notion/NotionConnectionsSheet.js +47 -13
  10. package/lib/features/notion/NotionConnectionsSheet.js.map +1 -1
  11. package/lib/features/notion/NotionPageView.js +68 -8
  12. package/lib/features/notion/NotionPageView.js.map +1 -1
  13. package/lib/features/notion/NotionSidebarSections.js +1 -1
  14. package/lib/features/notion/NotionSidebarSections.js.map +1 -1
  15. package/lib/features/notion/NotionWorkspaceView.js +14 -9
  16. package/lib/features/notion/NotionWorkspaceView.js.map +1 -1
  17. package/lib/features/notion/database/DatabaseCells.js +3 -1
  18. package/lib/features/notion/database/DatabaseCells.js.map +1 -1
  19. package/lib/features/notion/database/DatabaseDateLayouts.js +1 -1
  20. package/lib/features/notion/database/DatabaseDateLayouts.js.map +1 -1
  21. package/lib/features/notion/database/NotionDatabaseView.js +1 -1
  22. package/lib/features/notion/database/NotionDatabaseView.js.map +1 -1
  23. package/lib/features/notion/notionAgentRunStatus.js +2 -2
  24. package/lib/features/notion/notionAgentRunStatus.js.map +1 -1
  25. package/lib/features/notion/notionAgentRuns.js +57 -0
  26. package/lib/features/notion/notionAgentRuns.js.map +1 -0
  27. package/lib/features/notion/notionAiContext.js +91 -0
  28. package/lib/features/notion/notionAiContext.js.map +1 -0
  29. package/lib/features/notion/notionConnections.js +42 -4
  30. package/lib/features/notion/notionConnections.js.map +1 -1
  31. package/lib/features/notion/notionDocuments.js +61 -1
  32. package/lib/features/notion/notionDocuments.js.map +1 -1
  33. package/lib/features/notion/notionNotesAgent.js +173 -3
  34. package/lib/features/notion/notionNotesAgent.js.map +1 -1
  35. package/lib/features/notion/notionPageKinds.js +1 -1
  36. package/lib/features/webbuilder/WebBuilderExperience.js +229 -97
  37. package/lib/features/webbuilder/WebBuilderExperience.js.map +1 -1
  38. package/lib/features/webbuilder/buildFragments.js +33 -7
  39. package/lib/features/webbuilder/buildFragments.js.map +1 -1
  40. package/lib/features/webbuilder/buildJob.js +2 -2
  41. package/lib/features/webbuilder/buildJob.js.map +1 -1
  42. package/lib/features/webbuilder/codeFiles.js +18 -1
  43. package/lib/features/webbuilder/codeFiles.js.map +1 -1
  44. package/lib/features/webbuilder/components/BottomTabs.js.map +1 -1
  45. package/lib/features/webbuilder/components/CodeView.js +134 -56
  46. package/lib/features/webbuilder/components/CodeView.js.map +1 -1
  47. package/lib/features/webbuilder/components/Composer.js +2 -2
  48. package/lib/features/webbuilder/components/Composer.js.map +1 -1
  49. package/lib/features/webbuilder/components/PreviewFrame.js +19 -3
  50. package/lib/features/webbuilder/components/PreviewFrame.js.map +1 -1
  51. package/lib/features/webbuilder/components/PreviewScreen.js +310 -46
  52. package/lib/features/webbuilder/components/PreviewScreen.js.map +1 -1
  53. package/lib/features/webbuilder/components/ProjectChat.js +141 -12
  54. package/lib/features/webbuilder/components/ProjectChat.js.map +1 -1
  55. package/lib/features/webbuilder/components/ProjectSheets.js +792 -0
  56. package/lib/features/webbuilder/components/ProjectSheets.js.map +1 -0
  57. package/lib/features/webbuilder/components/ProjectsScreen.js +14 -2
  58. package/lib/features/webbuilder/components/ProjectsScreen.js.map +1 -1
  59. package/lib/features/webbuilder/components/PublishSheet.js +914 -58
  60. package/lib/features/webbuilder/components/PublishSheet.js.map +1 -1
  61. package/lib/features/webbuilder/components/TemplateCard.js +9 -6
  62. package/lib/features/webbuilder/components/TemplateCard.js.map +1 -1
  63. package/lib/features/webbuilder/components/TemplatesSheet.js +5 -17
  64. package/lib/features/webbuilder/components/TemplatesSheet.js.map +1 -1
  65. package/lib/features/webbuilder/connectorTemplates.js +171 -0
  66. package/lib/features/webbuilder/connectorTemplates.js.map +1 -0
  67. package/lib/features/webbuilder/fileTree.js +163 -0
  68. package/lib/features/webbuilder/fileTree.js.map +1 -0
  69. package/lib/features/webbuilder/followUps.js +67 -0
  70. package/lib/features/webbuilder/followUps.js.map +1 -0
  71. package/lib/features/webbuilder/previewProbe.js +49 -0
  72. package/lib/features/webbuilder/previewProbe.js.map +1 -0
  73. package/lib/features/webbuilder/previewRoutes.js +156 -0
  74. package/lib/features/webbuilder/previewRoutes.js.map +1 -0
  75. package/lib/features/webbuilder/projectTools.js +341 -0
  76. package/lib/features/webbuilder/projectTools.js.map +1 -0
  77. package/lib/features/webbuilder/publishTools.js +475 -0
  78. package/lib/features/webbuilder/publishTools.js.map +1 -0
  79. package/lib/features/webbuilder/sleepNotice.js +13 -0
  80. package/lib/features/webbuilder/sleepNotice.js.map +1 -0
  81. package/lib/features/webbuilder/stepLabels.js +37 -7
  82. package/lib/features/webbuilder/stepLabels.js.map +1 -1
  83. package/lib/features/webbuilder/studioCatalog.js +5 -1
  84. package/lib/features/webbuilder/studioCatalog.js.map +1 -1
  85. package/lib/features/webbuilder/templateCatalog.js +140 -0
  86. package/lib/features/webbuilder/templateCatalog.js.map +1 -0
  87. package/lib/features/webbuilder/webbuilderPrompts.js +31 -5
  88. package/lib/features/webbuilder/webbuilderPrompts.js.map +1 -1
  89. package/lib/features/webbuilder/workflow.js +8 -4
  90. package/lib/features/webbuilder/workflow.js.map +1 -1
  91. package/lib/screens/WebBuilderNative/codeWorkspaceApi.js +9 -6
  92. package/lib/screens/WebBuilderNative/codeWorkspaceApi.js.map +1 -1
  93. package/lib/screens/WebBuilderNative/index.js +1 -1
  94. package/lib/screens/WebBuilderNative/index.js.map +1 -1
  95. package/lib/screens/WebBuilderNative/keepAlive.js +53 -3
  96. package/lib/screens/WebBuilderNative/keepAlive.js.map +1 -1
  97. package/lib/screens/WebBuilderNative/unreachableRetry.js +23 -0
  98. package/lib/screens/WebBuilderNative/unreachableRetry.js.map +1 -0
  99. package/lib/screens/WebBuilderNative/useConnectorTemplates.js +37 -0
  100. package/lib/screens/WebBuilderNative/useConnectorTemplates.js.map +1 -0
  101. package/lib/screens/WebBuilderNative/useSandboxKeepAlive.js +6 -0
  102. package/lib/screens/WebBuilderNative/useSandboxKeepAlive.js.map +1 -1
  103. package/lib/screens/WebBuilderNative/useWebBuilderHost.js +302 -40
  104. package/lib/screens/WebBuilderNative/useWebBuilderHost.js.map +1 -1
  105. package/lib/screens/WebBuilderNative/useWebBuilderJobs.js +2 -2
  106. package/lib/screens/WebBuilderNative/useWebBuilderJobs.js.map +1 -1
  107. package/lib/screens/WebBuilderNative/versionUndo.js +1 -1
  108. package/lib/screens/WebBuilderNative/versionUndo.js.map +1 -1
  109. package/lib/screens/WebBuilderNative/webbuilderTransport.js +147 -77
  110. package/lib/screens/WebBuilderNative/webbuilderTransport.js.map +1 -1
  111. package/package.json +2 -2
@@ -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":";;;AAKO,MAAM,wBAAwB,EAAK,GAAA;AACnC,MAAM,oBAAoB,EAAK,GAAA;AAC/B,MAAM,mBAAsB,GAAA;AAE5B,MAAM,iBAAoB,GAAA;AAE1B,MAAM,sBAAyB,GAAA;AAC/B,MAAM,wBAA2B,GAAA;AAcjC,SAAS,kBAAkB,CAAsC,EAAA;AACtE,EAAI,IAAA,CAAC,EAAE,OAAW,IAAA,CAAC,EAAE,SAAa,IAAA,CAAC,CAAE,CAAA,IAAA,EAAa,OAAA,MAAA;AAClD,EAAA,IAAI,CAAE,CAAA,GAAA,GAAM,CAAE,CAAA,cAAA,GAAiB,mBAA0B,OAAA,MAAA;AACzD,EAAI,IAAA,CAAA,CAAE,eAAe,IAAQ,IAAA,CAAA,CAAE,MAAM,CAAE,CAAA,UAAA,GAAa,uBAA8B,OAAA,MAAA;AAClF,EAAO,OAAA,MAAA;AACT;AAGO,SAAS,yBAAyB,OAA6C,EAAA;AACpF,EAAA,OAAO,2JAA4J,CAAA,IAAA,CAAK,MAAO,CAAA,OAAA,IAAW,EAAE,CAAC,CAAA;AAC/L;AAOA,MAAM,OAAU,GAAA,8KAAA;AAGT,SAAS,cAAc,CAAgC,EAAA;AAC5D,EAAA,IAAI,EAAE,UAAY,EAAA;AAChB,IAAM,MAAA,CAAA,GAAI,EAAE,IAAQ,IAAA,OAAO,EAAE,IAAS,KAAA,QAAA,GAAW,CAAE,CAAA,IAAA,GAAkC,EAAC;AACtF,IAAO,OAAA,CAAA,CAAE,OAAY,KAAA,IAAA,GAAO,SAAY,GAAA,OAAA;AAAA;AAE1C,EAAA,IAAI,wBAAyB,CAAA,CAAA,CAAE,KAAK,CAAA,EAAU,OAAA,aAAA;AAC9C,EAAA,IAAI,QAAQ,IAAK,CAAA,CAAA,CAAE,KAAS,IAAA,EAAE,GAAU,OAAA,MAAA;AACxC,EAAO,OAAA,QAAA;AACT;AAWO,MAAM,kBAAmB,CAAA;AAAA,EAU9B,YAAY,IAAqB,EAAA;AATjC,IAAA,aAAA,CAAA,IAAA,EAAQ,SAAU,EAAA,IAAA,CAAA;AAClB,IAAA,aAAA,CAAA,IAAA,EAAQ,WAAY,EAAA,EAAA,CAAA;AACpB,IAAA,aAAA,CAAA,IAAA,EAAQ,MAAO,EAAA,KAAA,CAAA;AACf,IAAQ,aAAA,CAAA,IAAA,EAAA,gBAAA,CAAA;AACR,IAAQ,aAAA,CAAA,IAAA,EAAA,YAAA,sBAAiB,GAAoB,EAAA,CAAA;AAC7C,IAAQ,aAAA,CAAA,IAAA,EAAA,UAAA,sBAAe,GAAoB,EAAA,CAAA;AAC3C,IAAQ,aAAA,CAAA,IAAA,EAAA,KAAA,sBAAU,GAAY,EAAA,CAAA;AAC9B,IAAA,aAAA,CAAA,IAAA,EAAQ,UAAW,EAAA,KAAA,CAAA;AACnB,IAAQ,aAAA,CAAA,IAAA,EAAA,MAAA,CAAA;AAEN,IAAA,IAAA,CAAK,IAAO,GAAA,IAAA;AACZ,IAAK,IAAA,CAAA,cAAA,GAAiB,KAAK,GAAI,EAAA;AAAA;AACjC,EACA,YAAqB,GAAA;AACnB,IAAK,IAAA,CAAA,cAAA,GAAiB,IAAK,CAAA,IAAA,CAAK,GAAI,EAAA;AAAA;AACtC,EACA,WAAW,OAAwB,EAAA;AACjC,IAAA,IAAA,CAAK,OAAU,GAAA,OAAA;AAAA;AACjB,EACA,SAAA,CAAU,WAAsC,IAAqB,EAAA;AACnE,IAAA,IAAA,CAAK,SAAY,GAAA,MAAA,CAAO,SAAa,IAAA,EAAE,EAAE,IAAK,EAAA;AAC9C,IAAA,IAAA,CAAK,IAAO,GAAA,IAAA;AAAA;AACd;AAAA,EAGA,KAAA,CAAM,SAAY,GAAA,IAAA,CAAK,SAAoB,EAAA;AACzC,IAAO,OAAA,IAAA,CAAK,GAAI,CAAA,GAAA,CAAI,SAAS,CAAA;AAAA;AAC/B,EACA,QAA8B,GAAA;AA9FhC,IAAA,IAAA,EAAA;AA+FI,IAAI,IAAA,CAAC,IAAK,CAAA,SAAA,IAAa,IAAK,CAAA,GAAA,CAAI,GAAI,CAAA,IAAA,CAAK,SAAS,CAAA,IAAK,IAAK,CAAA,QAAA,EAAiB,OAAA,MAAA;AAC7E,IAAA,OAAO,iBAAkB,CAAA;AAAA,MACvB,SAAS,IAAK,CAAA,OAAA;AAAA,MACd,WAAW,IAAK,CAAA,SAAA;AAAA,MAChB,MAAM,IAAK,CAAA,IAAA;AAAA,MACX,GAAA,EAAK,IAAK,CAAA,IAAA,CAAK,GAAI,EAAA;AAAA,MACnB,gBAAgB,IAAK,CAAA,cAAA;AAAA,MACrB,aAAY,EAAK,GAAA,IAAA,CAAA,UAAA,CAAW,IAAI,IAAK,CAAA,SAAS,MAAlC,IAAuC,GAAA,EAAA,GAAA;AAAA,KACpD,CAAA;AAAA;AACH,EACA,MAAM,IAAmD,GAAA;AAzG3D,IAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AA0GI,IAAM,MAAA,CAAA,GAAI,KAAK,QAAS,EAAA;AACxB,IAAI,IAAA,CAAA,KAAM,QAAe,OAAA,CAAA;AACzB,IAAA,MAAM,KAAK,IAAK,CAAA,SAAA;AAChB,IAAA,IAAA,CAAK,QAAW,GAAA,IAAA;AAChB,IAAA,IAAA,CAAK,WAAW,GAAI,CAAA,EAAA,EAAI,IAAK,CAAA,IAAA,CAAK,KAAK,CAAA;AACvC,IAAI,IAAA,OAAA;AACJ,IAAI,IAAA;AACF,MAAA,OAAA,GAAU,cAAc,MAAM,IAAA,CAAK,IAAK,CAAA,MAAA,CAAO,EAAE,CAAC,CAAA;AAAA,aAC3C,CAAG,EAAA;AACV,MAAA,OAAA,GAAU,aAAc,CAAA;AAAA,QACtB,UAAY,EAAA,KAAA;AAAA,QACZ,OAAO,CAAa,YAAA,KAAA,GAAQ,CAAE,CAAA,OAAA,GAAU,OAAO,CAAC;AAAA,OACjD,CAAA;AAAA,KACD,SAAA;AACA,MAAA,IAAA,CAAK,QAAW,GAAA,KAAA;AAAA;AAElB,IAAI,IAAA,OAAA,KAAY,SAAa,IAAA,OAAA,KAAY,OAAS,EAAA;AAChD,MAAK,IAAA,CAAA,QAAA,CAAS,OAAO,EAAE,CAAA;AACvB,MAAA,IAAI,OAAY,KAAA,SAAA,EAAgB,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,IAAA,CAAA,IAAA,EAAK,cAAV,IAAsB,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,CAAA,EAAA,EAAA,EAAA,CAAA;AACjD,MAAO,OAAA,OAAA;AAAA;AAET,IAAA,IAAI,YAAY,aAAe,EAAA;AAC7B,MAAK,IAAA,CAAA,GAAA,CAAI,IAAI,EAAE,CAAA;AACf,MAAO,OAAA,OAAA;AAAA;AAET,IAAA,MAAM,MAAK,EAAK,GAAA,IAAA,CAAA,QAAA,CAAS,IAAI,EAAE,CAAA,KAApB,YAAyB,CAAK,IAAA,CAAA;AACzC,IAAK,IAAA,CAAA,QAAA,CAAS,GAAI,CAAA,EAAA,EAAI,CAAC,CAAA;AACvB,IAAA,IAAI,YAAY,MAAQ,EAAA;AACtB,MAAK,IAAA,CAAA,GAAA,CAAI,IAAI,EAAE,CAAA;AACf,MAAK,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,IAAA,CAAA,IAAA,EAAK,WAAV,IAAmB,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,CAAA,EAAA,EAAA,EAAA,CAAA;AAAA,KACrB,MAAA,IAAW,KAAK,sBAAwB,EAAA;AACtC,MAAK,IAAA,CAAA,GAAA,CAAI,IAAI,EAAE,CAAA;AAAA;AAEjB,IAAO,OAAA,OAAA;AAAA;AACT;AAAA,EAGA,MAAM,SAAyB,EAAA;AAC7B,IAAK,IAAA,CAAA,GAAA,CAAI,OAAO,SAAS,CAAA;AACzB,IAAK,IAAA,CAAA,QAAA,CAAS,OAAO,SAAS,CAAA;AAC9B,IAAK,IAAA,CAAA,UAAA,CAAW,OAAO,SAAS,CAAA;AAAA;AAEpC"}
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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"}