automerge / hypermerge

Build p2p collaborative applications without any server infrastructure in Node.js
MIT License
1.28k stars 66 forks source link

Problems in using channel.ts of the chat example in an electron.js app #84

Closed raphael10-collab closed 3 years ago

raphael10-collab commented 3 years ago

I'm trying to make the chat example working in an electron.js app I'm developing.

The chat example within the hypermerge folder works fine:

image

But with the electron.js app I'm developing I get these errors:

ERROR in /home/marco/webMatters/electronMatters/GGC-Electron/src/services/p2p/chat/channel.ts(20,24):
20:24 Cannot use namespace 'DocUrl' as a type.
    18 | class Channel extends EventEmitter {
    19 |   public readonly nick: string
  > 20 |   public readonly url: DocUrl
       |                        ^
    21 | 
    22 |   private _doc?: Doc<ChatChannel>
    23 |   private repo: Repo
ERROR in /home/marco/webMatters/electronMatters/GGC-Electron/src/services/p2p/chat/channel.ts(23,17):
23:17 Cannot use namespace 'Repo' as a type.
    21 | 
    22 |   private _doc?: Doc<ChatChannel>
  > 23 |   private repo: Repo
       |                 ^
    24 |   private swarm?: any
    25 | 
    26 |   constructor(nick: string, channelKey?: string) {   
ERROR in /home/marco/webMatters/electronMatters/GGC-Electron/src/services/p2p/chat/channel.ts(45,32):
45:32 Cannot use namespace 'DocUrl' as a type.
    43 |     } else {
    44 |       console.log(`Searching for chat channel ${channelKey} on network...`)
  > 45 |       this.url = channelKey as DocUrl
       |                                ^
    46 |     }
    47 |   }
    48 | 
ERROR in /home/marco/webMatters/electronMatters/GGC-Electron/src/services/p2p/chat/channel.ts(59,46):
59:46 Parameter 'state' implicitly has an 'any' type.
    57 |     })
    58 | 
  > 59 |     this.repo.change<ChatChannel>(this.url, (state) => {
       |                                              ^
    60 |       state.messages[Date.now()] = {
    61 |         joined: true,
    62 |         nick: this.nick,
ERROR in /home/marco/webMatters/electronMatters/GGC-Electron/src/services/p2p/chat/channel.ts(72,48):
72:48 Parameter 'state' implicitly has an 'any' type.
    70 |     const message = line.trim()
    71 |     if (message.length > 0) {
  > 72 |       this.repo.change<ChatChannel>(this.url, (state) => {
       |                                                ^
    73 |         state.messages[Date.now()] = {
    74 |           content: message,
    75 |           nick: this.nick,
ERROR in /home/marco/webMatters/electronMatters/GGC-Electron/src/types/hyperswarm.d.ts(8,18):
8:18 The expression of an export assignment must be an identifier or qualified name in an ambient context.
     6 |   export type SocketType = 'tcp' | 'utp'
     7 | 
  >  8 |   export default (options?: Options) => Hyperswarm
       |                  ^
     9 | 
    10 |   export interface Options {
    11 |     /** Optionally overwrite the default set of bootstrap servers */
ERROR in /home/marco/webMatters/electronMatters/GGC-Electron/src/types/hyperswarm.d.ts(8,41):
8:41 'Hyperswarm' only refers to a type, but is being used as a value here.
     6 |   export type SocketType = 'tcp' | 'utp'
     7 | 
  >  8 |   export default (options?: Options) => Hyperswarm
       |                                         ^
     9 | 
    10 |   export interface Options {
    11 |     /** Optionally overwrite the default set of bootstrap servers */
ERROR in /home/marco/webMatters/electronMatters/GGC-Electron/src/types/hyperswarm.d.ts(70,20):
70:20 Interface 'Hyperswarm' incorrectly extends interface 'EventEmitter'.
  The types returned by 'removeAllListeners(...)' are incompatible between these types.
    Type 'void' is not assignable to type 'this'.
      'this' could be instantiated with an arbitrary type which could be unrelated to 'void'.
    68 |   }
    69 | 
  > 70 |   export interface Hyperswarm extends EventEmitter {
       |                    ^
    71 |     join(dk: Buffer, options?: JoinOptions): void
    72 |     leave(dk: Buffer): void
    73 |     on<K extends keyof SwarmEvents>(name: K, cb: SwarmEvents[K]): this
ERROR in /home/marco/webMatters/electronMatters/GGC-Electron/src/types/sodium-native.d.ts(75,19):
75:19 'crypto_box_easy', which lacks return-type annotation, implicitly has an 'any' return type.
    73 |   ): boolean
    74 | 
  > 75 |   export function crypto_box_easy(
       |                   ^
    76 |     ciphertext: BoxCiphertext,
    77 |     message: Buffer,
    78 |     nonce: BoxNonce,
ERROR in /home/marco/webMatters/electronMatters/GGC-Electron/src/types/streamx.d.ts(6,16):
6:16 Class 'Readable' incorrectly implements interface 'ReadableStream'.
  Type 'Readable' is missing the following properties from type 'ReadableStream': addListener, once, removeListener,    
removeAllListeners, and 9 more.
    4 |   }
    5 | 
  > 6 |   export class Readable extends NodeJS.EventEmitter implements NodeJS.ReadableStream {
      |                ^
    7 |     static isBackpressured(readable: Readable): boolean
    8 | 
    9 |     [Symbol.asyncIterator]: () => AsyncIterableIterator<string | Buffer> 
ERROR in /home/marco/webMatters/electronMatters/GGC-Electron/src/types/streamx.d.ts(6,33):
6:33 Cannot extend an interface 'NodeJS.EventEmitter'. Did you mean 'implements'?
    4 |   }
    5 | 
  > 6 |   export class Readable extends NodeJS.EventEmitter implements NodeJS.ReadableStream {
      |                                 ^
   7 |     static isBackpressured(readable: Readable): boolean
    8 | 
    9 |     [Symbol.asyncIterator]: () => AsyncIterableIterator<string | Buffer>
ERROR in /home/marco/webMatters/electronMatters/GGC-Electron/src/types/streamx.d.ts(67,16):
67:16 Class 'Writable' incorrectly implements interface 'WritableStream'.
  Type 'Writable' is missing the following properties from type 'WritableStream': addListener, once, removeListener, 
removeAllListeners, and 9 more.
    65 |   }
   66 | 
  > 67 |   export class Writable extends NodeJS.EventEmitter implements NodeJS.WritableStream {
       |                ^
    68 |     static isBackpressured(writable: Writable): boolean
    69 | 
    70 |     writable: boolean
ERROR in /home/marco/webMatters/electronMatters/GGC-Electron/src/types/streamx.d.ts(67,33):
67:33 Cannot extend an interface 'NodeJS.EventEmitter'. Did you mean 'implements'?
    65 |   }
    66 | 
  > 67 |   export class Writable extends NodeJS.EventEmitter implements NodeJS.WritableStream {
       |                                 ^
    68 |     static isBackpressured(writable: Writable): boolean
    69 | 
   70 |     writable: boolean
ERROR in /home/marco/webMatters/electronMatters/GGC-Electron/src/types/streamx.d.ts(96,16):
96:16 Class 'Duplex' incorrectly implements interface 'ReadWriteStream'.
   Type 'Duplex' is missing the following properties from type 'ReadWriteStream': addListener, once, removeListener,     removeAllListeners, and 9 more.
    94 |   interface DuplexOptions extends ReadableOptions, WritableOptions {}
    95 | 
  > 96 |   export class Duplex extends Readable implements Writable, NodeJS.ReadWriteStream {
       |                ^
    97 |     static isBackpressured(stream: Writable | Readable | Duplex): boolean
    98 | 
99 |     writable: boolean
Version: typescript 4.0.2
Time: 4758ms

This is the complete package.json :

{
  "name": "GGC",
  "version": "0.1.0",
  "private": true,
  "license": "UNLICENSED",
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "test:unit": "vue-cli-service test:unit",
    "test:e2e": "vue-cli-service test:e2e",
    "electron:build": "vue-cli-service electron:build",
    "electron:serve": "vue-cli-service electron:serve",
    "postinstall": "electron-builder install-app-deps",
    "postuninstall": "electron-builder install-app-deps"
  },
  "main": "background.js",
  "dependencies": {
    "@types/prompt-sync": "^4.1.0",
    "chai-as-promised": "^7.1.1",
    "core-js": "^3.6.5",
    "diffy": "^2.1.0",
    "element-ui": "^2.13.2",
    "hypercore": "^9.5.0",
    "hypermerge": "^0.4.0",
    "immutable": "^4.0.0-rc.12",
    "lodash-id": "^0.14.0",
    "lowdb": "^1.0.0",
    "minimist": "^1.2.5",
    "moment": "^2.27.0",
    "node-gyp": "^7.1.0",
    "prompt-sync": "^4.2.0",
    "sodium-native": "^3.2.0",
    "strip-ansi": "^6.0.0",
    "tesseract.js": "^2.1.1",
    "utp-native": "^2.2.1",
    "vue": "^2.6.11",
    "vue-class-component": "^7.2.5",
    "vue-i18n": "^8.20.0",
    "vue-property-decorator": "^9.0.0",
    "vue-router": "^3.2.0",
    "vuex": "^3.5.1",
    "vuex-class": "^0.3.2"
  },
  "devDependencies": {
    "@types/bs58": "^4.0.1",
    "@types/chai": "^4.2.12",
    "@types/electron-devtools-installer": "^2.2.0",
    "@types/lowdb": "^1.0.9",
    "@types/minimist": "^1.2.0",
    "@types/mocha": "^8.0.1",
    "@types/node": "^14.6.4",
    "@types/proper-lockfile": "^4.1.1",
    "@types/pump": "^1.1.0",
    "@types/sodium-native": "^2.3.5",
    "@types/strip-ansi": "^5.2.1",
    "@types/tape": "^4.13.0",
    "@types/uuid": "^8.3.0",
    "@types/ws": "^7.2.6",
    "@vue/cli-plugin-babel": "~4.4.0",
    "@vue/cli-plugin-e2e-cypress": "~4.4.0",
    "@vue/cli-plugin-router": "~4.4.0",
    "@vue/cli-plugin-typescript": "~4.4.0",
    "@vue/cli-plugin-unit-mocha": "~4.4.0",
    "@vue/cli-plugin-vuex": "~4.4.0",
    "@vue/cli-service": "~4.4.0",
    "@vue/test-utils": "^1.0.3",
    "chai": "^4.1.2",
    "electron": "^10.0.0",
    "electron-devtools-installer": "^3.1.1",
    "hyperswarm": "^2.15.0",
    "prettier": "^2.1.1",
    "sass": "^1.26.10",
    "sass-loader": "^9.0.3",
    "spectron": "^11.0.0",
    "tape": "^5.0.1",
    "ts-node": "^9.0.0",
    "typescript": "^4.0.2",
    "vue-cli-plugin-electron-builder": "~2.0.0-rc.4",
    "vue-template-compiler": "^2.6.11",
    "webpack": "^4.44.1",
    "worker-plugin": "^5.0.0"
  }
}

I imported all hymerge types in /src/types:

/src/types$ ls -lah
total 64K
drwxr-xr-x  2 marco marco 4,0K set  7 17:45 .
drwxr-xr-x 10 marco marco 4,0K set  4 10:51 ..
-rw-r--r--  1 marco marco 3,1K ago 10 19:35 global.d.ts
-rw-r--r--  1 marco marco  975 set  7 17:31 hypercore-crypto.d.ts
-rw-r--r--  1 marco marco 6,1K set  7 17:43 hypercore.d.ts
-rw-r--r--  1 marco marco 3,5K set  7 17:42 hypercore-protocol.d.ts
-rw-r--r--  1 marco marco 3,7K set  7 17:43 hyperswarm.d.ts
-rw-r--r--  1 marco marco  504 set  7 17:04 locale.d.ts
-rw-r--r--  1 marco marco  622 set  7 17:43 noise-peer.d.ts
-rw-r--r--  1 marco marco   36 set  7 17:44 random-access-file.d.ts
-rw-r--r--  1 marco marco   38 set  7 17:44 random-access-memory.d.ts
-rw-r--r--  1 marco marco 1,1K set  7 17:44 simple-message-channels.d.ts
-rw-r--r--  1 marco marco 2,7K set  7 17:45 sodium-native.d.ts
-rw-r--r--  1 marco marco 4,6K set  7 17:45 streamx.d.ts

(base) marco@pc01:~/webMatters/electronMatters/GGC-Electron$ vue info

Environment Info:

  System:
    OS: Linux 5.4 Ubuntu 18.04.5 LTS (Bionic Beaver)
    CPU: (8) x64 Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz
  Binaries:
    Node: 14.5.0 - ~/.nvm/versions/node/v14.5.0/bin/node
    Yarn: 1.22.5 - /usr/bin/yarn
    npm: 6.14.5 - ~/.nvm/versions/node/v14.5.0/bin/npm
  Browsers:
    Chrome: 85.0.4183.83
    Firefox: 80.0
  npmPackages:
    @vue/babel-helper-vue-jsx-merge-props:  1.0.0 
    @vue/babel-plugin-transform-vue-jsx:  1.1.2 
    @vue/babel-preset-app:  4.4.6 
    @vue/babel-preset-jsx:  1.1.2 
    @vue/babel-sugar-functional-vue:  1.1.2 
    @vue/babel-sugar-inject-h:  1.1.2 
    @vue/babel-sugar-v-model:  1.1.2 
    @vue/babel-sugar-v-on:  1.1.2 
    @vue/cli-overlay:  4.4.6 
    @vue/cli-plugin-babel: ~4.4.0 => 4.4.6 
    @vue/cli-plugin-e2e-cypress: ~4.4.0 => 4.4.6 
    @vue/cli-plugin-router: ~4.4.0 => 4.4.6 
    @vue/cli-plugin-typescript: ~4.4.0 => 4.4.6 
    @vue/cli-plugin-unit-mocha: ~4.4.0 => 4.4.6 
    @vue/cli-plugin-vuex: ~4.4.0 => 4.4.6 
    @vue/cli-service: ~4.4.0 => 4.4.6 
    @vue/cli-shared-utils:  4.4.6 
    @vue/component-compiler-utils:  3.2.0 
    @vue/preload-webpack-plugin:  1.1.2 
    @vue/test-utils: ^1.0.3 => 1.0.3 
    @vue/web-component-wrapper:  1.2.0 
    babel-helper-vue-jsx-merge-props:  2.0.3 
    typescript: ^4.0.2 => 4.0.2 
    vue: ^2.6.11 => 2.6.11 
    vue-class-component: ^7.2.5 => 7.2.5 
    vue-cli-plugin-electron-builder: ~2.0.0-rc.4 => 2.0.0-rc.4 
    vue-hot-reload-api:  2.3.4 
    vue-i18n: ^8.20.0 => 8.20.0 
    vue-loader:  15.9.3 
    vue-property-decorator: ^9.0.0 => 9.0.0 
    vue-router: ^3.2.0 => 3.3.4 
    vue-style-loader:  4.1.2 
    vue-template-compiler: ^2.6.11 => 2.6.11 
    vue-template-es2015-compiler:  1.9.1 
    vuex: ^3.5.1 => 3.5.1 
    vuex-class: ^0.3.2 => 0.3.2 
  npmGlobalPackages:
    @vue/cli: 4.4.6

I discovered that these error disappear one by one if I put in /src folder of my electron.js app all these files: https://github.com/automerge/hypermerge/tree/master/src

But all these files are indeed already present in node_modules/hypermerge/src folder :

(base) marco@pc01:~/webMatters/electronMatters/GGC-Electron/node_modules/hypermerge/src$ ls -lah
total 252K
drwxr-xr-x  4 marco marco 4,0K set  7 14:30 .
drwxr-xr-x 10 marco marco 4,0K set  7 14:30 ..
-rw-r--r--  1 marco marco 3,4K giu 30 08:49 Actor.ts
-rw-r--r--  1 marco marco 1,2K giu 30 08:49 Block.ts
-rw-r--r--  1 marco marco 5,1K giu 30 08:49 ClockStore.ts
-rw-r--r--  1 marco marco 3,2K giu 30 08:49 Clock.ts
-rw-r--r--  1 marco marco 1,5K giu 30 08:49 Crawler.ts
-rw-r--r--  1 marco marco 3,6K giu 30 08:49 CryptoClient.ts
-rw-r--r--  1 marco marco 7,1K giu 30 08:49 Crypto.ts
-rw-r--r--  1 marco marco 3,5K giu 30 08:49 CursorStore.ts
-rw-r--r--  1 marco marco  450 giu 30 08:49 Debug.ts
-rw-r--r--  1 marco marco 4,3K giu 30 08:49 DocBackend.ts
-rw-r--r--  1 marco marco 5,0K giu 30 08:49 DocFrontend.ts
-rw-r--r--  1 marco marco 6,3K giu 30 08:49 FeedStore.ts
-rw-r--r--  1 marco marco 3,2K giu 30 08:49 FileServerClient.ts
-rw-r--r--  1 marco marco 3,8K giu 30 08:49 FileServer.ts
-rw-r--r--  1 marco marco 2,2K giu 30 08:49 FileStore.ts
-rw-r--r--  1 marco marco 2,9K giu 30 08:49 Handle.ts
-rw-r--r--  1 marco marco 1,4K giu 30 08:49 Heartbeat.ts
-rw-r--r--  1 marco marco 1,3K giu 30 08:49 hypercore.ts
-rw-r--r--  1 marco marco  582 giu 30 08:49 index.ts
-rw-r--r--  1 marco marco  568 giu 30 08:49 JsonBuffer.ts
-rw-r--r--  1 marco marco 1,3K giu 30 08:49 KeyStore.ts
-rw-r--r--  1 marco marco 1,8K giu 30 08:49 Keys.ts
-rw-r--r--  1 marco marco 1,2K giu 30 08:49 MapSet.ts
-rw-r--r--  1 marco marco 1,1K giu 30 08:49 MessageBus.ts
-rw-r--r--  1 marco marco 1,3K giu 30 08:49 MessageRouter.ts
-rw-r--r--  1 marco marco 7,7K giu 30 08:49 Metadata.ts
drwxr-xr-x  2 marco marco 4,0K set  7 14:30 migrations
-rw-r--r--  1 marco marco 4,3K giu 30 08:49 Misc.ts
-rw-r--r--  1 marco marco 6,4K giu 30 08:49 Multiplex.ts
-rw-r--r--  1 marco marco 3,6K giu 30 08:49 NetworkPeer.ts
-rw-r--r--  1 marco marco 3,9K giu 30 08:49 Network.ts
-rw-r--r--  1 marco marco 3,0K giu 30 08:49 PeerConnection.ts
-rw-r--r--  1 marco marco  341 giu 30 08:49 PeerMsg.ts
-rw-r--r--  1 marco marco 1,6K giu 30 08:49 Queue.ts
-rw-r--r--  1 marco marco 4,1K giu 30 08:49 ReplicationManager.ts
-rw-r--r--  1 marco marco  24K giu 30 08:49 RepoBackend.ts
-rw-r--r--  1 marco marco 7,9K giu 30 08:49 RepoFrontend.ts
-rw-r--r--  1 marco marco 5,8K giu 30 08:49 RepoMsg.ts
-rw-r--r--  1 marco marco 2,5K giu 30 08:49 Repo.ts
-rw-r--r--  1 marco marco  636 giu 30 08:49 SqlDatabase.ts
-rw-r--r--  1 marco marco 3,2K giu 30 08:49 StreamLogic.ts
-rw-r--r--  1 marco marco  818 giu 30 08:49 SwarmInterface.ts
-rw-r--r--  1 marco marco 1,9K giu 30 08:49 TraverseLogic.ts
drwxr-xr-x  2 marco marco 4,0K set  7 14:30 types
-rw-r--r--  1 marco marco  306 giu 30 08:49 WeakCache.ts

So.. why I get for example this error:

ERROR in /home/marco/webMatters/electronMatters/GGC-Electron/src/services/p2p/chat/channel.ts(20,24):
20:24 Cannot use namespace 'DocUrl' as a type.

?

How to solve the problem?

pvh commented 3 years ago

I haven't tried integrating hypermerge and vue, so I'm glad to see someone working on it. I suspect the issues are coming from directly including sodium-native, which I bet has had its interface changed since we last imported it to hypermerge.

You might want to look at pushpin, or github.com/pvh/needle, which already has all the electron bits hooked up, and just strip the React front-end out and replace it with vue.

raphael10-collab commented 3 years ago

@pvh does it mean that it would be better to remove sodium-native from the packages installed?

I will definetely have a look at pushpin and needle in order to understand how to, step by step, use hypermerge with vue.js and electron.js

pvh commented 3 years ago

sodium-native should already be included transitively as part of the hypermerge package dependencies and shouldn't require manual installation at the electron app level (see, for example: https://github.com/automerge/pushpin/blob/master/package.json).

raphael10-collab commented 3 years ago

Thank you Peter

pvh commented 3 years ago

BTW, feel free to ping me on the automerge slack -- would be happy to have a synchronous conversation about what you're trying to do and while I probably can't troubleshoot all your problems I'm quite willing to discuss your overall plan and tell you about the various bits we've already overcome.