@xyo-network/diviner-image-thumbnail 2.75.9 → 2.75.11

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.
Files changed (51) hide show
  1. package/dist/browser/Diviner/Diviner.cjs +233 -0
  2. package/dist/browser/Diviner/Diviner.cjs.map +1 -0
  3. package/dist/browser/Diviner/Diviner.d.cts +43 -0
  4. package/dist/browser/Diviner/Diviner.d.cts.map +1 -0
  5. package/dist/browser/Diviner/Diviner.d.mts +43 -0
  6. package/dist/browser/Diviner/Diviner.d.mts.map +1 -0
  7. package/dist/browser/Diviner/Diviner.d.ts +43 -0
  8. package/dist/browser/Diviner/Diviner.d.ts.map +1 -0
  9. package/dist/browser/Diviner/Diviner.js +218 -0
  10. package/dist/browser/Diviner/Diviner.js.map +1 -0
  11. package/dist/browser/Diviner/index.cjs +235 -0
  12. package/dist/browser/Diviner/index.cjs.map +1 -0
  13. package/dist/browser/Diviner/index.d.cts +2 -0
  14. package/dist/browser/Diviner/index.d.cts.map +1 -0
  15. package/dist/browser/Diviner/index.d.mts +2 -0
  16. package/dist/browser/Diviner/index.d.mts.map +1 -0
  17. package/dist/browser/Diviner/index.d.ts +2 -0
  18. package/dist/browser/Diviner/index.d.ts.map +1 -0
  19. package/dist/browser/Diviner/index.js +218 -0
  20. package/dist/browser/Diviner/index.js.map +1 -0
  21. package/dist/browser/index.cjs +235 -0
  22. package/dist/browser/index.cjs.map +1 -0
  23. package/dist/browser/index.d.cts +2 -0
  24. package/dist/browser/index.d.cts.map +1 -0
  25. package/dist/browser/index.d.mts +2 -0
  26. package/dist/browser/index.d.mts.map +1 -0
  27. package/dist/browser/index.d.ts +2 -0
  28. package/dist/browser/index.d.ts.map +1 -0
  29. package/dist/browser/index.js +218 -0
  30. package/dist/browser/index.js.map +1 -0
  31. package/dist/docs.json +74 -60
  32. package/dist/node/Diviner/Diviner.d.cts +4 -0
  33. package/dist/node/Diviner/Diviner.d.cts.map +1 -1
  34. package/dist/node/Diviner/Diviner.d.mts +4 -0
  35. package/dist/node/Diviner/Diviner.d.mts.map +1 -1
  36. package/dist/node/Diviner/Diviner.d.ts +4 -0
  37. package/dist/node/Diviner/Diviner.d.ts.map +1 -1
  38. package/dist/node/Diviner/Diviner.js +44 -26
  39. package/dist/node/Diviner/Diviner.js.map +1 -1
  40. package/dist/node/Diviner/Diviner.mjs +44 -26
  41. package/dist/node/Diviner/Diviner.mjs.map +1 -1
  42. package/dist/node/Diviner/index.js +44 -26
  43. package/dist/node/Diviner/index.js.map +1 -1
  44. package/dist/node/Diviner/index.mjs +44 -26
  45. package/dist/node/Diviner/index.mjs.map +1 -1
  46. package/dist/node/index.js +44 -26
  47. package/dist/node/index.js.map +1 -1
  48. package/dist/node/index.mjs +44 -26
  49. package/dist/node/index.mjs.map +1 -1
  50. package/package.json +27 -25
  51. package/src/Diviner/Diviner.ts +64 -31
@@ -7,9 +7,10 @@ import { isBoundWitness } from '@xyo-network/boundwitness-model'
7
7
  import { PayloadHasher } from '@xyo-network/core'
8
8
  import { BoundWitnessDivinerQueryPayload, BoundWitnessDivinerQuerySchema } from '@xyo-network/diviner-boundwitness-model'
9
9
  import { asDivinerInstance, DivinerConfigSchema } from '@xyo-network/diviner-model'
10
- import { PayloadDivinerQueryPayload, PayloadDivinerQuerySchema } from '@xyo-network/diviner-payload-model'
10
+ import { PayloadDivinerQueryPayload, PayloadDivinerQuerySchema, SortDirection } from '@xyo-network/diviner-payload-model'
11
11
  import { DivinerWrapper } from '@xyo-network/diviner-wrapper'
12
12
  import {
13
+ ImageThumbnail,
13
14
  ImageThumbnailDivinerConfig,
14
15
  ImageThumbnailDivinerConfigSchema,
15
16
  ImageThumbnailDivinerParams,
@@ -23,7 +24,7 @@ import { isModuleState, ModuleState, ModuleStateSchema, StateDictionary } from '
23
24
  import { PayloadBuilder } from '@xyo-network/payload-builder'
24
25
  import { Payload } from '@xyo-network/payload-model'
25
26
  import { isUrlPayload, UrlPayload } from '@xyo-network/url-payload-plugin'
26
- import { isTimestamp, TimestampSchema } from '@xyo-network/witness-timestamp'
27
+ import { isTimestamp, TimeStamp, TimestampSchema } from '@xyo-network/witness-timestamp'
27
28
 
28
29
  export type ImageThumbnailDivinerState = StateDictionary & {
29
30
  offset: number
@@ -61,6 +62,10 @@ export class ImageThumbnailDiviner<TParams extends ImageThumbnailDivinerParams =
61
62
  return this.config.pollFrequency ?? 10_000
62
63
  }
63
64
 
65
+ /**
66
+ * Works in the background to populate index for the Diviner
67
+ * @returns
68
+ */
64
69
  protected backgroundDivine = async (): Promise<void> => {
65
70
  // Load last state
66
71
  const lastState = (await this.retrieveState()) ?? { offset: 0 }
@@ -75,22 +80,39 @@ export class ImageThumbnailDiviner<TParams extends ImageThumbnailDivinerParams =
75
80
  })
76
81
  const batch = await boundWitnessDiviner.divine([query])
77
82
  if (batch.length === 0) return
78
- const imageThumbnailTimestampTuples = batch
79
- .filter(isBoundWitness)
80
- .map((bw) => {
81
- const imageThumbnailIndexes = bw.payload_schemas?.map((schema, index) => (schema === ImageThumbnailSchema ? index : undefined)).filter(exists)
82
- const timestampIndex = bw.payload_schemas?.findIndex((schema) => schema === TimestampSchema)
83
- if (!imageThumbnailIndexes.length || timestampIndex === -1) return undefined
84
- const imageThumbnails = bw.payload_hashes.map((hash, index) => (imageThumbnailIndexes.includes(index) ? hash : undefined)).filter(exists)
85
- const timestamp = bw.payload_hashes?.[timestampIndex]
86
- return imageThumbnails.map((imageThumbnail) => [imageThumbnail, timestamp] as const)
87
- })
83
+ // Find all the indexable hashes in this batch
84
+ type IndexableHashes = Readonly<[boundWitnessHash: string, imageThumbnailHash: string, timestampHash: string]>
85
+ const indexableHashes: IndexableHashes[] = (
86
+ await Promise.all(
87
+ batch.filter(isBoundWitness).map(async (bw) => {
88
+ const imageThumbnailIndexes = bw.payload_schemas
89
+ ?.map((schema, index) => (schema === ImageThumbnailSchema ? index : undefined))
90
+ .filter(exists)
91
+ const timestampIndex = bw.payload_schemas?.findIndex((schema) => schema === TimestampSchema)
92
+ if (!imageThumbnailIndexes.length || timestampIndex === -1) return undefined
93
+ const imageThumbnails = bw.payload_hashes.map((hash, index) => (imageThumbnailIndexes.includes(index) ? hash : undefined)).filter(exists)
94
+ const timestampHash = bw.payload_hashes?.[timestampIndex]
95
+ const boundWitnessHash = await PayloadHasher.hashAsync(bw)
96
+ return imageThumbnails.map((imageThumbnailHash) => [boundWitnessHash, imageThumbnailHash, timestampHash] as const)
97
+ }),
98
+ )
99
+ )
88
100
  .flat()
89
101
  .filter(exists)
90
102
  const archivist = await this.getArchivistForStore('thumbnailStore')
91
- const payloadTuples = (
103
+ // Find all the indexable data associated with the indexable hashes
104
+ type IndexableData = Readonly<
105
+ [
106
+ boundWitnessHash: string,
107
+ imageThumbnailHash: string,
108
+ imageThumbnailPayload: ImageThumbnail,
109
+ timestampHash: string,
110
+ timestampPayload: TimeStamp,
111
+ ]
112
+ >
113
+ const indexableData: IndexableData[] = (
92
114
  await Promise.all(
93
- imageThumbnailTimestampTuples.map(async ([imageThumbnailHash, timestampHash]) => {
115
+ indexableHashes.map(async ([boundWitnessHash, imageThumbnailHash, timestampHash]) => {
94
116
  const results = await archivist.get([imageThumbnailHash, timestampHash])
95
117
  const imageThumbnailPayload = results.find(isImageThumbnail)
96
118
  const timestampPayload = results.find(isTimestamp)
@@ -98,24 +120,26 @@ export class ImageThumbnailDiviner<TParams extends ImageThumbnailDivinerParams =
98
120
  const calculatedImageThumbnailHash = await PayloadHasher.hashAsync(imageThumbnailPayload)
99
121
  const calculatedTimestampHash = await PayloadHasher.hashAsync(timestampPayload)
100
122
  if (imageThumbnailHash !== calculatedImageThumbnailHash || timestampHash !== calculatedTimestampHash) return undefined
101
- return [imageThumbnailHash, imageThumbnailPayload, timestampHash, timestampPayload] as const
123
+ return [boundWitnessHash, imageThumbnailHash, imageThumbnailPayload, timestampHash, timestampPayload] as const
102
124
  }),
103
125
  )
104
126
  ).filter(exists)
105
- // Build index results
106
- const indexedResults = payloadTuples.map(([thumbnailHash, thumbnailPayload, timestampHash, timestampPayload]) => {
107
- const { sourceUrl: url } = thumbnailPayload
108
- const { timestamp } = timestampPayload
109
- const status = thumbnailPayload.http?.status ?? -1
110
- const sources = [thumbnailHash, timestampHash]
111
- const result = new PayloadBuilder<ImageThumbnailResult>({ schema: ImageThumbnailResultIndexSchema })
112
- .fields({ sources, status, timestamp, url })
113
- .build()
114
- return result
115
- })
127
+ // Build index results from the indexable data
128
+ const indexes: ImageThumbnailResult[] = indexableData.map(
129
+ ([boundWitnessHash, thumbnailHash, thumbnailPayload, timestampHash, timestampPayload]) => {
130
+ const { sourceUrl: url } = thumbnailPayload
131
+ const { timestamp } = timestampPayload
132
+ const status = thumbnailPayload.http?.status ? true : false
133
+ const sources = [boundWitnessHash, thumbnailHash, timestampHash]
134
+ const result = new PayloadBuilder<ImageThumbnailResult>({ schema: ImageThumbnailResultIndexSchema })
135
+ .fields({ sources, status, timestamp, url })
136
+ .build()
137
+ return result
138
+ },
139
+ )
116
140
  // Insert index results
117
141
  const indexArchivist = await this.getArchivistForStore('indexStore')
118
- await indexArchivist.insert(indexedResults)
142
+ await indexArchivist.insert(indexes)
119
143
  // Update state
120
144
  const nextOffset = offset + batch.length + 1
121
145
  const currentState = { ...lastState, offset: nextOffset }
@@ -144,11 +168,20 @@ export class ImageThumbnailDiviner<TParams extends ImageThumbnailDivinerParams =
144
168
  const results = (
145
169
  await Promise.all(
146
170
  urls.map(async (payload) => {
147
- const { url, status: payloadStatus } = payload as UrlPayload & { status: number }
148
- const status = payloadStatus ?? 200
171
+ const {
172
+ limit: payloadLimit,
173
+ offset: payloadOffset,
174
+ order: payloadOrder,
175
+ status: payloadStatus,
176
+ url,
177
+ } = payload as UrlPayload & { limit: number; offset: number; order: SortDirection; status: boolean }
178
+ // TODO: Expose status, limit (and possibly offset) to caller. Currently only exposing URL
179
+ const limit = payloadLimit ?? 1
180
+ const order = payloadOrder ?? 'desc'
181
+ const offset = payloadOffset ?? 0
182
+ const status = payloadStatus ?? true
149
183
  const query = new PayloadBuilder<ImageThumbnailResultQuery>({ schema: PayloadDivinerQuerySchema })
150
- // TODO: Expose status, limit (and possibly offset) to caller. Currently only exposing URL
151
- .fields({ limit: 1, offset: 0, order: 'desc', status, url })
184
+ .fields({ limit, offset, order, status, url })
152
185
  .build()
153
186
  return await diviner.divine([query])
154
187
  }),