@synonymdev/slashtags-rpc
Advanced tools
Comparing version 0.1.2 to 1.0.0-alpha.0
116
index.js
@@ -1,1 +0,115 @@ | ||
module.exports = require('./cjs/src/index.js') | ||
import ProtomuxRPC from 'protomux-rpc' | ||
import EventEmitter from 'events' | ||
import Protomux from 'protomux' | ||
const RPCS_SYMBOL = Symbol.for('slashtags-rpcs') | ||
export class SlashtagsRPC extends EventEmitter { | ||
/** @param {Slashtag} slashtag */ | ||
constructor (slashtag) { | ||
super() | ||
this.slashtag = slashtag | ||
this.slashtag.on('connection', this.setup.bind(this)) | ||
} | ||
/** | ||
* RPC Identifier | ||
* @type {string} | ||
*/ | ||
get id () { throw new Error('id should be defined') } | ||
/** | ||
* Default value encoding for requests and responses | ||
* @type {import ('compact-encoding').Encoding | undefined} | ||
*/ | ||
get valueEncoding () { return undefined } | ||
/** | ||
* Handshake value encoding | ||
* @type {import ('compact-encoding').Encoding | undefined } | ||
*/ | ||
get handshakeEncoding () { return undefined } | ||
/** | ||
* Return a Handshake sent on channel opening. | ||
* @param {SecretStream} stream | ||
*/ | ||
handshake (stream) { return null } | ||
/** | ||
* Callback function on opening a channel | ||
* @param {any} handshake | ||
* @param {SecretStream} socket | ||
*/ | ||
onopen (handshake, socket) { } | ||
/** | ||
* RPC methods | ||
* @type {RPCMethod[]} | ||
*/ | ||
get methods () { return [] } | ||
/** | ||
* Create a new RPC instance on the stream if doesn't already exist | ||
* @param {SecretStream} socket | ||
*/ | ||
setup (socket) { | ||
// @ts-ignore Deduplicate ProtomuxRPC instances on the same socket | ||
if (socket[RPCS_SYMBOL]?.get(this.id)) return | ||
// @ts-ignore | ||
if (!socket[RPCS_SYMBOL]) socket[RPCS_SYMBOL] = new Map() | ||
const options = { | ||
id: Buffer.from(this.id), | ||
valueEncoding: this.valueEncoding, | ||
handshakeEncoding: this.handshakeEncoding, | ||
handshake: this.handshake(socket) | ||
} | ||
const rpc = new ProtomuxRPC(getMux(socket), options) | ||
// @ts-ignore | ||
socket[RPCS_SYMBOL].set(this.id, rpc) | ||
rpc.on('open', (handshake) => this.onopen.bind(this)(handshake, socket)) | ||
this.methods.forEach(m => | ||
rpc.respond(m.name, m.options || {}, req => m.handler(req, socket)) | ||
) | ||
} | ||
/** | ||
* Connect to a peer if not already connected, and return Protomux RPC instance. | ||
* @param {Parameters<Slashtag['connect']>[0]} key | ||
* @returns {Promise<ProtomuxRPC | undefined>} | ||
*/ | ||
async rpc (key) { | ||
const socket = this.slashtag.connect(key) | ||
await socket.opened | ||
if (!socket) return | ||
this.setup(socket) | ||
// @ts-ignore | ||
return socket[RPCS_SYMBOL].get(this.id) | ||
} | ||
} | ||
/** @param {any} socket */ | ||
function getMux (socket) { | ||
// @ts-ignore TODO: temporary solution until Protomux is deduplicated | ||
// https://github.com/mafintosh/protomux/pull/5 | ||
socket.protomux = socket.protomux || socket.userData || Protomux.from(socket) | ||
return socket.protomux | ||
} | ||
export default SlashtagsRPC | ||
/** | ||
* @typedef {{ | ||
* name: string, | ||
* options?: import('protomux-rpc').methodOpts, | ||
* handler: (req: any, socket: SecretStream) => any | ||
* }} RPCMethod | ||
* | ||
* @typedef {import('@synonymdev/slashtag').Slashtag}Slashtag | ||
* @typedef {import('@synonymdev/slashtag/lib/interfaces').SecretStream} SecretStream | ||
*/ |
{ | ||
"name": "@synonymdev/slashtags-rpc", | ||
"version": "0.1.2", | ||
"description": "JsonRPC on top of Hyperswarm's secret-stream", | ||
"keywords": [ | ||
"slashtags", | ||
"rpc", | ||
"hyperswarm", | ||
"dht", | ||
"secret-stream" | ||
], | ||
"homepage": "https://github.com/synonymdev/slashtags/tree/master/packages/rpc/#readme", | ||
"version": "1.0.0-alpha.0", | ||
"description": "helper module for creating RPCs using Slashtags nodes", | ||
"type": "module", | ||
"main": "index.js", | ||
"types": "types/index.d.ts", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/synonymdev/slashtags.git" | ||
}, | ||
"scripts": { | ||
"build": "tsc", | ||
"clean": "rimraf types", | ||
"lint": "standard --fix", | ||
"test": "brittle test/** -cov", | ||
"depcheck": "npx depcheck", | ||
"fullcheck": "npm run lint && npm run clean && npm run build && npm run test && npm run depcheck", | ||
"prepublishOnly": "npm run fullcheck" | ||
}, | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/synonymdev/slashtags/issues" | ||
}, | ||
"license": "MIT", | ||
"homepage": "https://github.com/synonymdev/slashtags/tree/master/packages/rpc/#readme", | ||
"files": [ | ||
"*", | ||
"index.js", | ||
"lib/**.js", | ||
"types", | ||
"!**/*.tsbuildinfo" | ||
], | ||
"types": "./types/packages/rpc/src/index.d.ts", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/synonymdev/slashtags.git" | ||
}, | ||
"scripts": { | ||
"lint": "standard ./src ./test --fix", | ||
"build": "rm -rf dist types && ipjs build && tsc && cp -r types/ dist/types", | ||
"test": "hundreds ava", | ||
"prepublishOnly": "npm run lint && npm run build && npm run test && dependency-check dist --no-dev" | ||
}, | ||
"dependencies": { | ||
"dht-universal": "^0.3.2", | ||
"jsonrpc-lite": "^2.2.0" | ||
"protomux": "^3.3.0", | ||
"protomux-rpc": "^1.3.0" | ||
}, | ||
"peerDependencies": { | ||
"b4a": "^1.3.1" | ||
}, | ||
"gitHead": "0839320ecf3633eacdaa3f0ee2067859eeff2684", | ||
"browser": { | ||
".": "./cjs/src/index.js" | ||
}, | ||
"exports": { | ||
".": { | ||
"browser": "./esm/src/index.js", | ||
"require": "./cjs/src/index.js", | ||
"import": "./esm/src/index.js" | ||
} | ||
"devDependencies": { | ||
"@hyperswarm/testnet": "^3.1.0", | ||
"@synonymdev/slashtag": "^1.0.0-alpha.10", | ||
"brittle": "^3.0.2", | ||
"compact-encoding": "^2.11.0", | ||
"depcheck": "^1.4.3", | ||
"standard": "^17.0.0", | ||
"typescript": "^4.8.2" | ||
} | ||
} | ||
} |
109
README.md
@@ -1,3 +0,108 @@ | ||
# Slashtags Core | ||
# rpc | ||
> JsonRPC on top of Hyperswarm's secret-stream | ||
helper module for creating RPCs using Slashtags nodes | ||
## Installation | ||
``` | ||
npm install @synonymdev/slashtags-rpc | ||
``` | ||
## Usage | ||
```js | ||
import Slashtag from '@synonymdev/slashtag'; | ||
import c from 'compact-encoding'; | ||
class Foo extends SlashtagsRPC { | ||
get id() { | ||
return 'foo'; | ||
} | ||
get valueEncoding() { | ||
return c.string; | ||
} | ||
get handshakeEncoding() { | ||
return c.string; | ||
} | ||
handshake(socket) { | ||
return this.id + '-handshake:for:' + socket.remoteSlashtag.id; | ||
} | ||
onopen(handshake, socket) { | ||
this.emit('handshake', handshake, socket.remoteSlashtag); | ||
} | ||
get methods() { | ||
const self = this; | ||
return [ | ||
{ | ||
name: 'echo', | ||
handler: (req) => req, | ||
}, | ||
]; | ||
} | ||
async echo(key, message) { | ||
const rpc = await this.rpc(key); | ||
return rpc?.request('echo', message); | ||
} | ||
} | ||
const alice = new Slashtag(); | ||
const aliceFoo = new Foo(alice); | ||
``` | ||
## API | ||
#### `id` | ||
String identifies your RPC protocol. | ||
#### `valueEncoding` | ||
Default [compact encoding](https://github.com/compact-encoding/compact-encoding) for all requests and responses. | ||
#### `handshakeEncoding` | ||
Default [compact encoding](https://github.com/compact-encoding/compact-encoding) for handshake message, sent first thing on opening the channel. | ||
#### `handshake(stream) => any` | ||
A callback function that should returns the handshake value. The stream is passed with all the information needed including `stream.remoteSlashtag`. | ||
#### `onopen(handshake, stream)` | ||
A callback on opening the rpc, passing the handshake value from the remote peer, as well as the stream including `stream.remoteSlashtag` | ||
#### `methods` | ||
An array of methods objects that should be as following: | ||
```js | ||
{ | ||
name: string, | ||
options?: { | ||
// Optional encoding for both the request and response | ||
valueEncoding: Encoding, | ||
// Optional encoding for requests | ||
requestEncoding: Encoding, | ||
// Optional encoding for responses | ||
responseEncoding: Encoding | ||
}, | ||
// Handler that takes the decoded request and returns a response value | ||
handler: (req) => any | ||
} | ||
``` | ||
#### `rpc(key)` | ||
Returns a [ProtomuxRPC](https://www.npmjs.com/package/protomux-rpc) instance after connecting to a Slashtag by its key, id or url. If connection is already opened, the same RPC instance is returned. | ||
Internally, it uses `Slashtags.connect(key)` then sets up the RPC instance using `setup(socket)` | ||
#### `setup(socket)` | ||
Create a new [ProtomuxRPC](https://www.npmjs.com/package/protomux-rpc) instance on any stream if doesn't already exist. |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
2
109
Yes
9498
7
5
156
1
+ Addedprotomux@^3.3.0
+ Addedprotomux-rpc@^1.3.0
+ Addedbits-to-bytes@1.3.0(transitive)
+ Addedcompact-encoding-bitfield@1.0.0(transitive)
+ Addedprotomux@3.10.1(transitive)
+ Addedprotomux-rpc@1.6.0(transitive)
+ Addedunslab@1.3.0(transitive)
- Removeddht-universal@^0.3.2
- Removedjsonrpc-lite@^2.2.0
- Removed@hyperswarm/dht@5.0.25(transitive)
- Removed@hyperswarm/dht-relay@0.1.2(transitive)
- Removed@hyperswarm/secret-stream@5.2.0(transitive)
- Removedbind-easy@1.1.2(transitive)
- Removedblake2b@2.1.4(transitive)
- Removedblake2b-wasm@2.4.0(transitive)
- Removedbogon@1.1.0(transitive)
- Removedchacha20-universal@1.0.4(transitive)
- Removedcompact-encoding-net@1.2.0(transitive)
- Removeddebugging-stream@2.0.0(transitive)
- Removeddht-rpc@5.0.6(transitive)
- Removeddht-universal@0.3.2(transitive)
- Removedevents@3.3.0(transitive)
- Removedfast-fifo@1.3.2(transitive)
- Removedfunction-bind@1.1.2(transitive)
- Removedhasown@2.0.2(transitive)
- Removedhmac-blake2b@2.0.2(transitive)
- Removedinherits@2.0.4(transitive)
- Removedis-core-module@2.16.1(transitive)
- Removedisomorphic-ws@4.0.1(transitive)
- Removedjsonrpc-lite@2.2.0(transitive)
- Removedkademlia-routing-table@1.0.6(transitive)
- Removednanoassert@2.0.0(transitive)
- Removednapi-macros@2.2.2(transitive)
- Removednat-sampler@1.0.1(transitive)
- Removednode-gyp-build@4.8.4(transitive)
- Removednoise-curve-ed@1.0.4(transitive)
- Removednoise-handshake@2.2.0(transitive)
- Removedpath-parse@1.0.7(transitive)
- Removedprotomux@2.0.0(transitive)
- Removedreadable-stream@3.6.2(transitive)
- Removedrecord-cache@1.2.0(transitive)
- Removedresolve@1.22.10(transitive)
- Removedsafe-buffer@5.2.1(transitive)
- Removedsha256-universal@1.2.1(transitive)
- Removedsha256-wasm@2.2.2(transitive)
- Removedsha512-universal@1.2.1(transitive)
- Removedsha512-wasm@2.3.4(transitive)
- Removedsiphash24@1.3.1(transitive)
- Removedsodium-javascript@0.8.0(transitive)
- Removedsodium-native@3.4.14.3.1(transitive)
- Removedsodium-secretstream@1.1.1(transitive)
- Removedsodium-universal@3.1.04.0.1(transitive)
- Removedstreamx@2.21.1(transitive)
- Removedstring_decoder@1.3.0(transitive)
- Removedsupports-preserve-symlinks-flag@1.0.0(transitive)
- Removedtext-decoder@1.2.3(transitive)
- Removedtime-ordered-set@1.0.2(transitive)
- Removedtimeout-refresh@1.0.32.0.1(transitive)
- Removedunordered-set@2.0.1(transitive)
- Removedutil-deprecate@1.0.2(transitive)
- Removedutp-native@2.5.3(transitive)
- Removedws@8.18.0(transitive)
- Removedxache@1.2.1(transitive)
- Removedxsalsa20@1.2.0(transitive)