libp2r2p 0.0.2 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,101 +0,0 @@
1
- import { afterEach, test } from 'node:test'
2
- import assert from 'node:assert/strict'
3
- import { generateSecretKey } from 'nostr-tools'
4
-
5
- import TestSigner from './helpers/test-signer.js'
6
- import { bytesToHex } from '../base16/index.js'
7
- import { makeContentKeyEvent } from '../content-key/event/index.js'
8
- import { getIykcProofs, clearContentKeyCache } from '../content-key/services/iykc-proof.js'
9
- import { cacheRelayListEvent, clearRelayQueryCache, getRelaysByPubkey, subscribeRelayListUpdates } from '../relay/services/query.js'
10
- import { pickRelaysForPubkeys } from '../relay/helpers/routing.js'
11
-
12
- afterEach(() => {
13
- clearRelayQueryCache()
14
- clearContentKeyCache()
15
- TestSigner.releaseAll()
16
- })
17
-
18
- function signer () {
19
- return TestSigner.getOrCreate(bytesToHex(generateSecretKey()))
20
- }
21
-
22
- function relayListEvent (pubkey, createdAt, tags) {
23
- return { kind: 10002, pubkey, created_at: createdAt, tags, content: '' }
24
- }
25
-
26
- test('cacheRelayListEvent tracks newer relay-list events and exposes changed sets', () => {
27
- const first = cacheRelayListEvent(relayListEvent('alice', 1, [['r', 'wss://one.example']]))
28
- const older = cacheRelayListEvent(relayListEvent('alice', 1, [['r', 'wss://two.example']]))
29
- const newer = cacheRelayListEvent(relayListEvent('alice', 2, [['r', 'wss://two.example', 'write']]))
30
-
31
- assert.deepEqual(first.relays, { read: ['wss://one.example'], write: ['wss://one.example'] })
32
- assert.equal(older, null)
33
- assert.deepEqual(newer.previousRelays, { read: ['wss://one.example'], write: ['wss://one.example'] })
34
- assert.deepEqual(newer.relays, { read: [], write: ['wss://two.example'] })
35
- assert.deepEqual(newer.changes, { read: true, write: true, both: true })
36
- })
37
-
38
- test('pickRelaysForPubkeys covers pubkeys with shared relay preference', () => {
39
- const picked = pickRelaysForPubkeys(['alice', 'bob'], {
40
- alice: { write: ['wss://shared.example', 'wss://alice.example'] },
41
- bob: { write: ['wss://shared.example', 'wss://bob.example'] }
42
- }, { maxPerPubkey: 1 })
43
-
44
- assert.deepEqual([...picked.entries()], [['wss://shared.example', ['alice', 'bob']]])
45
- })
46
-
47
- test('getRelaysByPubkey fetches latest relay lists and falls back when absent', async () => {
48
- const calls = []
49
- const relays = await getRelaysByPubkey(['alice', 'bob'], {
50
- _getEvents: async (filter, relayUrls, options) => {
51
- calls.push({ filter, relayUrls })
52
- assert.deepEqual(options, { timeout: 5000, timeoutAfterFirstEose: null })
53
- return { result: [relayListEvent('alice', 9, [['r', 'wss://alice.example', 'write']])] }
54
- }
55
- })
56
-
57
- assert.equal(calls.length, 1)
58
- assert.deepEqual(calls[0].filter.authors, ['alice', 'bob'])
59
- assert.deepEqual(relays.alice, { read: [], write: ['wss://alice.example'] })
60
- assert.deepEqual(relays.bob.write.slice(0, 2), ['wss://relay.44billion.net', 'wss://nos.lol'])
61
- })
62
-
63
- test('getIykcProofs finds latest content-key events through relay routing', async () => {
64
- const user = signer()
65
- const older = signer()
66
- const newer = signer()
67
- const userPubkey = await user.getPublicKey()
68
- const olderEvent = await makeContentKeyEvent({ userSigner: user, contentKeySigner: older, createdAt: 7 })
69
- const newerEvent = await makeContentKeyEvent({ userSigner: user, contentKeySigner: newer, createdAt: 8 })
70
-
71
- const found = await getIykcProofs([userPubkey], {
72
- _getRelaysByPubkey: async () => ({ [userPubkey]: { write: ['wss://one.example'] } }),
73
- _getEvents: async () => ({ result: [olderEvent, newerEvent] })
74
- })
75
-
76
- assert.equal(found[userPubkey].iykcPubkey, await newer.getPublicKey())
77
- })
78
-
79
- test('subscribeRelayListUpdates only reports watched relay-type changes', async () => {
80
- const changes = []
81
- let aborted = false
82
- async function * events (_filter, _relays, { signal }) {
83
- signal.addEventListener('abort', () => { aborted = true }, { once: true })
84
- yield relayListEvent('alice', 1, [['r', 'wss://read.example', 'read']])
85
- yield relayListEvent('alice', 2, [['r', 'wss://write.example', 'write']])
86
- await new Promise(resolve => signal.addEventListener('abort', resolve, { once: true }))
87
- }
88
-
89
- const stop = subscribeRelayListUpdates(['alice'], {
90
- relayType: 'write',
91
- onChange: change => changes.push(change),
92
- _eventsFeedGenerator: events
93
- })
94
- await new Promise(resolve => setImmediate(resolve))
95
- stop()
96
- await new Promise(resolve => setImmediate(resolve))
97
-
98
- assert.equal(changes.length, 1)
99
- assert.deepEqual(changes[0].relays, { read: [], write: ['wss://write.example'] })
100
- assert.ok(aborted)
101
- })
@@ -1,105 +0,0 @@
1
- import { test } from 'node:test'
2
- import assert from 'node:assert/strict'
3
- import { IDBFactory } from 'fake-indexeddb'
4
- import { createQueue as createIdbQueue } from '../idb-queue/index.js'
5
- import { createQueue as createWebStorageQueue } from '../web-storage-queue/index.js'
6
-
7
- const CORE_METHODS = [
8
- 'enqueue', 'push', 'pop', 'unshift', 'shift', 'items', 'reverseItems',
9
- 'storedItems', 'reverseStoredItems', 'setAt', 'insertAt', 'insertWhere',
10
- 'removeAt', 'removeWhere', 'some', 'clear'
11
- ]
12
-
13
- function createStorageArea () {
14
- const values = new Map()
15
- return {
16
- getItem: key => values.get(String(key)) ?? null,
17
- removeItem: key => { values.delete(String(key)) },
18
- setItem: (key, value) => { values.set(String(key), String(value)) }
19
- }
20
- }
21
-
22
- async function call (queue, method, ...args) {
23
- return queue[method](...args)
24
- }
25
-
26
- async function storedValues (queue) {
27
- const values = []
28
- for await (const value of queue.storedItems()) values.push(value)
29
- return values
30
- }
31
-
32
- async function coreTrace (queue) {
33
- const returns = []
34
- returns.push(await call(queue, 'push', { value: 'middle' }))
35
- returns.push(await call(queue, 'unshift', { value: 'first' }))
36
- returns.push(await call(queue, 'push', { value: 'last' }))
37
- returns.push(await call(queue, 'setAt', 1, { value: 'MIDDLE' }))
38
- returns.push(await call(queue, 'insertAt', 2, { value: 'between' }))
39
- const beforeRemoval = await storedValues(queue)
40
- const hasBetween = await call(queue, 'some', item => item.value === 'between')
41
- await call(queue, 'removeWhere', item => item.value === 'between')
42
-
43
- return {
44
- returns,
45
- beforeRemoval,
46
- hasBetween,
47
- afterRemoval: await storedValues(queue),
48
- drained: [
49
- await call(queue, 'shift'),
50
- await call(queue, 'pop'),
51
- await call(queue, 'shift'),
52
- await call(queue, 'shift')
53
- ]
54
- }
55
- }
56
-
57
- test('idb queue preserves the web-storage queue core API and semantics', async () => {
58
- const webStorageQueue = createWebStorageQueue({
59
- prefix: 'web',
60
- storageArea: createStorageArea()
61
- })
62
- const idbQueue = await createIdbQueue({
63
- prefix: 'idb',
64
- indexedDB: new IDBFactory()
65
- })
66
-
67
- assert.deepEqual(Object.keys(webStorageQueue).sort(), [...CORE_METHODS].sort())
68
- assert.deepEqual(
69
- Object.keys(idbQueue).filter(method => CORE_METHODS.includes(method)).sort(),
70
- [...CORE_METHODS].sort()
71
- )
72
- assert.equal(typeof idbQueue.getBy, 'function')
73
- assert.equal(typeof idbQueue.someBy, 'function')
74
- assert.equal(typeof idbQueue.removeBy, 'function')
75
- assert.equal(typeof idbQueue.storedItemsBy, 'function')
76
-
77
- assert.deepEqual(await coreTrace(idbQueue), await coreTrace(webStorageQueue))
78
- })
79
-
80
- test('queues preserve caller ids without injecting queue positions', async () => {
81
- const queues = [
82
- createWebStorageQueue({ prefix: 'web', storageArea: createStorageArea() }),
83
- await createIdbQueue({ prefix: 'idb', indexedDB: new IDBFactory() })
84
- ]
85
-
86
- for (const queue of queues) {
87
- await call(queue, 'push', { value: 'generated' })
88
- await call(queue, 'push', { id: 'caller-id', value: 'provided' })
89
- assert.deepEqual(await call(queue, 'shift'), { value: 'generated' })
90
- assert.deepEqual(await call(queue, 'shift'), { id: 'caller-id', value: 'provided' })
91
- }
92
- })
93
-
94
- test('both queue types require a prefix and predicate callbacks', async () => {
95
- const storageArea = createStorageArea()
96
- assert.throws(() => createWebStorageQueue({ storageArea }), /QUEUE_PREFIX_REQUIRED/)
97
- await assert.rejects(createIdbQueue({ indexedDB: new IDBFactory() }), /QUEUE_PREFIX_REQUIRED/)
98
-
99
- const webStorageQueue = createWebStorageQueue({ prefix: 'web', storageArea })
100
- const idbQueue = await createIdbQueue({ prefix: 'idb', indexedDB: new IDBFactory() })
101
- for (const method of ['insertWhere', 'removeWhere', 'some']) {
102
- assert.throws(() => webStorageQueue[method](), /QUEUE_PREDICATE_REQUIRED/)
103
- await assert.rejects(idbQueue[method](), /QUEUE_PREDICATE_REQUIRED/)
104
- }
105
- })
@@ -1,32 +0,0 @@
1
- import assert from 'node:assert/strict'
2
- import { test } from 'node:test'
3
- import { decodeHll, encodeHll, estimateHllCount, mergeHll } from '../relay/helpers/hll.js'
4
-
5
- function registers (entries = {}) {
6
- const value = new Uint8Array(256)
7
- for (const [index, register] of Object.entries(entries)) value[Number(index)] = register
8
- return value
9
- }
10
-
11
- test('HLL helpers validate and normalize NIP-45 register payloads', () => {
12
- const value = registers({ 0: 10, 255: 15 })
13
- const encoded = encodeHll(value)
14
-
15
- assert.equal(encoded.length, 512)
16
- assert.equal(encoded.slice(0, 2), '0a')
17
- assert.equal(encoded.slice(-2), '0f')
18
- assert.deepEqual(decodeHll(encoded.toUpperCase()), value)
19
- assert.equal(decodeHll(''), null)
20
- assert.equal(decodeHll('x'.repeat(512)), null)
21
- assert.equal(decodeHll('0'.repeat(511)), null)
22
- })
23
-
24
- test('HLL helpers merge registers and estimate cardinality', () => {
25
- const target = registers({ 0: 1, 1: 5 })
26
- const source = registers({ 0: 4, 2: 3 })
27
-
28
- assert.deepEqual(mergeHll(target, source), registers({ 0: 4, 1: 5, 2: 3 }))
29
- assert.equal(estimateHllCount(registers()), 0)
30
- assert.equal(estimateHllCount(registers({ 8: 1 })), 1)
31
- assert.equal(estimateHllCount(new Uint8Array(256).fill(1)), 367)
32
- })