owlservable 0.2.10 → 0.2.11

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/auto.cjs CHANGED
@@ -1 +1 @@
1
- require('./index.cjs').init()
1
+ require('./index.cjs').init({ save: true })
package/auto.js CHANGED
@@ -1,2 +1,2 @@
1
1
  import { init } from './index.js'
2
- init()
2
+ init({ save: true })
package/dashboard.html CHANGED
@@ -227,20 +227,21 @@ function detailHtml(r){
227
227
  }
228
228
 
229
229
  function addRow(r,prepend){
230
- total++;if(!r.status||r.error)errs++;sumMs+=r.latency||0;
230
+ if(!r.pending){total++;if(!r.status||r.error)errs++;sumMs+=r.latency||0;}
231
231
  if(r.tokens)totalTok+=r.tokens.total||0;
232
232
  storeSize=Math.min(storeSize+1,500);
233
233
  nReq.textContent=total;nErr.textContent=errs;
234
- nLat.textContent=fms(Math.round(sumMs/total));
234
+ nLat.textContent=total?fms(Math.round(sumMs/total)):'—';
235
235
  nTok.textContent=fn(totalTok);nStore.textContent=storeSize+'/500';
236
236
  var method=r.method||'GET',parts=splitUrl(r.url||'');
237
- var sTxt=r.status||(r.error?'ERR':'—');
237
+ var statusHtml=r.pending?'<span class="pending" title="in-flight"></span>':'<span class="badge '+sc(r.status)+'">'+esc(r.status||(r.error?'ERR':'—'))+'</span>';
238
+ var latHtml=r.pending?'<span class="muted">…</span>':fms(r.latency||0);
238
239
  var tr=document.createElement('tr');tr.className='req new';tr.dataset.id=r.id;
239
240
  tr.innerHTML=
240
241
  '<td class="c-time muted">'+ftime(r.timestamp)+'</td>'+
241
242
  '<td class="c-method"><span class="'+esc(method)+'">'+esc(method)+'</span></td>'+
242
- '<td class="c-status"><span class="badge '+sc(r.status)+'">'+esc(sTxt)+'</span></td>'+
243
- '<td class="c-lat muted">'+fms(r.latency||0)+'</td>'+
243
+ '<td class="c-status">'+statusHtml+'</td>'+
244
+ '<td class="c-lat muted">'+latHtml+'</td>'+
244
245
  '<td class="c-tok">'+tokHtml(r)+'</td>'+
245
246
  '<td class="c-url" title="'+esc(r.url||'')+'"><span class="muted">'+esc(parts.host)+'</span>'+esc(parts.path)+'</td>';
246
247
  var dtd=document.createElement('td');dtd.colSpan=6;dtd.innerHTML=detailHtml(r);
@@ -258,7 +259,15 @@ function addRow(r,prepend){
258
259
  function applyUpdate(id,patch){
259
260
  var e=byId[id];if(!e)return;
260
261
  var prevTok=(e.data.tokens&&e.data.tokens.total)||0;
262
+ var wasPending=e.data.pending;
261
263
  Object.assign(e.data,patch);
264
+ if(wasPending&&!e.data.pending){
265
+ total++;if(!e.data.status||e.data.error)errs++;sumMs+=e.data.latency||0;
266
+ nReq.textContent=total;nErr.textContent=errs;
267
+ nLat.textContent=total?fms(Math.round(sumMs/total)):'—';
268
+ e.tr.querySelector('.c-status').innerHTML='<span class="badge '+sc(e.data.status)+'">'+esc(e.data.status||(e.data.error?'ERR':'—'))+'</span>';
269
+ e.tr.querySelector('.c-lat').innerHTML=fms(e.data.latency||0);
270
+ }
262
271
  if(patch.tokens){
263
272
  totalTok+=(patch.tokens.total||0)-prevTok;
264
273
  nTok.textContent=fn(totalTok);
@@ -364,7 +373,7 @@ function poll(){
364
373
  }
365
374
  reqs.forEach(function(r){
366
375
  if(!byId[r.id]){addRow(r,true);}
367
- else if(byId[r.id].data.metaPending&&!r.metaPending){applyUpdate(r.id,r);}
376
+ else{var e=byId[r.id];if((e.data.pending&&!r.pending)||(e.data.metaPending&&!r.metaPending)){applyUpdate(r.id,r);}}
368
377
  });
369
378
  }).catch(function(){});
370
379
  }
package/index.cjs CHANGED
@@ -165,18 +165,19 @@ function patchFetch() {
165
165
  reqBody = bodyFromInit(init?.body ?? null)
166
166
  } catch (_) {}
167
167
 
168
+ const r = addRequest({ url, method, status: null, latency: null, reqBody, metaPending: false, pending: true })
168
169
  const start = Date.now()
169
170
  try {
170
171
  const res = await orig.call(this, input, init)
171
172
  const ct = res.headers.get('content-type') || ''
172
173
  const isJson = ct.includes('application/json')
173
174
  const isSse = ct.includes('text/event-stream')
174
- const r = addRequest({ url, method, status: res.status, latency: Date.now() - start, reqBody, metaPending: isJson || isSse })
175
+ updateRequest(r.id, { status: res.status, latency: Date.now() - start, pending: false, metaPending: isJson || isSse })
175
176
  if (r && isJson) handleJsonResponse(r, () => res.clone().text())
176
177
  if (r && isSse) handleSseResponse(r, () => res.clone().text())
177
178
  return res
178
179
  } catch (err) {
179
- try { addRequest({ url, method, status: 0, latency: Date.now() - start, reqBody, error: err.message }) } catch (_) {}
180
+ try { updateRequest(r.id, { status: 0, latency: Date.now() - start, pending: false, error: err.message }) } catch (_) {}
180
181
  throw err
181
182
  }
182
183
  }
@@ -198,6 +199,7 @@ function patchHttpModule(mod, protocol) {
198
199
  } catch (_) {}
199
200
 
200
201
  const req = orig.apply(mod, args)
202
+ const r = addRequest({ url, method: method.toUpperCase(), status: null, latency: null, reqBody: null, metaPending: false, pending: true })
201
203
  const reqChunks = []; let reqSize = 0
202
204
  const origWrite = req.write
203
205
  req.write = function(chunk, encoding, cb) {
@@ -215,8 +217,7 @@ function patchHttpModule(mod, protocol) {
215
217
  const reqBody = reqSize > 0 ? reqChunks.join('').slice(0, MAX_REQ_BODY) : null
216
218
  const ct = res.headers['content-type'] || ''
217
219
  const isJson = ct.includes('application/json')
218
- const isSse = ct.includes('text/event-stream')
219
- const r = addRequest({ url, method: method.toUpperCase(), status: res.statusCode, latency: Date.now() - start, reqBody, metaPending: isJson })
220
+ updateRequest(r.id, { status: res.statusCode, latency: Date.now() - start, reqBody, pending: false, metaPending: isJson })
220
221
  if (r && isJson) {
221
222
  try {
222
223
  const chunks = []; let size = 0
@@ -227,12 +228,11 @@ function patchHttpModule(mod, protocol) {
227
228
  res.once('error', reject)
228
229
  })
229
230
  if (isJson) handleJsonResponse(r, getText)
230
- if (isSse) handleSseResponse(r, getText)
231
231
  } catch (_) { updateRequest(r.id, { metaPending: false }) }
232
232
  }
233
233
  })
234
234
  req.once('error', err => {
235
- try { addRequest({ url, method: method.toUpperCase(), status: 0, latency: Date.now() - start, error: err.message }) } catch (_) {}
235
+ try { updateRequest(r.id, { status: 0, latency: Date.now() - start, pending: false, error: err.message }) } catch (_) {}
236
236
  })
237
237
  } catch (_) {}
238
238
 
package/index.js CHANGED
@@ -165,18 +165,19 @@ function patchFetch() {
165
165
  reqBody = bodyFromInit(init?.body ?? null)
166
166
  } catch (_) {}
167
167
 
168
+ const r = addRequest({ url, method, status: null, latency: null, reqBody, metaPending: false, pending: true })
168
169
  const start = Date.now()
169
170
  try {
170
171
  const res = await orig.call(this, input, init)
171
172
  const ct = res.headers.get('content-type') || ''
172
173
  const isJson = ct.includes('application/json')
173
174
  const isSse = ct.includes('text/event-stream')
174
- const r = addRequest({ url, method, status: res.status, latency: Date.now() - start, reqBody, metaPending: isJson || isSse })
175
+ updateRequest(r.id, { status: res.status, latency: Date.now() - start, pending: false, metaPending: isJson || isSse })
175
176
  if (r && isJson) handleJsonResponse(r, () => res.clone().text())
176
177
  if (r && isSse) handleSseResponse(r, () => res.clone().text())
177
178
  return res
178
179
  } catch (err) {
179
- try { addRequest({ url, method, status: 0, latency: Date.now() - start, reqBody, error: err.message }) } catch (_) {}
180
+ try { updateRequest(r.id, { status: 0, latency: Date.now() - start, pending: false, error: err.message }) } catch (_) {}
180
181
  throw err
181
182
  }
182
183
  }
@@ -198,6 +199,7 @@ function patchHttpModule(mod, protocol) {
198
199
  } catch (_) {}
199
200
 
200
201
  const req = orig.apply(mod, args)
202
+ const r = addRequest({ url, method: method.toUpperCase(), status: null, latency: null, reqBody: null, metaPending: false, pending: true })
201
203
  const reqChunks = []; let reqSize = 0
202
204
  const origWrite = req.write
203
205
  req.write = function(chunk, encoding, cb) {
@@ -215,8 +217,7 @@ function patchHttpModule(mod, protocol) {
215
217
  const reqBody = reqSize > 0 ? reqChunks.join('').slice(0, MAX_REQ_BODY) : null
216
218
  const ct = res.headers['content-type'] || ''
217
219
  const isJson = ct.includes('application/json')
218
- const isSse = ct.includes('text/event-stream')
219
- const r = addRequest({ url, method: method.toUpperCase(), status: res.statusCode, latency: Date.now() - start, reqBody, metaPending: isJson })
220
+ updateRequest(r.id, { status: res.statusCode, latency: Date.now() - start, reqBody, pending: false, metaPending: isJson })
220
221
  if (r && isJson) {
221
222
  try {
222
223
  const chunks = []; let size = 0
@@ -227,12 +228,11 @@ function patchHttpModule(mod, protocol) {
227
228
  res.once('error', reject)
228
229
  })
229
230
  if (isJson) handleJsonResponse(r, getText)
230
- if (isSse) handleSseResponse(r, getText)
231
231
  } catch (_) { updateRequest(r.id, { metaPending: false }) }
232
232
  }
233
233
  })
234
234
  req.once('error', err => {
235
- try { addRequest({ url, method: method.toUpperCase(), status: 0, latency: Date.now() - start, error: err.message }) } catch (_) {}
235
+ try { updateRequest(r.id, { status: 0, latency: Date.now() - start, pending: false, error: err.message }) } catch (_) {}
236
236
  })
237
237
  } catch (_) {}
238
238
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "owlservable",
3
- "version": "0.2.10",
3
+ "version": "0.2.11",
4
4
  "description": "Minimalist Observability Platform. Zero config, zero dependencies.",
5
5
  "type": "module",
6
6
  "main": "index.js",