@xyo-network/diviner-temporal-indexing-memory 5.1.22 → 5.1.23
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.
- package/package.json +40 -37
- package/dist/browser/DivinerQueryToIndexQueryDiviner/spec/Diviner.spec.d.ts +0 -2
- package/dist/browser/DivinerQueryToIndexQueryDiviner/spec/Diviner.spec.d.ts.map +0 -1
- package/dist/browser/IndexCandidateToIndexDiviner/spec/Diviner.spec.d.ts +0 -2
- package/dist/browser/IndexCandidateToIndexDiviner/spec/Diviner.spec.d.ts.map +0 -1
- package/dist/browser/IndexQueryResponseToDivinerQueryResponseDiviner/spec/Diviner.spec.d.ts +0 -2
- package/dist/browser/IndexQueryResponseToDivinerQueryResponseDiviner/spec/Diviner.spec.d.ts.map +0 -1
- package/dist/browser/StateToIndexCandidateDiviner/spec/Diviner.spec.d.ts +0 -2
- package/dist/browser/StateToIndexCandidateDiviner/spec/Diviner.spec.d.ts.map +0 -1
- package/dist/browser/spec/Diviner.Multiple.spec.d.ts +0 -2
- package/dist/browser/spec/Diviner.Multiple.spec.d.ts.map +0 -1
- package/dist/browser/spec/Diviner.spec.d.ts +0 -2
- package/dist/browser/spec/Diviner.spec.d.ts.map +0 -1
- package/dist/neutral/DivinerQueryToIndexQueryDiviner/spec/Diviner.spec.d.ts +0 -2
- package/dist/neutral/DivinerQueryToIndexQueryDiviner/spec/Diviner.spec.d.ts.map +0 -1
- package/dist/neutral/IndexCandidateToIndexDiviner/spec/Diviner.spec.d.ts +0 -2
- package/dist/neutral/IndexCandidateToIndexDiviner/spec/Diviner.spec.d.ts.map +0 -1
- package/dist/neutral/IndexQueryResponseToDivinerQueryResponseDiviner/spec/Diviner.spec.d.ts +0 -2
- package/dist/neutral/IndexQueryResponseToDivinerQueryResponseDiviner/spec/Diviner.spec.d.ts.map +0 -1
- package/dist/neutral/StateToIndexCandidateDiviner/spec/Diviner.spec.d.ts +0 -2
- package/dist/neutral/StateToIndexCandidateDiviner/spec/Diviner.spec.d.ts.map +0 -1
- package/dist/neutral/spec/Diviner.Multiple.spec.d.ts +0 -2
- package/dist/neutral/spec/Diviner.Multiple.spec.d.ts.map +0 -1
- package/dist/neutral/spec/Diviner.spec.d.ts +0 -2
- package/dist/neutral/spec/Diviner.spec.d.ts.map +0 -1
- package/dist/node/DivinerQueryToIndexQueryDiviner/spec/Diviner.spec.d.ts +0 -2
- package/dist/node/DivinerQueryToIndexQueryDiviner/spec/Diviner.spec.d.ts.map +0 -1
- package/dist/node/IndexCandidateToIndexDiviner/spec/Diviner.spec.d.ts +0 -2
- package/dist/node/IndexCandidateToIndexDiviner/spec/Diviner.spec.d.ts.map +0 -1
- package/dist/node/IndexQueryResponseToDivinerQueryResponseDiviner/spec/Diviner.spec.d.ts +0 -2
- package/dist/node/IndexQueryResponseToDivinerQueryResponseDiviner/spec/Diviner.spec.d.ts.map +0 -1
- package/dist/node/StateToIndexCandidateDiviner/spec/Diviner.spec.d.ts +0 -2
- package/dist/node/StateToIndexCandidateDiviner/spec/Diviner.spec.d.ts.map +0 -1
- package/dist/node/spec/Diviner.Multiple.spec.d.ts +0 -2
- package/dist/node/spec/Diviner.Multiple.spec.d.ts.map +0 -1
- package/dist/node/spec/Diviner.spec.d.ts +0 -2
- package/dist/node/spec/Diviner.spec.d.ts.map +0 -1
- package/src/DivinerQueryToIndexQueryDiviner/spec/Diviner.spec.ts +0 -244
- package/src/IndexCandidateToIndexDiviner/spec/Diviner.spec.ts +0 -247
- package/src/IndexQueryResponseToDivinerQueryResponseDiviner/spec/Diviner.spec.ts +0 -103
- package/src/StateToIndexCandidateDiviner/spec/Diviner.spec.ts +0 -167
- package/src/spec/Diviner.Multiple.spec.ts +0 -214
- package/src/spec/Diviner.spec.ts +0 -225
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
import '@xylabs/vitest-extended'
|
|
2
|
-
|
|
3
|
-
import { filterAs } from '@xylabs/array'
|
|
4
|
-
import { assertEx } from '@xylabs/assert'
|
|
5
|
-
import { delay } from '@xylabs/delay'
|
|
6
|
-
import { AsObjectFactory } from '@xylabs/object'
|
|
7
|
-
import type { MemoryArchivist } from '@xyo-network/archivist-memory'
|
|
8
|
-
import { asArchivistInstance } from '@xyo-network/archivist-model'
|
|
9
|
-
import { BoundWitnessBuilder } from '@xyo-network/boundwitness-builder'
|
|
10
|
-
import { asBoundWitness } from '@xyo-network/boundwitness-model'
|
|
11
|
-
import { asDivinerInstance } from '@xyo-network/diviner-model'
|
|
12
|
-
import type { PayloadDivinerQueryPayload } from '@xyo-network/diviner-payload-model'
|
|
13
|
-
import { PayloadDivinerQuerySchema } from '@xyo-network/diviner-payload-model'
|
|
14
|
-
import { isTemporalIndexingDivinerResultIndex } from '@xyo-network/diviner-temporal-indexing-model'
|
|
15
|
-
import type { PackageManifestPayload } from '@xyo-network/manifest'
|
|
16
|
-
import { ManifestWrapper } from '@xyo-network/manifest'
|
|
17
|
-
import { ModuleFactoryLocator } from '@xyo-network/module-factory-locator'
|
|
18
|
-
import type {
|
|
19
|
-
Labels, ModuleState, StateDictionary,
|
|
20
|
-
} from '@xyo-network/module-model'
|
|
21
|
-
import { isModuleState } from '@xyo-network/module-model'
|
|
22
|
-
import type { MemoryNode } from '@xyo-network/node-memory'
|
|
23
|
-
import { PayloadBuilder } from '@xyo-network/payload-builder'
|
|
24
|
-
import type { Payload } from '@xyo-network/payload-model'
|
|
25
|
-
import { HDWallet } from '@xyo-network/wallet'
|
|
26
|
-
import type { TimeStamp } from '@xyo-network/witness-timestamp'
|
|
27
|
-
import { TimestampSchema } from '@xyo-network/witness-timestamp'
|
|
28
|
-
import {
|
|
29
|
-
beforeAll,
|
|
30
|
-
describe, expect, it,
|
|
31
|
-
} from 'vitest'
|
|
32
|
-
|
|
33
|
-
import { TemporalIndexingDiviner } from '../Diviner.ts'
|
|
34
|
-
import { TemporalIndexingDivinerDivinerQueryToIndexQueryDiviner } from '../DivinerQueryToIndexQueryDiviner/index.ts'
|
|
35
|
-
import { TemporalIndexingDivinerIndexCandidateToIndexDiviner } from '../IndexCandidateToIndexDiviner/index.ts'
|
|
36
|
-
import { TemporalIndexingDivinerIndexQueryResponseToDivinerQueryResponseDiviner } from '../IndexQueryResponseToDivinerQueryResponseDiviner/index.ts'
|
|
37
|
-
import { TemporalIndexingDivinerStateToIndexCandidateDiviner } from '../StateToIndexCandidateDiviner/index.ts'
|
|
38
|
-
import imageThumbnailDivinerManifest from './TemporalDiviner.json' with { type: 'json' }
|
|
39
|
-
|
|
40
|
-
type ImageThumbnail = Payload<{
|
|
41
|
-
http?: {
|
|
42
|
-
code?: string
|
|
43
|
-
ipAddress?: string
|
|
44
|
-
status?: number
|
|
45
|
-
}
|
|
46
|
-
// schema: 'network.xyo.image.thumbnail'
|
|
47
|
-
sourceHash?: string
|
|
48
|
-
sourceUrl: string
|
|
49
|
-
url?: string
|
|
50
|
-
}>
|
|
51
|
-
|
|
52
|
-
type Query = PayloadDivinerQueryPayload & { status?: number; success?: boolean; url?: string }
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* @group slow
|
|
56
|
-
*/
|
|
57
|
-
describe('TemporalIndexingDiviner - Multiple', () => {
|
|
58
|
-
const sourceUrl = 'https://placekitten.com/200/300'
|
|
59
|
-
const thumbnailHttpSuccess: ImageThumbnail = {
|
|
60
|
-
http: { status: 200 },
|
|
61
|
-
schema: 'network.xyo.image.thumbnail',
|
|
62
|
-
sourceHash: '7f39363514d9d9b958a5a993edeba35cb44f912c7072ed9ddd628728ac0fd681',
|
|
63
|
-
sourceUrl,
|
|
64
|
-
url: 'data:image/png;base64,===',
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const thumbnailHttpFail: ImageThumbnail = {
|
|
68
|
-
http: {
|
|
69
|
-
|
|
70
|
-
ipAddress: '104.17.96.13',
|
|
71
|
-
status: 429,
|
|
72
|
-
},
|
|
73
|
-
schema: 'network.xyo.image.thumbnail',
|
|
74
|
-
sourceUrl,
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const thumbnailCodeFail: ImageThumbnail = {
|
|
78
|
-
http: { code: 'FAILED' },
|
|
79
|
-
schema: 'network.xyo.image.thumbnail',
|
|
80
|
-
sourceUrl,
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const thumbnailWitnessFail: ImageThumbnail = {
|
|
84
|
-
|
|
85
|
-
http: { ipAddress: '104.17.96.13' },
|
|
86
|
-
schema: 'network.xyo.image.thumbnail',
|
|
87
|
-
sourceUrl,
|
|
88
|
-
}
|
|
89
|
-
const witnessedThumbnails = [thumbnailHttpSuccess, thumbnailHttpFail, thumbnailCodeFail, thumbnailWitnessFail]
|
|
90
|
-
|
|
91
|
-
let sut: TemporalIndexingDiviner
|
|
92
|
-
let node: MemoryNode
|
|
93
|
-
|
|
94
|
-
beforeAll(async () => {
|
|
95
|
-
const labels: Labels = { 'network.xyo.image.thumbnail': 'diviner' }
|
|
96
|
-
const wallet = await HDWallet.random()
|
|
97
|
-
const locator = new ModuleFactoryLocator()
|
|
98
|
-
locator.register(TemporalIndexingDivinerDivinerQueryToIndexQueryDiviner.factory(), labels)
|
|
99
|
-
locator.register(TemporalIndexingDivinerIndexCandidateToIndexDiviner.factory(), labels)
|
|
100
|
-
locator.register(TemporalIndexingDivinerIndexQueryResponseToDivinerQueryResponseDiviner.factory(), labels)
|
|
101
|
-
locator.register(TemporalIndexingDivinerStateToIndexCandidateDiviner.factory(), labels)
|
|
102
|
-
locator.register(TemporalIndexingDiviner.factory(), labels)
|
|
103
|
-
const manifest = imageThumbnailDivinerManifest as PackageManifestPayload
|
|
104
|
-
const manifestWrapper = new ManifestWrapper(manifest, wallet, locator)
|
|
105
|
-
node = await manifestWrapper.loadNodeFromIndex(0)
|
|
106
|
-
await node.start()
|
|
107
|
-
|
|
108
|
-
// Insert previously witnessed payloads into thumbnail archivist
|
|
109
|
-
const timestamp: TimeStamp = { schema: TimestampSchema, timestamp: Date.now() }
|
|
110
|
-
const [boundWitness, payloads] = await new BoundWitnessBuilder().payloads([timestamp, ...witnessedThumbnails]).build()
|
|
111
|
-
|
|
112
|
-
const thumbnailArchivist = assertEx(asArchivistInstance<MemoryArchivist>(await node.resolve('ImageThumbnailArchivist')))
|
|
113
|
-
await thumbnailArchivist.insert([boundWitness, ...payloads])
|
|
114
|
-
|
|
115
|
-
sut = assertEx(asDivinerInstance(await node.resolve('ImageThumbnailDiviner'))) as TemporalIndexingDiviner
|
|
116
|
-
|
|
117
|
-
// Allow enough time for diviner to divine
|
|
118
|
-
await delay(1000)
|
|
119
|
-
}, 40_000)
|
|
120
|
-
describe('diviner state', () => {
|
|
121
|
-
let stateArchivist: MemoryArchivist
|
|
122
|
-
beforeAll(async () => {
|
|
123
|
-
const mod = await node.resolve('AddressStateArchivist')
|
|
124
|
-
stateArchivist = assertEx(asArchivistInstance<MemoryArchivist>(mod))
|
|
125
|
-
})
|
|
126
|
-
it('has expected bound witnesses', async () => {
|
|
127
|
-
const payloads = await stateArchivist.all()
|
|
128
|
-
const stateBoundWitnesses = filterAs(payloads, asBoundWitness)
|
|
129
|
-
expect(stateBoundWitnesses).toBeArrayOfSize(1)
|
|
130
|
-
for (const stateBoundWitness of stateBoundWitnesses) {
|
|
131
|
-
expect(stateBoundWitness).toBeObject()
|
|
132
|
-
expect(stateBoundWitness.addresses).toBeArrayOfSize(1)
|
|
133
|
-
expect(stateBoundWitness.addresses).toContain(sut.address)
|
|
134
|
-
}
|
|
135
|
-
})
|
|
136
|
-
it('has expected state', async () => {
|
|
137
|
-
const payloads = await stateArchivist.all()
|
|
138
|
-
try {
|
|
139
|
-
const asModuleState = AsObjectFactory.create<ModuleState<StateDictionary>>(isModuleState)
|
|
140
|
-
const statePayloads = filterAs(payloads, asModuleState)
|
|
141
|
-
expect(statePayloads).toBeArrayOfSize(1)
|
|
142
|
-
expect(statePayloads.at(-1)).toBeObject()
|
|
143
|
-
const statePayload = assertEx(statePayloads.at(-1))
|
|
144
|
-
expect(statePayload.state).toBeObject()
|
|
145
|
-
expect(statePayload.state?.cursor).toBeDefined()
|
|
146
|
-
} catch (ex) {
|
|
147
|
-
console.error('State payloads:', payloads)
|
|
148
|
-
throw ex
|
|
149
|
-
}
|
|
150
|
-
})
|
|
151
|
-
})
|
|
152
|
-
describe('diviner index', () => {
|
|
153
|
-
let indexArchivist: MemoryArchivist
|
|
154
|
-
beforeAll(async () => {
|
|
155
|
-
const mod = await node.resolve('ImageThumbnailDivinerIndexArchivist')
|
|
156
|
-
indexArchivist = assertEx(asArchivistInstance<MemoryArchivist>(mod))
|
|
157
|
-
})
|
|
158
|
-
// NOTE: We're not signing indexes for performance reasons
|
|
159
|
-
it.skip('has expected bound witnesses', async () => {
|
|
160
|
-
const payloads = await indexArchivist.all()
|
|
161
|
-
const indexBoundWitnesses = filterAs(payloads, asBoundWitness)
|
|
162
|
-
expect(indexBoundWitnesses).toBeArrayOfSize(1)
|
|
163
|
-
const indexBoundWitness = indexBoundWitnesses[0]
|
|
164
|
-
expect(indexBoundWitness).toBeObject()
|
|
165
|
-
expect(indexBoundWitness.addresses).toBeArrayOfSize(1)
|
|
166
|
-
expect(indexBoundWitness.addresses).toContain(sut.address)
|
|
167
|
-
})
|
|
168
|
-
it('has expected index', async () => {
|
|
169
|
-
const payloads = await indexArchivist.all()
|
|
170
|
-
const indexPayloads = payloads.filter(isTemporalIndexingDivinerResultIndex)
|
|
171
|
-
expect(indexPayloads).toBeArrayOfSize((witnessedThumbnails).length)
|
|
172
|
-
})
|
|
173
|
-
})
|
|
174
|
-
describe('with no thumbnail for the provided URL', () => {
|
|
175
|
-
const url = 'https://does.not.exist.io'
|
|
176
|
-
const schema = PayloadDivinerQuerySchema
|
|
177
|
-
it('returns nothing', async () => {
|
|
178
|
-
const query: Query = { schema, url }
|
|
179
|
-
const result = await sut.divine([query])
|
|
180
|
-
expect(result).toBeArrayOfSize(0)
|
|
181
|
-
})
|
|
182
|
-
})
|
|
183
|
-
describe('with thumbnails for the provided URL', () => {
|
|
184
|
-
const url = sourceUrl
|
|
185
|
-
const schema = PayloadDivinerQuerySchema
|
|
186
|
-
describe('with no filter criteria', () => {
|
|
187
|
-
it('returns the most recent result', async () => {
|
|
188
|
-
const query: Query = { schema, url }
|
|
189
|
-
const results = await sut.divine([query])
|
|
190
|
-
const result = results.find(isTemporalIndexingDivinerResultIndex)
|
|
191
|
-
expect(result).toBeDefined()
|
|
192
|
-
const payload = assertEx((witnessedThumbnails).at(-1))
|
|
193
|
-
const expected = await PayloadBuilder.dataHash(payload)
|
|
194
|
-
expect(result?.$sources).toContain(expected)
|
|
195
|
-
})
|
|
196
|
-
})
|
|
197
|
-
describe('with filter criteria', () => {
|
|
198
|
-
describe('for status code', () => {
|
|
199
|
-
const cases: ImageThumbnail[] = [thumbnailHttpSuccess, thumbnailHttpFail]
|
|
200
|
-
it.each(cases)('returns the most recent instance of that status code', async (payload) => {
|
|
201
|
-
const { status } = payload.http ?? {}
|
|
202
|
-
const query: Query = {
|
|
203
|
-
schema, status, url,
|
|
204
|
-
}
|
|
205
|
-
const results = await sut.divine([query])
|
|
206
|
-
const result = results.find(isTemporalIndexingDivinerResultIndex)
|
|
207
|
-
expect(result).toBeDefined()
|
|
208
|
-
const expected = await PayloadBuilder.dataHash(payload)
|
|
209
|
-
expect(result?.$sources).toContain(expected)
|
|
210
|
-
})
|
|
211
|
-
})
|
|
212
|
-
})
|
|
213
|
-
})
|
|
214
|
-
})
|
package/src/spec/Diviner.spec.ts
DELETED
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
import '@xylabs/vitest-extended'
|
|
2
|
-
|
|
3
|
-
import { filterAs } from '@xylabs/array'
|
|
4
|
-
import { assertEx } from '@xylabs/assert'
|
|
5
|
-
import { delay } from '@xylabs/delay'
|
|
6
|
-
import type { MemoryArchivist } from '@xyo-network/archivist-memory'
|
|
7
|
-
import { asArchivistInstance } from '@xyo-network/archivist-model'
|
|
8
|
-
import { BoundWitnessBuilder } from '@xyo-network/boundwitness-builder'
|
|
9
|
-
import { asBoundWitness } from '@xyo-network/boundwitness-model'
|
|
10
|
-
import { asDivinerInstance } from '@xyo-network/diviner-model'
|
|
11
|
-
import type { PayloadDivinerQueryPayload } from '@xyo-network/diviner-payload-model'
|
|
12
|
-
import { PayloadDivinerQuerySchema } from '@xyo-network/diviner-payload-model'
|
|
13
|
-
import { isTemporalIndexingDivinerResultIndex } from '@xyo-network/diviner-temporal-indexing-model'
|
|
14
|
-
import type { PackageManifestPayload } from '@xyo-network/manifest'
|
|
15
|
-
import { ManifestWrapper } from '@xyo-network/manifest'
|
|
16
|
-
import { ModuleFactoryLocator } from '@xyo-network/module-factory-locator'
|
|
17
|
-
import type { Labels } from '@xyo-network/module-model'
|
|
18
|
-
import { asModuleState } from '@xyo-network/module-model'
|
|
19
|
-
import type { MemoryNode } from '@xyo-network/node-memory'
|
|
20
|
-
import { PayloadBuilder } from '@xyo-network/payload-builder'
|
|
21
|
-
import type { Payload } from '@xyo-network/payload-model'
|
|
22
|
-
import { HDWallet } from '@xyo-network/wallet'
|
|
23
|
-
import type { TimeStamp } from '@xyo-network/witness-timestamp'
|
|
24
|
-
import { TimestampSchema } from '@xyo-network/witness-timestamp'
|
|
25
|
-
import {
|
|
26
|
-
beforeAll,
|
|
27
|
-
describe, expect, it,
|
|
28
|
-
} from 'vitest'
|
|
29
|
-
|
|
30
|
-
import { TemporalIndexingDiviner } from '../Diviner.ts'
|
|
31
|
-
import { TemporalIndexingDivinerDivinerQueryToIndexQueryDiviner } from '../DivinerQueryToIndexQueryDiviner/index.ts'
|
|
32
|
-
import { TemporalIndexingDivinerIndexCandidateToIndexDiviner } from '../IndexCandidateToIndexDiviner/index.ts'
|
|
33
|
-
import { TemporalIndexingDivinerIndexQueryResponseToDivinerQueryResponseDiviner } from '../IndexQueryResponseToDivinerQueryResponseDiviner/index.ts'
|
|
34
|
-
import { TemporalIndexingDivinerStateToIndexCandidateDiviner } from '../StateToIndexCandidateDiviner/index.ts'
|
|
35
|
-
import imageThumbnailDivinerManifest from './TemporalDiviner.json' with { type: 'json' }
|
|
36
|
-
|
|
37
|
-
type ImageThumbnail = Payload<{
|
|
38
|
-
http?: {
|
|
39
|
-
code?: string
|
|
40
|
-
ipAddress?: string
|
|
41
|
-
status?: number
|
|
42
|
-
}
|
|
43
|
-
// schema: 'network.xyo.image.thumbnail'
|
|
44
|
-
sourceHash?: string
|
|
45
|
-
sourceUrl: string
|
|
46
|
-
url?: string
|
|
47
|
-
}>
|
|
48
|
-
|
|
49
|
-
type Query = PayloadDivinerQueryPayload & { status?: number; success?: boolean; url?: string }
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* @group slow
|
|
53
|
-
*/
|
|
54
|
-
describe('TemporalIndexingDiviner', () => {
|
|
55
|
-
const sourceUrl = 'https://placekitten.com/200/300'
|
|
56
|
-
const thumbnailHttpSuccess: ImageThumbnail = {
|
|
57
|
-
http: { status: 200 },
|
|
58
|
-
schema: 'network.xyo.image.thumbnail',
|
|
59
|
-
sourceHash: '7f39363514d9d9b958a5a993edeba35cb44f912c7072ed9ddd628728ac0fd681',
|
|
60
|
-
sourceUrl,
|
|
61
|
-
url: 'data:image/png;base64,===',
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const thumbnailHttpFail: ImageThumbnail = {
|
|
65
|
-
http: {
|
|
66
|
-
|
|
67
|
-
ipAddress: '104.17.96.13',
|
|
68
|
-
status: 429,
|
|
69
|
-
},
|
|
70
|
-
schema: 'network.xyo.image.thumbnail',
|
|
71
|
-
sourceUrl,
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const thumbnailCodeFail: ImageThumbnail = {
|
|
75
|
-
http: { code: 'FAILED' },
|
|
76
|
-
schema: 'network.xyo.image.thumbnail',
|
|
77
|
-
sourceUrl,
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const thumbnailWitnessFail: ImageThumbnail = {
|
|
81
|
-
|
|
82
|
-
http: { ipAddress: '104.17.96.13' },
|
|
83
|
-
schema: 'network.xyo.image.thumbnail',
|
|
84
|
-
sourceUrl,
|
|
85
|
-
}
|
|
86
|
-
const witnessedThumbnails = [thumbnailHttpSuccess, thumbnailHttpFail, thumbnailCodeFail, thumbnailWitnessFail]
|
|
87
|
-
|
|
88
|
-
let sut: TemporalIndexingDiviner
|
|
89
|
-
let node: MemoryNode
|
|
90
|
-
|
|
91
|
-
beforeAll(async () => {
|
|
92
|
-
const labels: Labels = { 'network.xyo.image.thumbnail': 'diviner' }
|
|
93
|
-
const wallet = await HDWallet.random()
|
|
94
|
-
const locator = new ModuleFactoryLocator()
|
|
95
|
-
locator.register(TemporalIndexingDivinerDivinerQueryToIndexQueryDiviner.factory(), labels)
|
|
96
|
-
locator.register(TemporalIndexingDivinerIndexCandidateToIndexDiviner.factory(), labels)
|
|
97
|
-
locator.register(TemporalIndexingDivinerIndexQueryResponseToDivinerQueryResponseDiviner.factory(), labels)
|
|
98
|
-
locator.register(TemporalIndexingDivinerStateToIndexCandidateDiviner.factory(), labels)
|
|
99
|
-
locator.register(TemporalIndexingDiviner.factory(), labels)
|
|
100
|
-
const manifest = imageThumbnailDivinerManifest as PackageManifestPayload
|
|
101
|
-
const manifestWrapper = new ManifestWrapper(manifest, wallet, locator)
|
|
102
|
-
node = await manifestWrapper.loadNodeFromIndex(0)
|
|
103
|
-
await node.start()
|
|
104
|
-
|
|
105
|
-
// Insert previously witnessed payloads into thumbnail archivist
|
|
106
|
-
const httpSuccessTimestamp: TimeStamp = { schema: TimestampSchema, timestamp: Date.now() }
|
|
107
|
-
const [httpSuccessBoundWitness, httpSuccessPayloads] = await new BoundWitnessBuilder()
|
|
108
|
-
.payloads([thumbnailHttpSuccess, httpSuccessTimestamp])
|
|
109
|
-
.build()
|
|
110
|
-
const httpFailTimestamp: TimeStamp = { schema: TimestampSchema, timestamp: Date.now() }
|
|
111
|
-
const [httpFailBoundWitness, httpFailPayloads] = await new BoundWitnessBuilder().payloads([thumbnailHttpFail, httpFailTimestamp]).build()
|
|
112
|
-
|
|
113
|
-
const witnessFailTimestamp: TimeStamp = { schema: TimestampSchema, timestamp: Date.now() }
|
|
114
|
-
const [witnessFailBoundWitness, witnessFailPayloads] = await new BoundWitnessBuilder()
|
|
115
|
-
.payloads([thumbnailWitnessFail, witnessFailTimestamp])
|
|
116
|
-
.build()
|
|
117
|
-
|
|
118
|
-
const codeFailTimestamp: TimeStamp = { schema: TimestampSchema, timestamp: Date.now() }
|
|
119
|
-
const [codeFailBoundWitness, codeFailPayloads] = await new BoundWitnessBuilder().payloads([thumbnailCodeFail, codeFailTimestamp]).build()
|
|
120
|
-
|
|
121
|
-
const thumbnailArchivist = assertEx(asArchivistInstance<MemoryArchivist>(await node.resolve('ImageThumbnailArchivist')))
|
|
122
|
-
await thumbnailArchivist.insert([
|
|
123
|
-
httpSuccessBoundWitness,
|
|
124
|
-
...httpSuccessPayloads,
|
|
125
|
-
httpFailBoundWitness,
|
|
126
|
-
...httpFailPayloads,
|
|
127
|
-
witnessFailBoundWitness,
|
|
128
|
-
...witnessFailPayloads,
|
|
129
|
-
codeFailBoundWitness,
|
|
130
|
-
...codeFailPayloads,
|
|
131
|
-
])
|
|
132
|
-
|
|
133
|
-
sut = assertEx(asDivinerInstance(await node.resolve('ImageThumbnailDiviner'))) as TemporalIndexingDiviner
|
|
134
|
-
|
|
135
|
-
// Allow enough time for diviner to divine
|
|
136
|
-
await delay(1000)
|
|
137
|
-
}, 40_000)
|
|
138
|
-
describe('diviner state', () => {
|
|
139
|
-
let stateArchivist: MemoryArchivist
|
|
140
|
-
beforeAll(async () => {
|
|
141
|
-
const mod = await node.resolve('AddressStateArchivist')
|
|
142
|
-
stateArchivist = assertEx(asArchivistInstance<MemoryArchivist>(mod))
|
|
143
|
-
})
|
|
144
|
-
it('has expected bound witnesses', async () => {
|
|
145
|
-
const payloads = await stateArchivist.all()
|
|
146
|
-
const stateBoundWitnesses = filterAs(payloads, asBoundWitness)
|
|
147
|
-
expect(stateBoundWitnesses).toBeArrayOfSize(1)
|
|
148
|
-
for (const stateBoundWitness of stateBoundWitnesses) {
|
|
149
|
-
expect(stateBoundWitness).toBeObject()
|
|
150
|
-
expect(stateBoundWitness.addresses).toBeArrayOfSize(1)
|
|
151
|
-
expect(stateBoundWitness.addresses).toContain(sut.address)
|
|
152
|
-
}
|
|
153
|
-
})
|
|
154
|
-
it('has expected state', async () => {
|
|
155
|
-
const payloads = await stateArchivist.all()
|
|
156
|
-
const statePayloads = filterAs(payloads, asModuleState)
|
|
157
|
-
expect(statePayloads).toBeArrayOfSize(1)
|
|
158
|
-
expect(statePayloads.at(-1)).toBeObject()
|
|
159
|
-
const statePayload = assertEx(statePayloads.at(-1))
|
|
160
|
-
expect(statePayload.state).toBeObject()
|
|
161
|
-
expect(statePayload.state?.cursor).toBeDefined()
|
|
162
|
-
})
|
|
163
|
-
})
|
|
164
|
-
describe('diviner index', () => {
|
|
165
|
-
let indexArchivist: MemoryArchivist
|
|
166
|
-
beforeAll(async () => {
|
|
167
|
-
const mod = await node.resolve('ImageThumbnailDivinerIndexArchivist')
|
|
168
|
-
indexArchivist = assertEx(asArchivistInstance<MemoryArchivist>(mod))
|
|
169
|
-
})
|
|
170
|
-
// NOTE: We're not signing indexes for performance reasons
|
|
171
|
-
it.skip('has expected bound witnesses', async () => {
|
|
172
|
-
const payloads = await indexArchivist.all()
|
|
173
|
-
const indexBoundWitnesses = filterAs(payloads, asBoundWitness)
|
|
174
|
-
expect(indexBoundWitnesses).toBeArrayOfSize(1)
|
|
175
|
-
const indexBoundWitness = indexBoundWitnesses[0]
|
|
176
|
-
expect(indexBoundWitness).toBeObject()
|
|
177
|
-
expect(indexBoundWitness.addresses).toBeArrayOfSize(1)
|
|
178
|
-
expect(indexBoundWitness.addresses).toContain(sut.address)
|
|
179
|
-
})
|
|
180
|
-
it('has expected index', async () => {
|
|
181
|
-
const payloads = await indexArchivist.all()
|
|
182
|
-
const indexPayloads = payloads.filter(isTemporalIndexingDivinerResultIndex)
|
|
183
|
-
expect(indexPayloads).toBeArrayOfSize(witnessedThumbnails.length)
|
|
184
|
-
})
|
|
185
|
-
})
|
|
186
|
-
describe('with no thumbnail for the provided URL', () => {
|
|
187
|
-
const url = 'https://does.not.exist.io'
|
|
188
|
-
const schema = PayloadDivinerQuerySchema
|
|
189
|
-
it('returns nothing', async () => {
|
|
190
|
-
const query: Query = { schema, url }
|
|
191
|
-
const result = await sut.divine([query])
|
|
192
|
-
expect(result).toBeArrayOfSize(0)
|
|
193
|
-
})
|
|
194
|
-
})
|
|
195
|
-
describe('with thumbnails for the provided URL', () => {
|
|
196
|
-
const url = sourceUrl
|
|
197
|
-
const schema = PayloadDivinerQuerySchema
|
|
198
|
-
describe('with no filter criteria', () => {
|
|
199
|
-
it('returns the most recent result', async () => {
|
|
200
|
-
const query: Query = { schema, url }
|
|
201
|
-
const results = await sut.divine([query])
|
|
202
|
-
const result = results.find(isTemporalIndexingDivinerResultIndex)
|
|
203
|
-
expect(result).toBeDefined()
|
|
204
|
-
const expected = await PayloadBuilder.dataHash(thumbnailCodeFail)
|
|
205
|
-
expect(result?.$sources).toContain(expected)
|
|
206
|
-
})
|
|
207
|
-
})
|
|
208
|
-
describe('with filter criteria', () => {
|
|
209
|
-
describe('for status code', () => {
|
|
210
|
-
const cases: ImageThumbnail[] = [thumbnailHttpSuccess, thumbnailHttpFail]
|
|
211
|
-
it.each(cases)('returns the most recent instance of that status code', async (payload) => {
|
|
212
|
-
const { status } = payload.http ?? {}
|
|
213
|
-
const query: Query = {
|
|
214
|
-
schema, status, url,
|
|
215
|
-
}
|
|
216
|
-
const results = await sut.divine([query])
|
|
217
|
-
const result = results.find(isTemporalIndexingDivinerResultIndex)
|
|
218
|
-
expect(result).toBeDefined()
|
|
219
|
-
const expected = await PayloadBuilder.dataHash(payload)
|
|
220
|
-
expect(result?.$sources).toContain(expected)
|
|
221
|
-
})
|
|
222
|
-
})
|
|
223
|
-
})
|
|
224
|
-
})
|
|
225
|
-
})
|