@volter/teams 0.1.45 → 0.1.46

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 (2) hide show
  1. package/package.json +1 -1
  2. package/server/core.mjs +10 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/teams",
3
- "version": "0.1.45",
3
+ "version": "0.1.46",
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",
package/server/core.mjs CHANGED
@@ -84,6 +84,14 @@ export async function maintain(api){const now=api.clock.nowMs();
84
84
  {sql:'UPDATE messages SET revision=(SELECT MIN(k.revision) FROM session_versions k WHERE k.team_id=messages.team_id AND k.session_id=messages.session_id AND k.revision>messages.revision AND k.revision<COALESCE(messages.until_revision,messages.revision+1)) WHERE team_id=? AND session_id=? AND revision=? AND EXISTS (SELECT 1 FROM session_versions k WHERE k.team_id=messages.team_id AND k.session_id=messages.session_id AND k.revision>messages.revision AND k.revision<COALESCE(messages.until_revision,messages.revision+1))',params:[team_id,session_id,revision]},
85
85
  ...['messages','session_artifacts','session_versions'].map(table=>({sql:`DELETE FROM ${table} WHERE team_id=? AND session_id=? AND revision=?`,params:[team_id,session_id,revision]})),
86
86
  ]);
87
+ // Retired versions release their native bundles. Keep every bundle still named by a version,
88
+ // continuation (including completed receipts), or in-flight capture, and leave a full day for uploads.
89
+ const orphaned=await api.store.query(`SELECT u.team_id,u.id FROM uploads u WHERE u.committed=1 AND u.created_at+86400000<=?
90
+ AND NOT EXISTS (SELECT 1 FROM session_artifacts a WHERE a.team_id=u.team_id AND a.upload_id=u.id)
91
+ AND NOT EXISTS (SELECT 1 FROM continuations c WHERE c.team_id=u.team_id AND instr(c.value_json,u.id)>0)
92
+ AND NOT EXISTS (SELECT 1 FROM captures c WHERE c.team_id=u.team_id AND c.state='staging' AND instr(c.begin_json,u.id)>0)
93
+ LIMIT 10`,[now]);
94
+ for(const upload of orphaned)await api.store.transaction([{sql:'DELETE FROM uploads WHERE team_id=? AND id=?',params:[upload.team_id,upload.id]}]);
87
95
  await api.store.transaction([
88
96
  {sql:'DELETE FROM cursors WHERE expires_at<=?',params:[now]},
89
97
  {sql:'DELETE FROM global_cursors WHERE expires_at<=?',params:[now]},
@@ -96,8 +104,8 @@ export async function maintain(api){const now=api.clock.nowMs();
96
104
  {sql:'INSERT OR IGNORE INTO capture_expiries(team_id,source_id,id,expired_at) SELECT team_id,source_id,id,? FROM uploads WHERE committed=0 AND created_at+86400000<=?',params:[now,now]},
97
105
  {sql:'DELETE FROM uploads WHERE committed=0 AND created_at+86400000<=?',params:[now]},
98
106
  ]).catch(()=>{});
99
- const result={pruned_versions:stale.length,pruned_parts:parts.length,pruned_idempotency:expired.length,backlog:expired.length>=1000||stale.length>=VERSION_PRUNE_BATCH||parts.length>=PART_PRUNE_BATCH};
100
- if(result.pruned_versions||result.pruned_parts||result.pruned_idempotency)console.log(`maintain: pruned ${result.pruned_idempotency} expired replay records, ${result.pruned_parts} parts, ${result.pruned_versions} versions${result.backlog?' (backlog)':''}`);
107
+ const result={pruned_versions:stale.length,pruned_parts:parts.length,pruned_idempotency:expired.length,pruned_uploads:orphaned.length,backlog:orphaned.length>=10||expired.length>=1000||stale.length>=VERSION_PRUNE_BATCH||parts.length>=PART_PRUNE_BATCH};
108
+ if(result.pruned_versions||result.pruned_parts||result.pruned_idempotency||result.pruned_uploads)console.log(`maintain: pruned ${result.pruned_uploads} unreachable bundles, ${result.pruned_idempotency} expired replay records, ${result.pruned_parts} parts, ${result.pruned_versions} versions${result.backlog?' (backlog)':''}`);
101
109
  return result;}
102
110
  /** Session versions `maintain` removes per run: small enough for one Durable Object alarm; a backlog runs again in seconds. */
103
111
  const VERSION_PRUNE_BATCH=20;