Browse Source

test queue, add some tasks but make them inactive for now.

feature/task-queue
dskvr 2 years ago
parent
commit
3ba985bed1
  1. 12
      scripts/canonicals.js
  2. 0
      src/components/TaskManager.vue
  3. 65
      src/components/relays/blocks/RelaysResultTable.vue
  4. 92
      src/components/relays/tasks/RefreshTask.vue
  5. 151
      src/components/relays/tasks/RelayCanonicalsTask.vue
  6. 164
      src/components/relays/tasks/RelayOperatorTask.vue
  7. 45
      src/components/relays/tasks/TasksManager.vue
  8. 106
      src/components/relays/tasks/TemplateTask.vue
  9. 28
      src/components/user/AuthComponent.vue
  10. 2
      src/store/profiles.js
  11. 7
      src/store/relays.js
  12. 2
      src/store/tasks.js

12
scripts/canonicals.js

@ -39,13 +39,7 @@ async function run(){
// console.log(`wtf`, relays.length) // console.log(`wtf`, relays.length)
// console.log(`hashes`, Object.keys(hashes).length) // console.log(`hashes`, Object.keys(hashes).length)
await sieve() await sieve()
setInterval( ()=> {
console.log('status', '\ntotal sent:', totalSent, '\noks:', oks, '\nnotices:', notices, '\n\n')
}, 60000)
await broadcast() await broadcast()
process.exit() process.exit()
} }
@ -131,6 +125,10 @@ function checkMissing(){
} }
async function broadcast(){ async function broadcast(){
setInterval( ()=> {
console.log('status', '\ntotal sent:', totalSent, '\noks:', oks, '\nnotices:', notices, '\n\n')
}, 60000)
for(let i=0;i<missing.length;i++){ for(let i=0;i<missing.length;i++){
const relay = missing[i] const relay = missing[i]
const event = { const event = {
@ -152,7 +150,7 @@ async function broadcast(){
pool.send(['EVENT', signedEvent]) pool.send(['EVENT', signedEvent])
totalSent++ totalSent++
console.log('total sent, backlog', totalSent) console.log('total sent, backlog', totalSent)
await delay(60*1000) await delay(10*1000)
} }
console.log('finished.') console.log('finished.')
} }

0
src/components/TaskManager.vue

65
src/components/relays/blocks/RelaysResultTable.vue

@ -27,6 +27,12 @@
</label> </label>
</span> </span>
</th> </th>
<th scope="col" class="relative py-3.5 pl-0 pr-0 sm:pr-0">
<code class="text-xs block">Favorite</code>
</th>
<!-- <th scope="col" class="relative py-3.5 pl-0 pr-0 sm:pr-0" v-if="isLoggedIn()">
<code class="text-xs block">Upvote</code>
</th> -->
<th scope="col" class="hidden md:table-cell lg:table-cell xl:table-cell verified"> <th scope="col" class="hidden md:table-cell lg:table-cell xl:table-cell verified">
<!-- <span class="verified-shape-wrapper"> <!-- <span class="verified-shape-wrapper">
<span class="shape verified"></span> <span class="shape verified"></span>
@ -53,9 +59,6 @@
<code class="text-xs block">Write</code> <code class="text-xs block">Write</code>
<!-- --> <!-- -->
</th> </th>
<th scope="col" class="relative py-3.5 pl-0 pr-0 sm:pr-0">
<code class="text-xs block">Favorite</code>
</th>
</tr> </tr>
</thead> </thead>
<tbody class="divide-y divide-gray-200 bg-white"> <tbody class="divide-y divide-gray-200 bg-white">
@ -74,6 +77,23 @@
<a :href="`/relay/${relayClean(relay)}`">{{ relay.replace('wss://', '') }}</a> <a :href="`/relay/${relayClean(relay)}`">{{ relay.replace('wss://', '') }}</a>
</td> </td>
<td class="w-16 fav text-center">
<a
class="hover:opacity-100 cursor-pointer"
:class="store.relays.isFavorite(relay) ? 'opacity-100' : 'opacity-10'"
@click="store.relays.toggleFavorite(relay)">
</a>
</td>
<!-- <td class="w-16 fav text-center" v-if="isLoggedIn()">
<a
class=" hover:opacity-100 cursor-pointer opacity-20"
@click="likeRelay(relay)">
👍
</a>
</td> -->
<td class="w-12 verified text-center md:table-cell lg:table-cell xl:table-cell"> <td class="w-12 verified text-center md:table-cell lg:table-cell xl:table-cell">
<span v-if="this.results[relay]?.identities"> <span v-if="this.results[relay]?.identities">
<span v-tooltip:top.tooltip="identityList(relay)"> <span class="verified-shape-wrapper cursor-pointer" v-if="Object.entries(results[relay]?.identities).length"><span class="shape verified"></span></span></span> <span v-tooltip:top.tooltip="identityList(relay)"> <span class="verified-shape-wrapper cursor-pointer" v-if="Object.entries(results[relay]?.identities).length"><span class="shape verified"></span></span></span>
@ -107,14 +127,7 @@
<span class="m-auto block" :class="getCheckIndicator(relay, 'write')">&nbsp;</span> <span class="m-auto block" :class="getCheckIndicator(relay, 'write')">&nbsp;</span>
</td> </td>
<td class="w-16 fav text-center" :key="generateKey(relay, 'check.write')">
<a
class=" hover:opacity-100 cursor-pointer"
:class="store.relays.isFavorite(relay) ? 'opacity-100' : 'opacity-10'"
@click="store.relays.toggleFavorite(relay)">
</a>
</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@ -138,10 +151,36 @@
import NostrSyncPopoverNag from '@/components/relays/partials/NostrSyncPopoverNag.vue' import NostrSyncPopoverNag from '@/components/relays/partials/NostrSyncPopoverNag.vue'
import RelaysLib from '@/shared/relays-lib.js' import RelaysLib from '@/shared/relays-lib.js'
import UserLib from '@/shared/user-lib.js'
import {validateEvent, getEventHash, verifySignature} from 'nostr-tools'
import { setupStore } from '@/store' import { setupStore } from '@/store'
const localMethods = {} const localMethods = {
async likeRelay(relay){
const id = this.store.relays.getCanonical(relay)
const event = {
created_at: Math.floor(Date.now()/1000),
kind: 7,
content: '+',
tags: [
['e', id],
['p', this.store.user.getPublicKey]
],
pubkey: this.store.user.getPublicKey
}
event.id = getEventHash(event)
console.log('like event', event)
const signedEvent = await window.nostr.signEvent(event)
let ok = validateEvent(signedEvent)
let veryOk = await verifySignature(signedEvent)
console.log('valid event?', ok, veryOk)
},
}
export default defineComponent({ export default defineComponent({
name: 'ListClearnet', name: 'ListClearnet',
@ -310,7 +349,7 @@
return (relay) => relay.replace('wss://', '') return (relay) => relay.replace('wss://', '')
}, },
}, },
methods: Object.assign(RelaysLib, localMethods), methods: Object.assign(RelaysLib, UserLib, localMethods),
}) })
</script> </script>

92
src/components/relays/tasks/RefreshTask.vue

@ -1,23 +1,26 @@
<template> <template>
<span class="text-white lg:text-sm mr-2 ml-2 mt-1.5 text-xs"> <span
<span v-if="!store.tasks.isProcessing(`relays`)">Checked {{ sinceLast }} ago</span> v-if="!store.tasks.isActive || store.tasks.getActiveSlug === this.taskSlug"
<span v-if="store.tasks.isProcessing(`relays`)" class="italic lg:pr-9"> class="text-white lg:text-sm mr-2 ml-2 mt-1.5 text-xs">
<span v-if="!store.tasks.isProcessing(this.taskSlug)">Checked {{ sinceLast }} ago</span>
<span v-if="store.tasks.isProcessing(this.taskSlug)" class="italic lg:pr-9">
<svg class="animate-spin mr-1 -mt-0.5 h-4 w-5 text-white inline" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"> <svg class="animate-spin mr-1 -mt-0.5 h-4 w-5 text-white inline" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle> <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path> <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg> </svg>
{{ this.store.tasks.getProcessed('relays').length }}/{{ this.relays.length }} Relays Checked {{ this.store.tasks.getProcessed(this.taskSlug).length }}/{{ this.relays.length }} Relays Checked
</span> </span>
</span> </span>
<span class="text-white text-sm mr-2 mt-1.5" v-if="!store.tasks.isProcessing(`relays`)">-</span> <span class="text-white text-sm mr-2 mt-1.5" v-if="!store.tasks.isProcessing(this.taskSlug)">-</span>
<span class="text-white text-sm mr-2 mt-1.5" v-if="store.prefs.refresh && !store.tasks.isProcessing(`relays`)"> <span class="text-white text-sm mr-2 mt-1.5" v-if="store.prefs.refresh && !store.tasks.isProcessing(this.taskSlug)">
Next check in: {{ untilNext }} Next check in: {{ untilNext }}
</span> </span>
<button <button
v-if="!store.tasks.isProcessing(`relays`)" v-if="!store.tasks.isProcessing(this.taskSlug)"
class="mr-8 my-1 py-0 px-3 text-xs rounded border-b-3 border-slate-700 bg-slate-500 font-bold text-white hover:border-slate-500 hover:bg-slate-400" class="mr-8 my-1 py-0 px-3 text-xs rounded border-b-3 border-slate-700 bg-slate-500 font-bold text-white hover:border-slate-500 hover:bg-slate-400"
:disabled='store.tasks.isProcessing(`relays`)' :disabled='store.tasks.isProcessing(this.taskSlug)'
@click="refreshNow()"> @click="refreshNow()">
Check{{ relay ? ` ${relay}` : "" }} Now Check{{ relay ? ` ${relay}` : "" }} Now
</button> </button>
@ -63,7 +66,7 @@ const localMethods = {
} }
}, },
addToQueue: function(id, fn, unique){ queueJob: function(id, fn, unique){
this.store.tasks.addJob({ this.store.tasks.addJob({
id: id, id: id,
handler: fn, handler: fn,
@ -80,12 +83,12 @@ const localMethods = {
this.untilNext = this.timeUntilRefresh() this.untilNext = this.timeUntilRefresh()
this.sinceLast = this.timeSinceRefresh() this.sinceLast = this.timeSinceRefresh()
if(this.store.tasks.getProcessed('relays').length >= this.relays.length){ if(this.store.tasks.getProcessed(this.taskSlug).length >= this.relays.length){
this.store.tasks.updateNow('relays') this.store.tasks.updateNow(this.taskSlug)
this.store.tasks.finishProcessing('relays') this.store.tasks.finishProcessing(this.taskSlug)
} }
if(!this.store.tasks.isProcessing('relays')) if(!this.store.tasks.isProcessing(this.taskSlug))
this.invalidate() this.invalidate()
}, 1000) }, 1000)
}, },
@ -103,19 +106,19 @@ const localMethods = {
}, },
invalidate: async function(force, single){ invalidate: async function(force, single){
// console.log('expired', !this.store.tasks.getLastUpdate('relays'), Date.now() - this.store.tasks.getLastUpdate('relays') > this.store.prefs.expireAfter) // console.log('expired', !this.store.tasks.getLastUpdate(this.taskSlug), Date.now() - this.store.tasks.getLastUpdate(this.taskSlug) > this.store.prefs.expireAfter)
if( (!this.isExpired('relays') && !force) ) if( (!this.isExpired(this.taskSlug) && !force) )
return return
// console.log('windowActive', this.windowActive) // console.log('windowActive', this.windowActive)
if(!this.windowActive) if(!this.windowActive)
return return
this.addToQueue('relays', async () => { this.queueJob(this.taskSlug, async () => {
const relays = this.relays.filter( relay => !this.store.tasks.isProcessed('relays', relay) ) const relays = this.relays.filter( relay => !this.store.tasks.isProcessed(this.taskSlug, relay) )
console.log('unprocessed relays', console.log('unprocessed relays',
this.relays.filter( relay => !this.store.tasks.getProcessed('relays').includes(relay))) this.relays.filter( relay => !this.store.tasks.getProcessed(this.taskSlug).includes(relay)))
if(single) { if(single) {
await this.check(single) await this.check(single)
@ -139,25 +142,25 @@ const localMethods = {
}, },
completeRelay: function(relay, result){ completeRelay: function(relay, result){
if(this.store.tasks.isProcessed('relays', relay)) if(this.store.tasks.isProcessed(this.taskSlug, relay))
return return
this.store.tasks.addProcessed('relays', relay) this.store.tasks.addProcessed(this.taskSlug, relay)
if(result) { if(result) {
this.results[relay] = result this.results[relay] = result
this.setCache(result) this.setCache(result)
} }
if(this.store.tasks.getProcessed('relays').length >= this.relays.length) if(this.store.tasks.getProcessed(this.taskSlug).length >= this.relays.length)
this.completeAll() this.completeAll()
}, },
completeAll: function(){ completeAll: function(){
//console.log('completed') //console.log('completed')
this.store.tasks.completeJob() this.store.tasks.completeJob()
// this.store.tasks.finishProcessing('relays') // this.store.tasks.finishProcessing(this.taskSlug)
this.store.tasks.updateNow('relays') this.store.tasks.updateNow(this.taskSlug)
this.store.relays.setAggregateCache('public', Object.keys(this.results).filter( result => this.results[result].aggregate === 'public' )) this.store.relays.setAggregateCache('public', Object.keys(this.results).filter( result => this.results[result].aggregate === 'public' ))
this.store.relays.setAggregateCache('restricted', Object.keys(this.results).filter( result => this.results[result].aggregate === 'restricted' )) this.store.relays.setAggregateCache('restricted', Object.keys(this.results).filter( result => this.results[result].aggregate === 'restricted' ))
this.store.relays.setAggregateCache('offline', Object.keys(this.results).filter( result => this.results[result].aggregate === 'offline' )) this.store.relays.setAggregateCache('offline', Object.keys(this.results).filter( result => this.results[result].aggregate === 'offline' ))
@ -171,7 +174,7 @@ const localMethods = {
checkLatency: true, checkLatency: true,
getInfo: true, getInfo: true,
getIdentities: true, getIdentities: true,
debug: true, // debug: true,
connectTimeout: this.getDynamicTimeout, connectTimeout: this.getDynamicTimeout,
readTimeout: this.getDynamicTimeout, readTimeout: this.getDynamicTimeout,
writeTimeout: this.getDynamicTimeout, writeTimeout: this.getDynamicTimeout,
@ -216,10 +219,10 @@ const localMethods = {
return Math.floor(parseFloat(sum/total)); return Math.floor(parseFloat(sum/total));
}, },
timeUntilRefresh(){ timeUntilRefresh(){
return this.timeSince(Date.now()-(this.store.tasks.getLastUpdate('relays')+this.store.prefs.duration-Date.now())) return this.timeSince(Date.now()-(this.store.tasks.getLastUpdate(this.taskSlug)+this.store.prefs.duration-Date.now()))
}, },
timeSinceRefresh(){ timeSinceRefresh(){
return this.timeSince(this.store.tasks.getLastUpdate('relays')) || Date.now() return this.timeSince(this.store.tasks.getLastUpdate(this.taskSlug)) || Date.now()
}, },
} }
@ -233,6 +236,22 @@ export default defineComponent({
results: results results: results
} }
}, },
data() {
return {
relay: "",
relays: [],
refresh: {},
untilNext: null,
lastUpdate: null,
sinceLast: null,
interval: null,
windowActive: true,
averageLatency: 200,
pageOpen: 0,
taskSlug: 'relays/check'
// history: null
}
},
created(){ created(){
clearInterval(this.interval) clearInterval(this.interval)
// document.addEventListener("visibilitychange", () => { // document.addEventListener("visibilitychange", () => {
@ -254,7 +273,7 @@ export default defineComponent({
// document.removeEventListener("visibilitychange", this.handleVisibility, false); // document.removeEventListener("visibilitychange", this.handleVisibility, false);
}, },
beforeMount(){ beforeMount(){
this.lastUpdate = this.store.tasks.getLastUpdate('relays') this.lastUpdate = this.store.tasks.getLastUpdate(this.taskSlug)
this.untilNext = this.timeUntilRefresh() this.untilNext = this.timeUntilRefresh()
this.sinceLast = this.timeSinceRefresh() this.sinceLast = this.timeSinceRefresh()
@ -274,9 +293,9 @@ export default defineComponent({
mounted(){ mounted(){
this.migrateLegacy() this.migrateLegacy()
console.log('is processing', this.store.tasks.isProcessing(`relays`)) console.log('is processing', this.store.tasks.isProcessing(this.taskSlug))
if(this.store.tasks.isProcessing(`relays`)) if(this.store.tasks.isProcessing(this.taskSlug))
this.invalidate(true) this.invalidate(true)
else else
this.invalidate() this.invalidate()
@ -298,21 +317,6 @@ export default defineComponent({
} }
}, },
}, },
data() {
return {
relay: "",
relays: [],
refresh: {},
untilNext: null,
lastUpdate: null,
sinceLast: null,
interval: null,
windowActive: true,
averageLatency: 200,
pageOpen: 0,
// history: null
}
},
}) })
</script> </script>

151
src/components/relays/tasks/RelayCanonicalsTask.vue

@ -1,7 +1,158 @@
<template> <template>
<span
v-if="this.store.tasks.getActiveSlug === taskSlug"
class="text-white lg:text-sm mr-2 ml-2 mt-1.5 text-xs">
<span>Getting canonicals...</span>
</span>
</template> </template>
<style scoped>
</style>
<script> <script>
import crypto from 'crypto'
import { RelayPool } from 'nostr'
import { defineComponent, toRefs } from 'vue'
import { setupStore } from '@/store'
import SharedMethods from '@/shared/relays-lib.js'
import SharedComputed from '@/shared/computed.js'
import { relays } from '../../../../relays.yaml'
const localMethods = {
queueJob: function(id, fn, unique){
this.store.tasks.addJob({
id: id,
handler: fn,
unique: unique
})
},
invalidate(force){
if( (!this.isExpired(this.taskSlug) && !force) )
return
const subid = crypto.randomBytes(40).toString('hex')
this.queueJob(
this.taskSlug,
async () => {
const instance = new RelayPool(['wss://nostr.sandwich.farm', 'wss://relay.nostr.ch'])
instance
.on('open', r => {
r.subscribe(subid, {
limit: 1000,
kinds: [1],
"#t": ['canonical'],
authors:[ 'b3b0d247f66bf40c4c9f4ce721abfe1fd3b7529fbc1ea5e64d5f0f8df3a4b6e6' ]
})
})
.on('event', (relay, _subid, event) => {
if(_subid.includes(subid)){
console.log('canonical event', event.id)
const hash = event.tags.filter( tag => tag[0] === 'h')[0][1]
this.hashes[hash] = event.id
}
})
await this.delay(5000)
instance.unsubscribe()
instance.close()
relays.forEach( relay => {
const hash = this.hash(relay)
if( typeof this.hashes[hash] === "undefined" )
return
this.canonicals[relay] = this.hashes[hash] //event.id
})
console.log('hashes found', Object.keys(this.hashes).length)
console.log('canonicals found', Object.keys(this.canonicals).length, this.canonicals)
console.log('from store', this.store.relays.getCanonicals)
this.store.relays.setCanonicals(this.canonicals)
this.store.tasks.completeJob()
},
true
)
},
timeUntilRefresh(){
return this.timeSince(Date.now()-(this.store.tasks.getLastUpdate(this.taskSlug)+this.store.prefs.duration-Date.now()))
},
timeSinceRefresh(){
return this.timeSince(this.store.tasks.getLastUpdate(this.taskSlug)) || Date.now()
},
hash(relay){
return crypto.createHash('md5').update(relay).digest('hex');
}
}
export default defineComponent({
name: 'TemplateTask',
components: {},
data() {
return {
taskSlug: 'relays/canonicals',
canonicals: new Object(),
hashes: new Object()
}
},
setup(props){
const {resultsProp: results} = toRefs(props)
return {
store : setupStore(),
results: results
}
},
created(){
clearInterval(this.interval)
},
unmounted(){
clearInterval(this.interval)
},
beforeMount(){
this.lastUpdate = this.store.tasks.getLastUpdate(this.taskSlug)
this.untilNext = this.timeUntilRefresh()
this.sinceLast = this.timeSinceRefresh()
this.relays = Array.from(new Set(relays))
},
mounted(){
console.log('task', this.taskSlug, 'is processing:', this.store.tasks.isProcessing(this.taskSlug))
if(this.store.tasks.isProcessing(this.taskSlug))
this.invalidate(true)
else
this.invalidate()
},
updated(){},
computed: Object.assign(SharedComputed, {
getDynamicTimeout: function(){
return this.averageLatency*this.relays.length
},
}),
methods: Object.assign(localMethods, SharedMethods),
props: {
resultsProp: {
type: Object,
default(){
return {}
}
},
},
})
</script> </script>
<style scoped>
#refresh { font-size: 12pt; color:#666; margin-bottom:15px }
#refresh button { cursor: pointer; border-radius: 3px; border: 1px solid #a0a0a0; color:#333 }
#refresh button:hover {color:#000;}
#refresh button[disabled] {color:#999 !important; border-color:#e0e0e0}
</style>

164
src/components/relays/tasks/RelayOperatorTask.vue

@ -0,0 +1,164 @@
<template>
<span
v-if="this.store.tasks.getActiveSlug === taskSlug"
class="text-white lg:text-sm mr-2 ml-2 mt-1.5 text-xs">
<span>Retrieving operator profiles...</span>
</span>
</template>
<style scoped>
</style>
<script>
import { defineComponent, toRefs } from 'vue'
import crypto from 'crypto'
import { setupStore } from '@/store'
import { RelayPool } from 'nostr'
import SharedMethods from '@/shared/relays-lib.js'
import SharedComputed from '@/shared/computed.js'
import { relays } from '../../../../relays.yaml'
const localMethods = {
queueJob: function(id, fn, unique){
this.store.tasks.addJob({
id: id,
handler: fn,
unique: unique
})
},
invalidate(force){
if( !this.isExpired(this.taskSlug) && !force )
return
this.queueJob(
this.taskSlug,
() => {
const relays = this.store.relays.getAggregateCache('public')
console.log('public relays', this.store.relays.getAggregateCache('public').length)
const pool = new RelayPool(relays)
const subid = crypto.randomBytes(40).toString('hex')
const uniques = {
0: new Set(),
1: new Set(),
7: new Set(),
}
const limits = {
0: 1,
1: 20,
7: 100
}
const kinds = [0,1,7]
//remove kind 1 for non-single page tasks
pool
.on('open', relay => {
relay.subscribe(subid, { limit:10, kinds:kinds, authors:[this.result.info.pubkey] })
})
.on('event', (relay, sub_id, event) => {
console.log(event)
if(!kinds.includes(event.kind))
return
if(sub_id !== subid)
return
const u = uniques[event.kind],
l = limits[event.kind]
if( u.has(event.id) || u.size > l )
return
if( !(event instanceof Object) )
return
if( !( this.events[event.kind] instanceof Object ))
this.events[event.kind] = new Object()
this.events[event.kind][event.id] = event
u.add(event.id)
if(event.kind === 0)
this.store.profile.setProfile(JSON.parse(event.content)).catch()
console.log(`kind: ${event.kind} found`, '... total', u.size, Object.keys(this.events[event.kind]).length)
console.log( 'event!', event.content )
})
this.store.tasks.completeJob()
// .on('eose', relay => {
// relay.close()
// })
},
true
)
},
timeUntilRefresh(){
return this.timeSince(Date.now()-(this.store.tasks.getLastUpdate(this.taskSlug)+this.store.prefs.duration-Date.now()))
},
timeSinceRefresh(){
return this.timeSince(this.store.tasks.getLastUpdate(this.taskSlug)) || Date.now()
},
}
export default defineComponent({
name: 'TemplateTask',
components: {},
data() {
return {
taskSlug: 'relays/operatorprofiles'
}
},
setup(props){
const {resultsProp: results} = toRefs(props)
return {
store : setupStore(),
results: results
}
},
created(){
clearInterval(this.interval)
},
unmounted(){
clearInterval(this.interval)
},
beforeMount(){
this.lastUpdate = this.store.tasks.getLastUpdate(this.taskSlug)
this.untilNext = this.timeUntilRefresh()
this.sinceLast = this.timeSinceRefresh()
this.relays = Array.from(new Set(relays))
},
mounted(){
console.log('task', this.taskSlug, 'is processing:', this.store.tasks.isProcessing(this.taskSlug))
if(this.store.tasks.isProcessing(this.taskSlug))
this.invalidate(true)
else
this.invalidate()
},
updated(){},
computed: Object.assign(SharedComputed, {
getDynamicTimeout: function(){
return this.averageLatency*this.relays.length
},
}),
methods: Object.assign(localMethods, SharedMethods),
props: {
resultsProp: {
type: Object,
default(){
return {}
}
},
},
})
</script>
<style scoped>
#refresh { font-size: 12pt; color:#666; margin-bottom:15px }
#refresh button { cursor: pointer; border-radius: 3px; border: 1px solid #a0a0a0; color:#333 }
#refresh button:hover {color:#000;}
#refresh button[disabled] {color:#999 !important; border-color:#e0e0e0}
</style>

45
src/components/relays/tasks/TasksManager.vue

@ -1,10 +1,10 @@
<template> <template>
<RefreshTask <RefreshTask
v-if="showRefreshRelays"
v-bind:resultsProp="results" />
<RelayCanonicalsTask
v-else-if="showGetRelayCanonicals"
v-bind:resultsProp="results" /> v-bind:resultsProp="results" />
<!-- <RelayCanonicalsTask
:resultsProp="results" />
<RelayOperatorTask
:resultsProp="results" /> -->
</template> </template>
<script> <script>
@ -16,11 +16,15 @@ import { setupStore } from '@/store'
import SharedComputed from '@/shared/computed.js' import SharedComputed from '@/shared/computed.js'
import RefreshTask from './RefreshTask.vue' import RefreshTask from './RefreshTask.vue'
// import RelayCanonicalsTask from './RelayCanonicalsTask.vue'
// import RelayOperatorTask from './RelayOperatorTask.vue'
export default defineComponent({ export default defineComponent({
name: "TasksManager", name: "TasksManager",
components: { components: {
RefreshTask RefreshTask,
// RelayCanonicalsTask,
// RelayOperatorTask
}, },
setup(props){ setup(props){
const {resultsProp: results} = toRefs(props) const {resultsProp: results} = toRefs(props)
@ -60,37 +64,6 @@ export default defineComponent({
}, },
computed: Object.assign(SharedComputed, { computed: Object.assign(SharedComputed, {
path: function() { return useRoute().path }, path: function() { return useRoute().path },
showRefreshRelays: function(){
return (
this.path.includes('/relays/find')
|| this.path.includes(`/relay/`)
)
&&
(
(
this.store.tasks.isProcessing('relays')
&& this.store.tasks.currentTask == 'relays'
)
||
(
!this.store.tasks.isAnyProcessing
)
)
},
showGetRelayCanonicals: function(){
return (
(
this.store.tasks.isProcessing('relays/canonicals')
&& this.store.tasks.currentTask == 'relays/canonicals'
)
||
(
!this.store.tasks.isAnyProcessing
)
)
&&
this.isExpired('relays/canonicals')
}
}) })
}); });
</script> </script>

106
src/components/relays/tasks/TemplateTask.vue

@ -0,0 +1,106 @@
<template>
<span class="text-white lg:text-sm mr-2 ml-2 mt-1.5 text-xs">
<span">Task Status here</span>
</span>
</template>
<style scoped>
</style>
<script>
import { defineComponent, toRefs } from 'vue'
import { setupStore } from '@/store'
import SharedMethods from '@/shared/relays-lib.js'
import SharedComputed from '@/shared/computed.js'
import { relays } from '../../../../relays.yaml'
const localMethods = {
queueJob: function(id, fn, unique){
this.store.tasks.addJob({
id: id,
handler: fn,
unique: unique
})
},
invalidate(force){
if( (!this.isExpired(this.taskSlug) && !force) )
return
},
timeUntilRefresh(){
return this.timeSince(Date.now()-(this.store.tasks.getLastUpdate(this.taskSlug)+this.store.prefs.duration-Date.now()))
},
timeSinceRefresh(){
return this.timeSince(this.store.tasks.getLastUpdate(this.taskSlug)) || Date.now()
},
}
export default defineComponent({
name: 'TemplateTask',
components: {},
data() {
return {
taskSlug: 'relays/*'
}
},
setup(props){
const {resultsProp: results} = toRefs(props)
return {
store : setupStore(),
results: results
}
},
created(){
clearInterval(this.interval)
},
unmounted(){
clearInterval(this.interval)
},
beforeMount(){
this.lastUpdate = this.store.tasks.getLastUpdate(this.taskSlug)
this.untilNext = this.timeUntilRefresh()
this.sinceLast = this.timeSinceRefresh()
this.relays = Array.from(new Set(relays))
},
mounted(){
this.migrateLegacy()
console.log('is processing', this.store.tasks.isProcessing(this.taskSlug))
if(this.store.tasks.isProcessing(this.taskSlug))
this.invalidate(true)
else
this.invalidate()
this.setRefreshInterval()
},
updated(){},
computed: Object.assign(SharedComputed, {
getDynamicTimeout: function(){
return this.averageLatency*this.relays.length
},
}),
methods: Object.assign(localMethods, SharedMethods),
props: {
resultsProp: {
type: Object,
default(){
return {}
}
},
},
})
</script>
<style scoped>
#refresh { font-size: 12pt; color:#666; margin-bottom:15px }
#refresh button { cursor: pointer; border-radius: 3px; border: 1px solid #a0a0a0; color:#333 }
#refresh button:hover {color:#000;}
#refresh button[disabled] {color:#999 !important; border-color:#e0e0e0}
</style>

28
src/components/user/AuthComponent.vue

@ -91,24 +91,24 @@ export default defineComponent({
}) })
}, },
generateCodeChallenge: async function(codeVerifier) { // generateCodeChallenge: async function(codeVerifier) {
let digest = await crypto.subtle.digest("SHA-256", // let digest = await crypto.subtle.digest("SHA-256",
new TextEncoder().encode(codeVerifier)); // new TextEncoder().encode(codeVerifier));
return btoa(String.fromCharCode(...new Uint8Array(digest))) // return btoa(String.fromCharCode(...new Uint8Array(digest)))
.replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_') // .replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_')
}, // },
generateRandomString: function(length) { // generateRandomString: function(length) {
let text = ""; // let text = "";
let possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; // let possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (let i = 0; i < length; i++) { // for (let i = 0; i < length; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length)); // text += possible.charAt(Math.floor(Math.random() * possible.length));
} // }
return text; // return text;
}, // },
}), }),
props: {}, props: {},
}) })

2
src/store/profiles.js

@ -10,7 +10,7 @@ export const useProfileStore = defineStore('profiles', {
}), }),
getters: {}, getters: {},
actions: { actions: {
set(profile){ setProfile(profile){
Object.keys(profile).forEach( key => { Object.keys(profile).forEach( key => {
if( !(profile[key] instanceof String) ) if( !(profile[key] instanceof String) )
return return

7
src/store/relays.js

@ -49,7 +49,8 @@ export const useRelaysStore = defineStore('relays', {
getAggregateCache: state => aggregate => state.cached[aggregate] instanceof Array ? state.cached[aggregate] : [], getAggregateCache: state => aggregate => state.cached[aggregate] instanceof Array ? state.cached[aggregate] : [],
getCanonical: state => relay => state.canonicals[relay] getCanonicals: state => state.canonicals,
getCanonical: state => relay => state.canonicals[relay],
}, },
actions: { actions: {
addRelay(relayUrl){ this.urls.push(relayUrl) }, addRelay(relayUrl){ this.urls.push(relayUrl) },
@ -99,6 +100,10 @@ export const useRelaysStore = defineStore('relays', {
if( !(this.cached[aggregate] instanceof Array) ) if( !(this.cached[aggregate] instanceof Array) )
this.cached[aggregate] = new Array() this.cached[aggregate] = new Array()
this.cached[aggregate] = array this.cached[aggregate] = array
},
setCanonicals(c){
this.canonicals = c
} }
}, },
}) })

2
src/store/tasks.js

@ -37,7 +37,6 @@ export const useTaskStore = defineStore('tasks', {
isActive: (state) => Object.keys( state.active ).length > 0, isActive: (state) => Object.keys( state.active ).length > 0,
isIdle: (state) => Object.keys( state.active ).length == 0, isIdle: (state) => Object.keys( state.active ).length == 0,
arePending: (state) => state.pending.length > 0, arePending: (state) => state.pending.length > 0,
}, },
actions: { actions: {
updateNow(key){ this.lastUpdate[key] = Date.now() }, updateNow(key){ this.lastUpdate[key] = Date.now() },
@ -69,6 +68,7 @@ export const useTaskStore = defineStore('tasks', {
}, },
completeJob(){ completeJob(){
console.log('compelteJob', this.active.id, this.active) console.log('compelteJob', this.active.id, this.active)
this.updateNow(this.active.id)
this.finishProcessing(this.active.id) this.finishProcessing(this.active.id)
this.completed.push(this.active) this.completed.push(this.active)
this.startNextJob() this.startNextJob()

Loading…
Cancel
Save