@xyo-network/archivist-abstract 2.91.0 → 2.91.1

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 (35) hide show
  1. package/dist/browser/AbstractArchivist.d.cts +12 -9
  2. package/dist/browser/AbstractArchivist.d.cts.map +1 -1
  3. package/dist/browser/AbstractArchivist.d.mts +12 -9
  4. package/dist/browser/AbstractArchivist.d.mts.map +1 -1
  5. package/dist/browser/AbstractArchivist.d.ts +12 -9
  6. package/dist/browser/AbstractArchivist.d.ts.map +1 -1
  7. package/dist/browser/StorageMeta.d.cts +2 -1
  8. package/dist/browser/StorageMeta.d.cts.map +1 -1
  9. package/dist/browser/StorageMeta.d.mts +2 -1
  10. package/dist/browser/StorageMeta.d.mts.map +1 -1
  11. package/dist/browser/StorageMeta.d.ts +2 -1
  12. package/dist/browser/StorageMeta.d.ts.map +1 -1
  13. package/dist/browser/index.cjs +50 -21
  14. package/dist/browser/index.cjs.map +1 -1
  15. package/dist/browser/index.js +50 -21
  16. package/dist/browser/index.js.map +1 -1
  17. package/dist/node/AbstractArchivist.d.cts +12 -9
  18. package/dist/node/AbstractArchivist.d.cts.map +1 -1
  19. package/dist/node/AbstractArchivist.d.mts +12 -9
  20. package/dist/node/AbstractArchivist.d.mts.map +1 -1
  21. package/dist/node/AbstractArchivist.d.ts +12 -9
  22. package/dist/node/AbstractArchivist.d.ts.map +1 -1
  23. package/dist/node/StorageMeta.d.cts +2 -1
  24. package/dist/node/StorageMeta.d.cts.map +1 -1
  25. package/dist/node/StorageMeta.d.mts +2 -1
  26. package/dist/node/StorageMeta.d.mts.map +1 -1
  27. package/dist/node/StorageMeta.d.ts +2 -1
  28. package/dist/node/StorageMeta.d.ts.map +1 -1
  29. package/dist/node/index.cjs +50 -21
  30. package/dist/node/index.cjs.map +1 -1
  31. package/dist/node/index.js +50 -21
  32. package/dist/node/index.js.map +1 -1
  33. package/package.json +13 -12
  34. package/src/AbstractArchivist.ts +73 -32
  35. package/src/StorageMeta.ts +7 -3
@@ -2,6 +2,7 @@ import { assertEx } from '@xylabs/assert'
2
2
  import { Address, Hash } from '@xylabs/hex'
3
3
  import { compact } from '@xylabs/lodash'
4
4
  import { Promisable, PromisableArray } from '@xylabs/promise'
5
+ import { difference } from '@xylabs/set'
5
6
  import {
6
7
  ArchivistAllQuerySchema,
7
8
  ArchivistClearQuerySchema,
@@ -12,9 +13,9 @@ import {
12
13
  ArchivistInsertQuerySchema,
13
14
  ArchivistInstance,
14
15
  ArchivistModuleEventData,
16
+ ArchivistNextOptions,
15
17
  ArchivistParams,
16
- ArchivistQuery,
17
- ArchivistQueryBase,
18
+ ArchivistQueries,
18
19
  asArchivistInstance,
19
20
  isArchivistInstance,
20
21
  } from '@xyo-network/archivist-model'
@@ -57,7 +58,7 @@ export abstract class AbstractArchivist<
57
58
  return this.config.requireAllParents ?? false
58
59
  }
59
60
 
60
- protected override get _queryAccountPaths(): Record<ArchivistQueryBase['schema'], string> {
61
+ protected override get _queryAccountPaths(): Record<ArchivistQueries['schema'], string> {
61
62
  return {
62
63
  'network.xyo.query.archivist.all': '1/1',
63
64
  'network.xyo.query.archivist.clear': '1/2',
@@ -65,6 +66,7 @@ export abstract class AbstractArchivist<
65
66
  'network.xyo.query.archivist.delete': '1/4',
66
67
  'network.xyo.query.archivist.get': '1/5',
67
68
  'network.xyo.query.archivist.insert': '1/6',
69
+ 'network.xyo.query.archivist.next': '1/7',
68
70
  }
69
71
  }
70
72
 
@@ -76,7 +78,7 @@ export abstract class AbstractArchivist<
76
78
  this._noOverride('all')
77
79
  return this.busy(async () => {
78
80
  await this.started('throw')
79
- return await this.allHandler()
81
+ return await PayloadBuilder.build(await this.allHandler())
80
82
  })
81
83
  }
82
84
 
@@ -96,7 +98,7 @@ export abstract class AbstractArchivist<
96
98
  })
97
99
  }
98
100
 
99
- async delete(hashes: Hash[]): Promise<string[]> {
101
+ async delete(hashes: Hash[]): Promise<Hash[]> {
100
102
  this._noOverride('delete')
101
103
  return await this.busy(async () => {
102
104
  await this.started('throw')
@@ -108,7 +110,7 @@ export abstract class AbstractArchivist<
108
110
  this._noOverride('get')
109
111
  return await this.busy(async () => {
110
112
  await this.started('throw')
111
- return await this.getWithConfig(hashes)
113
+ return await PayloadBuilder.build(await this.getWithConfig(hashes))
112
114
  })
113
115
  }
114
116
 
@@ -121,7 +123,15 @@ export abstract class AbstractArchivist<
121
123
  })
122
124
  }
123
125
 
124
- protected allHandler(): PromisableArray<WithMeta<Payload>> {
126
+ async next?(options?: ArchivistNextOptions): Promise<WithMeta<Payload>[]> {
127
+ this._noOverride('next')
128
+ return await this.busy(async () => {
129
+ await this.started('throw')
130
+ return await this.nextWithConfig(options)
131
+ })
132
+ }
133
+
134
+ protected allHandler(): PromisableArray<Payload> {
125
135
  throw new Error('Not implemented')
126
136
  }
127
137
 
@@ -133,11 +143,11 @@ export abstract class AbstractArchivist<
133
143
  throw new Error('Not implemented')
134
144
  }
135
145
 
136
- protected deleteHandler(_hashes: string[]): PromisableArray<string> {
146
+ protected deleteHandler(_hashes: Hash[]): PromisableArray<Hash> {
137
147
  throw new Error('Not implemented')
138
148
  }
139
149
 
140
- protected async deleteWithConfig(hashes: string[], config?: ActionConfig): Promise<string[]> {
150
+ protected async deleteWithConfig(hashes: Hash[], config?: ActionConfig): Promise<Hash[]> {
141
151
  const emitEvents = config?.emitEvents ?? true
142
152
 
143
153
  const deletedHashes = await this.deleteHandler(hashes)
@@ -166,13 +176,13 @@ export abstract class AbstractArchivist<
166
176
  return [foundPayloads, notfound]
167
177
  }
168
178
 
169
- protected async getFromParents(hashes: Hash[]): Promise<[WithMeta<Payload>[], string[]]> {
179
+ protected async getFromParents(hashes: Hash[]): Promise<[WithMeta<Payload>[], Hash[]]> {
170
180
  const parents = Object.values((await this.parents())?.read ?? {})
171
181
  let remainingHashes = [...hashes]
172
182
  let parentIndex = 0
173
183
  let result: WithMeta<Payload>[] = []
174
184
 
175
- //intentionally doing this serially
185
+ // NOTE: intentionally doing this serially
176
186
  while (parentIndex < parents.length && remainingHashes.length > 0) {
177
187
  const [found, notfound] = await this.getFromParent(remainingHashes, parents[parentIndex])
178
188
  result = [...result, ...found]
@@ -186,37 +196,59 @@ export abstract class AbstractArchivist<
186
196
  throw new Error('Not implemented')
187
197
  }
188
198
 
189
- protected async getWithConfig(hashes: Hash[], config?: InsertConfig): Promise<WithMeta<Payload>[]> {
190
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
191
- const emitEvents = config?.emitEvents ?? true
192
- const gotten = await this.getHandler(hashes)
193
- const map = await PayloadBuilder.toHashMap(gotten)
194
- const dataMap = await PayloadBuilder.toDataHashMap(gotten)
195
-
196
- const foundPayloads: WithMeta<Payload>[] = []
197
- const notfoundHashes: Hash[] = []
198
- for (const hash of hashes) {
199
- const found = map[hash] ?? dataMap[hash]
200
- if (found) {
201
- foundPayloads.push(await PayloadBuilder.build<Payload>(found, true))
202
- } else {
203
- notfoundHashes.push(hash)
199
+ protected async getWithConfig(hashes: Hash[], _config?: InsertConfig): Promise<WithMeta<Payload>[]> {
200
+ // Filter out duplicates
201
+ const requestedHashes = new Set(hashes)
202
+
203
+ // Attempt to find the payloads in the store
204
+ const gotten = await this.getHandler([...requestedHashes])
205
+
206
+ // Do not just blindly return what the archivist told us but
207
+ // ensure to only return requested payloads and keep track of
208
+ // the ones it did not find so we can ask the parents.
209
+ const foundPayloads: PayloadWithMeta[] = []
210
+ const foundHashes = new Set<Hash>()
211
+
212
+ // NOTE: We are iterating over the returned result from the archivist
213
+ // (not the array of hashes passed in) to preserve the natural order of the
214
+ // hashes as returned by the archivist as that should loosely
215
+ // correspond to the order when iterated and the symmetry will
216
+ // be helpful for debugging
217
+ for (const payload of gotten) {
218
+ // Compute the hashes for this payload
219
+ const map = await PayloadBuilder.toAllHashMap([payload])
220
+ let requestedPayloadFound = false
221
+ for (const [key, payload] of Object.entries(map)) {
222
+ const hash = key as Hash // NOTE: Required cast as Object.entries always returns string keys
223
+ // If this hash was requested
224
+ if (requestedHashes.has(hash)) {
225
+ // Indicate that we found it (but do not insert it yet). Since
226
+ // one payload could satisfy two requested hashes (vit its dataHash
227
+ // & rootHash) we only want to insert that payload once but we want
228
+ // to keep track of all the hashes it satisfies so we can ask th
229
+ // parents for the ones we did not find
230
+ requestedPayloadFound = true
231
+ // Add it to the list of found hashes
232
+ foundHashes.add(hash)
233
+ }
234
+ if (requestedPayloadFound) foundPayloads.push(payload)
204
235
  }
205
236
  }
206
-
207
- const [parentFoundPayloads] = await this.getFromParents(notfoundHashes)
237
+ // For all the hashes we did not find, ask the parents
238
+ const notFoundHashes = [...difference(requestedHashes, foundHashes)]
239
+ const [parentFoundPayloads] = await this.getFromParents(notFoundHashes)
208
240
 
209
241
  if (this.storeParentReads) {
210
242
  await this.insertWithConfig(parentFoundPayloads)
211
243
  }
212
- return [...foundPayloads, ...parentFoundPayloads]
244
+ return await PayloadBuilder.build([...foundPayloads, ...parentFoundPayloads])
213
245
  }
214
246
 
215
247
  protected head(): Promisable<Payload | undefined> {
216
248
  return this._lastInsertedPayload
217
249
  }
218
250
 
219
- protected insertHandler(_payloads: WithMeta<Payload>[]): Promise<WithMeta<Payload>[]> {
251
+ protected insertHandler(_payloads: Payload[]): Promise<WithMeta<Payload>[]> {
220
252
  throw new Error('Not implemented')
221
253
  }
222
254
 
@@ -241,7 +273,7 @@ export abstract class AbstractArchivist<
241
273
  const emitEvents = config?.emitEvents ?? true
242
274
  const writeToParents = config?.writeToParents ?? true
243
275
 
244
- const insertedPayloads = await this.insertHandler(await PayloadBuilder.build(payloads, true))
276
+ const insertedPayloads = await PayloadBuilder.build(await this.insertHandler(payloads), true)
245
277
 
246
278
  if (writeToParents) {
247
279
  await this.writeToParents(insertedPayloads)
@@ -253,6 +285,15 @@ export abstract class AbstractArchivist<
253
285
  return insertedPayloads
254
286
  }
255
287
 
288
+ protected nextHandler(_options?: ArchivistNextOptions): Promisable<WithMeta<Payload>[]> {
289
+ throw new Error('Not implemented')
290
+ }
291
+
292
+ protected async nextWithConfig(options?: ArchivistNextOptions, _config?: InsertConfig): Promise<WithMeta<Payload>[]> {
293
+ const foundPayloads = await this.nextHandler(options)
294
+ return await PayloadBuilder.build(foundPayloads)
295
+ }
296
+
256
297
  protected async parents() {
257
298
  this._parents = this._parents ?? {
258
299
  commit: await this.resolveArchivists(this.config?.parents?.commit),
@@ -267,7 +308,7 @@ export abstract class AbstractArchivist<
267
308
  payloads: Payload[],
268
309
  queryConfig?: TConfig,
269
310
  ): Promise<ModuleQueryHandlerResult> {
270
- const wrappedQuery = await QueryBoundWitnessWrapper.parseQuery<ArchivistQuery>(query, payloads)
311
+ const wrappedQuery = await QueryBoundWitnessWrapper.parseQuery<ArchivistQueries>(query, payloads)
271
312
  const builtQuery = await PayloadBuilder.build(query, true)
272
313
  const queryPayload = await wrappedQuery.getQuery()
273
314
  assertEx(await this.queryable(query, payloads, queryConfig))
@@ -16,18 +16,22 @@ export const addStorageMeta = <T extends PayloadWithMeta>(payload: T, index = 0)
16
16
  return { ...payload, _sequence: sequenceNumber(index) } as WithStorageMeta<T>
17
17
  }
18
18
 
19
- export const sortByStorageMeta = <T extends PayloadWithMeta>(payloads: WithStorageMeta<T>[]) => {
19
+ export const sortByStorageMeta = <T extends PayloadWithMeta>(payloads: WithStorageMeta<T>[], direction: -1 | 1 = 1) => {
20
20
  return payloads.sort((a, b) =>
21
- a._sequence < b._sequence ? -1
22
- : a._sequence > b._sequence ? 1
21
+ a._sequence < b._sequence ? -direction
22
+ : a._sequence > b._sequence ? direction
23
23
  : 0,
24
24
  )
25
25
  }
26
26
 
27
27
  export function removeStorageMeta<T extends PayloadWithMeta>(payload: WithStorageMeta<T>): T
28
+ export function removeStorageMeta<T extends PayloadWithMeta>(payloads: WithStorageMeta<T>[]): T[]
28
29
  export function removeStorageMeta<T extends PayloadWithMeta>(payload?: WithStorageMeta<T>): T | undefined
29
30
  export function removeStorageMeta<T extends PayloadWithMeta>(payload?: WithStorageMeta<T>) {
30
31
  if (!payload) return
32
+ if (Array.isArray(payload)) {
33
+ return payload.map((p) => removeStorageMeta(p))
34
+ }
31
35
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
32
36
  const { _sequence, ...noMeta } = payload as WithStorageMeta<T>
33
37
  return noMeta as T