diff --git a/package-lock.json b/package-lock.json index 10335c0..37838bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -150,6 +150,11 @@ "node": ">=6.0.0" } }, + "node_modules/@assemblyscript/loader": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.9.4.tgz", + "integrity": "sha512-HazVq9zwTVwGmqdwYzu7WyQ6FQVZ7SwET0KKQuKm55jD0IfUpZgN0OPIiZG3zV1iSrVYcN0bdwLRXI/VNCYsUA==" + }, "node_modules/@babel/code-frame": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", @@ -1764,6 +1769,86 @@ "progress-events": "^1.0.0" } }, + "node_modules/@helia/ipns": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@helia/ipns/-/ipns-1.1.3.tgz", + "integrity": "sha512-VnEQ4KPdRhrZTpMsrX6LlVCZdOwRY6YM4Cb0+GfzPPt0iDHSGuZ3dThlteHk7g1CLChzmjEgroUKNKjCU11PZQ==", + "dependencies": { + "@libp2p/interface-content-routing": "^2.1.0", + "@libp2p/interface-peer-id": "^2.0.1", + "@libp2p/interface-pubsub": "^4.0.1", + "@libp2p/interfaces": "^3.3.1", + "@libp2p/logger": "^2.0.6", + "@libp2p/peer-id": "^2.0.1", + "@libp2p/record": "^3.0.0", + "hashlru": "^2.3.0", + "interface-datastore": "^8.0.0", + "ipns": "^6.0.0", + "is-ipfs": "^8.0.1", + "multiformats": "^11.0.1", + "p-queue": "^7.3.0", + "progress-events": "^1.0.0", + "uint8arrays": "^4.0.3" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@helia/unixfs": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@helia/unixfs/-/unixfs-1.4.1.tgz", + "integrity": "sha512-IS/VLLXwGg+53ojyb3JPB3j8kxt5UtkYc92K/OTh3tPm22kMGmTm93AL6iBChGBiWOgVhtjNEwXEsQoDQkVRVw==", + "dependencies": { + "@helia/interface": "^1.0.0", + "@ipld/dag-pb": "^4.0.0", + "@libp2p/interfaces": "^3.3.1", + "@libp2p/logger": "^2.0.6", + "@multiformats/murmur3": "^2.1.2", + "hamt-sharding": "^3.0.2", + "interface-blockstore": "^5.0.0", + "ipfs-unixfs": "^11.0.0", + "ipfs-unixfs-exporter": "^13.1.0", + "ipfs-unixfs-importer": "^15.1.0", + "it-glob": "^2.0.4", + "it-last": "^3.0.1", + "it-pipe": "^3.0.1", + "merge-options": "^3.0.4", + "multiformats": "^11.0.1", + "progress-events": "^1.0.0", + "sparse-array": "^1.3.2" + } + }, + "node_modules/@ipld/dag-cbor": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@ipld/dag-cbor/-/dag-cbor-9.0.4.tgz", + "integrity": "sha512-HBNVngk/47pKNLTAelN6ORWgKkjJtQj96Xb+jIBtRShJGCsXgghj1TzTynTTIp1dZxwPe5rVIL6yjZmvdyP2Wg==", + "dependencies": { + "cborg": "^2.0.1", + "multiformats": "^12.0.1" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@ipld/dag-cbor/node_modules/cborg": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/cborg/-/cborg-2.0.3.tgz", + "integrity": "sha512-f1IbyqgRLQK4ruNM+V3WikfYfXQg/f/zC1oneOw1P7F/Dn2OJX6MaXIdei3JMpz361IjY7OENBKcE53nkJFVCQ==", + "bin": { + "cborg": "cli.js" + } + }, + "node_modules/@ipld/dag-cbor/node_modules/multiformats": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-12.0.1.tgz", + "integrity": "sha512-s01wijBJoDUqESWSzePY0lvTw7J3PVO9x2Cc6ASI5AMZM2Gnhh7BC17+nlFhHKU7dDzaCaRfb+NiqNzOsgPUoQ==", + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, "node_modules/@ipld/dag-pb": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/@ipld/dag-pb/-/dag-pb-4.0.5.tgz", @@ -2838,6 +2923,28 @@ "npm": ">=7.0.0" } }, + "node_modules/@multiformats/murmur3": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@multiformats/murmur3/-/murmur3-2.1.6.tgz", + "integrity": "sha512-kpJDN+o8B0gJaaqbdV/spIVPj35hqew4rEw8VzPmcITsLpHSgP8pJDeaVaGGVeX/UM8n4IGctLCxw7PBfVks+A==", + "dependencies": { + "multiformats": "^12.0.1", + "murmurhash3js-revisited": "^3.0.0" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@multiformats/murmur3/node_modules/multiformats": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-12.0.1.tgz", + "integrity": "sha512-s01wijBJoDUqESWSzePY0lvTw7J3PVO9x2Cc6ASI5AMZM2Gnhh7BC17+nlFhHKU7dDzaCaRfb+NiqNzOsgPUoQ==", + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, "node_modules/@noble/ciphers": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.1.4.tgz", @@ -4855,8 +4962,7 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/base-x": { "version": "3.0.9", @@ -4871,7 +4977,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, "funding": [ { "type": "github", @@ -4973,6 +5078,16 @@ "node": ">=8" } }, + "node_modules/bl": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", + "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", + "dependencies": { + "buffer": "^6.0.3", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "node_modules/blakejs": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", @@ -5165,7 +5280,6 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, "funding": [ { "type": "github", @@ -8441,6 +8555,19 @@ "node": ">=4.x" } }, + "node_modules/hamt-sharding": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/hamt-sharding/-/hamt-sharding-3.0.2.tgz", + "integrity": "sha512-f0DzBD2tSmLFdFsLAvOflIBqFPjerbA7BfmwO8mVho/5hXwgyyYhv+ijIzidQf/DpDX3bRjAQvhGoBFj+DBvPw==", + "dependencies": { + "sparse-array": "^1.3.1", + "uint8arrays": "^4.0.2" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, "node_modules/handlebars": { "version": "4.7.8", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", @@ -9072,7 +9199,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, "funding": [ { "type": "github", @@ -9154,8 +9280,7 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/ini": { "version": "1.3.8", @@ -9316,6 +9441,75 @@ "varint-decoder": "^1.0.0" } }, + "node_modules/ipfs-unixfs": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/ipfs-unixfs/-/ipfs-unixfs-11.0.1.tgz", + "integrity": "sha512-SD9dqn14bfgMfkPstsR/2Av3zCzYMj2ntQJab4HZucgX4nNV6K7guZh4Hf3kiL8ONff1Ogft1ekFU083DIKEdQ==", + "dependencies": { + "err-code": "^3.0.1", + "protons-runtime": "^5.0.0", + "uint8arraylist": "^2.4.3" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/ipfs-unixfs-exporter": { + "version": "13.1.6", + "resolved": "https://registry.npmjs.org/ipfs-unixfs-exporter/-/ipfs-unixfs-exporter-13.1.6.tgz", + "integrity": "sha512-pfFQThwa4/mbnLriHQso3wt25xcx5V0mBAOBPWx2jQv0QhgDtJSASyQrwwA2xE8F9zn0N3CWn7WDHhmM+EQ3sg==", + "dependencies": { + "@ipld/dag-cbor": "^9.0.0", + "@ipld/dag-pb": "^4.0.0", + "@multiformats/murmur3": "^2.0.0", + "err-code": "^3.0.1", + "hamt-sharding": "^3.0.0", + "interface-blockstore": "^5.0.0", + "ipfs-unixfs": "^11.0.0", + "it-filter": "^3.0.2", + "it-last": "^3.0.2", + "it-map": "^3.0.3", + "it-parallel": "^3.0.0", + "it-pipe": "^3.0.1", + "it-pushable": "^3.1.0", + "multiformats": "^11.0.0", + "p-queue": "^7.3.0", + "progress-events": "^1.0.0", + "uint8arrays": "^4.0.2" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/ipfs-unixfs-importer": { + "version": "15.1.7", + "resolved": "https://registry.npmjs.org/ipfs-unixfs-importer/-/ipfs-unixfs-importer-15.1.7.tgz", + "integrity": "sha512-dhcgfW5tigCcL3GhCCzEnNliU2M35mj23KYlcAHh7SCEMOHjNPZjm7kT8prrV24lJLite1QvS//BdcFS/yYY4Q==", + "dependencies": { + "@ipld/dag-pb": "^4.0.0", + "@multiformats/murmur3": "^2.0.0", + "err-code": "^3.0.1", + "hamt-sharding": "^3.0.0", + "interface-blockstore": "^5.0.0", + "interface-store": "^5.0.1", + "ipfs-unixfs": "^11.0.0", + "it-all": "^3.0.2", + "it-batch": "^3.0.2", + "it-first": "^3.0.2", + "it-parallel-batch": "^3.0.1", + "multiformats": "^11.0.0", + "progress-events": "^1.0.0", + "rabin-wasm": "^0.1.4", + "uint8arraylist": "^2.4.3", + "uint8arrays": "^4.0.2" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, "node_modules/ipns": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/ipns/-/ipns-6.0.3.tgz", @@ -9536,6 +9730,78 @@ "npm": ">=3" } }, + "node_modules/is-ipfs": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/is-ipfs/-/is-ipfs-8.0.1.tgz", + "integrity": "sha512-hoBSElmPath3aDdtaOpVZsuCh2SXTqvLML+H75S7iDgKdqNmENJ6tsRucP1HLfpqEyZ/uIlj/+ZBxIC/F8B5Eg==", + "dependencies": { + "@multiformats/mafmt": "^11.0.3", + "@multiformats/multiaddr": "^11.0.0", + "iso-url": "^1.1.3", + "multiformats": "^11.0.0", + "uint8arrays": "^4.0.2" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/is-ipfs/node_modules/@multiformats/mafmt": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@multiformats/mafmt/-/mafmt-11.1.2.tgz", + "integrity": "sha512-3n1o5eLU7WzTAPLuz3AodV7Iql6NWf7Ws8fqVaGT7o5nDDabUPYGBm2cZuh3OrqmwyCY61LrNUIsjzivU6UdpQ==", + "dependencies": { + "@multiformats/multiaddr": "^12.0.0" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/is-ipfs/node_modules/@multiformats/mafmt/node_modules/@multiformats/multiaddr": { + "version": "12.1.6", + "resolved": "https://registry.npmjs.org/@multiformats/multiaddr/-/multiaddr-12.1.6.tgz", + "integrity": "sha512-/2QwhnBzAJbR/f6halEzkbQLOrjwodrJsplfCbDfOOOZGOVBlNttNavb4fU6ks58yAs1aQ6bZrar8y08R+bagg==", + "dependencies": { + "@chainsafe/is-ip": "^2.0.1", + "@chainsafe/netmask": "^2.0.0", + "@libp2p/interface": "^0.1.1", + "dns-over-http-resolver": "^2.1.0", + "multiformats": "^12.0.1", + "uint8arrays": "^4.0.2", + "varint": "^6.0.0" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.6.0" + } + }, + "node_modules/is-ipfs/node_modules/@multiformats/mafmt/node_modules/multiformats": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-12.0.1.tgz", + "integrity": "sha512-s01wijBJoDUqESWSzePY0lvTw7J3PVO9x2Cc6ASI5AMZM2Gnhh7BC17+nlFhHKU7dDzaCaRfb+NiqNzOsgPUoQ==", + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/is-ipfs/node_modules/@multiformats/multiaddr": { + "version": "11.6.1", + "resolved": "https://registry.npmjs.org/@multiformats/multiaddr/-/multiaddr-11.6.1.tgz", + "integrity": "sha512-doST0+aB7/3dGK9+U5y3mtF3jq85KGbke1QiH0KE1F5mGQ9y56mFebTeu2D9FNOm+OT6UHb8Ss8vbSnpGjeLNw==", + "dependencies": { + "@chainsafe/is-ip": "^2.0.1", + "dns-over-http-resolver": "^2.1.0", + "err-code": "^3.0.1", + "multiformats": "^11.0.0", + "uint8arrays": "^4.0.2", + "varint": "^6.0.0" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, "node_modules/is-loopback-addr": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-loopback-addr/-/is-loopback-addr-2.0.1.tgz", @@ -9750,6 +10016,15 @@ "npm": ">=7.0.0" } }, + "node_modules/it-batch": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/it-batch/-/it-batch-3.0.2.tgz", + "integrity": "sha512-Ypepz/vCxNFOvFkUPFvoxGb8WzqainzhflRaJahp1MBo3Y42ICdrgR3xIwOFE6WAgO+UWUM0zeMlbUStsW9AIQ==", + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, "node_modules/it-batched-bytes": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/it-batched-bytes/-/it-batched-bytes-2.0.3.tgz", @@ -9805,6 +10080,40 @@ "npm": ">=7.0.0" } }, + "node_modules/it-glob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/it-glob/-/it-glob-2.0.4.tgz", + "integrity": "sha512-dRe4uw3MMScqx0vzx67T4gNfk6OMg7E2EjSZMiNoqnN9/wbTSrFEC/rZBEGJH3hMECW8ZX1iSjMCFHDAP8TXCA==", + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/it-glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/it-glob/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/it-handshake": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/it-handshake/-/it-handshake-4.1.3.tgz", @@ -9821,6 +10130,15 @@ "npm": ">=7.0.0" } }, + "node_modules/it-last": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/it-last/-/it-last-3.0.2.tgz", + "integrity": "sha512-aWoA5moJ7XSKe7+YuutBKhySroDDWkfjpo+UknekPh1M5YYdK4YNSPDarR+7o/NqRwzazwgzCi2UZzU0oqsprQ==", + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, "node_modules/it-length": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/it-length/-/it-length-3.0.2.tgz", @@ -9895,6 +10213,18 @@ "npm": ">=7.0.0" } }, + "node_modules/it-parallel-batch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/it-parallel-batch/-/it-parallel-batch-3.0.1.tgz", + "integrity": "sha512-4KTvYVYpCdrYUrAHSeH6o5hnHuDVHWzB8TztV/hdckUZzZIjbax4kVblmnzoYREX8Huj5+50irBu7b+c8jyKQg==", + "dependencies": { + "it-batch": "^3.0.0" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, "node_modules/it-pb-stream": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/it-pb-stream/-/it-pb-stream-4.0.2.tgz", @@ -10878,7 +11208,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -11258,6 +11587,14 @@ "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==" }, + "node_modules/murmurhash3js-revisited": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/murmurhash3js-revisited/-/murmurhash3js-revisited-3.0.0.tgz", + "integrity": "sha512-/sF3ee6zvScXMb1XFJ8gDsSnY+X8PbOyjIuBhtgis10W2Jx4ZjIhikUCIF9c4gpJxVnQIsPAFrSwTCuAjicP6g==", + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", @@ -11353,7 +11690,6 @@ "version": "2.6.12", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", - "dev": true, "dependencies": { "whatwg-url": "^5.0.0" }, @@ -11372,20 +11708,17 @@ "node_modules/node-fetch/node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "node_modules/node-fetch/node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "node_modules/node-fetch/node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -12508,6 +12841,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/rabin-wasm": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/rabin-wasm/-/rabin-wasm-0.1.5.tgz", + "integrity": "sha512-uWgQTo7pim1Rnj5TuWcCewRDTf0PEFTSlaUjWP4eY9EbLV9em08v89oCz/WO+wRxpYuO36XEHp4wgYQnAgOHzA==", + "dependencies": { + "@assemblyscript/loader": "^0.9.4", + "bl": "^5.0.0", + "debug": "^4.3.1", + "minimist": "^1.2.5", + "node-fetch": "^2.6.1", + "readable-stream": "^3.6.0" + }, + "bin": { + "rabin-wasm": "cli/bin.js" + } + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -12578,7 +12927,6 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -14399,6 +14747,11 @@ "source-map": "^0.6.0" } }, + "node_modules/sparse-array": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/sparse-array/-/sparse-array-1.3.2.tgz", + "integrity": "sha512-ZT711fePGn3+kQyLuv1fpd3rNSkNF8vd5Kv2D+qnOANeyKs3fx6bUMGWRPvgTTcYV64QMqZKZwcuaQSP3AZ0tg==" + }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", @@ -15872,8 +16225,7 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/uuid": { "version": "8.3.2", @@ -16447,7 +16799,10 @@ "watcher": { "name": "@mjolnir/watcher", "dependencies": { - "helia": "^1.3.12" + "@helia/ipns": "^1.1.3", + "@helia/unixfs": "^1.4.1", + "helia": "^1.3.12", + "it-to-buffer": "^4.0.2" }, "devDependencies": { "electron": "^25.4.0" diff --git a/watcher/assets/styles/global.css b/watcher/assets/styles/global.css index 52461a8..56fb84e 100644 --- a/watcher/assets/styles/global.css +++ b/watcher/assets/styles/global.css @@ -58,20 +58,6 @@ body { font-weight: bold; } -.input-file { - position: relative; -} - -.input-file input { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - opacity: 0; - cursor: pointer; -} - .input-file__text { display: flex; align-items: center; @@ -108,6 +94,10 @@ body { font-size: 0.8rem; } +.form .result.hidden { + display: none; +} + .form .result.error { background-color: #ef4444; } diff --git a/watcher/helia.mjs b/watcher/helia.mjs index 84b9c6a..7e89381 100644 --- a/watcher/helia.mjs +++ b/watcher/helia.mjs @@ -1,5 +1,15 @@ import { createHelia } from 'helia' +import { unixfs } from '@helia/unixfs' +import { ipns } from '@helia/ipns' -export async function createNode () { +export async function createNode() { return await createHelia() } + +export async function createUnixFs(helia) { + return await unixfs(helia) +} + +export async function createIPNS(helia) { + return await ipns(helia) +} diff --git a/watcher/main.js b/watcher/main.js index 87ec130..add2748 100644 --- a/watcher/main.js +++ b/watcher/main.js @@ -1,8 +1,20 @@ const path = require('path') -const { app, BrowserWindow, shell } = require('electron') +const fs = require('fs') +const { app, BrowserWindow, shell, ipcMain, dialog } = require('electron') -const gotTheLock = app.requestSingleInstanceLock() let mainWindow = null +const gotTheLock = app.requestSingleInstanceLock() +const data = { + node: null, + unixfs: null, + ipns: null +} + +const uploadPlaylist = async (dir, filename) => { + const bytes = fs.readFileSync(path.join(dir, filename)) + const cid = await data.unixfs.addBytes(bytes) + return cid +} const createWindow = () => { mainWindow = new BrowserWindow({ @@ -10,7 +22,8 @@ const createWindow = () => { height: 600, webPreferences: { preload: path.join(__dirname, './pages/preload.js'), - nodeIntegration: true + nodeIntegration: true, + enableRemoteModule: true } }) @@ -26,11 +39,167 @@ const createWindow = () => { return { action: 'deny' }; }); - if (process.env.NODE_ENV !== 'production') { + ipcMain.handle('dialog:openDirectory', async () => { + const { canceled, filePaths } = await dialog.showOpenDialog(mainWindow, { + properties: ['openDirectory'] + }) + if (canceled) { + return + } else { + return filePaths[0] + } + }) + + ipcMain.handle('upload:start', async (e, dir) => { + if (data.node === null) { + createHeliaNode() + return + } + + try { + if (!dir) { + throw new Error() + } + + const stat = await fs.promises.stat(dir) + if (!stat.isDirectory()) { + throw new Error() + } + } catch (err) { + return { + error: "Selected path is not a directory" + } + } + + let playlistFilename = null + let playlistFile = null + const uploadedFiles = [] + if (fs.readdirSync(dir).length !== 0) { + // sort files by created date + let fileNames = fs.readdirSync(dir) + + playlistFilename = fileNames.find((filename) => { + return filename.endsWith('.m3u8') + }) + + if (playlistFilename) { + mainWindow.webContents.send("upload:message", { message: "found playlist file", playlistFilename }) + fileNames = fileNames + .filter((filename) => filename !== playlistFilename) + .map((filename) => { + const stat = fs.statSync(path.join(dir, filename)) + return { + filename, + stat + } + }).sort((a, b) => { + return a.stat.birthtimeMs - b.stat.birthtimeMs + }) + + mainWindow.webContents.send("upload:message", { message: "catching up with existing files" }) + playlistFile = fs.readFileSync(path.join(dir, playlistFilename), 'utf8') + const files = fileNames.map(({ filename }) => { + return { + path: filename, + content: fs.readFileSync(path.join(dir, filename)) + } + }) + + for await (const file of data.unixfs.addAll(files, { wrapWithDirectory: true })) { + mainWindow.webContents.send("upload:message", { message: "uploaded segment", segment: file.path, matchingCID: file.cid.toString()}) + playlistFile = playlistFile.replace(file.path, file.cid.toString()) + uploadedFiles.push(file.path) + } + + fs.writeFileSync(path.join(dir, playlistFilename), playlistFile) + mainWindow.webContents.send("upload:message", { message: "updated playlist file", playlistFile }) + + const cid = await uploadPlaylist(dir, playlistFilename) + mainWindow.webContents.send("upload:message", { message: "uploaded playlist file", playlistFile: cid.toString() }) + const tb = await import('it-to-buffer') + const newFilename = "./sample.m3u8" + const d = await tb.default(await data.unixfs.cat(cid.toString())) + fs.writeFileSync(newFilename, d) + } + } + + mainWindow.webContents.send("upload:message", { message: "waiting for changes" }) + fs.watch(dir, async (eventType, filename) => { + if (playlistFilename) { + if (eventType !== 'rename' || filename !== playlistFilename) { + return + } + } else { + if (filename.endsWith('.m3u8')) { + mainWindow.webContents.send("upload:message", { message: "playlist file is created", filename }) + playlistFilename = filename + playlistFile = fs.readFileSync(path.join(dir, playlistFilename), 'utf8') + const files = fs.readdirSync(dir).map(({ filename }) => { + return { + path: filename, + content: fs.readFileSync(path.join(dir, filename)) + } + }) + + mainWindow.webContents.send("upload:message", { message: "uploading files" }) + for await (const file of data.unixfs.addAll(files, { wrapWithDirectory: true })) { + mainWindow.webContents.send("upload:message", { message: "uploaded segment", segment: file.path, matchingCID: file.cid.toString()}) + playlistFile = playlistFile.replace(file.path, file.cid.toString()) + uploadedFiles.push(file.path) + } + + fs.writeFileSync(path.join(dir, playlistFilename), playlistFile) + mainWindow.webContents.send("upload:message", { message: "updated playlist file", playlistFile }) + + const cid = await uploadPlaylist(dir, playlistFilename) + mainWindow.webContents.send("upload:message", { message: "uploaded playlist file", playlistFile: cid.toString() }) + } + return + } + + playlistFile = fs.readFileSync(path.join(dir, playlistFilename), 'utf8') + const files = fs.readdirSync(dir) + .map(({ filename }) => { + return { + path: filename, + content: fs.readFileSync(path.join(dir, filename)) + } + }) + + for await (const file of data.unixfs.addAll(files, { wrapWithDirectory: true })) { + mainWindow.webContents.send("upload:message", { message: "uploaded segment", segment: file.path, matchingCID: file.cid.toString()}) + playlistFile = playlistFile.replace(file.path, file.cid.toString()) + uploadedFiles.push(file.path) + } + fs.writeFileSync(path.join(dir, playlistFilename), playlistFile) + mainWindow.webContents.send("upload:message", { message: "updated playlist file", playlistFile }) + }) + + }) + + if (process.env.NODE_ENV !== 'production' && process.env.DISABLE_DEVTOOLS.toLowerCase() !== 'true') { mainWindow.webContents.openDevTools() } } +const createHeliaNode = async () => { + try { + // Helia is an ESM-only module but Electron currently only supports CJS + // at the top level, so we have to use dynamic imports to load it + const { createNode, createUnixFs, createIPNS } = await import('./helia.mjs') + data.node = await createNode() + const id = data.node.libp2p.peerId + data.unixfs = await createUnixFs(data.node) + data.ipns = await createIPNS(data.node) + + if (process.env.NODE_ENV !== 'production') { + console.log(id) + } + } catch (err) { + console.error(err) + } +} + if (!gotTheLock) { app.quit() } else { @@ -43,17 +212,7 @@ if (!gotTheLock) { app.whenReady().then(async () => { createWindow() - - try { - // Helia is an ESM-only module but Electron currently only supports CJS - // at the top level, so we have to use dynamic imports to load it - const { createNode } = await import('./helia.mjs') - const node = await createNode() - const id = node.libp2p.peerId - console.log(id) - } catch (err) { - console.error(err) - } + createHeliaNode() app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) createWindow() diff --git a/watcher/package.json b/watcher/package.json index e04aa82..3fa483a 100644 --- a/watcher/package.json +++ b/watcher/package.json @@ -8,6 +8,9 @@ "start": "electron ./main.js" }, "dependencies": { - "helia": "^1.3.12" + "@helia/ipns": "^1.1.3", + "@helia/unixfs": "^1.4.1", + "helia": "^1.3.12", + "it-to-buffer": "^4.0.2" } } diff --git a/watcher/pages/index.html b/watcher/pages/index.html index 380336a..1922765 100644 --- a/watcher/pages/index.html +++ b/watcher/pages/index.html @@ -15,12 +15,11 @@