@scp-dev/hub 0.5.0 → 0.5.1

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/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _scp_dev_core from '@scp-dev/core';
2
- import { Envelope, RelayCore, CoreOptions, EndpointRow, PolicySubject, ScopeSubject, ScopeNode, ScopeDirection, Admission, MessageRow, EndpointView, ScopeCap, ScopeEntry, Claim, SendParams, SendResult, EndpointKind, Presence, StatusState, Verdict, JudgeModelConfig, JudgeClient, Sql, JudgePolicy, Wake, CrossAccountLink, XDelivered, XListed, ActivityRow, XRelease } from '@scp-dev/core';
2
+ import { Envelope, RelayCore, CoreOptions, EndpointRow, EndpointView, PolicySubject, ScopeSubject, ScopeNode, ScopeDirection, Admission, MessageRow, ScopeCap, ScopeEntry, Claim, SendParams, SendResult, EndpointKind, Presence, StatusState, Verdict, JudgeModelConfig, JudgeClient, Sql, JudgePolicy, Wake, CrossAccountLink, XDelivered, XListed, ActivityRow, XRelease } from '@scp-dev/core';
3
3
 
4
4
  type RelayAuth = Envelope["from"]["auth"];
5
5
  /** a machine name: one relay host of an account */
@@ -162,6 +162,8 @@ declare class FederatedCore extends RelayCore {
162
162
  protected resolve(address: unknown): EndpointRow;
163
163
  protected addressUsers(): string[];
164
164
  protected localRow(row: EndpointRow): boolean;
165
+ /** a live mirrored row shows the presence its machine mirrored, not one its last_seen decays to here */
166
+ protected view(row: EndpointRow, shown?: Set<string>): EndpointView;
165
167
  protected address(row: EndpointRow): string;
166
168
  protected subject(row: EndpointRow): PolicySubject;
167
169
  /** a stand-in for another account's sender is no endpoint of this relay: list, peers and snapshots leave it out */
package/dist/index.js CHANGED
@@ -90,6 +90,7 @@ var FederatedCore = class extends RelayCore {
90
90
  if (!columns.includes("incarnation")) this.sql.all(`ALTER TABLE endpoints ADD COLUMN incarnation TEXT`);
91
91
  if (!columns.includes("scope_epoch")) this.sql.all(`ALTER TABLE endpoints ADD COLUMN scope_epoch INTEGER`);
92
92
  if (!columns.includes("mirrored_caps")) this.sql.all(`ALTER TABLE endpoints ADD COLUMN mirrored_caps TEXT`);
93
+ if (!columns.includes("mirrored_presence")) this.sql.all(`ALTER TABLE endpoints ADD COLUMN mirrored_presence TEXT`);
93
94
  this.sql.all(`CREATE UNIQUE INDEX IF NOT EXISTS endpoints_remote ON endpoints (remote) WHERE remote IS NOT NULL`);
94
95
  if (this.xinbox) for (const statement of XACCT_MIGRATION) this.sql.all(statement);
95
96
  }
@@ -222,6 +223,12 @@ var FederatedCore = class extends RelayCore {
222
223
  localRow(row) {
223
224
  return !row.remote;
224
225
  }
226
+ /** a live mirrored row shows the presence its machine mirrored, not one its last_seen decays to here */
227
+ view(row, shown) {
228
+ const view = super.view(row, shown);
229
+ const { remote, mirrored_presence: mirrored } = row;
230
+ return remote && row.connections > 0 && (mirrored === "online" || mirrored === "idle") ? { ...view, presence: mirrored } : view;
231
+ }
225
232
  address(row) {
226
233
  const remote = row.remote;
227
234
  if (remote && isForeign(remote)) return remote.slice(1);
@@ -391,6 +398,7 @@ var FederatedCore = class extends RelayCore {
391
398
  status_note: view.status?.note ?? null,
392
399
  token_hash: null,
393
400
  connections: live ? 1 : 0,
401
+ mirrored_presence: view.presence,
394
402
  last_seen: view.lastSeen ?? (live ? now : before?.last_seen ?? null),
395
403
  auth: auth ?? row.auth,
396
404
  ...view.kind === "agent" ? this.scopeColumns(machine, view.scope, row, place(view.handle)) : {}
@@ -3468,7 +3476,7 @@ var RelayHub = class _RelayHub {
3468
3476
  return count;
3469
3477
  });
3470
3478
  this.stored = null;
3471
- this.toBridges(name, { machine: name, endpoints: [], full: true });
3479
+ this.toBridges(name, { machine: name, endpoints: [], full: true, released: true });
3472
3480
  this.dash({ type: "endpoints", at: new Date(this.now()).toISOString(), machine: name });
3473
3481
  this.deps.log?.("relay_action", { account: this.account, machine: name, method: "machine_release", code: "ok" });
3474
3482
  return { removed: name, endpoints: dropped };
@@ -3505,7 +3513,7 @@ var RelayHub = class _RelayHub {
3505
3513
  core.record("machine_expire", null, name, { machine: name, endpoints: count });
3506
3514
  return count;
3507
3515
  });
3508
- this.toBridges(name, { machine: name, endpoints: [], full: true });
3516
+ this.toBridges(name, { machine: name, endpoints: [], full: true, released: true });
3509
3517
  this.deps.log?.("relay_action", { account: this.account, machine: name, method: "machine_expire", code: "ok", endpoints: dropped });
3510
3518
  }
3511
3519
  }
@@ -3523,7 +3531,7 @@ var RelayHub = class _RelayHub {
3523
3531
  for (const name of unbound) this.relay.record("machine_forget", null, name, { machine: name, endpoints: this.relay.dropMachine(name, { queue: true }) });
3524
3532
  return unbound;
3525
3533
  });
3526
- for (const name of forgotten) this.toBridges(name, { machine: name, endpoints: [], full: true });
3534
+ for (const name of forgotten) this.toBridges(name, { machine: name, endpoints: [], full: true, released: true });
3527
3535
  }
3528
3536
  /** the hub_state keys (`denied:<tokenId>`) of tokens revoked lately, to when; loaded once per object lifetime */
3529
3537
  deniedGrants() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scp-dev/hub",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "Swarm Communication Protocol federation and account hub: mirrored endpoints across machines, bridges, direct clients and cross-account delivery.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://scp.dev",
@@ -29,7 +29,7 @@
29
29
  "typecheck": "tsc -p ."
30
30
  },
31
31
  "dependencies": {
32
- "@scp-dev/core": "0.1.5"
32
+ "@scp-dev/core": "0.1.6"
33
33
  },
34
34
  "devDependencies": {
35
35
  "tsup": "^8.5.1"
package/src/federation.ts CHANGED
@@ -82,6 +82,8 @@ interface FederatedRow extends EndpointRow {
82
82
  scope_epoch: number | null
83
83
  /** this machine's own agent: the wire caps it mirrored last */
84
84
  mirrored_caps: string | null
85
+ /** another machine's row: the presence its bridge mirrored last */
86
+ mirrored_presence: Presence | null
85
87
  }
86
88
 
87
89
  /** own rules as they cross machines: selector lists per direction */
@@ -290,6 +292,7 @@ export class FederatedCore extends RelayCore {
290
292
  if (!columns.includes("incarnation")) this.sql.all(`ALTER TABLE endpoints ADD COLUMN incarnation TEXT`)
291
293
  if (!columns.includes("scope_epoch")) this.sql.all(`ALTER TABLE endpoints ADD COLUMN scope_epoch INTEGER`)
292
294
  if (!columns.includes("mirrored_caps")) this.sql.all(`ALTER TABLE endpoints ADD COLUMN mirrored_caps TEXT`)
295
+ if (!columns.includes("mirrored_presence")) this.sql.all(`ALTER TABLE endpoints ADD COLUMN mirrored_presence TEXT`)
293
296
  this.sql.all(`CREATE UNIQUE INDEX IF NOT EXISTS endpoints_remote ON endpoints (remote) WHERE remote IS NOT NULL`)
294
297
  if (this.xinbox) for (const statement of XACCT_MIGRATION) this.sql.all(statement)
295
298
  }
@@ -446,6 +449,13 @@ export class FederatedCore extends RelayCore {
446
449
  return !(row as FederatedRow).remote
447
450
  }
448
451
 
452
+ /** a live mirrored row shows the presence its machine mirrored, not one its last_seen decays to here */
453
+ protected override view(row: EndpointRow, shown?: Set<string>): EndpointView {
454
+ const view = super.view(row, shown)
455
+ const { remote, mirrored_presence: mirrored } = row as FederatedRow
456
+ return remote && row.connections > 0 && (mirrored === "online" || mirrored === "idle") ? { ...view, presence: mirrored } : view
457
+ }
458
+
449
459
  protected override address(row: EndpointRow): string {
450
460
  const remote = (row as FederatedRow).remote
451
461
  if (remote && isForeign(remote)) return remote.slice(1)
@@ -625,6 +635,7 @@ export class FederatedCore extends RelayCore {
625
635
  status_note: view.status?.note ?? null,
626
636
  token_hash: null,
627
637
  connections: live ? 1 : 0,
638
+ mirrored_presence: view.presence,
628
639
  last_seen: view.lastSeen ?? (live ? now : (before?.last_seen ?? null)),
629
640
  auth: auth ?? row.auth,
630
641
  ...(view.kind === "agent" ? this.scopeColumns(machine, view.scope, row, place(view.handle)) : {}),
package/src/hub.ts CHANGED
@@ -1774,7 +1774,7 @@ export class RelayHub {
1774
1774
  return count
1775
1775
  })
1776
1776
  this.stored = null
1777
- this.toBridges(name, { machine: name, endpoints: [], full: true })
1777
+ this.toBridges(name, { machine: name, endpoints: [], full: true, released: true })
1778
1778
  this.dash({ type: "endpoints", at: new Date(this.now()).toISOString(), machine: name })
1779
1779
  this.deps.log?.("relay_action", { account: this.account, machine: name, method: "machine_release", code: "ok" })
1780
1780
  return { removed: name, endpoints: dropped }
@@ -1812,7 +1812,7 @@ export class RelayHub {
1812
1812
  core.record("machine_expire", null, name, { machine: name, endpoints: count })
1813
1813
  return count
1814
1814
  })
1815
- this.toBridges(name, { machine: name, endpoints: [], full: true })
1815
+ this.toBridges(name, { machine: name, endpoints: [], full: true, released: true })
1816
1816
  this.deps.log?.("relay_action", { account: this.account, machine: name, method: "machine_expire", code: "ok", endpoints: dropped })
1817
1817
  }
1818
1818
  }
@@ -1831,7 +1831,7 @@ export class RelayHub {
1831
1831
  for (const name of unbound) this.relay.record("machine_forget", null, name, { machine: name, endpoints: this.relay.dropMachine(name, { queue: true }) })
1832
1832
  return unbound
1833
1833
  })
1834
- for (const name of forgotten) this.toBridges(name, { machine: name, endpoints: [], full: true })
1834
+ for (const name of forgotten) this.toBridges(name, { machine: name, endpoints: [], full: true, released: true })
1835
1835
  }
1836
1836
 
1837
1837
  /** the hub_state keys (`denied:<tokenId>`) of tokens revoked lately, to when; loaded once per object lifetime */