@ably/ai-transport 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/README.md +54 -47
  2. package/dist/ably-ai-transport.js +1006 -539
  3. package/dist/ably-ai-transport.js.map +1 -1
  4. package/dist/ably-ai-transport.umd.cjs +1 -1
  5. package/dist/ably-ai-transport.umd.cjs.map +1 -1
  6. package/dist/constants.d.ts +4 -0
  7. package/dist/core/codec/types.d.ts +19 -2
  8. package/dist/core/transport/decode-history.d.ts +8 -6
  9. package/dist/core/transport/headers.d.ts +4 -2
  10. package/dist/core/transport/index.d.ts +4 -1
  11. package/dist/core/transport/pipe-stream.d.ts +3 -2
  12. package/dist/core/transport/stream-router.d.ts +11 -1
  13. package/dist/core/transport/tree.d.ts +171 -0
  14. package/dist/core/transport/turn-manager.d.ts +4 -1
  15. package/dist/core/transport/types.d.ts +270 -119
  16. package/dist/core/transport/view.d.ts +166 -0
  17. package/dist/errors.d.ts +19 -2
  18. package/dist/index.d.ts +3 -1
  19. package/dist/react/ably-ai-transport-react.js +1019 -486
  20. package/dist/react/ably-ai-transport-react.js.map +1 -1
  21. package/dist/react/ably-ai-transport-react.umd.cjs +1 -1
  22. package/dist/react/ably-ai-transport-react.umd.cjs.map +1 -1
  23. package/dist/react/contexts/transport-context.d.ts +31 -0
  24. package/dist/react/contexts/transport-provider.d.ts +49 -0
  25. package/dist/react/create-transport-hooks.d.ts +124 -0
  26. package/dist/react/index.d.ts +14 -8
  27. package/dist/react/use-ably-messages.d.ts +14 -8
  28. package/dist/react/use-active-turns.d.ts +7 -3
  29. package/dist/react/use-client-transport.d.ts +78 -5
  30. package/dist/react/use-create-view.d.ts +22 -0
  31. package/dist/react/use-tree.d.ts +20 -0
  32. package/dist/react/use-view.d.ts +79 -0
  33. package/dist/vercel/ably-ai-transport-vercel.js +1478 -842
  34. package/dist/vercel/ably-ai-transport-vercel.js.map +1 -1
  35. package/dist/vercel/ably-ai-transport-vercel.umd.cjs +1 -1
  36. package/dist/vercel/ably-ai-transport-vercel.umd.cjs.map +1 -1
  37. package/dist/vercel/codec/tool-transitions.d.ts +50 -0
  38. package/dist/vercel/index.d.ts +3 -0
  39. package/dist/vercel/react/ably-ai-transport-vercel-react.js +9099 -852
  40. package/dist/vercel/react/ably-ai-transport-vercel-react.js.map +1 -1
  41. package/dist/vercel/react/ably-ai-transport-vercel-react.umd.cjs +45 -1
  42. package/dist/vercel/react/ably-ai-transport-vercel-react.umd.cjs.map +1 -1
  43. package/dist/vercel/react/contexts/chat-transport-context.d.ts +32 -0
  44. package/dist/vercel/react/contexts/chat-transport-provider.d.ts +84 -0
  45. package/dist/vercel/react/index.d.ts +5 -0
  46. package/dist/vercel/react/use-chat-transport.d.ts +61 -20
  47. package/dist/vercel/react/use-message-sync.d.ts +41 -9
  48. package/dist/vercel/react/use-staged-add-tool-approval-response.d.ts +30 -0
  49. package/dist/vercel/tool-approvals.d.ts +124 -0
  50. package/dist/vercel/tool-events.d.ts +26 -0
  51. package/dist/vercel/transport/chat-transport.d.ts +33 -11
  52. package/dist/vercel/transport/index.d.ts +5 -2
  53. package/package.json +23 -17
  54. package/src/constants.ts +6 -0
  55. package/src/core/codec/encoder.ts +10 -1
  56. package/src/core/codec/types.ts +19 -3
  57. package/src/core/transport/client-transport.ts +382 -364
  58. package/src/core/transport/decode-history.ts +229 -81
  59. package/src/core/transport/headers.ts +6 -2
  60. package/src/core/transport/index.ts +13 -5
  61. package/src/core/transport/pipe-stream.ts +8 -5
  62. package/src/core/transport/server-transport.ts +212 -58
  63. package/src/core/transport/stream-router.ts +21 -3
  64. package/src/core/transport/{conversation-tree.ts → tree.ts} +192 -77
  65. package/src/core/transport/turn-manager.ts +28 -10
  66. package/src/core/transport/types.ts +318 -139
  67. package/src/core/transport/view.ts +840 -0
  68. package/src/errors.ts +21 -1
  69. package/src/index.ts +10 -5
  70. package/src/react/contexts/transport-context.ts +37 -0
  71. package/src/react/contexts/transport-provider.tsx +164 -0
  72. package/src/react/create-transport-hooks.ts +144 -0
  73. package/src/react/index.ts +15 -8
  74. package/src/react/use-ably-messages.ts +34 -16
  75. package/src/react/use-active-turns.ts +28 -17
  76. package/src/react/use-client-transport.ts +184 -24
  77. package/src/react/use-create-view.ts +68 -0
  78. package/src/react/use-tree.ts +53 -0
  79. package/src/react/use-view.ts +233 -0
  80. package/src/react/vite.config.ts +4 -1
  81. package/src/vercel/codec/accumulator.ts +64 -79
  82. package/src/vercel/codec/decoder.ts +11 -8
  83. package/src/vercel/codec/encoder.ts +68 -54
  84. package/src/vercel/codec/index.ts +0 -2
  85. package/src/vercel/codec/tool-transitions.ts +122 -0
  86. package/src/vercel/index.ts +17 -0
  87. package/src/vercel/react/contexts/chat-transport-context.ts +40 -0
  88. package/src/vercel/react/contexts/chat-transport-provider.tsx +122 -0
  89. package/src/vercel/react/index.ts +14 -0
  90. package/src/vercel/react/use-chat-transport.ts +164 -42
  91. package/src/vercel/react/use-message-sync.ts +77 -19
  92. package/src/vercel/react/use-staged-add-tool-approval-response.ts +87 -0
  93. package/src/vercel/react/vite.config.ts +4 -2
  94. package/src/vercel/tool-approvals.ts +380 -0
  95. package/src/vercel/tool-events.ts +53 -0
  96. package/src/vercel/transport/chat-transport.ts +225 -79
  97. package/src/vercel/transport/index.ts +14 -3
  98. package/dist/core/transport/conversation-tree.d.ts +0 -9
  99. package/dist/react/use-conversation-tree.d.ts +0 -20
  100. package/dist/react/use-edit.d.ts +0 -7
  101. package/dist/react/use-history.d.ts +0 -19
  102. package/dist/react/use-messages.d.ts +0 -7
  103. package/dist/react/use-regenerate.d.ts +0 -7
  104. package/dist/react/use-send.d.ts +0 -7
  105. package/src/react/use-conversation-tree.ts +0 -71
  106. package/src/react/use-edit.ts +0 -24
  107. package/src/react/use-history.ts +0 -111
  108. package/src/react/use-messages.ts +0 -32
  109. package/src/react/use-regenerate.ts +0 -24
  110. package/src/react/use-send.ts +0 -25
@@ -1,2 +1,2 @@
1
- (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`react`),require(`ably`)):typeof define==`function`&&define.amd?define([`exports`,`react`,`ably`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.AblyAiTransportReact={},e.React,e.Ably))})(this,function(e,t,n){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var r=Object.create,i=Object.defineProperty,a=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,s=Object.getPrototypeOf,c=Object.prototype.hasOwnProperty,l=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var s=o(t),l=0,u=s.length,d;l<u;l++)d=s[l],!c.call(e,d)&&d!==n&&i(e,d,{get:(e=>t[e]).bind(null,d),enumerable:!(r=a(t,d))||r.enumerable});return e};n=((e,t,n)=>(n=e==null?{}:r(s(e)),l(t||!e||!e.__esModule?i(n,`default`,{value:e,enumerable:!0}):n,e)))(n);var u=e=>{let[n,r]=(0,t.useState)(()=>e.getAblyMessages());return(0,t.useEffect)(()=>(r(e.getAblyMessages()),e.on(`ably-message`,()=>{r(e.getAblyMessages())})),[e]),n},d=`x-ably-turn-id`,f=`x-ably-msg-id`,p=`x-ably-turn-client-id`,m=`x-ably-role`,h=`x-ably-cancel-turn-id`,g=`x-ably-cancel-own`,_=`x-ably-cancel-all`,v=`x-ably-cancel-client-id`,y=`x-ably-parent`,b=`x-ably-fork-of`,x=`x-ably-cancel`,S=`x-ably-turn-start`,C=`x-ably-turn-end`,w=e=>{let[n,r]=(0,t.useState)(()=>new Map);return(0,t.useEffect)(()=>{if(e)return r(e.getActiveTurnIds()),e.on(`turn`,e=>{r(t=>{let n=new Map(t);if(e.type===`x-ably-turn-start`){let t=new Set(n.get(e.clientId)??[]);t.add(e.turnId),n.set(e.clientId,t)}else{let t=n.get(e.clientId);t&&(t.delete(e.turnId),t.size===0?n.delete(e.clientId):n.set(e.clientId,new Set(t)))}return n})})},[e]),n},T=function(e){return e[e.BadRequest=4e4]=`BadRequest`,e[e.InvalidArgument=40003]=`InvalidArgument`,e[e.EncoderRecoveryFailed=104e3]=`EncoderRecoveryFailed`,e[e.TransportSubscriptionError=104001]=`TransportSubscriptionError`,e[e.CancelListenerError=104002]=`CancelListenerError`,e[e.TurnLifecycleError=104003]=`TurnLifecycleError`,e[e.TransportClosed=104004]=`TransportClosed`,e[e.TransportSendFailed=104005]=`TransportSendFailed`,e}({}),E=e=>({logAction:(t,n,r)=>{e.error(n,{detail:r})},shouldLog:()=>!0}),D=n.Realtime.EventEmitter,O=class extends D{constructor(e){super(E(e))}},k=function(e){return e.Trace=`trace`,e.Debug=`debug`,e.Info=`info`,e.Warn=`warn`,e.Error=`error`,e.Silent=`silent`,e}({}),A=(e,t,n)=>{let r=n?`, context: ${JSON.stringify(n)}`:``,i=`[${new Date().toISOString()}] ${t.valueOf().toUpperCase()} ably-ai-transport: ${e}${r}`;switch(t){case k.Trace:case k.Debug:console.log(i);break;case k.Info:console.info(i);break;case k.Warn:console.warn(i);break;case k.Error:console.error(i);break;case k.Silent:break}},j=e=>new P(e.logHandler??A,e.logLevel),M=function(e){return e[e.Trace=0]=`Trace`,e[e.Debug=1]=`Debug`,e[e.Info=2]=`Info`,e[e.Warn=3]=`Warn`,e[e.Error=4]=`Error`,e[e.Silent=5]=`Silent`,e}(M||{}),N=new Map([[k.Trace,M.Trace],[k.Debug,M.Debug],[k.Info,M.Info],[k.Warn,M.Warn],[k.Error,M.Error],[k.Silent,M.Silent]]),P=class e{constructor(e,t,r){this._handler=e,this._context=r;let i=N.get(t);if(i===void 0)throw new n.ErrorInfo(`unable to create logger; invalid log level: ${t}`,T.InvalidArgument,400);this._levelNumber=i}trace(e,t){this._write(e,k.Trace,M.Trace,t)}debug(e,t){this._write(e,k.Debug,M.Debug,t)}info(e,t){this._write(e,k.Info,M.Info,t)}warn(e,t){this._write(e,k.Warn,M.Warn,t)}error(e,t){this._write(e,k.Error,M.Error,t)}withContext(t){let n=[...N.entries()].find(([,e])=>e===this._levelNumber)?.[0]??k.Error;return new e(this._handler,n,this._mergeContext(t))}_write(e,t,n,r){n>=this._levelNumber&&this._handler(e,t,this._mergeContext(r))}_mergeContext(e){return this._context?e?{...this._context,...e}:this._context:e??void 0}},F=e=>{let t=e.extras;if(!t||typeof t!=`object`)return{};let n=t.headers;return!n||typeof n!=`object`?{}:n},I=class{constructor(e,t){this._nodeIndex=new Map,this._codecKeyIndex=new Map,this._sortedList=[],this._parentIndex=new Map,this._selections=new Map,this._seqCounter=0,this._getKey=e,this._logger=t}_compareNodes(e,t){let n=e.node.serial,r=t.node.serial;return n===void 0&&r===void 0?e.insertSeq-t.insertSeq:n===void 0?1:r===void 0||n<r?-1:n>r?1:e.insertSeq-t.insertSeq}_insertSorted(e){if(e.node.serial===void 0){this._sortedList.push(e);return}let t=0,n=this._sortedList.length;for(;t<n;){let r=t+n>>>1,i=this._sortedList[r];if(!i)break;this._compareNodes(i,e)<=0?t=r+1:n=r}this._sortedList.splice(t,0,e)}_removeSorted(e){let t=this._sortedList.indexOf(e);t!==-1&&this._sortedList.splice(t,1)}_addToParentIndex(e,t){let n=this._parentIndex.get(e);n||(n=new Set,this._parentIndex.set(e,n)),n.add(t)}_removeFromParentIndex(e,t){let n=this._parentIndex.get(e);n&&(n.delete(t),n.size===0&&this._parentIndex.delete(e))}_getSiblingGroup(e){let t=this._nodeIndex.get(e);if(!t)return[];let n=t.node,r=new Set([n.msgId]);for(;n.forkOf&&!r.has(n.forkOf);){let e=this._nodeIndex.get(n.forkOf);if(!e||e.node.parentId!==n.parentId)break;n=e.node,r.add(n.msgId)}let i=n.parentId,a=n.msgId,o=[],s=this._parentIndex.get(i);if(s)for(let e of s){let t=this._nodeIndex.get(e);t&&this._isSiblingOf(t.node,a)&&o.push(t)}return o.sort((e,t)=>this._compareNodes(e,t)),o.map(e=>e.node)}_isSiblingOf(e,t){if(e.msgId===t)return!0;let n=e,r=new Set([n.msgId]);for(;n.forkOf;){if(n.forkOf===t)return!0;if(r.has(n.forkOf))break;let e=this._nodeIndex.get(n.forkOf);if(!e)break;n=e.node,r.add(n.msgId)}return!1}_getGroupRoot(e){let t=this._nodeIndex.get(e);if(!t)return e;let n=t.node,r=new Set([n.msgId]);for(;n.forkOf&&!r.has(n.forkOf);){let e=this._nodeIndex.get(n.forkOf);if(!e||e.node.parentId!==n.parentId)break;n=e.node,r.add(n.msgId)}return n.msgId}flatten(){let e=[],t=new Set,n=new Map;for(let r of this._sortedList){let i=r.node,{msgId:a,parentId:o}=i;if(o!==void 0&&!t.has(o))continue;let s=this._getSiblingGroup(a);if(s.length>1){let e=this._getGroupRoot(a),t=n.get(e);if(t===void 0){let r=this._selections.get(e)??s.length-1,i=s[Math.max(0,Math.min(r,s.length-1))];if(!i)break;t=i.msgId,n.set(e,t)}if(a!==t)continue}t.add(a),e.push(i.message)}return e}getSiblings(e){return this._getSiblingGroup(e).map(e=>e.message)}hasSiblings(e){return this._getSiblingGroup(e).length>1}getSelectedIndex(e){let t=this._getSiblingGroup(e);if(t.length<=1)return 0;let n=this._getGroupRoot(e),r=this._selections.get(n);return r===void 0?t.length-1:Math.max(0,Math.min(r,t.length-1))}select(e,t){this._logger.debug(`ConversationTree.select();`,{msgId:e,index:t});let n=this._getSiblingGroup(e);if(n.length<=1)return;let r=this._getGroupRoot(e);this._selections.set(r,Math.max(0,Math.min(t,n.length-1)))}getNode(e){return this._nodeIndex.get(e)?.node}getNodeByKey(e){let t=this._codecKeyIndex.get(e);if(t)return this._nodeIndex.get(t)?.node}getHeaders(e){return this._nodeIndex.get(e)?.node.headers}upsert(e,t,n,r){let i=n[`x-ably-parent`]??void 0,a=n[`x-ably-fork-of`]??void 0;this._codecKeyIndex.set(this._getKey(t),e);let o=this._nodeIndex.get(e);if(o){o.node.message=t,Object.keys(n).length>0&&(o.node.headers={...n}),r&&!o.node.serial&&(this._logger.debug(`ConversationTree.upsert(); promoting serial`,{msgId:e,serial:r}),o.node.serial=r,this._removeSorted(o),this._insertSorted(o));return}this._logger.trace(`ConversationTree.upsert(); inserting new node`,{msgId:e,parentId:i,forkOf:a});let s={node:{message:t,msgId:e,parentId:i,forkOf:a,headers:{...n},serial:r},insertSeq:this._seqCounter++};this._nodeIndex.set(e,s),this._addToParentIndex(i,e),this._insertSorted(s)}delete(e){let t=this._nodeIndex.get(e);if(!t)return;this._logger.debug(`ConversationTree.delete();`,{msgId:e});let{node:n}=t,r=this._getKey(n.message);this._codecKeyIndex.get(r)===e&&this._codecKeyIndex.delete(r),this._removeFromParentIndex(n.parentId,e),this._removeSorted(t),this._nodeIndex.delete(e),this._selections.delete(e)}},L=(e,t)=>new I(e,t),R=e=>{let t=[...e.rawMessages].toReversed(),n=e.codec.createDecoder(),r=new Map,i=e.codec.createAccumulator(),a=0,o=new Map,s=new Map;for(let c of t){let t=n.decode(c),l=F(c),u=l[d],p=l[f],m=c.serial;if(u){let n=r.get(u);if(n||(n={accumulator:e.codec.createAccumulator(),firstSeen:a++,msgHeaders:new Map,msgSerials:new Map},r.set(u,n)),p){let e=n.msgHeaders.get(p);e?Object.keys(l).length>0&&Object.assign(e,l):(n.msgHeaders.set(p,{...l}),m&&n.msgSerials.set(p,m))}n.accumulator.processOutputs(t)}else i.processOutputs(t);for(let n of t)if(n.kind===`message`){let t=e.getMessageKey(n.message),r=o.get(t);r?Object.keys(l).length>0&&Object.assign(r,l):(o.set(t,{...l}),m&&s.set(t,m))}}let c=[];for(let t of i.completedMessages){let n=e.getMessageKey(t);c.push({message:t,headers:o.get(n)??{},serial:s.get(n)??``})}let l=[...r.values()].toSorted((e,t)=>e.firstSeen-t.firstSeen);for(let t of l){let n=new Set,r=new Map,i=new Map;for(let a of t.accumulator.completedMessages){let t=e.getMessageKey(a),c=o.get(t);if(c){r.set(t,c);let e=s.get(t);e&&i.set(t,e);let a=c[f];a&&n.add(a)}}let a=[...t.msgHeaders.entries()].filter(([e])=>!n.has(e)),l=0;for(let n of t.accumulator.completedMessages){let o=e.getMessageKey(n),s=a[l];if(!r.has(o)&&s){let[e,n]=s;r.set(o,n);let a=t.msgSerials.get(e);a&&i.set(o,a),l++}}for(let n of t.accumulator.completedMessages){let t=e.getMessageKey(n);c.push({message:n,headers:r.get(t)??{},serial:i.get(t)??``})}}return c.toReversed()},z=async(e,t,n)=>{e.rawMessages.push(...t.items),e.lastAblyPage=t;let r=R(e).length;for(;r<e.returnedCount+n&&t.hasNext();){e.logger.debug(`decodeHistory.fetchUntilLimit(); fetching next page`,{collected:e.rawMessages.length,decoded:r});let n=await t.next();if(!n)break;t=n,e.rawMessages.push(...n.items),e.lastAblyPage=n,r=R(e).length}},B=(e,t)=>{let n=R(e),r=n.slice(e.returnedCount,e.returnedCount+t),i=[...r].toReversed();e.returnedCount+=r.length;let a=n.length>e.returnedCount,o=e.lastAblyPage?.hasNext()??!1,s=e.rawMessages.length-e.returnedRawCount>0?e.rawMessages.slice(e.returnedRawCount).toReversed():[];return e.returnedRawCount=e.rawMessages.length,{items:i.map(e=>e.message),itemHeaders:i.map(e=>e.headers),itemSerials:i.map(e=>e.serial),rawMessages:s,hasNext:()=>a||o,next:async()=>{if(a)return B(e,t);if(!o||!e.lastAblyPage)return;let n=await e.lastAblyPage.next();if(n)return await z(e,n,t),B(e,t)}}},V=async(e,t,n,r)=>{let i=n?.limit??100,a={codec:t,rawMessages:[],returnedCount:0,returnedRawCount:0,lastAblyPage:void 0,getMessageKey:t.getMessageKey.bind(t),logger:r};r.trace(`decodeHistory();`,{limit:i});let o=i*10;return await e.attach(),await z(a,await e.history({untilAttach:!0,limit:o}),i),B(a,i)},H=e=>{let t={[m]:e.role,[d]:e.turnId,[f]:e.msgId};return e.turnClientId!==void 0&&(t[p]=e.turnClientId),e.parent&&(t[y]=e.parent),e.forkOf&&(t[b]=e.forkOf),t},U=class{constructor(e,t){this._turns=new Map,this._isTerminal=e,this._logger=t}createStream(e){this._logger.trace(`StreamRouter.createStream();`,{turnId:e});let t={},r=new ReadableStream({start(e){t.controller=e}});if(!t.controller)throw new n.ErrorInfo(`unable to create stream; ReadableStream start() was not called synchronously`,T.TransportSubscriptionError,500);return this._turns.set(e,{controller:t.controller,turnId:e}),r}closeStream(e){let t=this._turns.get(e);if(!t)return!1;this._logger.debug(`StreamRouter.closeStream(); closing stream`,{turnId:e});try{t.controller.close()}catch{}return this._turns.delete(e),!0}route(e,t){let n=this._turns.get(e);if(!n)return!1;try{n.controller.enqueue(t)}catch{return this._turns.delete(e),!1}return this._isTerminal(t)&&this.closeStream(e),!0}has(e){return this._turns.has(e)}},W=(e,t)=>new U(e,t),G=()=>{},K=class{constructor(e){if(this._ownMsgIds=new Set,this._ownTurnIds=new Set,this._turnClientIds=new Map,this._turnMsgIds=new Map,this._turnObservers=new Map,this._ablyMessages=[],this._withheldKeys=new Set,this._closed=!1,this._channel=e.channel,this._codec=e.codec,this._clientId=e.clientId,this._api=e.api??`/api/chat`,this._credentials=e.credentials,this._headersFn=typeof e.headers==`function`?e.headers:e.headers?()=>e.headers:void 0,this._bodyFn=typeof e.body==`function`?e.body:e.body?()=>e.body:void 0,this._fetchFn=e.fetch??globalThis.fetch.bind(globalThis),this._logger=(e.logger??j({logLevel:k.Silent})).withContext({component:`ClientTransport`}),this._emitter=new O(this._logger),this._tree=L(this._codec.getMessageKey.bind(this._codec),this._logger),this._router=W(this._codec.isTerminal.bind(this._codec),this._logger),this._decoder=this._codec.createDecoder(),e.messages){let t;for(let n of e.messages){let e=this._codec.getMessageKey(n),r={};t&&(r[y]=t),this._tree.upsert(e,n,r),t=e}this._emitter.emit(`message`)}this._onMessage=e=>{this._handleMessage(e)},this._attachPromise=this._channel.subscribe(this._onMessage)}_handleMessage(e){if(!this._closed){this._ablyMessages.push(e),this._emitter.emit(`ably-message`);try{if(e.name===`x-ably-turn-start`){let t=F(e),n=t[d],r=t[`x-ably-turn-client-id`]??``;n&&(this._turnClientIds.set(n,r),this._emitter.emit(`turn`,{type:S,turnId:n,clientId:r}));return}if(e.name===`x-ably-turn-end`){let t=F(e),n=t[d],r=t[`x-ably-turn-client-id`]??``,i=t[`x-ably-turn-reason`]??`complete`;if(n){this._router.closeStream(n),this._turnObservers.delete(n),this._turnClientIds.delete(n);let e=this._turnMsgIds.get(n);if(e){for(let t of e)this._ownMsgIds.delete(t);this._turnMsgIds.delete(n)}this._ownTurnIds.delete(n),this._emitter.emit(`turn`,{type:C,turnId:n,clientId:r,reason:i})}return}let t=this._decoder.decode(e),n=F(e),r=e.serial,i=n[d];i&&this._updateTurnObserverHeaders(i,n,r);for(let i of t)i.kind===`message`?this._handleMessageOutput(i.message,n,r,e.action):this._handleEventOutput(i,n)}catch(e){let t=e instanceof n.ErrorInfo?e:void 0;this._emitter.emit(`error`,new n.ErrorInfo(`unable to process channel message; ${e instanceof Error?e.message:String(e)}`,T.TransportSubscriptionError,500,t))}}}_handleMessageOutput(e,t,n,r){let i=t[f];if(i&&this._ownMsgIds.has(i)){this._upsertAndNotify(e,t,n);return}r===`message.create`&&this._upsertAndNotify(e,t,n)}_handleEventOutput(e,t){if(e.kind!==`event`)return;let n=e.event,r=t[d];if(r){if(this._router.route(r,n)){this._accumulateAndEmit(r,e),this._codec.isTerminal(n)&&this._turnObservers.delete(r);return}this._ownTurnIds.has(r)&&!this._turnObservers.has(r)||(this._accumulateAndEmit(r,e),this._codec.isTerminal(n)&&this._turnObservers.delete(r))}}_upsertAndNotify(e,t,n){let r=this._codec.getMessageKey(e),i=t[`x-ably-msg-id`]??r;this._tree.upsert(i,e,t,n),this._emitter.emit(`message`)}_updateTurnObserverHeaders(e,t,n){let r=this._turnObservers.get(e);r?(Object.keys(t).length>0&&Object.assign(r.headers,t),n!==void 0&&(r.serial=n)):this._turnObservers.set(e,{headers:{...t},serial:n,accumulator:this._codec.createAccumulator()})}_accumulateAndEmit(e,t){let n=this._turnObservers.get(e);if(!n)return;n.accumulator.processOutputs([t]);let r=n.accumulator.messages;if(r.length===0)return;let i;try{i=structuredClone(r.at(-1))}catch{i=r.at(-1)}i&&(this._tree.upsert(n.headers[`x-ably-msg-id`]??this._codec.getMessageKey(i),i,{...n.headers},n.serial),this._emitter.emit(`message`))}async _publishCancel(e){this._logger.trace(`ClientTransport._publishCancel();`,{filter:e});let t={};e.turnId?t[h]=e.turnId:e.own?t[g]=`true`:e.clientId?t[v]=e.clientId:e.all&&(t[_]=`true`),await this._channel.publish({name:x,extras:{headers:t}})}_closeMatchingTurnStreams(e){if(e.all)for(let e of this._ownTurnIds)this._router.closeStream(e);else if(e.own)for(let e of this._ownTurnIds)this._router.closeStream(e);else if(e.clientId)for(let[t,n]of this._turnClientIds)n===e.clientId&&this._router.closeStream(t);else e.turnId&&this._router.closeStream(e.turnId)}_getMatchingTurnIds(e){let t=new Set;if(e.all)for(let e of this._turnClientIds.keys())t.add(e);else if(e.own)for(let[e,n]of this._turnClientIds)n===this._clientId&&t.add(e);else if(e.clientId)for(let[n,r]of this._turnClientIds)r===e.clientId&&t.add(n);else e.turnId&&this._turnClientIds.has(e.turnId)&&t.add(e.turnId);return t}_getMessagesWithHeaders(){return this._tree.flatten().map(e=>({message:e,headers:this.getMessageHeaders(e)}))}_getHistoryBefore(e){let t=this._getMessagesWithHeaders(),n=t.findIndex(t=>t.headers?.[f]===e);return n===-1?t:t.slice(0,n)}_processHistoryPage(e){for(let[t,n]of e.items.entries()){let r=e.itemHeaders?.[t]??{},i=e.itemSerials?.[t],a=this._codec.getMessageKey(n),o=r[`x-ably-msg-id`]??a;this._tree.upsert(o,n,r,i)}this._emitter.emit(`message`),e.rawMessages&&e.rawMessages.length>0&&(this._ablyMessages.unshift(...e.rawMessages),this._emitter.emit(`ably-message`))}async _loadUntilVisible(e,t,n){this._processHistoryPage(e);let r=e,i=()=>{let e=0;for(let t of this._tree.flatten())n.has(this._codec.getMessageKey(t))||e++;return e};for(;i()<t&&r.hasNext();){let e=await r.next();if(!e)break;this._processHistoryPage(e),r=e}return{newVisible:this._tree.flatten().filter(e=>!n.has(this._codec.getMessageKey(e))),lastPage:r}}_releaseWithheld(e){for(let t of e)this._withheldKeys.delete(this._codec.getMessageKey(t));e.length>0&&this._emitter.emit(`message`)}async send(e,t){if(this._closed||(await this._attachPromise,this._closed))throw new n.ErrorInfo(`unable to send; transport is closed`,T.TransportClosed,400);this._logger.trace(`ClientTransport.send();`);let r=Array.isArray(e)?e:[e],i=crypto.randomUUID();this._ownTurnIds.add(i);let a=new Set,o=[],s=this._getMessagesWithHeaders(),c;if(t?.parent===void 0&&!t?.forkOf){let e=this._tree.flatten();if(e.length>0){let t=e.at(-1);if(t){let e=this._codec.getMessageKey(t);c=this._tree.getNodeByKey(e)?.msgId??e}}}let l=t?.parent===void 0?c:t.parent;for(let e of r){let n=crypto.randomUUID();this._ownMsgIds.add(n),a.add(n);let r=t?.parent===void 0?c:t.parent??void 0,s=H({role:`user`,turnId:i,msgId:n,turnClientId:this._clientId,parent:r,forkOf:t?.forkOf});this._upsertAndNotify(e,s);let l={[f]:n,[m]:`user`};r&&(l[y]=r),o.push({message:e,headers:l}),t?.parent===void 0&&!t?.forkOf&&(c=n)}this._turnMsgIds.set(i,a);let u=this._router.createStream(i),d=this._headersFn?.()??{},p={...this._bodyFn?.()??{},history:s,...t?.body,turnId:i,clientId:this._clientId,messages:o,...t?.forkOf!==void 0&&{forkOf:t.forkOf},...l!==void 0&&{parent:l}},h={...d,...t?.headers};return this._fetchFn(this._api,{method:`POST`,headers:{"Content-Type":`application/json`,...h},body:JSON.stringify(p),...this._credentials?{credentials:this._credentials}:{}}).then(e=>{e.ok||(this._emitter.emit(`error`,new n.ErrorInfo(`unable to send; HTTP POST to ${this._api} returned ${String(e.status)} ${e.statusText}`,T.TransportSendFailed,e.status)),this._router.closeStream(i))}).catch(e=>{let t=e instanceof n.ErrorInfo?e:void 0;this._emitter.emit(`error`,new n.ErrorInfo(`unable to send; HTTP POST to ${this._api} failed: ${e instanceof Error?e.message:String(e)}`,T.TransportSendFailed,500,t)),this._router.closeStream(i)}),{stream:u,turnId:i,cancel:async()=>this.cancel({turnId:i})}}async regenerate(e,t){this._logger.trace(`ClientTransport.regenerate();`,{messageId:e});let n=this._tree.getNode(e)?.parentId;return this.send([],{...t,body:{history:this._getHistoryBefore(e),...t?.body},forkOf:e,parent:n})}async edit(e,t,n){this._logger.trace(`ClientTransport.edit();`,{messageId:e});let r=this._tree.getNode(e)?.parentId;return this.send(t,{...n,body:{history:this._getHistoryBefore(e),...n?.body},forkOf:e,parent:r})}async cancel(e){if(this._closed)return;let t=e??{own:!0};this._logger.debug(`ClientTransport.cancel();`,{filter:t}),await this._publishCancel(t),this._closeMatchingTurnStreams(t)}async waitForTurn(e){if(this._closed)return;let t=e??{own:!0},n=this._getMatchingTurnIds(t);if(n.size!==0)return this._logger.debug(`ClientTransport.waitForTurn();`,{turnIds:[...n]}),new Promise(e=>{let t=r=>{r.type===`x-ably-turn-end`&&(n.delete(r.turnId),n.size===0&&(this._emitter.off(`turn`,t),e()))};this._emitter.on(`turn`,t)})}on(e,t){if(this._closed)return G;let n=t;return this._emitter.on(e,n),()=>{this._emitter.off(e,n)}}getTree(){return this._tree}getActiveTurnIds(){let e=new Map;for(let[t,n]of this._turnClientIds){let r=e.get(n);r||(r=new Set,e.set(n,r)),r.add(t)}return e}getMessageHeaders(e){let t=this._codec.getMessageKey(e);return this._tree.getNodeByKey(t)?.headers}getMessages(){return this._withheldKeys.size===0?this._tree.flatten():this._tree.flatten().filter(e=>!this._withheldKeys.has(this._codec.getMessageKey(e)))}getMessagesWithHeaders(){return this._getMessagesWithHeaders()}getAblyMessages(){return[...this._ablyMessages]}async history(e){if(this._closed)throw new n.ErrorInfo(`unable to load history; transport is closed`,T.TransportClosed,400);this._logger.trace(`ClientTransport.history();`,{limit:e?.limit});let t=e?.limit??100,r=new Set(this._tree.flatten().map(e=>this._codec.getMessageKey(e))),i=await V(this._channel,this._codec,e,this._logger),a=await this._loadUntilVisible(i,t,r);i=a.lastPage;let o=a.newVisible;for(let e of o)this._withheldKeys.add(this._codec.getMessageKey(e));let s=o.slice(-t),c=o.slice(0,-t);this._releaseWithheld(s);let l=e=>({items:e,hasNext:()=>c.length>0||i.hasNext(),next:async()=>{if(c.length>0){let e=c.splice(-t,t);return this._releaseWithheld(e),l(e)}if(!i.hasNext())return;let e=await i.next();if(!e)return;let n=new Set(r);for(let e of this._tree.flatten())n.add(this._codec.getMessageKey(e));let a=await this._loadUntilVisible(e,t,n);i=a.lastPage;let o=a.newVisible;for(let e of o)this._withheldKeys.add(this._codec.getMessageKey(e));let s=o.splice(-t,t);if(c.push(...o),this._releaseWithheld(s),s.length!==0)return l(s)}});return l(s)}async close(e){if(!this._closed){if(this._closed=!0,this._logger.info(`ClientTransport.close();`),e?.cancel){try{await this._publishCancel(e.cancel)}catch{}this._closeMatchingTurnStreams(e.cancel)}this._channel.unsubscribe(this._onMessage);for(let e of this._ownTurnIds)this._router.closeStream(e);this._turnObservers.clear(),this._emitter.off(),this._ownTurnIds.clear(),this._ownMsgIds.clear(),this._turnMsgIds.clear(),this._turnClientIds.clear(),this._withheldKeys.clear(),this._ablyMessages.length=0}}},q=e=>new K(e);e.useAblyMessages=u,e.useActiveTurns=w,e.useClientTransport=e=>{let n=(0,t.useRef)(null);return n.current===null&&(n.current=q(e)),n.current},e.useConversationTree=e=>{let[n,r]=(0,t.useState)(()=>e.getMessages());return(0,t.useEffect)(()=>(r(e.getMessages()),e.on(`message`,()=>{r(e.getMessages())})),[e]),{messages:n,getSiblings:(0,t.useCallback)(t=>e.getTree().getSiblings(t),[e]),hasSiblings:(0,t.useCallback)(t=>e.getTree().hasSiblings(t),[e]),getSelectedIndex:(0,t.useCallback)(t=>e.getTree().getSelectedIndex(t),[e]),selectSibling:(0,t.useCallback)((t,n)=>{e.getTree().select(t,n),r(e.getMessages())},[e])}},e.useEdit=e=>(0,t.useCallback)(async(t,n,r)=>e.edit(t,n,r),[e]),e.useHistory=(e,n)=>{let[r,i]=(0,t.useState)(!1),[a,o]=(0,t.useState)(!1),s=(0,t.useRef)(!1),c=(0,t.useRef)(null),l=(0,t.useRef)(e);l.current=e;let u=(0,t.useCallback)(async e=>{if(!(!l.current||s.current)){s.current=!0,o(!0);try{let t=await l.current.history(e);c.current=t,i(t.hasNext())}finally{s.current=!1,o(!1)}}},[]),d=(0,t.useCallback)(async()=>{let e=c.current;if(!(!e||!e.hasNext()||s.current||!l.current)){s.current=!0,o(!0);try{let t=await e.next();t?(c.current=t,i(t.hasNext())):i(!1)}finally{s.current=!1,o(!1)}}},[]),f=n!=null,p=(0,t.useRef)(!1),m=(0,t.useRef)(n);return m.current=n,(0,t.useEffect)(()=>{!f||p.current||!l.current||(p.current=!0,u(m.current??void 0))},[f,u]),{hasNext:r,loading:a,load:u,next:d}},e.useMessages=e=>{let[n,r]=(0,t.useState)(()=>e.getMessages());return(0,t.useEffect)(()=>(r(e.getMessages()),e.on(`message`,()=>{r(e.getMessages())})),[e]),n},e.useRegenerate=e=>(0,t.useCallback)(async(t,n)=>e.regenerate(t,n),[e]),e.useSend=e=>(0,t.useCallback)(async(t,n)=>e.send(t,n),[e])});
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`react`),require(`ably`),require(`ably/react`),require(`react/jsx-runtime`)):typeof define==`function`&&define.amd?define([`exports`,`react`,`ably`,`ably/react`,`react/jsx-runtime`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.AblyAiTransportReact={},e.React,e.Ably,e.AblyReact,e.ReactJsxRuntime))})(this,function(e,t,n,r,i){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var a=Object.create,o=Object.defineProperty,s=Object.getOwnPropertyDescriptor,c=Object.getOwnPropertyNames,l=Object.getPrototypeOf,u=Object.prototype.hasOwnProperty,d=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=c(t),a=0,l=i.length,d;a<l;a++)d=i[a],!u.call(e,d)&&d!==n&&o(e,d,{get:(e=>t[e]).bind(null,d),enumerable:!(r=s(t,d))||r.enumerable});return e};n=((e,t,n)=>(n=e==null?{}:a(l(e)),d(t||!e||!e.__esModule?o(n,`default`,{value:e,enumerable:!0}):n,e)))(n,1);var f=(0,t.createContext)({}),p=(0,t.createContext)(void 0),m=`x-ably-status`,h=`x-ably-turn-id`,g=`x-ably-msg-id`,_=`x-ably-turn-client-id`,v=`x-ably-role`,y=`x-ably-amend`,b=`x-ably-cancel-turn-id`,x=`x-ably-cancel-own`,ee=`x-ably-cancel-all`,te=`x-ably-cancel-client-id`,S=`x-ably-parent`,C=`x-ably-fork-of`,w=`x-ably-cancel`,T=`x-ably-turn-start`,ne=`x-ably-turn-end`,E=function(e){return e[e.BadRequest=4e4]=`BadRequest`,e[e.InvalidArgument=40003]=`InvalidArgument`,e[e.EncoderRecoveryFailed=104e3]=`EncoderRecoveryFailed`,e[e.TransportSubscriptionError=104001]=`TransportSubscriptionError`,e[e.CancelListenerError=104002]=`CancelListenerError`,e[e.TurnLifecycleError=104003]=`TurnLifecycleError`,e[e.TransportClosed=104004]=`TransportClosed`,e[e.TransportSendFailed=104005]=`TransportSendFailed`,e[e.ChannelContinuityLost=104006]=`ChannelContinuityLost`,e[e.ChannelNotReady=104007]=`ChannelNotReady`,e[e.StreamError=104008]=`StreamError`,e}({}),D=e=>({logAction:(t,n,r)=>{e.error(n,{detail:r})},shouldLog:()=>!0}),re=n.Realtime.EventEmitter,O=class extends re{constructor(e){super(D(e))}},k=function(e){return e.Trace=`trace`,e.Debug=`debug`,e.Info=`info`,e.Warn=`warn`,e.Error=`error`,e.Silent=`silent`,e}({}),A=(e,t,n)=>{let r=n?`, context: ${JSON.stringify(n)}`:``,i=`[${new Date().toISOString()}] ${t.valueOf().toUpperCase()} ably-ai-transport: ${e}${r}`;switch(t){case k.Trace:case k.Debug:console.log(i);break;case k.Info:console.info(i);break;case k.Warn:console.warn(i);break;case k.Error:console.error(i);break;case k.Silent:break}},j=e=>new P(e.logHandler??A,e.logLevel),M=function(e){return e[e.Trace=0]=`Trace`,e[e.Debug=1]=`Debug`,e[e.Info=2]=`Info`,e[e.Warn=3]=`Warn`,e[e.Error=4]=`Error`,e[e.Silent=5]=`Silent`,e}(M||{}),N=new Map([[k.Trace,M.Trace],[k.Debug,M.Debug],[k.Info,M.Info],[k.Warn,M.Warn],[k.Error,M.Error],[k.Silent,M.Silent]]),P=class e{constructor(e,t,r){this._handler=e,this._context=r;let i=N.get(t);if(i===void 0)throw new n.ErrorInfo(`unable to create logger; invalid log level: ${t}`,E.InvalidArgument,400);this._levelNumber=i}trace(e,t){this._write(e,k.Trace,M.Trace,t)}debug(e,t){this._write(e,k.Debug,M.Debug,t)}info(e,t){this._write(e,k.Info,M.Info,t)}warn(e,t){this._write(e,k.Warn,M.Warn,t)}error(e,t){this._write(e,k.Error,M.Error,t)}withContext(t){let n=[...N.entries()].find(([,e])=>e===this._levelNumber)?.[0]??k.Error;return new e(this._handler,n,this._mergeContext(t))}_write(e,t,n,r){n>=this._levelNumber&&this._handler(e,t,this._mergeContext(r))}_mergeContext(e){return this._context?e?{...this._context,...e}:this._context:e??void 0}},F=e=>{let t=e.extras;if(!t||typeof t!=`object`)return{};let n=t.headers;return!n||typeof n!=`object`?{}:n},ie=e=>{let t={[v]:e.role,[h]:e.turnId,[g]:e.msgId};return e.turnClientId!==void 0&&(t[_]=e.turnClientId),e.parent&&(t[S]=e.parent),e.forkOf&&(t[C]=e.forkOf),e.amend&&(t[y]=e.amend),t},ae=class{constructor(e,t){this._turns=new Map,this._isTerminal=e,this._logger=t}createStream(e){this._logger.trace(`StreamRouter.createStream();`,{turnId:e});let t={},r=new ReadableStream({start(e){t.controller=e}});if(!t.controller)throw new n.ErrorInfo(`unable to create stream; ReadableStream start() was not called synchronously`,E.TransportSubscriptionError,500);return this._turns.set(e,{controller:t.controller,turnId:e}),r}closeStream(e){let t=this._turns.get(e);if(!t)return!1;this._logger.debug(`StreamRouter.closeStream(); closing stream`,{turnId:e});try{t.controller.close()}catch{}return this._turns.delete(e),!0}errorStream(e,t){let n=this._turns.get(e);if(!n)return!1;this._logger.debug(`StreamRouter.errorStream(); erroring stream`,{turnId:e});try{n.controller.error(t)}catch{}return this._turns.delete(e),!0}route(e,t){let n=this._turns.get(e);if(!n)return!1;try{n.controller.enqueue(t)}catch{return this._turns.delete(e),!1}return this._isTerminal(t)&&this.closeStream(e),!0}has(e){return this._turns.has(e)}},oe=(e,t)=>new ae(e,t),se=class{get structuralVersion(){return this._structuralVersion}constructor(e){this._nodeIndex=new Map,this._sortedList=[],this._parentIndex=new Map,this._turnClientIds=new Map,this._seqCounter=0,this._structuralVersion=0,this._logger=e,this._emitter=new O(e)}_compareNodes(e,t){let n=e.node.serial,r=t.node.serial;return n===void 0&&r===void 0?e.insertSeq-t.insertSeq:n===void 0?1:r===void 0||n<r?-1:n>r?1:e.insertSeq-t.insertSeq}_insertSorted(e){if(e.node.serial===void 0){this._sortedList.push(e);return}let t=0,n=this._sortedList.length;for(;t<n;){let r=t+n>>>1,i=this._sortedList[r];if(!i)break;this._compareNodes(i,e)<=0?t=r+1:n=r}this._sortedList.splice(t,0,e)}_removeSorted(e){let t=this._sortedList.indexOf(e);t!==-1&&this._sortedList.splice(t,1)}_addToParentIndex(e,t){let n=this._parentIndex.get(e);n||(n=new Set,this._parentIndex.set(e,n)),n.add(t)}_removeFromParentIndex(e,t){let n=this._parentIndex.get(e);n&&(n.delete(t),n.size===0&&this._parentIndex.delete(e))}_getSiblingGroup(e){let t=this._nodeIndex.get(e);if(!t)return[];let n=t.node,r=new Set([n.msgId]);for(;n.forkOf&&!r.has(n.forkOf);){let e=this._nodeIndex.get(n.forkOf);if(!e||e.node.parentId!==n.parentId)break;n=e.node,r.add(n.msgId)}let i=n.parentId,a=n.msgId,o=[],s=this._parentIndex.get(i);if(s)for(let e of s){let t=this._nodeIndex.get(e);t&&this._isSiblingOf(t.node,a)&&o.push(t)}return o.sort((e,t)=>this._compareNodes(e,t)),o.map(e=>e.node)}_isSiblingOf(e,t){if(e.msgId===t)return!0;let n=e,r=new Set([n.msgId]);for(;n.forkOf;){if(n.forkOf===t)return!0;if(r.has(n.forkOf))break;let e=this._nodeIndex.get(n.forkOf);if(!e)break;n=e.node,r.add(n.msgId)}return!1}getGroupRoot(e){let t=this._nodeIndex.get(e);if(!t)return e;let n=t.node,r=new Set([n.msgId]);for(;n.forkOf&&!r.has(n.forkOf);){let e=this._nodeIndex.get(n.forkOf);if(!e||e.node.parentId!==n.parentId)break;n=e.node,r.add(n.msgId)}return n.msgId}flattenNodes(e){this._logger.trace(`DefaultTree.flattenNodes();`);let t=[],n=new Set,r=new Map;for(let i of this._sortedList){let a=i.node,{msgId:o,parentId:s}=a;if(s!==void 0&&!n.has(s))continue;let c=this._getSiblingGroup(o);if(c.length>1){let t=this.getGroupRoot(o),n=r.get(t);if(n===void 0){let i=e.get(t);if(i&&c.some(e=>e.msgId===i))n=i;else{let e=c.at(-1);if(!e)break;n=e.msgId}r.set(t,n)}if(o!==n)continue}n.add(o),t.push(a)}return t}getSiblings(e){return this._logger.trace(`DefaultTree.getSiblings();`,{msgId:e}),this._getSiblingGroup(e).map(e=>e.message)}getSiblingNodes(e){return this._getSiblingGroup(e)}hasSiblings(e){return this._getSiblingGroup(e).length>1}getNode(e){return this._logger.trace(`DefaultTree.getNode();`,{msgId:e}),this._nodeIndex.get(e)?.node}getHeaders(e){return this._logger.trace(`DefaultTree.getHeaders();`,{msgId:e}),this._nodeIndex.get(e)?.node.headers}upsert(e,t,n,r){let i=n[`x-ably-parent`]??void 0,a=n[`x-ably-fork-of`]??void 0,o=this._nodeIndex.get(e);if(o){o.node.message=t,Object.keys(n).length>0&&(o.node.headers={...n}),r&&!o.node.serial&&(this._logger.debug(`Tree.upsert(); promoting serial`,{msgId:e,serial:r}),o.node.serial=r,this._removeSorted(o),this._insertSorted(o),this._structuralVersion++),this._emitter.emit(`update`);return}this._logger.trace(`Tree.upsert(); inserting new node`,{msgId:e,parentId:i,forkOf:a});let s={node:{kind:`message`,message:t,msgId:e,parentId:i,forkOf:a,headers:{...n},serial:r},insertSeq:this._seqCounter++};this._nodeIndex.set(e,s),this._addToParentIndex(i,e),this._insertSorted(s),this._structuralVersion++,this._emitter.emit(`update`)}delete(e){let t=this._nodeIndex.get(e);if(!t)return;this._logger.debug(`Tree.delete();`,{msgId:e});let{node:n}=t;this._removeFromParentIndex(n.parentId,e),this._removeSorted(t),this._nodeIndex.delete(e),this._structuralVersion++,this._emitter.emit(`update`)}getActiveTurnIds(){this._logger.trace(`DefaultTree.getActiveTurnIds();`);let e=new Map;for(let[t,n]of this._turnClientIds){let r=e.get(n);r||(r=new Set,e.set(n,r)),r.add(t)}return e}on(e,t){let n=t;return this._emitter.on(e,n),()=>{this._emitter.off(e,n)}}emitAblyMessage(e){this._logger.trace(`DefaultTree.emitAblyMessage();`),this._emitter.emit(`ably-message`,e)}emitTurn(e){this._logger.trace(`DefaultTree.emitTurn();`,{turnId:e.turnId}),this._emitter.emit(`turn`,e)}trackTurn(e,t){this._logger.trace(`DefaultTree.trackTurn();`,{turnId:e,clientId:t}),this._turnClientIds.set(e,t)}untrackTurn(e){this._logger.trace(`DefaultTree.untrackTurn();`,{turnId:e}),this._turnClientIds.delete(e)}},ce=e=>new se(e),I=e=>{let t=[...e.rawMessages].toReversed(),n=e.codec.createDecoder(),r=new Map,i=e.codec.createAccumulator(),a=0,o=new Map,s=new Map,c=[],l=[];for(let u of t){let t=n.decode(u),d=F(u),f=d[h],p=d[g],m=u.serial,_=d[y];if(_){for(let e of r.values())if(e.msgHeaders.has(_)){let n=[...e.msgHeaders.keys()].indexOf(_),r=n===-1?void 0:e.accumulator.messages[n];r&&e.accumulator.initMessage(_,r),e.accumulator.processOutputs(t),l.push({accumulator:e.accumulator,messageId:_});break}continue}if(f){let n=r.get(f);if(n||(n={accumulator:e.codec.createAccumulator(),firstSeen:a++,msgHeaders:new Map,msgSerials:new Map},r.set(f,n)),p){let e=n.msgHeaders.get(p);e?Object.keys(d).length>0&&Object.assign(e,d):(n.msgHeaders.set(p,{...d}),m&&n.msgSerials.set(p,m))}n.accumulator.processOutputs(t)}else{i.processOutputs(t);for(let e of t)if(e.kind===`message`&&p){c.push(p);let e=o.get(p);e?Object.keys(d).length>0&&Object.assign(e,d):(o.set(p,{...d}),m&&s.set(p,m))}}}for(let{accumulator:e,messageId:t}of l)e.completeMessage(t);let u=[];for(let[e,t]of i.completedMessages.entries()){let n=c[e];u.push({message:t,headers:n?o.get(n)??{}:{},serial:n?s.get(n)??``:``})}let d=[...r.values()].toSorted((e,t)=>e.firstSeen-t.firstSeen);for(let e of d){let t=[...e.msgHeaders.entries()],n=0;for(let r of e.accumulator.completedMessages){let i=t[n];if(i){let[t,a]=i;u.push({message:r,headers:a,serial:e.msgSerials.get(t)??``}),n++}else u.push({message:r,headers:{},serial:``})}}return u.toReversed()},L=e=>{if(e.cachedDecode&&e.cachedAtRawLength===e.rawMessages.length)return e.cachedDecode;let t=I(e);return e.cachedDecode=t,e.cachedAtRawLength=e.rawMessages.length,t},R=(e,t)=>{for(let n of t){let t=F(n),r=t[g];if(!r||t[`x-ably-amend`])continue;let i=n.action,a=i===`message.create`&&`x-ably-discrete`in t,o=t[`x-ably-stream`]===`true`&&(i===`message.create`||i===`message.update`||i===`message.append`),s=t[m],c=s===`finished`||s===`aborted`;(a||o)&&e.startedMsgIds.add(r),(a||c)&&e.terminatedMsgIds.add(r),e.startedMsgIds.has(r)&&e.terminatedMsgIds.has(r)&&e.completedMsgIds.add(r)}},z=async(e,t,n)=>{e.rawMessages.push(...t.items),e.lastAblyPage=t,R(e,t.items);let r=e.returnedCount+n;for(;e.completedMsgIds.size<r&&t.hasNext();){e.logger.debug(`decodeHistory.fetchUntilLimit(); fetching next page`,{collected:e.rawMessages.length,completed:e.completedMsgIds.size});let n=await t.next();if(!n)break;t=n,e.rawMessages.push(...n.items),e.lastAblyPage=n,R(e,n.items)}},B=(e,t)=>{let n=L(e),r=n.slice(e.returnedCount,e.returnedCount+t),i=[...r].toReversed();e.returnedCount+=r.length;let a=n.length>e.returnedCount,o=e.lastAblyPage?.hasNext()??!1,s=e.rawMessages.length-e.returnedRawCount>0?e.rawMessages.slice(e.returnedRawCount).toReversed():[];return e.returnedRawCount=e.rawMessages.length,{items:i.map(e=>({message:e.message,headers:e.headers,serial:e.serial})),rawMessages:s,hasNext:()=>a||o,next:async()=>{if(a)return B(e,t);if(!o||!e.lastAblyPage)return;let n=await e.lastAblyPage.next();if(n)return await z(e,n,t),B(e,t)}}},V=async(e,t,n,r)=>{let i=n?.limit??100,a={codec:t,rawMessages:[],returnedCount:0,returnedRawCount:0,lastAblyPage:void 0,cachedDecode:void 0,cachedAtRawLength:0,startedMsgIds:new Set,terminatedMsgIds:new Set,completedMsgIds:new Set,logger:r};r.trace(`decodeHistory();`,{limit:i});let o=i*10;return await e.attach(),await z(a,await e.history({untilAttach:!0,limit:o}),i),B(a,i)},H=class{constructor(e){this._branchSelections=new Map,this._withheldMsgIds=new Set,this._lastVisibleIds=[],this._lastVisibleMessages=[],this._lastVisibleTurnIds=new Set,this._hasMoreHistory=!1,this._withheldBuffer=[],this._unsubs=[],this._cachedNodes=[],this._lastStructuralVersion=-1,this._loadingOlder=!1,this._processingHistory=!1,this._closed=!1,this._tree=e.tree,this._channel=e.channel,this._codec=e.codec,this._sendDelegate=e.sendDelegate,this._onClose=e.onClose,this._logger=e.logger.withContext({component:`View`}),this._logger.trace(`DefaultView();`),this._emitter=new O(this._logger),this._cachedNodes=this._computeFlatNodes(),this._lastStructuralVersion=this._tree.structuralVersion,this._updateVisibleSnapshot(this._cachedNodes),this._unsubs.push(this._tree.on(`update`,()=>{this._onTreeUpdate()}),this._tree.on(`ably-message`,e=>{this._onTreeAblyMessage(e)}),this._tree.on(`turn`,e=>{this._onTreeTurn(e)}))}getMessages(){return this.flattenNodes().map(e=>e.message)}flattenNodes(){return this._cachedNodes}_computeFlatNodes(){let e=this._tree.flattenNodes(this._resolveSelections());return this._withheldMsgIds.size===0?e:e.filter(e=>!this._withheldMsgIds.has(e.msgId))}hasOlder(){return this._withheldBuffer.length>0||this._hasMoreHistory}async loadOlder(e=100){if(!(this._closed||this._loadingOlder)){this._loadingOlder=!0,this._logger.trace(`DefaultView.loadOlder();`,{limit:e});try{if(this._withheldBuffer.length>0){let t=this._withheldBuffer.splice(-e,e);this._releaseWithheld(t);return}if(!this._hasMoreHistory&&!this._lastHistoryPage){await this._loadFirstPage(e);return}if(!this._hasMoreHistory)return;if(!this._lastHistoryPage?.hasNext()){this._hasMoreHistory=!1;return}let t=await this._lastHistoryPage.next();if(this._closed||!t){t||(this._hasMoreHistory=!1);return}await this._loadAndReveal(t,e)}catch(e){throw this._logger.error(`DefaultView.loadOlder(); failed`,{error:e}),e}finally{this._loadingOlder=!1}}}select(e,t){this._logger.trace(`DefaultView.select();`,{msgId:e,index:t});let n=this._tree.getSiblingNodes(e);if(n.length<=1)return;let r=this._tree.getGroupRoot(e),i=Math.max(0,Math.min(t,n.length-1)),a=n[i];a&&(this._branchSelections.set(r,{kind:`user`,selectedId:a.msgId}),this._logger.debug(`DefaultView.select();`,{msgId:e,index:i,selectedId:a.msgId}),this._cachedNodes=this._computeFlatNodes(),this._updateVisibleSnapshot(this._cachedNodes),this._emitter.emit(`update`))}getSelectedIndex(e){this._logger.trace(`DefaultView.getSelectedIndex();`,{msgId:e});let t=this._tree.getSiblingNodes(e);if(t.length<=1)return 0;let n=this._tree.getGroupRoot(e),r=this._branchSelections.get(n);if(!r||r.kind===`pending`)return t.length-1;let i=t.findIndex(e=>e.msgId===r.selectedId);return i===-1?t.length-1:i}getSiblings(e){return this._tree.getSiblings(e)}hasSiblings(e){return this._tree.hasSiblings(e)}getNode(e){return this._tree.getNode(e)}async send(e,t){if(this._logger.trace(`DefaultView.send();`),this._closed)throw new n.ErrorInfo(`unable to send; view is closed`,E.InvalidArgument,400);let r=this.flattenNodes(),i=await this._sendDelegate(e,t,r);if(t?.forkOf){let e=this._tree.getGroupRoot(t.forkOf);if(i.optimisticMsgIds.length>0){let t=i.optimisticMsgIds.at(-1);t&&(this._branchSelections.set(e,{kind:`auto`,selectedId:t}),this._cachedNodes=this._computeFlatNodes(),this._updateVisibleSnapshot(this._cachedNodes),this._emitter.emit(`update`))}else{this._branchSelections.set(e,{kind:`pending`,turnId:i.turnId}),this._logger.debug(`DefaultView.send(); deferring fork auto-selection`,{forkOf:t.forkOf,groupRoot:e,turnId:i.turnId});let n=this._tree.on(`turn`,t=>{if(t.type!==`x-ably-turn-end`||t.turnId!==i.turnId)return;let r=this._branchSelections.get(e);r?.kind===`pending`&&r.turnId===i.turnId&&this._branchSelections.delete(e),n();let a=this._unsubs.indexOf(n);a!==-1&&this._unsubs.splice(a,1)});this._unsubs.push(n)}}return i}async regenerate(e,t){this._logger.trace(`DefaultView.regenerate();`,{messageId:e});let r=this._tree.getNode(e);if(!r)throw new n.ErrorInfo(`unable to regenerate; message not found in tree: ${e}`,E.InvalidArgument,400);let i=r.parentId;return this.send([],{...t,body:{history:this._getHistoryBefore(e),...t?.body},forkOf:e,parent:i})}async edit(e,t,r){this._logger.trace(`DefaultView.edit();`,{messageId:e});let i=this._tree.getNode(e);if(!i)throw new n.ErrorInfo(`unable to edit; message not found in tree: ${e}`,E.InvalidArgument,400);let a=i.parentId;return this.send(t,{...r,body:{history:this._getHistoryBefore(e),...r?.body},forkOf:e,parent:a})}async update(e,t,r){if(this._closed)throw new n.ErrorInfo(`unable to update; view is closed`,E.InvalidArgument,400);this._logger.trace(`DefaultView.update();`,{msgId:e,eventCount:t.length});let i=[{kind:`event`,msgId:e,events:t}];return this._sendDelegate([],r,this.flattenNodes(),i)}_getHistoryBefore(e){this._logger.trace(`DefaultView._getHistoryBefore();`,{messageId:e});let t=this.flattenNodes(),n=t.findIndex(t=>t.msgId===e);return n===-1?(this._logger.warn(`DefaultView._getHistoryBefore(); target not in visible nodes, returning full list`,{messageId:e}),t):t.slice(0,n)}getActiveTurnIds(){this._logger.trace(`DefaultView.getActiveTurnIds();`);let e=this._tree.getActiveTurnIds();if(this._withheldMsgIds.size===0)return e;let t=new Map;for(let[n,r]of e){let e=new Set;for(let t of r)this._lastVisibleTurnIds.has(t)&&e.add(t);e.size>0&&t.set(n,e)}return t}on(e,t){let n=t;return this._emitter.on(e,n),()=>{this._emitter.off(e,n)}}close(){this._logger.info(`DefaultView.close();`),this._closed=!0,this._loadingOlder=!1;for(let e of this._unsubs)e();this._unsubs.length=0,this._emitter.off(),this._branchSelections.clear(),this._withheldMsgIds.clear(),this._withheldBuffer.length=0,this._onClose?.()}async _loadFirstPage(e){let t=new Set(this._tree.flattenNodes(this._resolveSelections()).map(e=>e.msgId)),n=await V(this._channel,this._codec,{limit:e},this._logger);if(this._closed)return;let{newVisible:r,lastPage:i}=await this._loadUntilVisible(n,e,t);if(this._closed)return;this._lastHistoryPage=i,this._hasMoreHistory=i.hasNext();let a=r.slice(-e),o=r.slice(0,-e);for(let e of o)this._withheldMsgIds.add(e.msgId);this._withheldBuffer.push(...o),this._releaseWithheld(a)}async _loadAndReveal(e,t){let n=new Set(this._tree.flattenNodes(this._resolveSelections()).map(e=>e.msgId)),{newVisible:r,lastPage:i}=await this._loadUntilVisible(e,t,n);if(this._closed)return;this._lastHistoryPage=i,this._hasMoreHistory=i.hasNext();let a=r.slice(-t),o=r.slice(0,-t);for(let e of o)this._withheldMsgIds.add(e.msgId);this._withheldBuffer.push(...o),this._releaseWithheld(a)}_processHistoryPage(e){this._processingHistory=!0;try{for(let t of e.items){let e=t.headers[g];e&&this._tree.upsert(e,t.message,t.headers,t.serial)}for(let t of e.rawMessages)this._tree.emitAblyMessage(t)}finally{this._processingHistory=!1}}async _loadUntilVisible(e,t,n){this._processHistoryPage(e);let r=e,i=()=>{let e=0;for(let t of this._tree.flattenNodes(this._resolveSelections()))n.has(t.msgId)||e++;return e};for(;i()<t&&r.hasNext();){let e=await r.next();if(!e||this._closed)break;this._processHistoryPage(e),r=e}return{newVisible:this._tree.flattenNodes(this._resolveSelections()).filter(e=>!n.has(e.msgId)),lastPage:r}}_releaseWithheld(e){for(let t of e)this._withheldMsgIds.delete(t.msgId);e.length>0&&(this._cachedNodes=this._computeFlatNodes(),this._updateVisibleSnapshot(this._cachedNodes),this._emitter.emit(`update`))}_updateVisibleSnapshot(e){let t=e??this.flattenNodes();this._lastVisibleIds=t.map(e=>e.msgId),this._lastVisibleMessages=t.map(e=>e.message),this._lastVisibleTurnIds=new Set;for(let e of t){let t=e.headers[h];t&&this._lastVisibleTurnIds.add(t)}}_onTreeUpdate(){if(this._processingHistory)return;let e=this._tree.structuralVersion;if(e===this._lastStructuralVersion){this._cachedNodes.some((e,t)=>e.message!==this._lastVisibleMessages[t])&&(this._lastVisibleMessages=this._cachedNodes.map(e=>e.message),this._cachedNodes=[...this._cachedNodes],this._emitter.emit(`update`));return}this._lastStructuralVersion=e,this._pinBranchSelections(),this._resolvePendingSelections();let t=this._computeFlatNodes(),n=t.map(e=>e.msgId),r=t.map(e=>e.message);this._visibleChanged(n,r)&&(this._cachedNodes=t,this._updateVisibleSnapshot(t),this._emitter.emit(`update`))}_resolveSelections(){let e=new Map;for(let[t,n]of this._branchSelections)n.kind!==`pending`&&e.set(t,n.selectedId);return e}_pinBranchSelections(){for(let e of this._lastVisibleIds){if(!this._tree.hasSiblings(e))continue;let t=this._tree.getGroupRoot(e),n=this._branchSelections.get(t);if(n?.kind===`pending`){let r=this._tree.getSiblingNodes(e).at(-1);r&&r.msgId!==e&&r.headers[`x-ably-turn-id`]===n.turnId&&(this._logger.debug(`DefaultView._pinBranchSelections(); auto-selecting pending fork`,{msgId:e,newestId:r.msgId,turnId:n.turnId}),this._branchSelections.set(t,{kind:`auto`,selectedId:r.msgId}));continue}n||this._branchSelections.set(t,{kind:`pinned`,selectedId:e})}}_resolvePendingSelections(){for(let[e,t]of this._branchSelections){if(t.kind!==`pending`)continue;let n=this._tree.getSiblingNodes(e);if(n.length<=1)continue;let r=n.at(-1);!r||r.msgId===e||r.headers[`x-ably-turn-id`]===t.turnId&&(this._logger.debug(`DefaultView._resolvePendingSelections(); resolving off-branch pending`,{groupRoot:e,newestId:r.msgId,turnId:t.turnId}),this._branchSelections.set(e,{kind:`auto`,selectedId:r.msgId}))}}_onTreeAblyMessage(e){let t=F(e)[g];if(!t){this._emitter.emit(`ably-message`,e);return}this._lastVisibleIds.includes(t)&&this._emitter.emit(`ably-message`,e)}_onTreeTurn(e){if(this._lastVisibleTurnIds.has(e.turnId)){this._emitter.emit(`turn`,e);return}e.type===`x-ably-turn-start`&&this._isTurnStartVisible(e)&&(this._lastVisibleTurnIds.add(e.turnId),this._emitter.emit(`turn`,e))}_isTurnStartVisible(e){let{parent:t}=e;return t===void 0?!0:this._lastVisibleIds.includes(t)}_visibleChanged(e,t){if(e.length!==this._lastVisibleIds.length)return!0;for(let[t,n]of e.entries())if(n!==this._lastVisibleIds[t])return!0;for(let[e,n]of t.entries())if(n!==this._lastVisibleMessages[e])return!0;return!1}},U=e=>new H(e),W=()=>{},G=function(e){return e.READY=`ready`,e.CLOSED=`closed`,e}(G||{}),le=class{constructor(e){if(this._ownMsgIds=new Set,this._ownTurnIds=new Set,this._turnMsgIds=new Map,this._turnObservers=new Map,this._closeResolvers=[],this._views=new Set,this._state=G.READY,this._pendingLocalEvents=[],this._channel=e.channel,this._codec=e.codec,this._clientId=e.clientId,this._api=e.api,this._credentials=e.credentials,this._headersFn=typeof e.headers==`function`?e.headers:e.headers?()=>e.headers:void 0,this._bodyFn=typeof e.body==`function`?e.body:e.body?()=>e.body:void 0,this._fetchFn=e.fetch??globalThis.fetch.bind(globalThis),this._logger=(e.logger??j({logLevel:k.Silent})).withContext({component:`ClientTransport`}),this._emitter=new O(this._logger),this._hasAttachedOnce=this._channel.state===`attached`,this._tree=ce(this._logger),this._view=U({tree:this._tree,channel:this._channel,codec:this._codec,sendDelegate:this._internalSend.bind(this),logger:this._logger,onClose:()=>this._views.delete(this._view)}),this._router=oe(this._codec.isTerminal.bind(this._codec),this._logger),this._decoder=this._codec.createDecoder(),this._views.add(this._view),this.tree=this._tree,this.view=this._view,e.messages){let t;for(let n of e.messages){let e=crypto.randomUUID(),r={[g]:e};t&&(r[S]=t),this._tree.upsert(e,n,r),t=e}}this._onMessage=e=>{this._handleMessage(e)},this._attachPromise=this._channel.subscribe(this._onMessage),this._onChannelStateChange=e=>{this._handleChannelStateChange(e)},this._channel.on(this._onChannelStateChange)}_handleMessage(e){if(this._state!==G.CLOSED)try{if(e.name===`x-ably-turn-start`){let t=F(e),n=t[h],r=t[`x-ably-turn-client-id`]??``;if(n){this._tree.trackTurn(n,r);let e=t[S],i=t[C];this._tree.emitTurn({type:T,turnId:n,clientId:r,...e!==void 0&&{parent:e},...i!==void 0&&{forkOf:i}})}this._tree.emitAblyMessage(e);return}if(e.name===`x-ably-turn-end`){let t=F(e),n=t[h],r=t[`x-ably-turn-client-id`]??``,i=t[`x-ably-turn-reason`]??`complete`;if(n){this._router.closeStream(n),this._turnObservers.delete(n),this._tree.untrackTurn(n);let e=this._turnMsgIds.get(n);if(e){for(let t of e)this._ownMsgIds.delete(t);this._turnMsgIds.delete(n)}this._ownTurnIds.delete(n),this._tree.emitTurn({type:ne,turnId:n,clientId:r,reason:i})}this._tree.emitAblyMessage(e);return}let t=this._decoder.decode(e),n=F(e),r=e.serial,i=n[y];if(i){for(let e of t)e.kind===`event`&&this._handleAmendmentEvent(i,e);return}let a=n[h];a&&this._updateTurnObserverHeaders(a,n,r);for(let i of t)i.kind===`message`?this._handleMessageOutput(i.message,n,r,e.action):this._handleEventOutput(i,n);this._tree.emitAblyMessage(e)}catch(e){let t=e instanceof n.ErrorInfo?e:void 0;this._emitter.emit(`error`,new n.ErrorInfo(`unable to process channel message; ${e instanceof Error?e.message:String(e)}`,E.TransportSubscriptionError,500,t))}}_handleMessageOutput(e,t,n,r){let i=t[g];if(i&&this._ownMsgIds.has(i)){this._upsertAndNotify(e,t,n);return}r===`message.create`&&this._upsertAndNotify(e,t,n)}_handleEventOutput(e,t){if(e.kind!==`event`)return;let n=e.event,r=t[h];if(r){if(this._router.route(r,n)){this._accumulateAndEmit(r,e),this._codec.isTerminal(n)&&this._turnObservers.delete(r);return}this._ownTurnIds.has(r)&&!this._turnObservers.has(r)||(this._accumulateAndEmit(r,e),this._codec.isTerminal(n)&&this._turnObservers.delete(r))}}_handleAmendmentEvent(e,t){this._logger.trace(`ClientTransport._handleAmendmentEvent();`,{targetMsgId:e});let n=this._tree.getNode(e);if(!n){this._logger.debug(`ClientTransport._handleAmendmentEvent(); target not found, dropping`,{targetMsgId:e});return}let r=this._codec.createAccumulator();r.initMessage(e,n.message),r.processOutputs([t]);let i=r.messages.at(-1);i&&this._tree.upsert(e,i,n.headers,n.serial)}_handleChannelStateChange(e){if(this._state===G.CLOSED)return;let{current:t,resumed:r}=e;if(t===`attached`&&!this._hasAttachedOnce){this._hasAttachedOnce=!0;return}if(!(t===`failed`||t===`suspended`||t===`detached`||t===`attached`&&!r))return;this._logger.error(`ClientTransport._handleChannelStateChange(); channel continuity lost`,{current:t,resumed:r,previous:e.previous});let i=new n.ErrorInfo(`unable to deliver events; channel continuity lost (${t}${t===`attached`?`, resumed: false`:``})`,E.ChannelContinuityLost,500,e.reason);for(let e of this._ownTurnIds)this._router.errorStream(e,i);this._emitter.emit(`error`,i)}_upsertAndNotify(e,t,n){let r=t[g];r&&this._tree.upsert(r,e,t,n)}_updateTurnObserverHeaders(e,t,n){let r=this._turnObservers.get(e);r?(Object.keys(t).length>0&&Object.assign(r.headers,t),n!==void 0&&(r.serial=n)):this._turnObservers.set(e,{headers:{...t},serial:n,accumulator:this._codec.createAccumulator()})}_accumulateAndEmit(e,t){let n=this._turnObservers.get(e);if(!n)return;let r=n.headers[g];if(r){let e=this._tree.getNode(r);e&&n.accumulator.initMessage(r,e.message)}n.accumulator.processOutputs([t]);let i=n.accumulator.messages;if(i.length===0)return;let a;try{a=structuredClone(i.at(-1))}catch{a=i.at(-1)}if(a){let e=n.headers[g];e&&this._tree.upsert(e,a,{...n.headers},n.serial)}}async _publishCancel(e){this._logger.trace(`ClientTransport._publishCancel();`,{filter:e});let t={};e.turnId?t[b]=e.turnId:e.own?t[x]=`true`:e.clientId?t[te]=e.clientId:e.all&&(t[ee]=`true`),await this._channel.publish({name:w,extras:{headers:t}})}_closeMatchingTurnStreams(e){for(let t of this._getMatchingTurnIds(e))this._router.closeStream(t)}_getMatchingTurnIds(e){let t=new Set,n=this._tree.getActiveTurnIds();if(e.all)for(let e of n.values())for(let n of e)t.add(n);else if(e.own){let e=n.get(this._clientId??``);if(e)for(let n of e)t.add(n)}else if(e.clientId){let r=n.get(e.clientId);if(r)for(let e of r)t.add(e)}else if(e.turnId){for(let r of n.values())if(r.has(e.turnId)){t.add(e.turnId);break}}return t}createView(){if(this._state===G.CLOSED)throw new n.ErrorInfo(`unable to create view; transport is closed`,E.TransportClosed,400);this._logger.trace(`DefaultClientTransport.createView();`);let e=U({tree:this._tree,channel:this._channel,codec:this._codec,sendDelegate:this._internalSend.bind(this),logger:this._logger,onClose:()=>this._views.delete(e)});return this._views.add(e),e}async _internalSend(e,t,r,i){if(this._state===G.CLOSED||(await this._attachPromise,this._state===G.CLOSED))throw new n.ErrorInfo(`unable to send; transport is closed`,E.TransportClosed,400);let a=this._channel.state;if(a!==`attached`&&a!==`attaching`)throw new n.ErrorInfo(`unable to send; channel is ${a}`,E.ChannelNotReady,400);this._logger.trace(`ClientTransport._internalSend();`);let o=Array.isArray(e)?e:[e],s=crypto.randomUUID();this._ownTurnIds.add(s),this._tree.trackTurn(s,this._clientId??``);let c=this._pendingLocalEvents;this._pendingLocalEvents=[],i&&i.length>0&&this._applyEventsToTree(i);let l=[...c,...i??[]],u=new Set,d=[],f=r,p;if(t?.parent===void 0&&!t?.forkOf){let e=f.at(-1);e&&(p=e.msgId)}let m=t?.parent===void 0?p:t.parent;for(let e of o){let n=crypto.randomUUID();this._ownMsgIds.add(n),u.add(n);let r=t?.parent===void 0?p:t.parent,i=ie({role:`user`,turnId:s,msgId:n,turnClientId:this._clientId,parent:r,forkOf:t?.forkOf});this._upsertAndNotify(e,i),d.push({kind:`message`,message:e,msgId:n,parentId:r,forkOf:t?.forkOf,headers:i,serial:void 0}),t?.parent===void 0&&!t?.forkOf&&(p=n)}this._turnMsgIds.set(s,u);let h=this._router.createStream(s),g=this._headersFn?.()??{},_={...this._bodyFn?.()??{},history:f,...t?.body,turnId:s,clientId:this._clientId,messages:d,...t?.forkOf!==void 0&&{forkOf:t.forkOf},...m!==void 0&&{parent:m},...l.length>0&&{events:l}},v={...g,...t?.headers};return this._fetchFn(this._api,{method:`POST`,headers:{"Content-Type":`application/json`,...v},body:JSON.stringify(_),...this._credentials?{credentials:this._credentials}:{}}).then(e=>{if(!e.ok){let t=new n.ErrorInfo(`unable to send; HTTP POST to ${this._api} returned ${String(e.status)} ${e.statusText}`,E.TransportSendFailed,e.status);this._emitter.emit(`error`,t),this._router.errorStream(s,t)}}).catch(e=>{let t=e instanceof n.ErrorInfo?e:void 0,r=new n.ErrorInfo(`unable to send; HTTP POST to ${this._api} failed: ${e instanceof Error?e.message:String(e)}`,E.TransportSendFailed,500,t);this._emitter.emit(`error`,r),this._router.errorStream(s,r)}),{stream:h,turnId:s,cancel:async()=>this.cancel({turnId:s}),optimisticMsgIds:[...u]}}async cancel(e){if(this._state===G.CLOSED)return;let t=e??{own:!0};this._logger.debug(`ClientTransport.cancel();`,{filter:t}),await this._publishCancel(t),this._closeMatchingTurnStreams(t)}stageEvents(e,t){if(this._logger.trace(`ClientTransport.stageEvents();`,{msgId:e,eventCount:t.length}),this._state===G.CLOSED){this._logger.warn(`ClientTransport.stageEvents(); transport is closed`,{msgId:e});return}if(!this._tree.getNode(e)){this._logger.warn(`ClientTransport.stageEvents(); msgId not found in tree`,{msgId:e});return}if(t.length===0)return;let n={kind:`event`,msgId:e,events:t};this._applyEventsToTree([n]),this._pendingLocalEvents.push(n)}stageMessage(e,t){if(this._logger.trace(`ClientTransport.stageMessage();`,{msgId:e}),this._state===G.CLOSED){this._logger.warn(`ClientTransport.stageMessage(); transport is closed`,{msgId:e});return}let n=this._tree.getNode(e);if(!n){this._logger.warn(`ClientTransport.stageMessage(); msgId not found in tree`,{msgId:e});return}this._tree.upsert(e,t,n.headers,n.serial)}_applyEventsToTree(e){for(let t of e){let e=this._tree.getNode(t.msgId);if(!e)continue;let n=t.events.map(e=>({kind:`event`,event:e,messageId:t.msgId})),r=this._codec.createAccumulator();r.initMessage(t.msgId,e.message),r.processOutputs(n);let i=r.messages.at(-1);i&&this._tree.upsert(t.msgId,i,e.headers,e.serial)}}async waitForTurn(e){if(this._state===G.CLOSED)return;let t=e??{own:!0},n=this._getMatchingTurnIds(t);if(n.size!==0)return this._logger.debug(`ClientTransport.waitForTurn();`,{turnIds:[...n]}),new Promise(e=>{let t=!1,r=()=>{if(t)return;t=!0,i();let n=this._closeResolvers.indexOf(r);n!==-1&&this._closeResolvers.splice(n,1),e()},i=this._tree.on(`turn`,e=>{e.type===`x-ably-turn-end`&&(n.delete(e.turnId),n.size===0&&r())});this._closeResolvers.push(r)})}on(e,t){if(this._state===G.CLOSED)return W;let n=t;return this._emitter.on(e,n),()=>{this._emitter.off(e,n)}}async close(e){if(this._state!==G.CLOSED){if(this._state=G.CLOSED,this._logger.info(`ClientTransport.close();`),e?.cancel){try{await this._publishCancel(e.cancel)}catch{}this._closeMatchingTurnStreams(e.cancel)}this._channel.unsubscribe(this._onMessage),this._channel.off(this._onChannelStateChange);for(let e of this._ownTurnIds)this._router.closeStream(e);this._turnObservers.clear(),this._emitter.off();for(let e of this._views)e.close();this._views.clear();for(let e of this._closeResolvers)e();this._closeResolvers.length=0,this._ownTurnIds.clear(),this._ownMsgIds.clear(),this._turnMsgIds.clear()}}},ue=e=>new le(e),de=({channelName:e,children:a,...o})=>{let{channel:s}=(0,r.useChannel)({channelName:e}),c=(0,t.useRef)(void 0),l=(0,t.useRef)(e),u=(0,t.useRef)([]),d=(0,t.useRef)(!1),m=(0,t.useRef)(void 0);if(!(c.current||m.current)||l.current!==e){l.current=e,c.current&&u.current.push(c.current);try{c.current=ue({...o,channel:s}),m.current=void 0}catch(e){c.current=void 0,m.current=e instanceof n.ErrorInfo?e:new n.ErrorInfo(`Unknown error while creating transport`,E.BadRequest,400)}}let h=(0,t.useContext)(f),g=c.current,_=m.current,v=(0,t.useMemo)(()=>({transport:g,error:_}),[g,_]),y=(0,t.useMemo)(()=>({...h,[e]:v}),[e,h,v]);return(0,t.useEffect)(()=>()=>{for(let e of u.current)e.close()},[e]),(0,t.useEffect)(()=>(d.current=!1,()=>{d.current=!0,Promise.resolve().then(()=>{d.current&&c.current?.close()})}),[]),(0,i.jsx)(f.Provider,{value:y,children:(0,i.jsx)(p.Provider,{value:v,children:a})})},K=e=>(0,i.jsx)(r.ChannelProvider,{channelName:e.channelName,children:(0,i.jsx)(de,{...e})}),q=({transport:e,skip:n}={})=>{let r=(0,t.useContext)(p),i=n?void 0:e??r?.transport,[a,o]=(0,t.useState)([]),s=(0,t.useRef)([]);return(0,t.useEffect)(()=>{if(s.current=[],o([]),i)return i.tree.on(`ably-message`,e=>{let t=[...s.current,e];s.current=t,o(t)})},[i]),a},J=({transport:e}={})=>{let n=(0,t.useContext)(p),r=e??n?.transport,[i,a]=(0,t.useState)(()=>new Map);return(0,t.useEffect)(()=>{if(r)return a(r.tree.getActiveTurnIds()),r.tree.on(`turn`,e=>{a(t=>{let n=new Map(t);if(e.type===`x-ably-turn-start`){let t=new Set(n.get(e.clientId));t.add(e.turnId),n.set(e.clientId,t)}else{let t=n.get(e.clientId);if(t){let r=new Set(t);r.delete(e.turnId),r.size===0?n.delete(e.clientId):n.set(e.clientId,r)}}return n})})},[r]),i},Y={get tree(){throw new n.ErrorInfo(`unable to access tree; hook is skipped`,E.InvalidArgument,400)},get view(){throw new n.ErrorInfo(`unable to access view; hook is skipped`,E.InvalidArgument,400)},createView:()=>{throw new n.ErrorInfo(`unable to create view; hook is skipped`,E.InvalidArgument,400)},cancel:()=>{throw new n.ErrorInfo(`unable to cancel; hook is skipped`,E.InvalidArgument,400)},stageEvents:()=>{throw new n.ErrorInfo(`unable to stage events; hook is skipped`,E.InvalidArgument,400)},stageMessage:()=>{throw new n.ErrorInfo(`unable to stage message; hook is skipped`,E.InvalidArgument,400)},waitForTurn:()=>{throw new n.ErrorInfo(`unable to wait for turn; hook is skipped`,E.InvalidArgument,400)},on:()=>{throw new n.ErrorInfo(`unable to subscribe; hook is skipped`,E.InvalidArgument,400)},close:()=>{throw new n.ErrorInfo(`unable to close; hook is skipped`,E.InvalidArgument,400)}},X=({channelName:e,skip:r,onError:i}={})=>{let a=(0,t.useContext)(f),o=(0,t.useContext)(p),s=(0,t.useRef)(i);s.current=i;let c=r?void 0:e===void 0?o?.transport:a[e]?.transport;if((0,t.useEffect)(()=>{if(c)return c.on(`error`,e=>{s.current?.(e)})},[c]),r)return{transport:Y};if(e!==void 0){let t=a[e];return t?t.transport?{transport:t.transport}:{transport:Y,transportError:t.error}:{transport:Y,transportError:new n.ErrorInfo(`unable to use transport; no TransportProvider found for channelName "${e}"`,E.BadRequest,400)}}return o?o.transport?{transport:o.transport}:{transport:Y,transportError:o.error}:{transport:Y,transportError:new n.ErrorInfo(`unable to use transport; no TransportProvider found in the tree`,E.BadRequest,400)}},Z=({transport:e,view:r,limit:i,skip:a}={})=>{let o=(0,t.useContext)(p),s=a?void 0:e??o?.transport,c=a?void 0:r??s?.view,[l,u]=(0,t.useState)(()=>c?.flattenNodes()??[]),[d,f]=(0,t.useState)(()=>c?.hasOlder()??!1),[m,h]=(0,t.useState)(!1),[g,_]=(0,t.useState)(),v=(0,t.useRef)(!1),y=i!==void 0,b=(0,t.useRef)(!1);(0,t.useEffect)(()=>{if(!c){u([]),f(!1),_(void 0);return}return b.current=!1,u(c.flattenNodes()),f(c.hasOlder()),_(void 0),c.on(`update`,()=>{u(c.flattenNodes()),f(c.hasOlder())})},[c]);let x=(0,t.useCallback)(async()=>{if(!(!c||v.current)){v.current=!0,h(!0);try{await c.loadOlder(i),_(void 0)}catch(e){e instanceof n.ErrorInfo?_(e):_(new n.ErrorInfo(`Unknown error loading older messages`,E.BadRequest,400))}finally{v.current=!1,h(!1)}}},[c,i]);return(0,t.useEffect)(()=>{!y||b.current||!c||(b.current=!0,x())},[y,c,x]),{messages:(0,t.useMemo)(()=>l.map(e=>e.message),[l]),nodes:l,hasOlder:d,loading:m,loadError:g,loadOlder:x,select:(0,t.useCallback)((e,t)=>{c?.select(e,t)},[c]),getSelectedIndex:(0,t.useCallback)(e=>c?.getSelectedIndex(e)??0,[c]),getSiblings:(0,t.useCallback)(e=>c?.getSiblings(e)??[],[c]),hasSiblings:(0,t.useCallback)(e=>c?.hasSiblings(e)??!1,[c]),getNode:(0,t.useCallback)(e=>c?.getNode(e),[c]),send:(0,t.useCallback)(async(e,t)=>{if(!c)throw new n.ErrorInfo(`unable to send; view is not available`,E.InvalidArgument,400);return c.send(e,t)},[c]),regenerate:(0,t.useCallback)(async(e,t)=>{if(!c)throw new n.ErrorInfo(`unable to regenerate; view is not available`,E.InvalidArgument,400);return c.regenerate(e,t)},[c]),edit:(0,t.useCallback)(async(e,t,r)=>{if(!c)throw new n.ErrorInfo(`unable to edit; view is not available`,E.InvalidArgument,400);return c.edit(e,t,r)},[c]),update:(0,t.useCallback)(async(e,t,r)=>{if(!c)throw new n.ErrorInfo(`unable to update; view is not available`,E.InvalidArgument,400);return c.update(e,t,r)},[c])}},Q=({transport:e,limit:n,skip:r}={})=>{let i=(0,t.useContext)(p),a=r?void 0:e??i?.transport,[o,s]=(0,t.useState)();return(0,t.useEffect)(()=>{if(!a){s(void 0);return}let e=a.createView();return s(e),()=>{e.close()}},[a]),Z({view:o,limit:n,skip:r})},$=({transport:e}={})=>{let n=(0,t.useContext)(p),r=e??n?.transport;return{getSiblings:(0,t.useCallback)(e=>r?.tree.getSiblings(e)??[],[r]),hasSiblings:(0,t.useCallback)(e=>r?.tree.hasSiblings(e)??!1,[r]),getNode:(0,t.useCallback)(e=>r?.tree.getNode(e),[r])}};e.NearestTransportContext=p,e.TransportProvider=K,e.createTransportHooks=()=>({TransportProvider:K,useClientTransport:e=>X(e??{}),useView:e=>Z(e??{}),useActiveTurns:e=>J(e??{}),useTree:e=>$(e??{}),useAblyMessages:e=>q(e??{}),useCreateView:e=>Q(e??{})}),e.useAblyMessages=q,e.useActiveTurns=J,e.useClientTransport=X,e.useCreateView=Q,e.useTree=$,e.useView=Z});
2
2
  //# sourceMappingURL=ably-ai-transport-react.umd.cjs.map