OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-deploy commits / 1b939cd

0.4.8: DeployServer.serveOnConnection — reusable content-channel attach
Factor the per-connection overlay-v2 content-channel attach out of _onConnection into a public serveOnConnection(conn) method. Rebuilds the content-hash -> disk-path map from the CURRENT manifest each call (so rescan({newHashes}) trees are served) and attaches the shared _overlayProtocol onto the connection's Protomux. Lets a caller mux content-serving onto a connection that already carries other protocols (e.g. registry replication): replicate(conn) first, then serveOnConnection(conn) — the keet many-protocols-one-connection pattern. _onConnection now just calls it. Behaviour-preserving for existing peers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1b939cd4462aebace9b57b64fbe9cf047761b0c5
by plankatron <fleeky@gmail.com> · 2026-06-18T00:41:23.000Z

Changed files (2) +52 -25

index.js +51 -24
……@@ -460,6 +460,56 @@ export class DeployServer extends ReadyResource {
460460 this.emit('indexed', this.manifest.files.length, totalSize)
461461 }
462462
463 /**
464 * Attach this server's hyper-overlay/v2 content channel to an EXISTING
465 * connection, so the peer can request any served file by its content
466 * hash. Idempotent-ish: rebuilds the content-hash → disk-path map from
467 * the CURRENT manifest on every call (so freshly-rescanned trees are
468 * served), then attaches the overlay protocol onto the connection's
469 * Protomux.
470 *
471 * Reuses the DeployServer's own `_overlayProtocol` (sharing its
472 * FileIndex / TransferManager) — NOT a separate FileIndex — so trees
473 * added by `rescan({ newHashes })` are immediately reachable here.
474 *
475 * Use this to mux content-serving onto a connection that already
476 * carries other protocols (e.g. a registry-replication connection): the
477 * caller does its own `corestore.replicate(conn)` first, then calls
478 * this. The keet "many protocols, one connection" pattern.
479 *
480 * No-op when trees are disabled (`enableTrees: false`).
481 *
482 * @param {Duplex} conn — an open connection (secret-stream / duplex)
483 * @returns {boolean} true if the content channel was attached
484 */
485 serveOnConnection (conn) {
486 if (!this._overlayProtocol) return false
487 try {
488 const mux = Protomux.from(conn)
489 // Build content-hash → disk-path map so content-request works.
490 const contentHashPaths = new Map()
491 const filePaths = new Map()
492 for (const f of (this.manifest && this.manifest.files) || []) {
493 if (f.hash) {
494 // f.diskPath points to the symlink-target blob for symlink
495 // entries and to the actual source file for regular files.
496 // Falls back to dir-relative path for back-compat with any
497 // older manifest shapes that lack f.diskPath.
498 const diskPath = f.diskPath || path.join(this.dir, f.path)
499 contentHashPaths.set(f.hash, diskPath)
500 filePaths.set(f.path, diskPath)
501 }
502 }
503 this._overlayProtocol._contentHashPaths = contentHashPaths
504 this._overlayProtocol._filePaths = filePaths
505 this._overlayProtocol.attach(mux)
506 return true
507 } catch (err) {
508 this.emit('error', new Error('failed to attach overlay-v2 protocol: ' + err.message))
509 return false
510 }
511 }
512
463513 _onConnection (conn) {
464514 const peerKey = conn.remotePublicKey
465515 ? conn.remotePublicKey.toString('hex').slice(0, 12)
……@@ -476,30 +526,7 @@ export class DeployServer extends ReadyResource {
476526 // Also attach hyper-overlay/v2 on the same stream (protomux handles
477527 // multiplexing). Populates contentHashPaths from the fileIndex so
478528 // content-request can serve any file by its contentHash.
479 if (this._overlayProtocol) {
480 try {
481 const mux = Protomux.from(conn)
482 // Build content-hash → disk-path map so content-request works
483 const contentHashPaths = new Map()
484 const filePaths = new Map()
485 for (const f of (this.manifest && this.manifest.files) || []) {
486 if (f.hash) {
487 // f.diskPath points to the symlink-target blob for symlink
488 // entries and to the actual source file for regular files.
489 // Falls back to dir-relative path for back-compat with any
490 // older manifest shapes that lack f.diskPath.
491 const diskPath = f.diskPath || path.join(this.dir, f.path)
492 contentHashPaths.set(f.hash, diskPath)
493 filePaths.set(f.path, diskPath)
494 }
495 }
496 this._overlayProtocol._contentHashPaths = contentHashPaths
497 this._overlayProtocol._filePaths = filePaths
498 this._overlayProtocol.attach(mux)
499 } catch (err) {
500 this.emit('error', new Error('failed to attach overlay-v2 protocol: ' + err.message))
501 }
502 }
529 this.serveOnConnection(conn)
503530
504531 const session = { peerKey, destroyed: false, filesServed: 0, bytesServed: 0 }
505532 this._sessions.add(session)
package.json +1 -1
……@@ -1,6 +1,6 @@
11{
22 "name": "hyper-deploy",
3 "version": "0.4.7",
3 "version": "0.4.8",
44 "description": "P2P release distribution — serve build artifacts to peers over Hyperswarm",
55 "type": "module",
66 "main": "index.js",