@volter/supercode-teams 0.2.161 → 0.2.163

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/supercode-teams",
3
- "version": "0.2.161",
3
+ "version": "0.2.163",
4
4
  "type": "module",
5
5
  "description": "A machine daemon serving this machine's doors, and a local or remote Teams server for shared session discovery, OpenTelemetry ingestion and access to enrolled machines.",
6
6
  "license": "MIT",
@@ -0,0 +1,31 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { MESSAGE_AT, OPEN_REVISION } from '@volter/teams/server/migrations';
3
+ import { normalizeSearch, textFromContent } from './catalog.mjs';
4
+
5
+ export function applyCaptureMessages({ get, run }, capture, revision) {
6
+ const { teamId, sessionId, sourceId, captureId, harness, nativeId, currentRevision, carriedCount, parts, messageNamespace } = capture;
7
+ let ordinal = carriedCount;
8
+ for (let index = 0; index < parts; index++) {
9
+ const heldPart = get('SELECT payload_json FROM capture_parts WHERE team_id=? AND capture_id=? AND part_index=?', [teamId, captureId, index]);
10
+ if (!heldPart) throw Object.assign(new Error('capture parts incomplete'), { status: 409, code: 'batch_gap' });
11
+ const part = JSON.parse(heldPart.payload_json);
12
+ for (const message of part.messages) {
13
+ const value = JSON.stringify(message.value);
14
+ const old = currentRevision == null ? null : get(`SELECT revision,source_id,native_key,recorded_at,value_json,until_revision FROM messages m WHERE m.team_id=? AND m.session_id=? AND m.ordinal=? AND ${MESSAGE_AT()} LIMIT 1`, [teamId, sessionId, ordinal, currentRevision, currentRevision]);
15
+ if (old && old.source_id === sourceId && old.native_key === message.native_key && old.recorded_at === message.recorded_at && old.value_json === value) {
16
+ if (old.until_revision !== OPEN_REVISION) run('UPDATE messages SET until_revision=? WHERE team_id=? AND session_id=? AND revision=? AND ordinal=?', [OPEN_REVISION, teamId, sessionId, old.revision, ordinal]);
17
+ ordinal++;
18
+ continue;
19
+ }
20
+ if (old?.until_revision === OPEN_REVISION) run('UPDATE messages SET until_revision=? WHERE team_id=? AND session_id=? AND revision=? AND ordinal=?', [revision, teamId, sessionId, old.revision, ordinal]);
21
+ let messageId = get('SELECT id FROM message_ids WHERE team_id=? AND source_id=? AND harness=? AND native_id=? AND native_key=?', [teamId, sourceId, harness, nativeId, message.native_key])?.id;
22
+ if (!messageId) {
23
+ messageId = `msg_${createHash('sha256').update(`${messageNamespace}\0${message.native_key}`).digest('hex').slice(0, 32)}`;
24
+ run('INSERT INTO message_ids(team_id,source_id,harness,native_id,native_key,id) VALUES (?,?,?,?,?,?)', [teamId, sourceId, harness, nativeId, message.native_key, messageId]);
25
+ }
26
+ run('INSERT INTO messages(team_id,session_id,revision,ordinal,id,source_id,native_key,recorded_at,value_json,search_text,until_revision) VALUES (?,?,?,?,?,?,?,?,?,?,?)', [teamId, sessionId, revision, ordinal++, messageId, sourceId, message.native_key, message.recorded_at, value, normalizeSearch(textFromContent(message.value.content)), OPEN_REVISION]);
27
+ }
28
+ }
29
+ if (currentRevision != null) run('UPDATE messages SET until_revision=? WHERE team_id=? AND session_id=? AND ordinal>=? AND revision<=? AND until_revision=?', [revision, teamId, sessionId, ordinal, currentRevision, OPEN_REVISION]);
30
+ return { messages: ordinal - carriedCount };
31
+ }
@@ -10,8 +10,8 @@ import { createHash } from 'node:crypto';
10
10
  import { bearer, hashToken, canRead, canManage, isAdmin } from '@volter/teams/server/auth';
11
11
  import { storageReport } from './storage-report.mjs';
12
12
  import { validateListQuery, validateSearchQuery, validateReadQuery, validateCaptureBegin, validateCapturePart, canonicalJson } from '../contracts/index.mjs';
13
- import { normalizeSearch, textFromContent, cursorHash, cursorToken } from './catalog.mjs';
14
- import { captureDigest, captureMessages, handleOtlpRoute, sha256, validateArtifactName } from './ingest.mjs';
13
+ import { normalizeSearch, cursorHash, cursorToken } from './catalog.mjs';
14
+ import { handleOtlpRoute, sha256, validateArtifactName } from './ingest.mjs';
15
15
  import { handleCatalogEvents, handleSessionEvents, sessionNames } from './event-routes.mjs';
16
16
  import { exact } from '@volter/teams/server/request-json';
17
17
  import { MESSAGE_AT, OPEN_REVISION } from '@volter/teams/server/migrations';
@@ -203,7 +203,10 @@ const ACTIVITY_FRESH_MS=60000;
203
203
  /** The connector's latest fresh native turn report; stale or unrecognized reports remain unknown. */
204
204
  async function activityOf(api,teamId,sessionId){
205
205
  const row=await api.store.one('SELECT a.turn,a.since,a.observed_at FROM session_activity a JOIN origins o ON o.team_id=a.team_id AND o.source_id=a.source_id AND o.harness=a.harness AND o.native_id=a.native_id WHERE a.team_id=? AND o.deleted_at IS NULL AND o.session_id IN (SELECT id FROM sessions WHERE team_id=? AND (id=? OR canonical_id=?)) ORDER BY a.observed_at DESC LIMIT 1',[teamId,teamId,sessionId,sessionId]);
206
- return row&&['working','idle','needs_input'].includes(row.turn)&&api.clock.nowMs()-row.observed_at<ACTIVITY_FRESH_MS?{state:row.turn,since:row.since??row.observed_at,observedAt:row.observed_at}:{state:'unknown'};
206
+ // Unknown is a fresh server determination too: give it an ordering time so
207
+ // an older known report cannot restore Working while the source is stale.
208
+ const now=api.clock.nowMs();
209
+ return row&&['working','idle','needs_input'].includes(row.turn)&&now-row.observed_at<ACTIVITY_FRESH_MS?{state:row.turn,since:row.since??row.observed_at,observedAt:row.observed_at}:{state:'unknown',observedAt:now};
207
210
  }
208
211
  async function sessionDescriptor(api,res,auth,id,requestId){
209
212
  const row=await api.store.authorizedSession({teamId:auth.team_id,principalId:auth.principal_id,credentialId:auth.credential_id,ref:id,now:api.clock.nowMs(),bound:auth.bound});
@@ -325,7 +328,26 @@ async function artifactChunk(api,req,res,auth,sourceId,uploadId,index,requestId)
325
328
  ],{status:200,body:response,targetId:uploadId});
326
329
  send(res,200,response,requestId);
327
330
  }
328
- async function captureCommit(api,req,res,auth,sourceId,captureId,requestId){const source=await sourceAuth(api,auth,sourceId);const commit=await parseJson(req);exact(commit,['capture_id','parts','digest','title','repository','reported_user','recorded_activity_at','parent_native_id','coverage','artifacts','native_bundle']);if(commit.capture_id!==captureId||!Number.isSafeInteger(commit.parts)||commit.parts<1)fail(400,'invalid_request','invalid commit');const cap=await api.store.one('SELECT * FROM captures WHERE team_id=? AND id=? AND source_id=?',[auth.team_id,captureId,sourceId]);if(await expireStaging(api,auth.team_id,sourceId,captureId,'captures',cap))fail(409,'resync_required','capture reservation expired');if(!cap)fail(404,'not_found','capture not found');if(cap.state==='committed'){const receipt=JSON.parse(cap.receipt_json);if(receipt.digest!==commit.digest)fail(409,'capture_conflict','commit replay differs');receipt.duplicate=true;return send(res,200,result(api,auth,receipt),requestId);}const rows=await api.store.query('SELECT * FROM capture_parts WHERE team_id=? AND capture_id=? ORDER BY part_index',[auth.team_id,captureId]);if(rows.length!==commit.parts)fail(409,'batch_gap','capture parts incomplete');const begin=JSON.parse(cap.begin_json);if(source.kind==='connector'){const rule=await api.store.one('SELECT * FROM sync_rules WHERE team_id=? AND id=? AND source_id=? AND machine_id=?',[auth.team_id,begin.rule_id,sourceId,auth.machine_id]);if(!rule||rule.state!=='active'||rule.revision!==begin.rule_revision||rule.visibility!==begin.visibility)fail(rule?.state==='paused'?409:403,rule?.state==='paused'?'source_paused':'forbidden','sync rule changed before commit');}const parts=rows.map(x=>JSON.parse(x.payload_json));if(captureDigest(begin,parts,commit)!==commit.digest)fail(409,'capture_conflict','capture digest differs');let messages=captureMessages(parts);if(messages.length>100000)fail(413,'request_too_large','capture contains too many messages');
331
+ async function captureCommit(api,req,res,auth,sourceId,captureId,requestId){const source=await sourceAuth(api,auth,sourceId);const commit=await parseJson(req);exact(commit,['capture_id','parts','digest','title','repository','reported_user','recorded_activity_at','parent_native_id','coverage','artifacts','native_bundle']);if(commit.capture_id!==captureId||!Number.isSafeInteger(commit.parts)||commit.parts<1)fail(400,'invalid_request','invalid commit');const cap=await api.store.one('SELECT * FROM captures WHERE team_id=? AND id=? AND source_id=?',[auth.team_id,captureId,sourceId]);if(await expireStaging(api,auth.team_id,sourceId,captureId,'captures',cap))fail(409,'resync_required','capture reservation expired');if(!cap)fail(404,'not_found','capture not found');if(cap.state==='committed'){const receipt=JSON.parse(cap.receipt_json);if(receipt.digest!==commit.digest)fail(409,'capture_conflict','commit replay differs');receipt.duplicate=true;return send(res,200,result(api,auth,receipt),requestId);}const begin=JSON.parse(cap.begin_json);if(source.kind==='connector'){const rule=await api.store.one('SELECT * FROM sync_rules WHERE team_id=? AND id=? AND source_id=? AND machine_id=?',[auth.team_id,begin.rule_id,sourceId,auth.machine_id]);if(!rule||rule.state!=='active'||rule.revision!==begin.rule_revision||rule.visibility!==begin.visibility)fail(rule?.state==='paused'?409:403,rule?.state==='paused'?'source_paused':'forbidden','sync rule changed before commit');}
332
+ const heldParts = await api.store.one('SELECT COUNT(*) count,MIN(part_index) first,MAX(part_index) last FROM capture_parts WHERE team_id=? AND capture_id=?', [auth.team_id, captureId]);
333
+ if (heldParts.count !== commit.parts || heldParts.first !== 0 || heldParts.last !== commit.parts - 1) fail(409, 'batch_gap', 'capture parts incomplete');
334
+ const unsignedCommit = { ...commit };
335
+ delete unsignedCommit.digest;
336
+ const captureHash = createHash('sha256').update(`{"begin":${canonicalJson(begin)},"commit":${canonicalJson(unsignedCommit)},"parts":[`);
337
+ const sentKeys = new Set();
338
+ let messageCount = 0;
339
+ for (let index = 0; index < commit.parts; index++) {
340
+ const part = await api.store.one('SELECT payload_json FROM capture_parts WHERE team_id=? AND capture_id=? AND part_index=?', [auth.team_id, captureId, index]);
341
+ if (!part) fail(409, 'batch_gap', 'capture parts incomplete');
342
+ if (index) captureHash.update(',');
343
+ captureHash.update(part.payload_json);
344
+ for (const message of JSON.parse(part.payload_json).messages) {
345
+ if (sentKeys.has(message.native_key)) fail(409, 'capture_conflict', 'duplicate native message key');
346
+ sentKeys.add(message.native_key);
347
+ if (++messageCount > 100000) fail(413, 'request_too_large', 'capture contains too many messages');
348
+ }
349
+ }
350
+ if (captureHash.update(']}').digest('hex') !== commit.digest) fail(409, 'capture_conflict', 'capture digest differs');
329
351
  // Native transcripts can be larger than the Worker's entire heap. Validate
330
352
  // the retained bytes one chunk at a time; never materialize a whole artifact.
331
353
  for (const manifest of commit.artifacts) {
@@ -355,9 +377,9 @@ async function captureCommit(api,req,res,auth,sourceId,captureId,requestId){cons
355
377
  if (begin.carry) {
356
378
  const { count, digest } = begin.carry;
357
379
  const session = origin ? await api.store.one('SELECT revision FROM sessions WHERE team_id=? AND id=?', [auth.team_id, origin.session_id]) : null;
358
- if (!session || count + messages.length > 100000) fail(409, 'carry_mismatch', 'the carried prefix is unavailable or too large');
380
+ if (!session || count + messageCount > 100000) fail(409, 'carry_mismatch', 'the carried prefix is unavailable or too large');
359
381
  carriedRevision = session.revision;
360
- const hash = createHash('sha256').update('['), sent = new Set(messages.map(m => m.native_key));
382
+ const hash = createHash('sha256').update('[');
361
383
  while (carriedCount < count) {
362
384
  const page = await api.store.query(`SELECT ordinal,source_id,native_key,recorded_at,value_json FROM messages m
363
385
  WHERE m.team_id=? AND m.session_id=? AND m.ordinal>=? AND m.ordinal<? AND ${MESSAGE_AT()} ORDER BY m.ordinal LIMIT 16`,
@@ -365,7 +387,7 @@ async function captureCommit(api,req,res,auth,sourceId,captureId,requestId){cons
365
387
  if (!page.length) fail(409, 'carry_mismatch', 'the carried messages are not what this session holds; send the capture whole');
366
388
  for (const row of page) {
367
389
  if (row.ordinal !== carriedCount || row.source_id !== sourceId) fail(409, 'carry_mismatch', 'the carried messages are not what this session holds; send the capture whole');
368
- if (sent.has(row.native_key)) fail(409, 'capture_conflict', 'duplicate native message key');
390
+ if (sentKeys.has(row.native_key)) fail(409, 'capture_conflict', 'duplicate native message key');
369
391
  if (carriedCount) hash.update(',');
370
392
  hash.update(canonicalJson({native_key:row.native_key, recorded_at:row.recorded_at ?? null, value:JSON.parse(row.value_json)}));
371
393
  carriedCount++;
@@ -382,15 +404,11 @@ async function captureCommit(api,req,res,auth,sourceId,captureId,requestId){cons
382
404
  // session that gained one message writes one row, not the whole session again.
383
405
  const carryGuards=[],currentRevision=origin?(await api.store.one('SELECT revision FROM sessions WHERE team_id=? AND id=?',[auth.team_id,sid]))?.revision??null:null;
384
406
  if (carriedRevision != null && currentRevision !== carriedRevision) fail(409, 'revision_mismatch', 'session changed during prefix verification; retry');
385
- const held=new Map();if(currentRevision!=null)for(const row of await api.store.query(`SELECT revision,ordinal,id,source_id,native_key,recorded_at,value_json,until_revision FROM messages m WHERE m.team_id=? AND m.session_id=? AND ${MESSAGE_AT()} AND ordinal>=?`,[auth.team_id,sid,currentRevision,currentRevision,carriedCount]))held.set(row.ordinal,row);
407
+ sentKeys.clear();
408
+ carryGuards.push({ sql: 'SELECT 1 ok WHERE (SELECT COUNT(*) FROM capture_parts WHERE team_id=? AND capture_id=?)=?', params: [auth.team_id, captureId, commit.parts], status: 409, code: 'batch_gap', message: 'capture parts changed before commit' });
386
409
  // Another commit to this session between this read and the write would make the carried rows wrong: refused, retried.
387
410
  if(currentRevision!=null)carryGuards.push({sql:'SELECT 1 ok FROM sessions WHERE team_id=? AND id=? AND revision=?',params:[auth.team_id,sid,currentRevision],code:'revision_mismatch',status:409,message:'session changed during capture; retry'});
388
- const close=row=>{if(row.until_revision===OPEN_REVISION)statements.push({sql:'UPDATE messages SET until_revision=? WHERE team_id=? AND session_id=? AND revision=? AND ordinal=?',params:[revisionParam,auth.team_id,sid,row.revision,row.ordinal]});};
389
- let ordinal=carriedCount;for(const m of messages){const value=JSON.stringify(m.value),old=held.get(ordinal);held.delete(ordinal);
390
- if(old&&old.source_id===sourceId&&old.native_key===m.native_key&&old.recorded_at===m.recorded_at&&old.value_json===value){if(old.until_revision!==OPEN_REVISION)statements.push({sql:'UPDATE messages SET until_revision=? WHERE team_id=? AND session_id=? AND revision=? AND ordinal=?',params:[OPEN_REVISION,auth.team_id,sid,old.revision,old.ordinal]});ordinal++;continue;}
391
- if(old)close(old);
392
- let mid=(await api.store.one('SELECT id FROM message_ids WHERE team_id=? AND source_id=? AND harness=? AND native_id=? AND native_key=?',[auth.team_id,sourceId,cap.harness,cap.native_id,m.native_key]))?.id;if(!mid){mid=api.ids.next('message');statements.push({sql:'INSERT INTO message_ids(team_id,source_id,harness,native_id,native_key,id) VALUES (?,?,?,?,?,?)',params:[auth.team_id,sourceId,cap.harness,cap.native_id,m.native_key,mid]});}statements.push({sql:'INSERT INTO messages(team_id,session_id,revision,ordinal,id,source_id,native_key,recorded_at,value_json,search_text,until_revision) VALUES (?,?,?,?,?,?,?,?,?,?,?)',params:[auth.team_id,sid,revisionParam,ordinal++,mid,sourceId,m.native_key,m.recorded_at,value,normalizeSearch(textFromContent(m.value.content)),OPEN_REVISION]});}
393
- for(const row of held.values())close(row);
411
+ statements.push({ kind: 'capture_messages', capture: { teamId: auth.team_id, sessionId: sid, sourceId, captureId, harness: cap.harness, nativeId: cap.native_id, currentRevision, carriedCount, parts: commit.parts, messageNamespace: api.ids.next('message') } });
394
412
  const bundle=commit.native_bundle??null,legacyBundle=commit.artifacts.length?captureId:null;for(let index=0;index<commit.artifacts.length;index++){const a=commit.artifacts[index],file=bundle?.files.find(x=>x.upload_id===a.upload_id);statements.push({sql:'UPDATE uploads SET manifest_json=?,committed=1 WHERE team_id=? AND id=?',params:[JSON.stringify(a),auth.team_id,a.upload_id]},{sql:'INSERT INTO session_artifacts(team_id,session_id,revision,bundle_id,upload_id,format,provenance,file_role,fidelity,residue_json) VALUES (?,?,?,?,?,?,?,?,?,?)',params:[auth.team_id,sid,revisionParam,bundle?.id??legacyBundle,a.upload_id,bundle?.harness??cap.harness,'capture',file?.role??(index===0?'primary':'bundle'),bundle?.fidelity??'semantic',JSON.stringify(bundle?.residue??['native_bundle_metadata_unavailable'])]});}const storedReceipt={source_id:sourceId,capture_id:captureId,session_id:sid,generation:cap.generation,sequence:cap.sequence,digest:commit.digest,revision:'__JOURNAL_REVISION__',duplicate:false};statements.push({sql:"UPDATE captures SET state='committed',commit_json=?,receipt_json=? WHERE team_id=? AND id=?",params:[JSON.stringify(commit),{$journalJsonValue:storedReceipt},auth.team_id,captureId]},{sql:'DELETE FROM capture_parts WHERE team_id=? AND capture_id=?',params:[auth.team_id,captureId]},{sql:'UPDATE sources SET last_received_at=? WHERE team_id=? AND id=?',params:[boundaryNow,auth.team_id,sourceId]},{sql:'UPDATE teams SET journal_revision=? WHERE id=?',params:[revisionParam,auth.team_id]},{sql:'INSERT INTO journal(team_id,revision,session_id,kind,created_at) VALUES (?,?,?,?,?)',params:[auth.team_id,revisionParam,sid,'capture',boundaryNow]});const guards=[{sql:'SELECT 1 ok FROM credentials WHERE id=? AND source_id=? AND revoked_at IS NULL AND (expires_at IS NULL OR expires_at>?)',params:[auth.credential_id,sourceId,boundaryNow],code:'authentication_required',status:401,message:'source credential expired or revoked'},...lineageGuards,...carryGuards,{sql:"SELECT 1 ok FROM captures c JOIN sources s ON s.team_id=c.team_id AND s.id=c.source_id LEFT JOIN machines m ON m.team_id=s.team_id AND m.id=s.machine_id LEFT JOIN sync_rules r ON r.team_id=c.team_id AND r.id=json_extract(c.begin_json,'$.rule_id') WHERE c.team_id=? AND c.id=? AND c.source_id=? AND c.state='staging' AND s.state='active' AND (s.kind!='connector' OR (m.revoked_at IS NULL AND r.machine_id=m.id AND r.source_id=s.id AND r.state='active' AND r.revision=json_extract(c.begin_json,'$.rule_revision') AND r.visibility=json_extract(c.begin_json,'$.visibility')))",params:[auth.team_id,captureId,sourceId],code:'conflict',status:409,message:'capture authorization changed'}],storedResponse=result(api,auth,storedReceipt),{revision}=await guardedMutation(api,res,auth,guards,statements,{status:200,body:storedResponse,targetId:captureId,journal:true}),receipt={...storedReceipt,revision};api.events.publish(auth.team_id,{type:'session_changed',cursor:String(revision),revision,session_id:sid,reason:'capture',read_required:true});send(res,200,result(api,auth,receipt),requestId);
395
413
  }
396
414
 
@@ -5,6 +5,7 @@
5
5
  // them on the object's own SQLite.
6
6
  import { ingestOtlpBatch, correlateSessions } from './arc2-transactions.mjs';
7
7
  import { claimEffect, getEffect, listEffects, reportEffect } from './effects-transactions.mjs';
8
+ import { applyCaptureMessages } from './capture-transactions.mjs';
8
9
  import { MIGRATIONS, MESSAGE_AT } from '@volter/teams/server/migrations';
9
10
 
10
11
  /** Bring a database to the newest schema. `version()`/`setVersion(n)` name where the host records it. */
@@ -119,7 +120,7 @@ export function createStoreHandlers({ all, get, run, tx }) {
119
120
  transaction: ({statements}) => tx(() => statements.map(s => s.kind === 'query' ? all(s.sql,s.params) : s.kind === 'one' ? get(s.sql,s.params) : run(s.sql,s.params))),
120
121
  snapshot: ({statements}) => tx(() => statements.map(s => s.kind === 'one' ? get(s.sql,s.params) : all(s.sql,s.params))),
121
122
  guardedTransaction: ({guards=[],statements}) => tx(() => { for(const guard of guards){const row=get(guard.sql,guard.params);if(!row){const error=new Error(guard.message??'transaction predicate changed');error.code=guard.code??'conflict';error.status=guard.status??409;throw error;}}return statements.map(s=>s.kind==='query'?all(s.sql,s.params):s.kind==='one'?get(s.sql,s.params):run(s.sql,s.params));}),
122
- journalTransaction: ({teamId,guards=[],statements}) => tx(() => { for(const guard of guards){const row=get(guard.sql,guard.params);if(!row){const error=new Error(guard.message??'transaction predicate changed');error.code=guard.code??'conflict';error.status=guard.status??409;throw error;}}const team=get('SELECT journal_revision FROM teams WHERE id=?',[teamId]);if(!team)throw new Error('team not found');const revision=team.journal_revision+1;const results=statements.map(s=>{const params=(s.params??[]).map(value=>journalParam(value,revision));return s.kind==='query'?all(s.sql,params):s.kind==='one'?get(s.sql,params):run(s.sql,params);});return{revision,results};}),
123
+ journalTransaction: ({teamId,guards=[],statements}) => tx(() => { for(const guard of guards){const row=get(guard.sql,guard.params);if(!row){const error=new Error(guard.message??'transaction predicate changed');error.code=guard.code??'conflict';error.status=guard.status??409;throw error;}}const team=get('SELECT journal_revision FROM teams WHERE id=?',[teamId]);if(!team)throw new Error('team not found');const revision=team.journal_revision+1;const results=statements.map(s=>{if(s.kind==='capture_messages')return applyCaptureMessages({get,run},s.capture,revision);const params=(s.params??[]).map(value=>journalParam(value,revision));return s.kind==='query'?all(s.sql,params):s.kind==='one'?get(s.sql,params):run(s.sql,params);});return{revision,results};}),
123
124
  ingestOtlpBatch: args => tx(() => ingestOtlpBatch({get,all,run},args)),
124
125
  correlateSessions: args => tx(() => correlateSessions({get,all,run},args)),
125
126
  listEffects: args => tx(() => listEffects({get,all,run},args)),