@volter/teams 0.2.32 → 0.2.34

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.
package/http-client.mjs CHANGED
@@ -28,7 +28,7 @@ export class TeamsClient {
28
28
  for(let attempt=0;attempt<5;attempt++) { try {
29
29
  const response=await this.fetch(this.server+path,{method,signal,redirect:'manual',headers:{Accept:'application/json',Authorization:`Bearer ${this.credential}`,...callerHeader(caller),...(body!==undefined?{'Content-Type':'application/json'}:{}),...(key?{'Idempotency-Key':key}:{}),...(ifMatch!==undefined?{'If-Match':String(ifMatch)}:{})},body:body===undefined?undefined:JSON.stringify(SIGN_IN.test(path)?body:redactValue(body))});
30
30
  if(response.type==='opaqueredirect'||(response.status>=300&&response.status<400))throw Object.assign(new Error('cross-origin redirects are refused'),{code:'invalid_request',status:400,retryable:false});
31
- const value=response.status===204?null:await response.json();if(!response.ok)throw Object.assign(new Error(value?.error?.message??`HTTP ${response.status}`),value?.error,{status:response.status});return value;
31
+ const value=response.status===204?null:await response.json();if(!response.ok){const message=answerMessage(value?.error?.message??`HTTP ${response.status}`,response,value?.error);throw Object.assign(new Error(message),value?.error,{status:response.status,message});}return value;
32
32
  } catch(error) { last=error;if(method!=='GET'||signal?.aborted||!(!error.status||error.retryable)||attempt===4)throw error;await retryWait(delay,signal);delay=Math.min(delay*2,5000); } }
33
33
  throw last;
34
34
  }
@@ -230,7 +230,14 @@ async function* attachmentEvents(root, base, attachment, { signal } = {}) {
230
230
  }
231
231
  const query=q=>{const p=new URLSearchParams();for(const [k,v]of Object.entries(q))if(v!==undefined)p.set(k,String(v));return p.size?'?'+p:'';};
232
232
  const retryWait=(delay,signal)=>new Promise((resolve,reject)=>{const done=()=>{signal?.removeEventListener('abort',abort);resolve();},timer=setTimeout(done,delay),abort=()=>{clearTimeout(timer);signal?.removeEventListener('abort',abort);reject(signal.reason);};signal?.addEventListener('abort',abort,{once:true});});
233
- async function sseError(response){let value=null;try{value=await response.json();}catch{}return Object.assign(new Error(value?.error?.message??`SSE HTTP ${response.status}`),value?.error,{status:response.status,retryable:value?.error?.retryable??(response.status===429||response.status>=500),retryAfterMs:retryAfterMs(value?.error,response)});}
233
+ // A server failure (5xx) says what the Worker's own log can be read by: its status, its request id and Cloudflare's
234
+ // ray (2026-10-06: "Teams server is temporarily unavailable" with no way to tell which request, or why, failed).
235
+ function answerMessage(message,response,error){
236
+ if(response.status<500)return message;
237
+ const ray=response.headers?.get?.('cf-ray');const id=error?.request_id??response.headers?.get?.('x-request-id');
238
+ return `${message} (HTTP ${response.status}${id?`, request ${id}`:''}${ray?`, cf-ray ${ray}`:''})`;
239
+ }
240
+ async function sseError(response){let value=null;try{value=await response.json();}catch{}const message=answerMessage(value?.error?.message??`SSE HTTP ${response.status}`,response,value?.error);return Object.assign(new Error(message),value?.error,{message,status:response.status,retryable:value?.error?.retryable??(response.status===429||response.status>=500),retryAfterMs:retryAfterMs(value?.error,response)});}
234
241
  // How long a refused stream waits before asking again: the server's retry_after (its body, else Retry-After), at least
235
242
  // 5 s; a refusal that names none waits 30 s. Null for an error that is not a refusal for load.
236
243
  export function retryAfterMs(error,response=null){
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/teams",
3
- "version": "0.2.32",
3
+ "version": "0.2.34",
4
4
  "type": "module",
5
5
  "description": "Volter Teams, the neutral team plane: machine identity and daemon core, the local door and server link, admission from machine grants, product doors, and the Teams server's neutral routes (company RFC 0008).",
6
6
  "license": "MIT",
@@ -603,7 +603,7 @@ export async function deliverSessionRoomNotice(api, access) {
603
603
  return await new Promise((resolve, reject) => {
604
604
  let text = '';
605
605
  const timeout = setTimeout(() => { reject(Object.assign(new Error('Room notice delivery not confirmed'),{status:503,code:'native_delivery_unconfirmed'})); stream.close('timeout'); }, 60000);
606
- // Channel data is already text; the machine writes remote-deliver's JSON reply as a string.
606
+ // Channel data is already text; the machine's mail door writes its JSON reply as a string.
607
607
  stream.on('data', chunk => { text += chunk; });
608
608
  stream.on('close', () => {
609
609
  clearTimeout(timeout);