@xyo-network/archivist 2.44.1 → 2.45.0-rc.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.
- package/dist/cjs/AbstractArchivist.js +31 -22
- package/dist/cjs/AbstractArchivist.js.map +1 -1
- package/dist/cjs/CookieArchivist.js +3 -1
- package/dist/cjs/CookieArchivist.js.map +1 -1
- package/dist/cjs/MemoryArchivist.js +42 -73
- package/dist/cjs/MemoryArchivist.js.map +1 -1
- package/dist/cjs/StorageArchivist.js +48 -76
- package/dist/cjs/StorageArchivist.js.map +1 -1
- package/dist/docs.json +8958 -9047
- package/dist/esm/AbstractArchivist.js +25 -18
- package/dist/esm/AbstractArchivist.js.map +1 -1
- package/dist/esm/CookieArchivist.js +2 -1
- package/dist/esm/CookieArchivist.js.map +1 -1
- package/dist/esm/MemoryArchivist.js +36 -71
- package/dist/esm/MemoryArchivist.js.map +1 -1
- package/dist/esm/StorageArchivist.js +42 -73
- package/dist/esm/StorageArchivist.js.map +1 -1
- package/dist/types/AbstractArchivist.d.ts +4 -5
- package/dist/types/AbstractArchivist.d.ts.map +1 -1
- package/dist/types/CookieArchivist.d.ts.map +1 -1
- package/dist/types/MemoryArchivist.d.ts.map +1 -1
- package/dist/types/StorageArchivist.d.ts.map +1 -1
- package/package.json +16 -15
- package/src/AbstractArchivist.ts +34 -25
- package/src/CookieArchivist.ts +2 -1
- package/src/MemoryArchivist.ts +42 -69
- package/src/StorageArchivist.ts +50 -73
- package/src/spec/StorageArchivist.spec.ts +13 -6
package/src/AbstractArchivist.ts
CHANGED
|
@@ -40,12 +40,8 @@ export abstract class AbstractArchivist<TConfig extends ArchivistConfig = Archiv
|
|
|
40
40
|
{
|
|
41
41
|
private _parents?: XyoArchivistParentWrappers
|
|
42
42
|
|
|
43
|
-
protected get
|
|
44
|
-
return !!this.config?.
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
protected get writeThrough() {
|
|
48
|
-
return !!this.config?.writeThrough
|
|
43
|
+
protected get storeParentReads() {
|
|
44
|
+
return !!this.config?.storeParentReads
|
|
49
45
|
}
|
|
50
46
|
|
|
51
47
|
public all(): PromisableArray<XyoPayload> {
|
|
@@ -74,6 +70,16 @@ export abstract class AbstractArchivist<TConfig extends ArchivistConfig = Archiv
|
|
|
74
70
|
}
|
|
75
71
|
}
|
|
76
72
|
|
|
73
|
+
public async get(hashes: string[]): Promise<XyoPayload[]> {
|
|
74
|
+
return compact(
|
|
75
|
+
await Promise.all(
|
|
76
|
+
hashes.map(async (hash) => {
|
|
77
|
+
return (await this.getFromParents(hash)) ?? null
|
|
78
|
+
}),
|
|
79
|
+
),
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
|
|
77
83
|
public override queries() {
|
|
78
84
|
return [ArchivistGetQuerySchema, ...super.queries()]
|
|
79
85
|
}
|
|
@@ -128,21 +134,25 @@ export abstract class AbstractArchivist<TConfig extends ArchivistConfig = Archiv
|
|
|
128
134
|
|
|
129
135
|
protected async getFromParents(hash: string) {
|
|
130
136
|
const parents = await this.parents()
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
137
|
+
if (Object.entries(parents.read ?? {}).length > 0) {
|
|
138
|
+
const results = compact(
|
|
139
|
+
await Promise.all(
|
|
140
|
+
Object.values(parents.read ?? {}).map(async (parent) => {
|
|
141
|
+
const queryPayload = PayloadWrapper.parse<ArchivistGetQuery>({ hashes: [hash], schema: ArchivistGetQuerySchema })
|
|
142
|
+
const query = await this.bindQuery(queryPayload)
|
|
143
|
+
const [, payloads] = (await parent?.query(query[0], query[1])) ?? []
|
|
144
|
+
const wrapper = payloads?.[0] ? new PayloadWrapper(payloads?.[0]) : undefined
|
|
145
|
+
if (wrapper && wrapper.hash !== hash) {
|
|
146
|
+
console.warn(`Parent [${parent?.address}] returned payload with invalid hash [${hash} != ${wrapper.hash}]`)
|
|
147
|
+
return null
|
|
148
|
+
}
|
|
149
|
+
return wrapper?.payload
|
|
150
|
+
}),
|
|
151
|
+
),
|
|
152
|
+
)
|
|
153
|
+
return results[0]
|
|
154
|
+
}
|
|
155
|
+
return null
|
|
146
156
|
}
|
|
147
157
|
|
|
148
158
|
protected async parents() {
|
|
@@ -171,9 +181,10 @@ export abstract class AbstractArchivist<TConfig extends ArchivistConfig = Archiv
|
|
|
171
181
|
).flat()
|
|
172
182
|
}
|
|
173
183
|
|
|
174
|
-
private async resolveArchivists(archivists
|
|
184
|
+
private async resolveArchivists(archivists: string[] = []) {
|
|
175
185
|
const resolvedWrappers: Record<string, ArchivistWrapper> = {}
|
|
176
|
-
const
|
|
186
|
+
const resolvedModules = await this.resolver?.resolve({ address: archivists })
|
|
187
|
+
const modules = resolvedModules ?? []
|
|
177
188
|
modules.forEach((module) => {
|
|
178
189
|
const wrapper = new ArchivistWrapper(module)
|
|
179
190
|
resolvedWrappers[wrapper.address] = wrapper
|
|
@@ -181,7 +192,5 @@ export abstract class AbstractArchivist<TConfig extends ArchivistConfig = Archiv
|
|
|
181
192
|
return resolvedWrappers
|
|
182
193
|
}
|
|
183
194
|
|
|
184
|
-
abstract get(hashes: string[]): PromisableArray<XyoPayload>
|
|
185
|
-
|
|
186
195
|
abstract insert(item: XyoPayload[]): PromisableArray<XyoBoundWitness>
|
|
187
196
|
}
|
package/src/CookieArchivist.ts
CHANGED
|
@@ -142,7 +142,8 @@ export class CookieArchivist extends AbstractArchivist<CookieArchivistConfig> {
|
|
|
142
142
|
})
|
|
143
143
|
const result = await this.bindResult([...storedPayloads])
|
|
144
144
|
const parentBoundWitnesses: XyoBoundWitness[] = []
|
|
145
|
-
|
|
145
|
+
const parents = await this.parents()
|
|
146
|
+
if (Object.entries(parents.write ?? {}).length) {
|
|
146
147
|
//we store the child bw also
|
|
147
148
|
parentBoundWitnesses.push(...(await this.writeToParents([result[0], ...storedPayloads])))
|
|
148
149
|
}
|
package/src/MemoryArchivist.ts
CHANGED
|
@@ -31,11 +31,11 @@ export type MemoryArchivistConfig = ArchivistConfig<{
|
|
|
31
31
|
export class MemoryArchivist<TConfig extends MemoryArchivistConfig = MemoryArchivistConfig> extends AbstractArchivist<TConfig> {
|
|
32
32
|
static override configSchema = MemoryArchivistConfigSchema
|
|
33
33
|
|
|
34
|
-
private cache: LruCache<string, XyoPayload>
|
|
34
|
+
private cache: LruCache<string, XyoPayload | null>
|
|
35
35
|
|
|
36
36
|
protected constructor(params: ModuleParams<TConfig>) {
|
|
37
37
|
super(params)
|
|
38
|
-
this.cache = new LruCache<string, XyoPayload>({ max: this.max })
|
|
38
|
+
this.cache = new LruCache<string, XyoPayload | null>({ max: this.max })
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
public get max() {
|
|
@@ -47,94 +47,67 @@ export class MemoryArchivist<TConfig extends MemoryArchivistConfig = MemoryArchi
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
public override all(): PromisableArray<XyoPayload> {
|
|
50
|
-
|
|
51
|
-
return this.cache.dump().map((value) => value[1].value)
|
|
52
|
-
} catch (ex) {
|
|
53
|
-
console.error(`Error: ${JSON.stringify(ex, null, 2)}`)
|
|
54
|
-
throw ex
|
|
55
|
-
}
|
|
50
|
+
return compact(this.cache.dump().map((value) => value[1].value))
|
|
56
51
|
}
|
|
57
52
|
|
|
58
53
|
public override clear(): void | Promise<void> {
|
|
59
|
-
|
|
60
|
-
this.cache.clear()
|
|
61
|
-
} catch (ex) {
|
|
62
|
-
console.error(`Error: ${JSON.stringify(ex, null, 2)}`)
|
|
63
|
-
throw ex
|
|
64
|
-
}
|
|
54
|
+
this.cache.clear()
|
|
65
55
|
}
|
|
66
56
|
|
|
67
57
|
public override async commit(): Promise<XyoBoundWitness[]> {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
return compact(settled.filter(fulfilled).map((result) => result.value))
|
|
84
|
-
} catch (ex) {
|
|
85
|
-
console.error(`Error: ${JSON.stringify(ex, null, 2)}`)
|
|
86
|
-
throw ex
|
|
87
|
-
}
|
|
58
|
+
const payloads = assertEx(await this.all(), 'Nothing to commit')
|
|
59
|
+
const settled = await Promise.allSettled(
|
|
60
|
+
compact(
|
|
61
|
+
Object.values((await this.parents()).commit ?? [])?.map(async (parent) => {
|
|
62
|
+
const queryPayload = PayloadWrapper.parse<ArchivistInsertQuery>({
|
|
63
|
+
payloads: payloads.map((payload) => PayloadWrapper.hash(payload)),
|
|
64
|
+
schema: ArchivistInsertQuerySchema,
|
|
65
|
+
})
|
|
66
|
+
const query = await this.bindQuery(queryPayload, payloads)
|
|
67
|
+
return (await parent?.query(query[0], query[1]))?.[0]
|
|
68
|
+
}),
|
|
69
|
+
),
|
|
70
|
+
)
|
|
71
|
+
await this.clear()
|
|
72
|
+
return compact(settled.filter(fulfilled).map((result) => result.value))
|
|
88
73
|
}
|
|
89
74
|
|
|
90
75
|
public override delete(hashes: string[]): PromisableArray<boolean> {
|
|
91
|
-
|
|
92
|
-
return
|
|
93
|
-
|
|
94
|
-
})
|
|
95
|
-
} catch (ex) {
|
|
96
|
-
console.error(`Error: ${JSON.stringify(ex, null, 2)}`)
|
|
97
|
-
throw ex
|
|
98
|
-
}
|
|
76
|
+
return hashes.map((hash) => {
|
|
77
|
+
return this.cache.delete(hash)
|
|
78
|
+
})
|
|
99
79
|
}
|
|
100
80
|
|
|
101
81
|
public async get(hashes: string[]): Promise<XyoPayload[]> {
|
|
102
|
-
|
|
103
|
-
|
|
82
|
+
return compact(
|
|
83
|
+
await Promise.all(
|
|
104
84
|
hashes.map(async (hash) => {
|
|
105
|
-
const payload = this.cache.get(hash) ?? (await
|
|
106
|
-
if (this.
|
|
85
|
+
const payload = this.cache.get(hash) ?? (await super.get([hash]))[0] ?? null
|
|
86
|
+
if (this.storeParentReads) {
|
|
107
87
|
this.cache.set(hash, payload)
|
|
108
88
|
}
|
|
109
89
|
return payload
|
|
110
90
|
}),
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
console.error(`Error: ${JSON.stringify(ex, null, 2)}`)
|
|
114
|
-
throw ex
|
|
115
|
-
}
|
|
91
|
+
),
|
|
92
|
+
)
|
|
116
93
|
}
|
|
117
94
|
|
|
118
95
|
public async insert(payloads: XyoPayload[]): Promise<XyoBoundWitness[]> {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
return [result[0], ...parentBoundWitnesses]
|
|
134
|
-
} catch (ex) {
|
|
135
|
-
console.error(`Error: ${JSON.stringify(ex, null, 2)}`)
|
|
136
|
-
throw ex
|
|
96
|
+
payloads.map((payload) => {
|
|
97
|
+
const wrapper = new PayloadWrapper(payload)
|
|
98
|
+
const payloadWithMeta = { ...payload, _hash: wrapper.hash, _timestamp: Date.now() }
|
|
99
|
+
this.cache.set(payloadWithMeta._hash, payloadWithMeta)
|
|
100
|
+
return payloadWithMeta
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
const result = await this.bindResult([...payloads])
|
|
104
|
+
const parentBoundWitnesses: XyoBoundWitness[] = []
|
|
105
|
+
const parents = await this.parents()
|
|
106
|
+
if (Object.entries(parents.write ?? {}).length) {
|
|
107
|
+
//we store the child bw also
|
|
108
|
+
parentBoundWitnesses.push(...(await this.writeToParents([result[0], ...payloads])))
|
|
137
109
|
}
|
|
110
|
+
return [result[0], ...parentBoundWitnesses]
|
|
138
111
|
}
|
|
139
112
|
|
|
140
113
|
public override queries() {
|
package/src/StorageArchivist.ts
CHANGED
|
@@ -81,100 +81,77 @@ export class XyoStorageArchivist extends AbstractArchivist<StorageArchivistConfi
|
|
|
81
81
|
|
|
82
82
|
public override all(): PromisableArray<XyoPayload> {
|
|
83
83
|
this.logger?.log(`this.storage.length: ${this.storage.length}`)
|
|
84
|
-
|
|
85
|
-
return Object.entries(this.storage.getAll()).map(([, value]) => value)
|
|
86
|
-
} catch (ex) {
|
|
87
|
-
console.error(`Error: ${JSON.stringify(ex, null, 2)}`)
|
|
88
|
-
throw ex
|
|
89
|
-
}
|
|
84
|
+
return Object.entries(this.storage.getAll()).map(([, value]) => value)
|
|
90
85
|
}
|
|
91
86
|
|
|
92
87
|
public override clear(): void | Promise<void> {
|
|
93
88
|
this.logger?.log(`this.storage.length: ${this.storage.length}`)
|
|
94
|
-
|
|
95
|
-
this.storage.clear()
|
|
96
|
-
} catch (ex) {
|
|
97
|
-
console.error(`Error: ${JSON.stringify(ex, null, 2)}`)
|
|
98
|
-
throw ex
|
|
99
|
-
}
|
|
89
|
+
this.storage.clear()
|
|
100
90
|
}
|
|
101
91
|
|
|
102
92
|
public override async commit(): Promise<XyoBoundWitness[]> {
|
|
103
93
|
this.logger?.log(`this.storage.length: ${this.storage.length}`)
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
return compact(settled.filter(fulfilled).map((result) => result.value))
|
|
122
|
-
} catch (ex) {
|
|
123
|
-
console.error(`Error: ${JSON.stringify(ex, null, 2)}`)
|
|
124
|
-
throw ex
|
|
125
|
-
}
|
|
94
|
+
const payloads = await this.all()
|
|
95
|
+
assertEx(payloads.length > 0, 'Nothing to commit')
|
|
96
|
+
const settled = await Promise.allSettled(
|
|
97
|
+
compact(
|
|
98
|
+
Object.values((await this.parents()).commit ?? [])?.map(async (parent) => {
|
|
99
|
+
const queryPayload = PayloadWrapper.parse<ArchivistInsertQuery>({
|
|
100
|
+
payloads: payloads.map((payload) => PayloadWrapper.hash(payload)),
|
|
101
|
+
schema: ArchivistInsertQuerySchema,
|
|
102
|
+
})
|
|
103
|
+
const query = await this.bindQuery(queryPayload, payloads)
|
|
104
|
+
return (await parent?.query(query[0], query[1]))?.[0]
|
|
105
|
+
}),
|
|
106
|
+
),
|
|
107
|
+
)
|
|
108
|
+
// TODO - rather than clear, delete the payloads that come back as successfully inserted
|
|
109
|
+
await this.clear()
|
|
110
|
+
return compact(settled.filter(fulfilled).map((result) => result.value))
|
|
126
111
|
}
|
|
127
112
|
|
|
128
113
|
public override delete(hashes: string[]): PromisableArray<boolean> {
|
|
129
114
|
this.logger?.log(`hashes.length: ${hashes.length}`)
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
})
|
|
135
|
-
} catch (ex) {
|
|
136
|
-
console.error(`Error: ${JSON.stringify(ex, null, 2)}`)
|
|
137
|
-
throw ex
|
|
138
|
-
}
|
|
115
|
+
return hashes.map((hash) => {
|
|
116
|
+
this.storage.remove(hash)
|
|
117
|
+
return true
|
|
118
|
+
})
|
|
139
119
|
}
|
|
140
120
|
|
|
141
121
|
public async get(hashes: string[]): Promise<XyoPayload[]> {
|
|
142
122
|
this.logger?.log(`hashes.length: ${hashes.length}`)
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
123
|
+
|
|
124
|
+
return await Promise.all(
|
|
125
|
+
hashes.map(async (hash) => {
|
|
126
|
+
const payload = this.storage.get(hash) ?? (await super.get([hash]))[0] ?? null
|
|
127
|
+
if (this.storeParentReads) {
|
|
128
|
+
this.storage.set(hash, payload)
|
|
129
|
+
}
|
|
130
|
+
return payload
|
|
131
|
+
}),
|
|
132
|
+
)
|
|
154
133
|
}
|
|
155
134
|
|
|
156
135
|
public async insert(payloads: XyoPayload[]): Promise<XyoBoundWitness[]> {
|
|
157
136
|
this.logger?.log(`payloads.length: ${payloads.length}`)
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
} catch (ex) {
|
|
175
|
-
console.error(`Error: ${ex}`)
|
|
176
|
-
throw ex
|
|
137
|
+
|
|
138
|
+
const storedPayloads = payloads.map((payload) => {
|
|
139
|
+
const wrapper = new PayloadWrapper(payload)
|
|
140
|
+
const hash = wrapper.hash
|
|
141
|
+
const value = JSON.stringify(wrapper.payload)
|
|
142
|
+
assertEx(value.length < this.maxEntrySize, `Payload too large [${wrapper.hash}, ${value.length}]`)
|
|
143
|
+
this.storage.set(hash, wrapper.payload)
|
|
144
|
+
return wrapper.payload
|
|
145
|
+
})
|
|
146
|
+
const [storageBoundWitness] = await this.bindResult([...storedPayloads])
|
|
147
|
+
const parentBoundWitnesses: XyoBoundWitness[] = []
|
|
148
|
+
const parents = await this.parents()
|
|
149
|
+
if (Object.entries(parents.write ?? {}).length) {
|
|
150
|
+
//we store the child bw also
|
|
151
|
+
const [parentBoundWitness] = await this.writeToParents([storageBoundWitness, ...storedPayloads])
|
|
152
|
+
parentBoundWitnesses.push(parentBoundWitness)
|
|
177
153
|
}
|
|
154
|
+
return [storageBoundWitness, ...parentBoundWitnesses]
|
|
178
155
|
}
|
|
179
156
|
|
|
180
157
|
public override queries() {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { Account } from '@xyo-network/account'
|
|
6
|
-
import {
|
|
6
|
+
import { CompositeModuleResolver } from '@xyo-network/module'
|
|
7
7
|
import { PayloadWrapper } from '@xyo-network/payload-wrapper'
|
|
8
8
|
|
|
9
9
|
import { MemoryArchivist } from '../MemoryArchivist'
|
|
@@ -76,14 +76,21 @@ test('XyoArchivist Parent Write Through', async () => {
|
|
|
76
76
|
schema: StorageArchivistConfigSchema,
|
|
77
77
|
type: 'local',
|
|
78
78
|
},
|
|
79
|
-
resolver: new
|
|
79
|
+
resolver: new CompositeModuleResolver().add(memory),
|
|
80
80
|
})
|
|
81
|
-
await storage.start()
|
|
81
|
+
expect(await storage.start()).toBeDefined()
|
|
82
82
|
|
|
83
83
|
const wrapper = new PayloadWrapper({ schema: 'network.xyo.test' })
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
expect(wrapper).toBeDefined()
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
const inserted = await storage.insert([wrapper.payload])
|
|
88
|
+
|
|
89
|
+
expect(inserted).toBeArrayOfSize(2)
|
|
90
|
+
|
|
91
|
+
const fromStorage = await storage.get([wrapper.hash])
|
|
92
|
+
const fromMemory = await memory.get([wrapper.hash])
|
|
93
|
+
|
|
94
|
+
expect(fromStorage).toBeArrayOfSize(1)
|
|
95
|
+
expect(fromMemory).toBeArrayOfSize(1)
|
|
89
96
|
})
|