diff --git a/dist/index.d.ts b/dist/index.d.ts index 793cd71..beda327 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -31,12 +31,14 @@ export declare class SwarmClient extends Client { export declare class Socket extends Client { private id; private eventUpdates; + private syncMutex; constructor(id: number); private _remotePublicKey?; get remotePublicKey(): Uint8Array; private _rawStream?; get rawStream(): Uint8Array; setup(): Promise; + private _initSync; on>(event: T, fn: EventEmitter.EventListener, context?: any): this; off>(event: T, fn?: EventEmitter.EventListener, context?: any, once?: boolean): this; write(message: string | Buffer): void; diff --git a/dist/index.d.ts.map b/dist/index.d.ts.map index 8b9f879..7baadef 100644 --- a/dist/index.d.ts.map +++ b/dist/index.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,MAAM,EAAW,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAU,QAAQ,EAAY,MAAM,gBAAgB,CAAC;AAI5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAKlD,qBAAa,WAAY,SAAQ,MAAM;IACrC,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,EAAE,CAAa;IACvB,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,eAAe,CAAM;IAE7B,OAAO,CAAC,MAAM,CAAC,CAAgB;IAC/B,OAAO,CAAC,mBAAmB,CAAC,CAG1B;IAEF,OAAO,CAAC,OAAO,CAA0C;IACzD,OAAO,CAAC,QAAQ,CAAkD;IAElE,IAAI,GAAG;;MAON;gBAEW,aAAa,UAAO,EAAE,aAAa,UAAQ;IAcvD,IAAI,KAAK,IAAI,MAAM,GAAG,SAAS,CAE9B;IAEY,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAgB5D,IAAI,IAAI,OAAO,CAAC,QAAQ,CAAC;IAGzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkBtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAMd,OAAO;IA2BR,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1C,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAG5B,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAI9B,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAQtE;AAQD,qBAAa,MAAO,SAAQ,MAAM;IAChC,OAAO,CAAC,EAAE,CAAS;IACnB,OAAO,CAAC,YAAY,CAAqC;gBAE7C,EAAE,EAAE,MAAM;IAKtB,OAAO,CAAC,gBAAgB,CAAC,CAAa;IAEtC,IAAI,eAAe,IAAI,UAAU,CAEhC;IAED,OAAO,CAAC,UAAU,CAAC,CAAa;IAEhC,IAAI,SAAS,IAAI,UAAU,CAE1B;IAEK,KAAK;IAOX,EAAE,CAAC,CAAC,SAAS,YAAY,CAAC,UAAU,CAAC,MAAM,GAAG,MAAM,CAAC,EACnD,KAAK,EAAE,CAAC,EACR,EAAE,EAAE,YAAY,CAAC,aAAa,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC,EAClD,OAAO,CAAC,EAAE,GAAG,GACZ,IAAI;IAiBP,GAAG,CAAC,CAAC,SAAS,YAAY,CAAC,UAAU,CAAC,MAAM,GAAG,MAAM,CAAC,EACpD,KAAK,EAAE,CAAC,EACR,EAAE,CAAC,EAAE,YAAY,CAAC,aAAa,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC,EACnD,OAAO,CAAC,EAAE,GAAG,EACb,IAAI,CAAC,EAAE,OAAO,GACb,IAAI;IASP,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAIrC,GAAG,IAAI,IAAI;IAUX,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,UAAU;CAInB;AAID,eAAO,MAAM,YAAY,+BAA4C,CAAC"} \ No newline at end of file +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,MAAM,EAAW,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAU,QAAQ,EAAY,MAAM,gBAAgB,CAAC;AAI5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAQlD,qBAAa,WAAY,SAAQ,MAAM;IACrC,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,EAAE,CAAa;IACvB,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,eAAe,CAAM;IAE7B,OAAO,CAAC,MAAM,CAAC,CAAgB;IAC/B,OAAO,CAAC,mBAAmB,CAAC,CAG1B;IAEF,OAAO,CAAC,OAAO,CAA0C;IACzD,OAAO,CAAC,QAAQ,CAAkD;IAElE,IAAI,GAAG;;MAON;gBAEW,aAAa,UAAO,EAAE,aAAa,UAAQ;IAcvD,IAAI,KAAK,IAAI,MAAM,GAAG,SAAS,CAE9B;IAEY,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAiB5D,IAAI,IAAI,OAAO,CAAC,QAAQ,CAAC;IAIzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkBtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAMd,OAAO;IA2BR,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1C,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAI9B,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAQtE;AAQD,qBAAa,MAAO,SAAQ,MAAM;IAChC,OAAO,CAAC,EAAE,CAAS;IACnB,OAAO,CAAC,YAAY,CAAqC;IAEzD,OAAO,CAAC,SAAS,CAAe;gBAEpB,EAAE,EAAE,MAAM;IAKtB,OAAO,CAAC,gBAAgB,CAAC,CAAa;IAEtC,IAAI,eAAe,IAAI,UAAU,CAEhC;IAED,OAAO,CAAC,UAAU,CAAC,CAAa;IAEhC,IAAI,SAAS,IAAI,UAAU,CAE1B;IAEK,KAAK;YASG,SAAS;IA4CvB,EAAE,CAAC,CAAC,SAAS,YAAY,CAAC,UAAU,CAAC,MAAM,GAAG,MAAM,CAAC,EACnD,KAAK,EAAE,CAAC,EACR,EAAE,EAAE,YAAY,CAAC,aAAa,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC,EAClD,OAAO,CAAC,EAAE,GAAG,GACZ,IAAI;IAiBP,GAAG,CAAC,CAAC,SAAS,YAAY,CAAC,UAAU,CAAC,MAAM,GAAG,MAAM,CAAC,EACpD,KAAK,EAAE,CAAC,EACR,EAAE,CAAC,EAAE,YAAY,CAAC,aAAa,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC,EACnD,OAAO,CAAC,EAAE,GAAG,EACb,IAAI,CAAC,EAAE,OAAO,GACb,IAAI;IASP,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAIrC,GAAG,IAAI,IAAI;IAUX,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,UAAU;CAInB;AAID,eAAO,MAAM,YAAY,+BAA4C,CAAC"} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index 2ec5ee6..e1ce452 100644 --- a/dist/index.js +++ b/dist/index.js @@ -4,6 +4,9 @@ import { blake2b } from "@noble/hashes/blake2b"; import b4a from "b4a"; // @ts-ignore import Backoff from "backoff.js"; +import { Mutex } from "async-mutex"; +// @ts-ignore +import Protomux from "protomux"; export class SwarmClient extends Client { useDefaultSwarm; id = 0; @@ -108,6 +111,7 @@ export class SwarmClient extends Client { export class Socket extends Client { id; eventUpdates = {}; + syncMutex = new Mutex(); constructor(id) { super(); this.id = id; @@ -124,6 +128,41 @@ export class Socket extends Client { let info = await this.callModuleReturn("socketGetInfo", { id: this.id }); this._remotePublicKey = info.remotePublicKey; this._rawStream = info.rawStream; + this._initSync(); + } + async _initSync() { + const mux = Protomux.from(this); + const [update] = this.connectModule("syncProtomux", { id: this.id }, async (data) => { + await this.syncMutex.acquire(); + ["remote", "local"].forEach((field) => { + const rField = `_${field}`; + data[field].forEach((item) => { + if (!mux[rField][item]) { + while (item > mux[rField].length) { + mux[rField].push(null); + } + } + if (!mux[rField][item]) { + mux[rField][item] = null; + } + }); + }); + data.free.forEach((index) => { + if (mux._free[index] === null) { + mux._free[index] = undefined; + } + }); + mux._free = mux._free.filter((item) => item !== undefined); + this.syncMutex.release(); + }); + const send = (mux) => { + update({ + remote: Object.keys(mux._remote), + local: Object.keys(mux._local), + free: mux._free, + }); + }; + mux.syncState = send.bind(undefined, mux); } on(event, fn, context) { const [update, promise] = this.connectModule("socketListenEvent", { id: this.id, event: event }, (data) => {