@volter/supercode-orchestrator 0.5.31 → 0.5.32

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.
@@ -28,7 +28,7 @@ export function followFleet({root,context,supercodeHome,wake,log}){
28
28
  try{
29
29
  const {team}=eventClient({context,supercodeHome});
30
30
  // Every connection begins with a complete, ACL-filtered snapshot. A process restart cannot trust an old cache.
31
- for await(const frame of team.events.follow({kinds:['session.started','session.ended','session.changed','resource.changed']}, {signal:abort.signal,after:cursor})){
31
+ for await(const frame of team.events.follow({kinds:['session.started','session.ended','session.changed','resource.changed']}, {signal:abort.signal,after:cursor,caller:'dispatch session-events'})){
32
32
  if(frame.type==='snapshot_begin'){snapshot={};connected=false;persist();}
33
33
  else if(frame.type==='snapshot_item')apply(snapshot??resources,frame);
34
34
  else if(frame.type==='snapshot_end'){resources=snapshot??resources;snapshot=null;cursor=frame.cursor;connected=true;refused=0;persist();wake('session-events-snapshot');}
@@ -1,6 +1,6 @@
1
1
  // App-owned source names/maps live here; the Teams core knows only a scoped event publisher.
2
2
  import { createHash } from 'node:crypto';
3
- import { eventClient } from '@volter/teams/event-client';
3
+ import { eventClient, spentClause } from '@volter/teams/event-client';
4
4
  import { EVENT_DATA_LIMIT } from '@volter/teams/event-limits';
5
5
  import { boardSourceName, publishableCard, recordCardPublications } from './published.mjs';
6
6
  import { listBoards, openBoard } from './store.mjs';
@@ -20,14 +20,14 @@ export function boardEventRelay({root,context,supercodeHome,log=()=>{}}) {
20
20
  try{
21
21
  const key=JSON.stringify({server:audience.server,org:audience.org,principal:audience.principal,board:slug});
22
22
  let source=sources.get(key);
23
- if(!source){source=(await team.events.createSource({name:boardSourceName(root,slug)})).data.id;sources.set(key,source);}
23
+ if(!source){source=(await team.events.createSource({name:boardSourceName(root,slug)},{caller:'board-relay source'})).data.id;sources.set(key,source);}
24
24
  const destination=createHash('sha256').update(`${key}:${source}`).digest('hex');
25
25
  for(;;){
26
26
  const rows=board.db.prepare('SELECT * FROM supercode_publications p WHERE NOT EXISTS (SELECT 1 FROM supercode_publication_receipts r WHERE r.event_id=p.id AND r.destination=?) ORDER BY sequence LIMIT 32').all(destination);if(!rows.length)break;
27
27
  for(const row of rows){
28
28
  if(closed)return;
29
29
  const id=`event_${createHash('sha256').update(`${row.id}:${destination}`).digest('hex')}`;
30
- await team.events.publish(source,{id,kind:row.kind,resource:{kind:'task',id:`${source}:${row.resource_id}`},revision:row.sequence,data:{board:slug,card:publishableCard(JSON.parse(row.snapshot),slug,EVENT_DATA_LIMIT)},actor:{session:row.actor?`session:${row.actor}`:null}},{idempotencyKey:id})
30
+ await team.events.publish(source,{id,kind:row.kind,resource:{kind:'task',id:`${source}:${row.resource_id}`},revision:row.sequence,data:{board:slug,card:publishableCard(JSON.parse(row.snapshot),slug,EVENT_DATA_LIMIT)},actor:{session:row.actor?`session:${row.actor}`:null}},{idempotencyKey:id,caller:'board-relay publish'})
31
31
  .catch(error=>{throw Object.assign(error,{message:`${row.resource_id} ${row.kind} (sequence ${row.sequence}): ${error.message}`});});
32
32
  board.tx(db=>db.prepare('INSERT OR IGNORE INTO supercode_publication_receipts VALUES (?,?)').run(row.id,destination));
33
33
  }
@@ -41,7 +41,7 @@ export function boardEventRelay({root,context,supercodeHome,log=()=>{}}) {
41
41
  // again and spend the allowance the credential shares with every other caller.
42
42
  if(Date.now()<heldUntil)return null;
43
43
  work=(async()=>{while(dirty&&!closed){dirty=false;await run();}})().catch(error=>{
44
- log(`board event delivery pending: ${error.code?`${error.code}: `:''}${error.message}`);
44
+ log(`board event delivery pending: ${error.code?`${error.code}: `:''}${error.message}${spentClause(error)}`);
45
45
  // Retry durable delivery, not a read of the board's current state.
46
46
  const wait=error.code==='rate_limited'?Math.max(5000,Number(error.details?.retry_after_seconds??30)*1000):5000;heldUntil=Date.now()+wait;
47
47
  clearTimeout(retry);retry=setTimeout(()=>{heldUntil=0;wake(false);},wait);retry.unref?.();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/supercode-orchestrator",
3
- "version": "0.5.31",
3
+ "version": "0.5.32",
4
4
  "type": "module",
5
5
  "description": "The orchestrator runtime over the Volter Harness ontology: one typed operational model whose folder is its serialization, read and written through the harness orchestration doors (docs/ORCHESTRATOR-IR.md)",
6
6
  "exports": {
@@ -25,7 +25,7 @@
25
25
  },
26
26
  "dependencies": {
27
27
  "@volter/supercode-harness-sdk": "^0.3.60",
28
- "@volter/teams": "0.2.12",
28
+ "@volter/teams": "0.2.13",
29
29
  "@volter/ztrack": "^2.4.23",
30
30
  "yaml": "^2.9.0"
31
31
  },