@kortix/sdk 0.13.3 → 0.13.5

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 (204) hide show
  1. package/dist/browser/cache/idb-sync-cache.d.ts +19 -1
  2. package/dist/browser/cache/idb-sync-cache.d.ts.map +1 -1
  3. package/dist/browser/cache/idb-sync-cache.js +39 -4
  4. package/dist/browser/cache/idb-sync-cache.js.map +1 -1
  5. package/dist/browser/session-sync/session-sync-registry.d.ts +20 -0
  6. package/dist/browser/session-sync/session-sync-registry.d.ts.map +1 -1
  7. package/dist/browser/session-sync/session-sync-registry.js +69 -6
  8. package/dist/browser/session-sync/session-sync-registry.js.map +1 -1
  9. package/dist/browser/session-sync/visibility.d.ts +19 -0
  10. package/dist/browser/session-sync/visibility.d.ts.map +1 -0
  11. package/dist/browser/session-sync/visibility.js +16 -0
  12. package/dist/browser/session-sync/visibility.js.map +1 -0
  13. package/dist/browser/stores/sandbox-connection-store.js +1 -1
  14. package/dist/browser/stores/sandbox-connection-store.js.map +1 -1
  15. package/dist/browser/stores/sync-store.d.ts +27 -1
  16. package/dist/browser/stores/sync-store.d.ts.map +1 -1
  17. package/dist/browser/stores/sync-store.js +198 -41
  18. package/dist/browser/stores/sync-store.js.map +1 -1
  19. package/dist/core/client/kortix.d.ts +0 -11
  20. package/dist/core/client/kortix.d.ts.map +1 -1
  21. package/dist/core/client/kortix.js +14 -8
  22. package/dist/core/client/kortix.js.map +1 -1
  23. package/dist/core/rest/projects-client/channels.d.ts +0 -3
  24. package/dist/core/rest/projects-client/channels.d.ts.map +1 -1
  25. package/dist/core/rest/projects-client/channels.js +0 -6
  26. package/dist/core/rest/projects-client/channels.js.map +1 -1
  27. package/dist/core/rest/projects-client/index.d.ts +0 -2
  28. package/dist/core/rest/projects-client/index.d.ts.map +1 -1
  29. package/dist/core/rest/projects-client/index.js +0 -2
  30. package/dist/core/rest/projects-client/index.js.map +1 -1
  31. package/dist/core/rest/projects-client/projects.d.ts +1 -1
  32. package/dist/core/rest/projects-client/projects.d.ts.map +1 -1
  33. package/dist/core/rest/projects-client/projects.js +5 -3
  34. package/dist/core/rest/projects-client/projects.js.map +1 -1
  35. package/dist/core/rest/projects-client/sessions.d.ts +8 -33
  36. package/dist/core/rest/projects-client/sessions.d.ts.map +1 -1
  37. package/dist/core/rest/projects-client/sessions.js +1 -18
  38. package/dist/core/rest/projects-client/sessions.js.map +1 -1
  39. package/dist/core/runtime/attachment-part.d.ts +26 -0
  40. package/dist/core/runtime/attachment-part.d.ts.map +1 -0
  41. package/dist/core/runtime/attachment-part.js +41 -0
  42. package/dist/core/runtime/attachment-part.js.map +1 -0
  43. package/dist/core/runtime/client.d.ts +4 -2
  44. package/dist/core/runtime/client.d.ts.map +1 -1
  45. package/dist/core/runtime/client.js +3 -2
  46. package/dist/core/runtime/client.js.map +1 -1
  47. package/dist/core/runtime/opencode-v2-event-aliases.d.ts +184 -0
  48. package/dist/core/runtime/opencode-v2-event-aliases.d.ts.map +1 -0
  49. package/dist/core/runtime/opencode-v2-event-aliases.js +2 -0
  50. package/dist/core/runtime/opencode-v2-event-aliases.js.map +1 -0
  51. package/dist/core/runtime/pty.d.ts +11 -1
  52. package/dist/core/runtime/pty.d.ts.map +1 -1
  53. package/dist/core/runtime/pty.js +19 -6
  54. package/dist/core/runtime/pty.js.map +1 -1
  55. package/dist/core/session/connection.d.ts +64 -0
  56. package/dist/core/session/connection.d.ts.map +1 -0
  57. package/dist/core/session/connection.js +36 -0
  58. package/dist/core/session/connection.js.map +1 -0
  59. package/dist/core/session/index.d.ts +1 -0
  60. package/dist/core/session/index.d.ts.map +1 -1
  61. package/dist/core/session/index.js +1 -0
  62. package/dist/core/session/index.js.map +1 -1
  63. package/dist/core/session/preview-auth.d.ts +25 -0
  64. package/dist/core/session/preview-auth.d.ts.map +1 -1
  65. package/dist/core/session/preview-auth.js +31 -1
  66. package/dist/core/session/preview-auth.js.map +1 -1
  67. package/dist/core/session/preview-config.d.ts +26 -0
  68. package/dist/core/session/preview-config.d.ts.map +1 -0
  69. package/dist/core/session/preview-config.js +95 -0
  70. package/dist/core/session/preview-config.js.map +1 -0
  71. package/dist/core/session/preview-options.d.ts +25 -0
  72. package/dist/core/session/preview-options.d.ts.map +1 -0
  73. package/dist/core/session/preview-options.js +45 -0
  74. package/dist/core/session/preview-options.js.map +1 -0
  75. package/dist/core/session/preview.d.ts +8 -3
  76. package/dist/core/session/preview.d.ts.map +1 -1
  77. package/dist/core/session/preview.js +11 -4
  78. package/dist/core/session/preview.js.map +1 -1
  79. package/dist/core/session/rewind.d.ts +67 -24
  80. package/dist/core/session/rewind.d.ts.map +1 -1
  81. package/dist/core/session/rewind.js +74 -26
  82. package/dist/core/session/rewind.js.map +1 -1
  83. package/dist/core/session/server-store/active.d.ts +10 -12
  84. package/dist/core/session/server-store/active.d.ts.map +1 -1
  85. package/dist/core/session/server-store/active.js +11 -9
  86. package/dist/core/session/server-store/active.js.map +1 -1
  87. package/dist/core/session/server-store/url-helpers.d.ts +11 -2
  88. package/dist/core/session/server-store/url-helpers.d.ts.map +1 -1
  89. package/dist/core/session/server-store/url-helpers.js +11 -2
  90. package/dist/core/session/server-store/url-helpers.js.map +1 -1
  91. package/dist/core/session/url.d.ts +25 -2
  92. package/dist/core/session/url.d.ts.map +1 -1
  93. package/dist/core/session/url.js +87 -11
  94. package/dist/core/session/url.js.map +1 -1
  95. package/dist/core/session/working.d.ts +44 -0
  96. package/dist/core/session/working.d.ts.map +1 -1
  97. package/dist/core/session/working.js +146 -4
  98. package/dist/core/session/working.js.map +1 -1
  99. package/dist/core/session-sync/durable-log.d.ts +96 -0
  100. package/dist/core/session-sync/durable-log.d.ts.map +1 -0
  101. package/dist/core/session-sync/durable-log.js +94 -0
  102. package/dist/core/session-sync/durable-log.js.map +1 -0
  103. package/dist/core/session-sync/fragment.d.ts +27 -0
  104. package/dist/core/session-sync/fragment.d.ts.map +1 -0
  105. package/dist/core/session-sync/fragment.js +24 -0
  106. package/dist/core/session-sync/fragment.js.map +1 -0
  107. package/dist/core/session-sync/session-sync-controller.d.ts +83 -9
  108. package/dist/core/session-sync/session-sync-controller.d.ts.map +1 -1
  109. package/dist/core/session-sync/session-sync-controller.js +183 -17
  110. package/dist/core/session-sync/session-sync-controller.js.map +1 -1
  111. package/dist/core/turns/grouping.d.ts.map +1 -1
  112. package/dist/core/turns/grouping.js +60 -23
  113. package/dist/core/turns/grouping.js.map +1 -1
  114. package/dist/index.d.ts +1 -0
  115. package/dist/index.d.ts.map +1 -1
  116. package/dist/index.js +1 -0
  117. package/dist/index.js.map +1 -1
  118. package/dist/kortix.esm.min.js +24 -24
  119. package/dist/kortix.global.js +24 -24
  120. package/dist/platform/auth-core.d.ts +13 -1
  121. package/dist/platform/auth-core.d.ts.map +1 -1
  122. package/dist/platform/auth-core.js +13 -1
  123. package/dist/platform/auth-core.js.map +1 -1
  124. package/dist/react/opencode.d.ts +1 -0
  125. package/dist/react/opencode.d.ts.map +1 -1
  126. package/dist/react/opencode.js +3 -0
  127. package/dist/react/opencode.js.map +1 -1
  128. package/dist/react/use-admin-accounts.d.ts +35 -0
  129. package/dist/react/use-admin-accounts.d.ts.map +1 -1
  130. package/dist/react/use-admin-accounts.js +18 -0
  131. package/dist/react/use-admin-accounts.js.map +1 -1
  132. package/dist/react/use-opencode-events/handle-event.d.ts.map +1 -1
  133. package/dist/react/use-opencode-events/handle-event.js +26 -0
  134. package/dist/react/use-opencode-events/handle-event.js.map +1 -1
  135. package/dist/react/use-opencode-events/index.d.ts.map +1 -1
  136. package/dist/react/use-opencode-events/index.js +59 -6
  137. package/dist/react/use-opencode-events/index.js.map +1 -1
  138. package/dist/react/use-opencode-events/rehydrate-targets.d.ts +18 -0
  139. package/dist/react/use-opencode-events/rehydrate-targets.d.ts.map +1 -0
  140. package/dist/react/use-opencode-events/rehydrate-targets.js +20 -0
  141. package/dist/react/use-opencode-events/rehydrate-targets.js.map +1 -0
  142. package/dist/react/use-opencode-events/stream-revival.d.ts +37 -0
  143. package/dist/react/use-opencode-events/stream-revival.d.ts.map +1 -0
  144. package/dist/react/use-opencode-events/stream-revival.js +53 -0
  145. package/dist/react/use-opencode-events/stream-revival.js.map +1 -0
  146. package/dist/react/use-opencode-pty.d.ts +7 -1
  147. package/dist/react/use-opencode-pty.d.ts.map +1 -1
  148. package/dist/react/use-opencode-pty.js +6 -2
  149. package/dist/react/use-opencode-pty.js.map +1 -1
  150. package/dist/react/use-opencode-sessions/agents.d.ts.map +1 -1
  151. package/dist/react/use-opencode-sessions/agents.js +13 -2
  152. package/dist/react/use-opencode-sessions/agents.js.map +1 -1
  153. package/dist/react/use-opencode-sessions/commands.d.ts +12 -0
  154. package/dist/react/use-opencode-sessions/commands.d.ts.map +1 -1
  155. package/dist/react/use-opencode-sessions/commands.js +15 -3
  156. package/dist/react/use-opencode-sessions/commands.js.map +1 -1
  157. package/dist/react/use-opencode-sessions/index.d.ts +1 -0
  158. package/dist/react/use-opencode-sessions/index.d.ts.map +1 -1
  159. package/dist/react/use-opencode-sessions/index.js +1 -0
  160. package/dist/react/use-opencode-sessions/index.js.map +1 -1
  161. package/dist/react/use-opencode-sessions/keys.d.ts +8 -0
  162. package/dist/react/use-opencode-sessions/keys.d.ts.map +1 -1
  163. package/dist/react/use-opencode-sessions/keys.js +8 -0
  164. package/dist/react/use-opencode-sessions/keys.js.map +1 -1
  165. package/dist/react/use-opencode-sessions/providers.d.ts.map +1 -1
  166. package/dist/react/use-opencode-sessions/providers.js +12 -2
  167. package/dist/react/use-opencode-sessions/providers.js.map +1 -1
  168. package/dist/react/use-opencode-sessions/shared.d.ts +23 -0
  169. package/dist/react/use-opencode-sessions/shared.d.ts.map +1 -1
  170. package/dist/react/use-opencode-sessions/shared.js +31 -0
  171. package/dist/react/use-opencode-sessions/shared.js.map +1 -1
  172. package/dist/react/use-opencode-sessions/vcs.d.ts +28 -0
  173. package/dist/react/use-opencode-sessions/vcs.d.ts.map +1 -0
  174. package/dist/react/use-opencode-sessions/vcs.js +42 -0
  175. package/dist/react/use-opencode-sessions/vcs.js.map +1 -0
  176. package/dist/react/use-session-prompts.d.ts +37 -2
  177. package/dist/react/use-session-prompts.d.ts.map +1 -1
  178. package/dist/react/use-session-prompts.js +62 -15
  179. package/dist/react/use-session-prompts.js.map +1 -1
  180. package/dist/react/use-session-send.d.ts +17 -0
  181. package/dist/react/use-session-send.d.ts.map +1 -1
  182. package/dist/react/use-session-send.js +40 -4
  183. package/dist/react/use-session-send.js.map +1 -1
  184. package/dist/react/use-session-sync.d.ts +13 -1
  185. package/dist/react/use-session-sync.d.ts.map +1 -1
  186. package/dist/react/use-session-sync.js +81 -55
  187. package/dist/react/use-session-sync.js.map +1 -1
  188. package/dist/react/use-session-working.d.ts +17 -0
  189. package/dist/react/use-session-working.d.ts.map +1 -1
  190. package/dist/react/use-session-working.js +33 -3
  191. package/dist/react/use-session-working.js.map +1 -1
  192. package/package.json +3 -3
  193. package/dist/browser/session-sync/session-transcript-cache.d.ts +0 -79
  194. package/dist/browser/session-sync/session-transcript-cache.d.ts.map +0 -1
  195. package/dist/browser/session-sync/session-transcript-cache.js +0 -91
  196. package/dist/browser/session-sync/session-transcript-cache.js.map +0 -1
  197. package/dist/core/rest/projects-client/public-voice-join.d.ts +0 -59
  198. package/dist/core/rest/projects-client/public-voice-join.d.ts.map +0 -1
  199. package/dist/core/rest/projects-client/public-voice-join.js +0 -64
  200. package/dist/core/rest/projects-client/public-voice-join.js.map +0 -1
  201. package/dist/core/rest/projects-client/transcription.d.ts +0 -5
  202. package/dist/core/rest/projects-client/transcription.d.ts.map +0 -1
  203. package/dist/core/rest/projects-client/transcription.js +0 -14
  204. package/dist/core/rest/projects-client/transcription.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../../src/core/session/connection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,MAAM,iBAAiB;AAC3B,+EAA+E;AAC7E,SAAS;AACX,mFAAmF;GACjF,QAAQ;AACV,uEAAuE;GACrE,YAAY;AACd,4EAA4E;GAC1E,MAAM;AACR,4EAA4E;GAC1E,aAAa,CAAC;AAElB;gFACgF;AAChF,MAAM,MAAM,gBAAgB;AAC1B;;;qBAGqB;AACnB,QAAQ,GACR,WAAW,GACX,cAAc,GACd,SAAS,GACT,SAAS,GACT,UAAU,GACV,QAAQ,GACR,WAAW,GACX,IAAI,CAAC;AAET,MAAM,WAAW,uBAAuB;IACtC,uEAAuE;IACvE,OAAO,EAAE,gBAAgB,CAAC;IAC1B,mDAAmD;IACnD,YAAY,EAAE,OAAO,CAAC;IACtB,sEAAsE;IACtE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,gFAAgF;IAChF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;0BAEsB;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,uBAAuB,GAAG,iBAAiB,CAwB1F;AAED;+DAC+D;AAC/D,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,iBAAiB,GAAG,OAAO,CAE1E"}
@@ -0,0 +1,36 @@
1
+ export function projectSessionConnection(input) {
2
+ // Content outranks every probe, including one that has given up: a runtime
3
+ // that is emitting parts is reachable by definition, whatever a health check
4
+ // on a different path concluded.
5
+ if (input.activityFresh)
6
+ return 'live';
7
+ if (input.runtimeReady)
8
+ return 'live';
9
+ if (input.unreachable || input.stalled)
10
+ return 'unreachable';
11
+ // Positive evidence, and the ONLY thing that earns the word "waking".
12
+ if (input.sandbox === 'stopped' || input.sandbox === 'archived')
13
+ return 'waking';
14
+ if (input.sandbox === 'provisioning' ||
15
+ input.sandbox === 'queued' ||
16
+ input.sandbox === 'branching') {
17
+ return 'waking';
18
+ }
19
+ // A finished session has no runtime to reach and nothing to wake. Nothing is
20
+ // wrong with it, so nothing is announced.
21
+ if (input.sandbox === 'completed')
22
+ return 'unknown';
23
+ if (input.sandbox === 'failed')
24
+ return 'unreachable';
25
+ // The box is up; we simply have not reached it yet. Not an alarm.
26
+ if (input.sandbox === 'running')
27
+ return 'connecting';
28
+ // The row has not loaded. We know nothing, and we say nothing.
29
+ return 'unknown';
30
+ }
31
+ /** Whether a surface may draw an alarm (a notice, a warning colour) from this
32
+ * state. `unknown` and `connecting` are waits, not faults. */
33
+ export function connectionIsFaulted(connection) {
34
+ return connection === 'unreachable';
35
+ }
36
+ //# sourceMappingURL=connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../../src/core/session/connection.ts"],"names":[],"mappings":"AAsEA,MAAM,UAAU,wBAAwB,CAAC,KAA8B;IACrE,2EAA2E;IAC3E,6EAA6E;IAC7E,iCAAiC;IACjC,IAAI,KAAK,CAAC,aAAa;QAAE,OAAO,MAAM,CAAC;IACvC,IAAI,KAAK,CAAC,YAAY;QAAE,OAAO,MAAM,CAAC;IACtC,IAAI,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,OAAO;QAAE,OAAO,aAAa,CAAC;IAC7D,sEAAsE;IACtE,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,KAAK,UAAU;QAAE,OAAO,QAAQ,CAAC;IACjF,IACE,KAAK,CAAC,OAAO,KAAK,cAAc;QAChC,KAAK,CAAC,OAAO,KAAK,QAAQ;QAC1B,KAAK,CAAC,OAAO,KAAK,WAAW,EAC7B,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,6EAA6E;IAC7E,0CAA0C;IAC1C,IAAI,KAAK,CAAC,OAAO,KAAK,WAAW;QAAE,OAAO,SAAS,CAAC;IACpD,IAAI,KAAK,CAAC,OAAO,KAAK,QAAQ;QAAE,OAAO,aAAa,CAAC;IACrD,kEAAkE;IAClE,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,YAAY,CAAC;IACrD,+DAA+D;IAC/D,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;+DAC+D;AAC/D,MAAM,UAAU,mBAAmB,CAAC,UAA6B;IAC/D,OAAO,UAAU,KAAK,aAAa,CAAC;AACtC,CAAC"}
@@ -19,6 +19,7 @@ export * from './preview.js';
19
19
  export * from './preview-auth.js';
20
20
  export * from './preview-probe.js';
21
21
  export * from './presentation.js';
22
+ export * from './connection.js';
22
23
  export * from './working.js';
23
24
  export * from './compaction.js';
24
25
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/session/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/session/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC"}
@@ -19,6 +19,7 @@ export * from './preview.js';
19
19
  export * from './preview-auth.js';
20
20
  export * from './preview-probe.js';
21
21
  export * from './presentation.js';
22
+ export * from './connection.js';
22
23
  export * from './working.js';
23
24
  export * from './compaction.js';
24
25
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/session/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/session/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC"}
@@ -29,4 +29,29 @@
29
29
  export declare function ensurePreviewSessionCookie(previewUrl: string, options?: {
30
30
  serverUrl?: string;
31
31
  }): Promise<boolean>;
32
+ /**
33
+ * The URL a caller should actually open for `previewUrl`, having given it a
34
+ * credential the destination will accept.
35
+ *
36
+ * The two preview forms take credentials in different ways, and using the wrong
37
+ * one fails silently — which is exactly what happened before this existed:
38
+ * `ensurePreviewSessionCookie` returns false for an ORIGIN URL (there is no
39
+ * `/v1/p/` path to derive an auth endpoint from), so "open in a new tab" opened
40
+ * the origin with no cookie and no token, and the person landed on the sign-in
41
+ * gate instead of their file.
42
+ *
43
+ * - Preview ORIGIN (`{env}-p{port}-{sandbox}.{domain}`, or the localhost
44
+ * form): the API's `__preview_session` cookie is host-scoped and can never
45
+ * reach it, so the credential rides in the URL as a one-shot `?token`. The
46
+ * proxy exchanges it for a host cookie and strips it from the address bar.
47
+ * - Path proxy (`/v1/p/{sandbox}/{port}/…`): same origin as the API, so the
48
+ * cookie works; mint it and return the URL untouched.
49
+ *
50
+ * Never throws. With no token, or for a URL that is not a preview at all, the
51
+ * input is returned unchanged — the destination then answers for itself, which
52
+ * is more honest than fabricating a URL that cannot work.
53
+ */
54
+ export declare function authorizePreviewUrl(previewUrl: string, options?: {
55
+ serverUrl?: string;
56
+ }): Promise<string>;
32
57
  //# sourceMappingURL=preview-auth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"preview-auth.d.ts","sourceRoot":"","sources":["../../../src/core/session/preview-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH;;;;;;;;GAQG;AACH,wBAAsB,0BAA0B,CAC9C,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GACnC,OAAO,CAAC,OAAO,CAAC,CAoBlB"}
1
+ {"version":3,"file":"preview-auth.d.ts","sourceRoot":"","sources":["../../../src/core/session/preview-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH;;;;;;;;GAQG;AACH,wBAAsB,0BAA0B,CAC9C,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GACnC,OAAO,CAAC,OAAO,CAAC,CAoBlB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GACnC,OAAO,CAAC,MAAM,CAAC,CAOjB"}
@@ -18,7 +18,7 @@
18
18
  * reloaded, bookmarked, or sent to anyone.
19
19
  */
20
20
  import { getAuthToken } from '../http/auth.js';
21
- import { buildPreviewAuthEndpoint } from './preview.js';
21
+ import { appendPreviewToken, buildPreviewAuthEndpoint, isSubdomainPreviewUrl } from './preview.js';
22
22
  /**
23
23
  * Mint the `__preview_session` cookie for `previewUrl`'s proxy origin.
24
24
  *
@@ -50,4 +50,34 @@ export async function ensurePreviewSessionCookie(previewUrl, options = {}) {
50
50
  return false;
51
51
  }
52
52
  }
53
+ /**
54
+ * The URL a caller should actually open for `previewUrl`, having given it a
55
+ * credential the destination will accept.
56
+ *
57
+ * The two preview forms take credentials in different ways, and using the wrong
58
+ * one fails silently — which is exactly what happened before this existed:
59
+ * `ensurePreviewSessionCookie` returns false for an ORIGIN URL (there is no
60
+ * `/v1/p/` path to derive an auth endpoint from), so "open in a new tab" opened
61
+ * the origin with no cookie and no token, and the person landed on the sign-in
62
+ * gate instead of their file.
63
+ *
64
+ * - Preview ORIGIN (`{env}-p{port}-{sandbox}.{domain}`, or the localhost
65
+ * form): the API's `__preview_session` cookie is host-scoped and can never
66
+ * reach it, so the credential rides in the URL as a one-shot `?token`. The
67
+ * proxy exchanges it for a host cookie and strips it from the address bar.
68
+ * - Path proxy (`/v1/p/{sandbox}/{port}/…`): same origin as the API, so the
69
+ * cookie works; mint it and return the URL untouched.
70
+ *
71
+ * Never throws. With no token, or for a URL that is not a preview at all, the
72
+ * input is returned unchanged — the destination then answers for itself, which
73
+ * is more honest than fabricating a URL that cannot work.
74
+ */
75
+ export async function authorizePreviewUrl(previewUrl, options = {}) {
76
+ if (isSubdomainPreviewUrl(previewUrl)) {
77
+ const token = await getAuthToken();
78
+ return token ? appendPreviewToken(previewUrl, token) : previewUrl;
79
+ }
80
+ await ensurePreviewSessionCookie(previewUrl, options);
81
+ return previewUrl;
82
+ }
53
83
  //# sourceMappingURL=preview-auth.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"preview-auth.js","sourceRoot":"","sources":["../../../src/core/session/preview-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAErD;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,UAAkB,EAClB,UAAkC,EAAE;IAEpC,MAAM,YAAY,GAAG,wBAAwB,CAAC,UAAU,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAC7E,IAAI,CAAC,YAAY;QAAE,OAAO,KAAK,CAAC;IAEhC,MAAM,KAAK,GAAG,MAAM,YAAY,EAAE,CAAC;IACnC,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IAEzB,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,YAAY,EAAE;YACzC,MAAM,EAAE,MAAM;YACd,WAAW,EAAE,SAAS;YACtB,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,KAAK,EAAE;gBAChC,cAAc,EAAE,kBAAkB;aACnC;SACF,CAAC,CAAC;QACH,OAAO,QAAQ,CAAC,EAAE,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"preview-auth.js","sourceRoot":"","sources":["../../../src/core/session/preview-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAEhG;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,UAAkB,EAClB,UAAkC,EAAE;IAEpC,MAAM,YAAY,GAAG,wBAAwB,CAAC,UAAU,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAC7E,IAAI,CAAC,YAAY;QAAE,OAAO,KAAK,CAAC;IAEhC,MAAM,KAAK,GAAG,MAAM,YAAY,EAAE,CAAC;IACnC,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IAEzB,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,YAAY,EAAE;YACzC,MAAM,EAAE,MAAM;YACd,WAAW,EAAE,SAAS;YACtB,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,KAAK,EAAE;gBAChC,cAAc,EAAE,kBAAkB;aACnC;SACF,CAAC,CAAC;QACH,OAAO,QAAQ,CAAC,EAAE,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,UAAkB,EAClB,UAAkC,EAAE;IAEpC,IAAI,qBAAqB,CAAC,UAAU,CAAC,EAAE,CAAC;QACtC,MAAM,KAAK,GAAG,MAAM,YAAY,EAAE,CAAC;QACnC,OAAO,KAAK,CAAC,CAAC,CAAC,kBAAkB,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;IACpE,CAAC;IACD,MAAM,0BAA0B,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACtD,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * The cached template for a backend, or null when this deployment serves none —
3
+ * and also null before the first `load` resolves. Both mean "use the path form",
4
+ * which is why they need no distinction at the call site.
5
+ */
6
+ export declare function cachedPreviewUrlTemplate(backendUrl: string): string | null;
7
+ /**
8
+ * Whether this backend has ANSWERED yet — as opposed to "answered null", which
9
+ * is a real answer meaning "this deployment serves no preview domain".
10
+ *
11
+ * The two look identical through `cachedPreviewUrlTemplate`, and conflating them
12
+ * is how a session gets stuck: during a rolling deploy the first `ensureReady()`
13
+ * can hit a task that predates `/v1/p/config`, and without this the handle would
14
+ * keep building path-proxy URLs for the rest of its life even though every later
15
+ * request would have been answered by a new task.
16
+ */
17
+ export declare function hasPreviewConfig(backendUrl: string): boolean;
18
+ /**
19
+ * Fetch and cache the template. Concurrent callers share one request; a failed
20
+ * fetch caches nothing, so a deployment that was briefly unreachable is asked
21
+ * again rather than being remembered as having no preview domain.
22
+ */
23
+ export declare function loadPreviewUrlTemplate(backendUrl: string): Promise<string | null>;
24
+ /** Drop everything remembered — for tests and for a host re-pointing its API. */
25
+ export declare function resetPreviewConfigCache(): void;
26
+ //# sourceMappingURL=preview-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-config.d.ts","sourceRoot":"","sources":["../../../src/core/session/preview-config.ts"],"names":[],"mappings":"AAiCA;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE1E;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAgCvF;AAED,iFAAiF;AACjF,wBAAgB,uBAAuB,IAAI,IAAI,CAG9C"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * How this deployment addresses previews, fetched once from `GET /v1/p/config`.
3
+ *
4
+ * The preview hostname shape (`{env}-p{port}-{sandbox}.{domain}`) is a property
5
+ * of the deployment, not of the client: it depends on the wildcard domain the
6
+ * operator serves and on which environment the API is. Re-deriving it here from
7
+ * `backendUrl` would mean two implementations of one rule, which is how they
8
+ * drift. So the API states it as a template and this caches the answer.
9
+ *
10
+ * `previewUrl()` is synchronous — a React render calls it — so the fetch cannot
11
+ * happen there. `ensureReady()` warms this first, and until it resolves callers
12
+ * get the path form, which still works for everything that is not a browser.
13
+ */
14
+ import { backendApi } from '../http/api-client.js';
15
+ const templates = new Map();
16
+ const inFlight = new Map();
17
+ /**
18
+ * Cache key: the backend URL without trailing slashes, stripped LINEARLY. The
19
+ * regex form (`/\/+$/`) backtracks quadratically on adversarial input (CodeQL
20
+ * js/polynomial-redos), and this runs on a host-supplied string.
21
+ */
22
+ function key(backendUrl) {
23
+ let end = backendUrl.length;
24
+ while (end > 0 && backendUrl.charCodeAt(end - 1) === 47 /* '/' */)
25
+ end--;
26
+ return backendUrl.slice(0, end);
27
+ }
28
+ /**
29
+ * The cached template for a backend, or null when this deployment serves none —
30
+ * and also null before the first `load` resolves. Both mean "use the path form",
31
+ * which is why they need no distinction at the call site.
32
+ */
33
+ export function cachedPreviewUrlTemplate(backendUrl) {
34
+ return templates.get(key(backendUrl)) ?? null;
35
+ }
36
+ /**
37
+ * Whether this backend has ANSWERED yet — as opposed to "answered null", which
38
+ * is a real answer meaning "this deployment serves no preview domain".
39
+ *
40
+ * The two look identical through `cachedPreviewUrlTemplate`, and conflating them
41
+ * is how a session gets stuck: during a rolling deploy the first `ensureReady()`
42
+ * can hit a task that predates `/v1/p/config`, and without this the handle would
43
+ * keep building path-proxy URLs for the rest of its life even though every later
44
+ * request would have been answered by a new task.
45
+ */
46
+ export function hasPreviewConfig(backendUrl) {
47
+ return templates.has(key(backendUrl));
48
+ }
49
+ /**
50
+ * Fetch and cache the template. Concurrent callers share one request; a failed
51
+ * fetch caches nothing, so a deployment that was briefly unreachable is asked
52
+ * again rather than being remembered as having no preview domain.
53
+ */
54
+ export async function loadPreviewUrlTemplate(backendUrl) {
55
+ const cacheKey = key(backendUrl);
56
+ const cached = templates.get(cacheKey);
57
+ if (cached !== undefined)
58
+ return cached;
59
+ const pending = inFlight.get(cacheKey);
60
+ if (pending)
61
+ return pending;
62
+ const request = (async () => {
63
+ try {
64
+ const response = await backendApi.get('/p/config', {
65
+ showErrors: false,
66
+ // A deployment without a preview domain, and an API too old to know the
67
+ // route, are both ordinary answers — not incidents to report.
68
+ errorContext: { operation: 'load preview config', silent: true },
69
+ });
70
+ if (!response.success)
71
+ return null;
72
+ const template = typeof response.data?.preview_url_template === 'string'
73
+ ? response.data.preview_url_template
74
+ : null;
75
+ templates.set(cacheKey, template);
76
+ return template;
77
+ }
78
+ catch {
79
+ // An older API has no such route, and a network blip is not an answer.
80
+ // Leave the cache empty so the next ensureReady() asks again.
81
+ return null;
82
+ }
83
+ finally {
84
+ inFlight.delete(cacheKey);
85
+ }
86
+ })();
87
+ inFlight.set(cacheKey, request);
88
+ return request;
89
+ }
90
+ /** Drop everything remembered — for tests and for a host re-pointing its API. */
91
+ export function resetPreviewConfigCache() {
92
+ templates.clear();
93
+ inFlight.clear();
94
+ }
95
+ //# sourceMappingURL=preview-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-config.js","sourceRoot":"","sources":["../../../src/core/session/preview-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAMhD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAyB,CAAC;AACnD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkC,CAAC;AAE3D;;;;GAIG;AACH,SAAS,GAAG,CAAC,UAAkB;IAC7B,IAAI,GAAG,GAAG,UAAU,CAAC,MAAM,CAAC;IAC5B,OAAO,GAAG,GAAG,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,SAAS;QAAE,GAAG,EAAE,CAAC;IACzE,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAClC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CAAC,UAAkB;IACzD,OAAO,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,IAAI,CAAC;AAChD,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,UAAkB;IACjD,OAAO,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;AACxC,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,UAAkB;IAC7D,MAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IACxC,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAE5B,MAAM,OAAO,GAAG,CAAC,KAAK,IAAI,EAAE;QAC1B,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,GAAG,CAAwB,WAAW,EAAE;gBACxE,UAAU,EAAE,KAAK;gBACjB,wEAAwE;gBACxE,8DAA8D;gBAC9D,YAAY,EAAE,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,EAAE,IAAI,EAAE;aACjE,CAAC,CAAC;YACH,IAAI,CAAC,QAAQ,CAAC,OAAO;gBAAE,OAAO,IAAI,CAAC;YACnC,MAAM,QAAQ,GAAG,OAAO,QAAQ,CAAC,IAAI,EAAE,oBAAoB,KAAK,QAAQ;gBACtE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,oBAAoB;gBACpC,CAAC,CAAC,IAAI,CAAC;YACT,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAClC,OAAO,QAAQ,CAAC;QAClB,CAAC;QAAC,MAAM,CAAC;YACP,uEAAuE;YACvE,8DAA8D;YAC9D,OAAO,IAAI,CAAC;QACd,CAAC;gBAAS,CAAC;YACT,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CAAC,EAAE,CAAC;IAEL,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,uBAAuB;IACrC,SAAS,CAAC,KAAK,EAAE,CAAC;IAClB,QAAQ,CAAC,KAAK,EAAE,CAAC;AACnB,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { SubdomainUrlOptions } from './url.js';
2
+ /**
3
+ * A fully-resolved options bag. Every field required — including
4
+ * `previewUrlTemplate`, whose `null` means "this deployment serves no preview
5
+ * domain" and is a real answer, not an omission.
6
+ */
7
+ export interface ResolvedPreviewOptions extends SubdomainUrlOptions {
8
+ previewUrlTemplate: string | null;
9
+ }
10
+ /**
11
+ * Resolve preview options for a sandbox against a backend.
12
+ *
13
+ * Reads the deployment's answer from the `GET /v1/p/config` cache, and asks
14
+ * again in the background when this backend has never answered — a rolling
15
+ * deploy can serve one request from a task that predates the route, and without
16
+ * the retry that single miss would pin the caller to the path proxy for its
17
+ * whole life. A backend that answered "no preview domain" HAS answered and is
18
+ * not re-asked.
19
+ */
20
+ export declare function resolvePreviewOptions(input: {
21
+ sandboxId: string;
22
+ apiBaseUrl: string;
23
+ backendPort: number;
24
+ }): ResolvedPreviewOptions;
25
+ //# sourceMappingURL=preview-options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-options.d.ts","sourceRoot":"","sources":["../../../src/core/session/preview-options.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAEjD;;;;GAIG;AACH,MAAM,WAAW,sBAAuB,SAAQ,mBAAmB;IACjE,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,sBAAsB,CASzB"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * The ONE way to build the options a preview URL is derived from.
3
+ *
4
+ * `rewriteLocalhostUrl` and its siblings in `url.ts` are pure: they answer
5
+ * "which URL" from an options bag and never touch the network. That purity is
6
+ * worth keeping — it is why they are exhaustively testable — but it puts the
7
+ * burden of assembling a COMPLETE bag on whoever calls them, and an incomplete
8
+ * bag does not fail. It falls back to the path proxy, silently, forever.
9
+ *
10
+ * That is not hypothetical. There are two call paths — a session handle
11
+ * (`kortix.session(...).previewUrl()`) and the ambient runtime
12
+ * (`deriveSubdomainOpts`, which the web app's preview iframe, `useSandboxProxy`
13
+ * and `buildStaticFilePreviewUrl` all use) — and each assembled the bag itself.
14
+ * When `previewUrlTemplate` was added, only the first was updated, so every
15
+ * preview in the session panel kept rendering `/v1/p/{sandbox}/{port}` however
16
+ * loudly the deployment advertised an origin. Nothing failed; the wrong thing
17
+ * merely kept working.
18
+ *
19
+ * So: one producer, and a return type whose fields are all REQUIRED. A future
20
+ * call path that forgets a field does not compile, which is the only kind of
21
+ * guarantee worth having for a failure mode this quiet.
22
+ */
23
+ import { cachedPreviewUrlTemplate, hasPreviewConfig, loadPreviewUrlTemplate } from './preview-config.js';
24
+ /**
25
+ * Resolve preview options for a sandbox against a backend.
26
+ *
27
+ * Reads the deployment's answer from the `GET /v1/p/config` cache, and asks
28
+ * again in the background when this backend has never answered — a rolling
29
+ * deploy can serve one request from a task that predates the route, and without
30
+ * the retry that single miss would pin the caller to the path proxy for its
31
+ * whole life. A backend that answered "no preview domain" HAS answered and is
32
+ * not re-asked.
33
+ */
34
+ export function resolvePreviewOptions(input) {
35
+ const { apiBaseUrl } = input;
36
+ if (!hasPreviewConfig(apiBaseUrl))
37
+ void loadPreviewUrlTemplate(apiBaseUrl).catch(() => { });
38
+ return {
39
+ sandboxId: input.sandboxId,
40
+ backendPort: input.backendPort,
41
+ apiBaseUrl,
42
+ previewUrlTemplate: cachedPreviewUrlTemplate(apiBaseUrl),
43
+ };
44
+ }
45
+ //# sourceMappingURL=preview-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-options.js","sourceRoot":"","sources":["../../../src/core/session/preview-options.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAYtG;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAIrC;IACC,MAAM,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC;IAC7B,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC;QAAE,KAAK,sBAAsB,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAC3F,OAAO;QACL,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,UAAU;QACV,kBAAkB,EAAE,wBAAwB,CAAC,UAAU,CAAC;KACzD,CAAC;AACJ,CAAC"}
@@ -14,9 +14,14 @@
14
14
  */
15
15
  export declare function buildPreviewAuthEndpoint(previewUrl: string, serverUrl?: string): string | null;
16
16
  /**
17
- * Subdomain preview form: `p{port}-{sandbox}.{host}/…`. These can't use the
18
- * host-only `/v1/p/` session cookie (it never reaches the preview subdomain),
19
- * so they authenticate via a one-shot `?token` on the first request.
17
+ * Preview ORIGIN form: `p{port}-{sandbox}.{host}` locally, or the deployed
18
+ * `{env}-p{port}-{sandbox}.{domain}`.
19
+ *
20
+ * These can't use the host-only `/v1/p/` session cookie — it never reaches
21
+ * another hostname — so they authenticate the FIRST request with a one-shot
22
+ * `?token`, which the proxy exchanges for a cookie on the preview origin and
23
+ * then strips. Every later request (sub-resources, `fetch`, WebSockets) rides
24
+ * that cookie, which is the only credential an app's own code can carry.
20
25
  */
21
26
  export declare function isSubdomainPreviewUrl(candidateUrl: string): boolean;
22
27
  /** Append a one-shot `?token` to a (subdomain) preview URL. */
@@ -1 +1 @@
1
- {"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../../src/core/session/preview.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA6CH;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,GAAG,IAAI,CAMf;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAMnE;AAED,+DAA+D;AAC/D,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAQ5E"}
1
+ {"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../../src/core/session/preview.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA6CH;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,GAAG,IAAI,CAMf;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAUnE;AAED,+DAA+D;AAC/D,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAQ5E"}
@@ -59,13 +59,20 @@ export function buildPreviewAuthEndpoint(previewUrl, serverUrl) {
59
59
  derivePreviewAuthEndpoint(previewUrl));
60
60
  }
61
61
  /**
62
- * Subdomain preview form: `p{port}-{sandbox}.{host}/…`. These can't use the
63
- * host-only `/v1/p/` session cookie (it never reaches the preview subdomain),
64
- * so they authenticate via a one-shot `?token` on the first request.
62
+ * Preview ORIGIN form: `p{port}-{sandbox}.{host}` locally, or the deployed
63
+ * `{env}-p{port}-{sandbox}.{domain}`.
64
+ *
65
+ * These can't use the host-only `/v1/p/` session cookie — it never reaches
66
+ * another hostname — so they authenticate the FIRST request with a one-shot
67
+ * `?token`, which the proxy exchanges for a cookie on the preview origin and
68
+ * then strips. Every later request (sub-resources, `fetch`, WebSockets) rides
69
+ * that cookie, which is the only credential an app's own code can carry.
65
70
  */
66
71
  export function isSubdomainPreviewUrl(candidateUrl) {
67
72
  try {
68
- return /^p\d+-[^.]+\./.test(new URL(candidateUrl).hostname);
73
+ const { hostname } = new URL(candidateUrl);
74
+ return (/^p\d+-[^.]+\./.test(hostname)
75
+ || /^(?:dev|staging|prod|preview)-p\d+-[a-z0-9-]+\./i.test(hostname));
69
76
  }
70
77
  catch {
71
78
  return false;
@@ -1 +1 @@
1
- {"version":3,"file":"preview.js","sourceRoot":"","sources":["../../../src/core/session/preview.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"preview.js","sourceRoot":"","sources":["../../../src/core/session/preview.ts"],"names":[],"mappings":"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"}
@@ -9,16 +9,27 @@
9
9
  * 1. Which locally-known messages does a staged rewind hide?
10
10
  * 2. When is a message id inside the range a committed rewind must delete?
11
11
  *
12
- * `watermark` exists to fix a real bug: hiding used to be "everything at-or-
13
- * after the boundary id", recomputed on every render off the CURRENT message
14
- * list. A message minted AFTER staging the user's replacement prompt, its
15
- * answer sorts above the boundary by id exactly like every OTHER later
16
- * message, so it fell inside "everything after the boundary" too and never
17
- * rendered until an unrelated remount flooded the whole transcript back,
18
- * interleaved. `watermark` freezes the upper edge of the hide window at the
19
- * newest message id known AT STAGE TIME, so only messages that were already
20
- * part of the abandoned trajectory are ever hidden anything newer always
21
- * renders.
12
+ * The window is a SET of message ids, captured at stage time. It used to be a
13
+ * lexical id RANGE — `id >= messageId && id <= watermark` which assumed ids
14
+ * ascend with time. OpenCode 1.18.15 retired that invariant outright (turn
15
+ * exit now reads `lastAssistant.parentID === lastUser.id`, and
16
+ * `MessageV2.latest()` orders by `time.created` with the id only as a
17
+ * tie-break), and the range failed in both directions:
18
+ *
19
+ * - **under-delete** a reverted assistant message whose id happens to sort
20
+ * BELOW the boundary falls outside the interval, survives the commit,
21
+ * is orphaned, and reappears at the top of the chat;
22
+ * - **over-delete** — `ascendingId` stubs sit ~2.8e13 above every real id, so
23
+ * a single in-flight optimistic message pushed the watermark to
24
+ * effectively infinity and the interval swallowed the user's replacement
25
+ * prompt and its answer.
26
+ *
27
+ * Membership has neither failure. `hiddenIds` is the exact list of messages
28
+ * that were part of the abandoned trajectory at the moment the rewind was
29
+ * staged: nothing minted afterwards can enter it, and nothing inside it can
30
+ * escape on an id comparison. `watermark` is retained as a published field —
31
+ * it names the newest message known at stage time — and still answers
32
+ * {@link isWithinRewindWindow} for a legacy state that carries no `hiddenIds`.
22
33
  */
23
34
  export interface SessionRewindState {
24
35
  /** The message the rewind pointer sits at — hidden along with everything
@@ -26,10 +37,25 @@ export interface SessionRewindState {
26
37
  messageId: string;
27
38
  /**
28
39
  * The newest message id known locally at the moment this rewind was staged
29
- * (or first observed). The upper bound of the hide window — fixed once,
30
- * never recomputed against a later, larger message list.
40
+ * (or first observed) see {@link newestMessageId}.
41
+ *
42
+ * No longer the upper bound of anything: {@link hiddenIds} is the window.
43
+ * Retained because it is a published field, and because it is the only
44
+ * bound available to a legacy state that carries no `hiddenIds`.
31
45
  */
32
46
  watermark: string;
47
+ /**
48
+ * The exact messages this rewind abandons — the boundary message and
49
+ * everything that followed it in the transcript, captured ONCE at stage
50
+ * time and never recomputed. Membership in this list is the whole of the
51
+ * hide/delete test; see the module comment for the two failures the lexical
52
+ * range it replaced produced.
53
+ *
54
+ * Optional only for backward compatibility: a `SessionRewindState` built by
55
+ * an older consumer (or restored from one) has none, and falls back to the
56
+ * legacy range. Everything in this SDK populates it.
57
+ */
58
+ hiddenIds?: readonly string[];
33
59
  /**
34
60
  * False once the replacement prompt has been sent (or a
35
61
  * `session.next.revert.committed` wire event says the server has). The
@@ -40,32 +66,49 @@ export interface SessionRewindState {
40
66
  */
41
67
  staged: boolean;
42
68
  }
43
- /** Whether `id` falls inside the [messageId, watermark] hide range — both
44
- * bounds inclusive: the boundary message itself is part of what an edit
45
- * replaces, and the watermark is the last message known at stage time. */
69
+ /** Whether `id` is one of the messages this rewind abandons.
70
+ *
71
+ * Membership in the set captured at stage time never a comparison between
72
+ * two id strings, which say nothing about which message came first. The
73
+ * legacy `[messageId, watermark]` range answers only for a state that
74
+ * carries no captured set. */
46
75
  export declare function isWithinRewindWindow(id: string, rewind: SessionRewindState): boolean;
47
76
  /**
48
- * The newest (highest sort-order) message id in `messages`, or `null` for an
49
- * empty list. Deliberately a max-scan, not "the last element" most callers
50
- * pass an ascending-sorted list, but an optimistic entry appended out of
51
- * order must never win the max by position alone.
77
+ * The newest message in `messages`, by `time.created` with the id as the only
78
+ * tie-break the same order the server's own `MessageV2.latest()` uses.
79
+ * `null` for an empty list.
80
+ *
81
+ * Deliberately a max-scan, not "the last element": most callers pass an
82
+ * ordered list, but an optimistic entry appended out of order must never win
83
+ * by position alone. A message with no `time` cannot be dated, so it competes
84
+ * on its id only.
52
85
  */
53
86
  export declare function newestMessageId<T extends {
54
87
  info: {
55
88
  id: string;
89
+ time?: {
90
+ created?: number;
91
+ };
56
92
  };
57
93
  }>(messages: T[]): string | null;
58
94
  /**
59
95
  * Build the state for a freshly staged (or freshly discovered) rewind.
60
- * `watermark` is captured HERE, from the message list at this exact moment —
61
- * never recomputed later. Falls back to `messageId` itself when nothing is
62
- * known locally yet (a cross-tab or reload discovery with no synced messages
63
- * for this session), which hides only the boundary message and nothing
64
- * else the narrowest correct answer with no other information available.
96
+ *
97
+ * The window is captured HERE and never recomputed: `hiddenIds` is the
98
+ * boundary message plus every message that follows it in `messages`, taken in
99
+ * the order the caller holds them which is the server's own
100
+ * `time.created` page order, not an id order. Falls back to `messageId`
101
+ * itself when the boundary is not in the list (a cross-tab or reload
102
+ * discovery with no synced messages for this session), which hides only the
103
+ * boundary message — the narrowest correct answer with no other information
104
+ * available.
65
105
  */
66
106
  export declare function stageSessionRewind<T extends {
67
107
  info: {
68
108
  id: string;
109
+ time?: {
110
+ created?: number;
111
+ };
69
112
  };
70
113
  }>(messages: T[], messageId: string): SessionRewindState;
71
114
  /** Hide the target message and every message up to the staged watermark.
@@ -1 +1 @@
1
- {"version":3,"file":"rewind.d.ts","sourceRoot":"","sources":["../../../src/core/session/rewind.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,WAAW,kBAAkB;IACjC;6BACyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;;OAOG;IACH,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;2EAE2E;AAC3E,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAEpF;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EAChE,QAAQ,EAAE,CAAC,EAAE,GACZ,MAAM,GAAG,IAAI,CAMf;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EACnE,QAAQ,EAAE,CAAC,EAAE,EACb,SAAS,EAAE,MAAM,GAChB,kBAAkB,CAMpB;AAED;;4EAE4E;AAC5E,wBAAgB,oBAAoB,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EACrE,QAAQ,EAAE,CAAC,EAAE,EACb,MAAM,EAAE,kBAAkB,GAAG,IAAI,GAChC,CAAC,EAAE,CAIL;AAED;;;4EAG4E;AAC5E,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,kBAAkB,GAAG,IAAI,GAChC,kBAAkB,GAAG,IAAI,CAE3B"}
1
+ {"version":3,"file":"rewind.d.ts","sourceRoot":"","sources":["../../../src/core/session/rewind.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,MAAM,WAAW,kBAAkB;IACjC;6BACyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;;OAOG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;;;;;OAUG;IACH,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B;;;;;;;OAOG;IACH,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;;+BAK+B;AAC/B,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAGpF;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,CAAC,SAAS;IAAE,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE;YAAE,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAA;CAAE,EAC/D,QAAQ,EAAE,CAAC,EAAE,GAAG,MAAM,GAAG,IAAI,CA4B9B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,CAAC,SAAS;IAAE,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE;YAAE,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAA;CAAE,EAC/D,QAAQ,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,kBAAkB,CAUtD;AAED;;4EAE4E;AAC5E,wBAAgB,oBAAoB,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EACrE,QAAQ,EAAE,CAAC,EAAE,EACb,MAAM,EAAE,kBAAkB,GAAG,IAAI,GAChC,CAAC,EAAE,CAIL;AAED;;;4EAG4E;AAC5E,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,kBAAkB,GAAG,IAAI,GAChC,kBAAkB,GAAG,IAAI,CAE3B"}