dskvr
2 years ago
12 changed files with 558 additions and 118 deletions
@ -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> |
||||
|
|
||||
|
@ -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> |
||||
|
|
@ -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> |
||||
|
|
Loading…
Reference in new issue