Updates
CI / Build & Test (push) Successful in 3m12s

This commit is contained in:
Raven Scott
2026-07-26 22:58:33 -04:00
parent 90b6033382
commit f4569b765e
21 changed files with 2152 additions and 220 deletions
+138 -2
View File
@@ -161,9 +161,29 @@
const conn = new BridgeSwarmConnection(payload.connId, payload.swarmId);
this._connections.set(payload.connId, conn);
conn.on('end', () => { if (this._connections) this._connections.delete(payload.connId); });
const peerInfo = payload.peerInfo || {};
const peerInfo = Object.assign({}, payload.peerInfo || {});
const swarm = this;
peerInfo.ban = function (banned) {
return swarm.ban(peerInfo.publicKey, banned !== false);
};
console.log('[BridgeSwarm-api] Emitting connection event for connId:', payload.connId);
this.emit('connection', conn, peerInfo);
this.emit('connection', conn, peerInfo, payload);
return;
}
if (msg.event === 'hrpc-chunk' || msg.event === 'hrpc-end' || msg.event === 'hrpc-error') {
this.emit(msg.event, payload);
if (this._hrpcStreams && payload.streamId && this._hrpcStreams.has(payload.streamId)) {
const h = this._hrpcStreams.get(payload.streamId);
if (msg.event === 'hrpc-chunk' && h.onChunk) h.onChunk(payload.chunk);
if (msg.event === 'hrpc-end') {
if (h.resolve) h.resolve(payload.result);
this._hrpcStreams.delete(payload.streamId);
}
if (msg.event === 'hrpc-error') {
if (h.reject) h.reject(new Error(payload.message || 'HRPC stream error'));
this._hrpcStreams.delete(payload.streamId);
}
}
return;
}
if (msg.event === 'data') {
@@ -237,6 +257,122 @@
});
};
/**
* Ban or unban a peer by public key hex. Also updates the host denylist.
* @param {string} publicKeyHex
* @param {boolean} [banned=true]
* @returns {Promise<object>}
*/
BridgeSwarm.prototype.ban = function (publicKeyHex, banned) {
return this._init().then(() =>
sendToBridge({
id: generateId(),
type: 'banPeer',
payload: {
swarmId: this.swarmId,
publicKeyHex: typeof publicKeyHex === 'string' ? publicKeyHex : bufferToHex(publicKeyHex),
banned: banned !== false,
},
}).then((res) => {
if (res && !res.ok) throw new Error(res.error || 'banPeer failed');
return res;
})
);
};
/**
* Set a serializable firewall policy for this swarm.
* @param {{ mode: 'off'|'allowlist'|'denylist', keys?: string[] }} opts
* @returns {Promise<object>}
*/
BridgeSwarm.prototype.setFirewall = function (opts) {
const o = opts || {};
return this._init().then(() =>
sendToBridge({
id: generateId(),
type: 'setFirewall',
payload: {
swarmId: this.swarmId,
mode: o.mode || 'off',
keys: o.keys || [],
},
}).then((res) => {
if (res && !res.ok) throw new Error(res.error || 'setFirewall failed');
return res;
})
);
};
/**
* Opt-in automatic Hypercore replication on new connections.
* When enabled, connections are taken over by the host (not usable for page chat/Protomux).
* @param {{ enabled: boolean, coreKeyHex?: string, resourceId?: string }} opts
* @returns {Promise<object>}
*/
BridgeSwarm.prototype.setAutoReplicate = function (opts) {
const o = opts || {};
return this._init().then(() =>
sendToBridge({
id: generateId(),
type: 'setAutoReplicate',
payload: {
swarmId: this.swarmId,
enabled: !!o.enabled,
coreKeyHex: o.coreKeyHex,
resourceId: o.resourceId,
},
}).then((res) => {
if (res && !res.ok) throw new Error(res.error || 'setAutoReplicate failed');
return res;
})
);
};
/**
* Call an HRPC method on a connection (host-side). Unary returns result;
* streaming methods resolve when the stream ends (with optional onChunk).
* @param {string} connId
* @param {string} method - ping | notify | fetchStream | streamSum | duplex
* @param {object} [args]
* @param {{ onChunk?: function, timeoutMs?: number }} [options]
* @returns {Promise<object>}
*/
BridgeSwarm.prototype.hrpcCall = function (connId, method, args, options) {
const opts = options || {};
const self = this;
if (!self._hrpcStreams) self._hrpcStreams = new Map();
return self._init().then(() => {
const streamId = 'hrpc_' + Date.now() + '_' + Math.random().toString(36).slice(2);
return sendToBridge({
id: generateId(),
type: 'hrpcInvoke',
payload: { connId, method, args: args || {}, streamId },
}).then((res) => {
if (res && !res.ok) throw new Error(res.error || 'hrpcInvoke failed');
if (!res.streaming) return res;
return new Promise((resolve, reject) => {
const timer = opts.timeoutMs > 0
? setTimeout(() => {
self._hrpcStreams.delete(streamId);
reject(new Error('hrpcCall timed out'));
}, opts.timeoutMs)
: null;
self._hrpcStreams.set(streamId, {
onChunk: opts.onChunk,
resolve: (result) => {
if (timer) clearTimeout(timer);
resolve({ ok: true, streamId, result: result != null ? result : null, chunksDone: true });
},
reject: (err) => {
if (timer) clearTimeout(timer);
reject(err);
},
});
});
});
});
};
/**
* Snapshot of current connection objects. After destroy() returns [].
* @returns {BridgeSwarmConnection[]}