@xyo-network/archivist 2.32.0-rc.1 → 2.32.0-rc.4

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 (65) hide show
  1. package/dist/cjs/Archivist.d.ts +5 -4
  2. package/dist/cjs/Archivist.d.ts.map +1 -1
  3. package/dist/cjs/XyoArchivist.d.ts +26 -5
  4. package/dist/cjs/XyoArchivist.d.ts.map +1 -1
  5. package/dist/cjs/XyoArchivist.js +53 -5
  6. package/dist/cjs/XyoArchivist.js.map +1 -1
  7. package/dist/cjs/XyoArchivistWrapper.d.ts +3 -2
  8. package/dist/cjs/XyoArchivistWrapper.d.ts.map +1 -1
  9. package/dist/cjs/XyoArchivistWrapper.js +2 -2
  10. package/dist/cjs/XyoArchivistWrapper.js.map +1 -1
  11. package/dist/cjs/XyoCookieArchivist.d.ts +33 -0
  12. package/dist/cjs/XyoCookieArchivist.d.ts.map +1 -0
  13. package/dist/cjs/XyoCookieArchivist.js +158 -0
  14. package/dist/cjs/XyoCookieArchivist.js.map +1 -0
  15. package/dist/cjs/XyoMemoryArchivist.d.ts +5 -10
  16. package/dist/cjs/XyoMemoryArchivist.d.ts.map +1 -1
  17. package/dist/cjs/XyoMemoryArchivist.js +27 -30
  18. package/dist/cjs/XyoMemoryArchivist.js.map +1 -1
  19. package/dist/cjs/XyoStorageArchivist.d.ts +33 -0
  20. package/dist/cjs/XyoStorageArchivist.d.ts.map +1 -0
  21. package/dist/cjs/XyoStorageArchivist.js +148 -0
  22. package/dist/cjs/XyoStorageArchivist.js.map +1 -0
  23. package/dist/cjs/index.d.ts +3 -0
  24. package/dist/cjs/index.d.ts.map +1 -1
  25. package/dist/cjs/index.js +3 -0
  26. package/dist/cjs/index.js.map +1 -1
  27. package/dist/docs.json +12677 -4302
  28. package/dist/esm/Archivist.d.ts +5 -4
  29. package/dist/esm/Archivist.d.ts.map +1 -1
  30. package/dist/esm/XyoArchivist.d.ts +26 -5
  31. package/dist/esm/XyoArchivist.d.ts.map +1 -1
  32. package/dist/esm/XyoArchivist.js +41 -5
  33. package/dist/esm/XyoArchivist.js.map +1 -1
  34. package/dist/esm/XyoArchivistWrapper.d.ts +3 -2
  35. package/dist/esm/XyoArchivistWrapper.d.ts.map +1 -1
  36. package/dist/esm/XyoArchivistWrapper.js +2 -2
  37. package/dist/esm/XyoArchivistWrapper.js.map +1 -1
  38. package/dist/esm/XyoCookieArchivist.d.ts +33 -0
  39. package/dist/esm/XyoCookieArchivist.d.ts.map +1 -0
  40. package/dist/esm/XyoCookieArchivist.js +139 -0
  41. package/dist/esm/XyoCookieArchivist.js.map +1 -0
  42. package/dist/esm/XyoMemoryArchivist.d.ts +5 -10
  43. package/dist/esm/XyoMemoryArchivist.d.ts.map +1 -1
  44. package/dist/esm/XyoMemoryArchivist.js +17 -18
  45. package/dist/esm/XyoMemoryArchivist.js.map +1 -1
  46. package/dist/esm/XyoStorageArchivist.d.ts +33 -0
  47. package/dist/esm/XyoStorageArchivist.d.ts.map +1 -0
  48. package/dist/esm/XyoStorageArchivist.js +130 -0
  49. package/dist/esm/XyoStorageArchivist.js.map +1 -0
  50. package/dist/esm/index.d.ts +3 -0
  51. package/dist/esm/index.d.ts.map +1 -1
  52. package/dist/esm/index.js +3 -0
  53. package/dist/esm/index.js.map +1 -1
  54. package/package.json +10 -5
  55. package/src/Archivist.ts +6 -5
  56. package/src/XyoArchivist.ts +58 -9
  57. package/src/XyoArchivistWrapper.ts +5 -4
  58. package/src/XyoCookieArchivist.spec.ts +9 -0
  59. package/src/XyoCookieArchivist.ts +176 -0
  60. package/src/XyoMemoryArchivist.ts +19 -28
  61. package/src/XyoStorageArchivist.spec.ts +14 -0
  62. package/src/XyoStorageArchivist.ts +167 -0
  63. package/src/index.ts +3 -0
  64. package/src/test.spec.test/index.ts +1 -0
  65. package/src/test.spec.test/testArchivist.ts +48 -0
@@ -1,5 +1,5 @@
1
1
  import { assertEx } from '@xylabs/sdk-js'
2
- import { XyoBoundWitness, XyoBoundWitnessBuilder } from '@xyo-network/boundwitness'
2
+ import { XyoBoundWitness } from '@xyo-network/boundwitness'
3
3
  import { XyoPayload, XyoPayloadWrapper } from '@xyo-network/payload'
4
4
  import { PromisableArray } from '@xyo-network/promisable'
5
5
  import compact from 'lodash/compact'
@@ -13,8 +13,6 @@ import {
13
13
  XyoArchivistCommitQuerySchema,
14
14
  XyoArchivistDeleteQuerySchema,
15
15
  XyoArchivistFindQuerySchema,
16
- XyoArchivistGetQuery,
17
- XyoArchivistGetQuerySchema,
18
16
  XyoArchivistInsertQuery,
19
17
  XyoArchivistInsertQuerySchema,
20
18
  } from './Queries'
@@ -42,14 +40,14 @@ export class XyoMemoryArchivist extends XyoArchivist<XyoMemoryArchivistConfig> {
42
40
 
43
41
  private cache: LruCache<string, XyoPayload>
44
42
 
45
- public override get queries() {
43
+ public override queries() {
46
44
  return [
47
- ...super.queries,
48
45
  XyoArchivistAllQuerySchema,
49
46
  XyoArchivistDeleteQuerySchema,
50
47
  XyoArchivistClearQuerySchema,
51
48
  XyoArchivistFindQuerySchema,
52
49
  XyoArchivistCommitQuerySchema,
50
+ ...super.queries(),
53
51
  ]
54
52
  }
55
53
 
@@ -76,25 +74,15 @@ export class XyoMemoryArchivist extends XyoArchivist<XyoMemoryArchivistConfig> {
76
74
  }
77
75
  }
78
76
 
79
- protected async getFromParents(hash: string) {
80
- return compact(
81
- await Promise.all(
82
- compact(
83
- Object.values(this.parents?.read ?? {}).map(async (parent) => {
84
- const query: XyoArchivistGetQuery = { hashes: [hash], schema: XyoArchivistGetQuerySchema }
85
- const [, payloads] = (await parent?.query(query)) ?? []
86
- return payloads?.[0]
87
- }),
88
- ),
89
- ),
90
- )[0]
91
- }
92
-
93
77
  public async get(hashes: string[]): Promise<(XyoPayload | null)[]> {
94
78
  try {
95
79
  return await Promise.all(
96
80
  hashes.map(async (hash) => {
97
- return this.cache.get(hash) ?? (await this.getFromParents(hash)) ?? null
81
+ const payload = this.cache.get(hash) ?? (await this.getFromParents(hash)) ?? null
82
+ if (this.cacheParentReads) {
83
+ this.cache.set(hash, payload)
84
+ }
85
+ return payload
98
86
  }),
99
87
  )
100
88
  } catch (ex) {
@@ -102,14 +90,19 @@ export class XyoMemoryArchivist extends XyoArchivist<XyoMemoryArchivistConfig> {
102
90
  }
103
91
  }
104
92
 
105
- public insert(payloads: XyoPayload[]): PromisableArray<XyoPayload> {
93
+ public async insert(payloads: XyoPayload[]): Promise<XyoBoundWitness> {
106
94
  try {
107
- return payloads.map((payload) => {
95
+ payloads.map((payload) => {
108
96
  const wrapper = new XyoPayloadWrapper(payload)
109
97
  const payloadWithmeta = { ...payload, _hash: wrapper.hash, _timestamp: Date.now() }
110
98
  this.cache.set(payloadWithmeta._hash, payloadWithmeta)
111
99
  return payloadWithmeta
112
100
  })
101
+ const boundwitness = this.bindPayloads(payloads)
102
+ if (this.writeThrough) {
103
+ await this.writeToParents(payloads)
104
+ }
105
+ return boundwitness
113
106
  } catch (ex) {
114
107
  throw new MemoryArchivistError('insert', ex, 'unexpected')
115
108
  }
@@ -129,7 +122,7 @@ export class XyoMemoryArchivist extends XyoArchivist<XyoMemoryArchivistConfig> {
129
122
  }
130
123
  }
131
124
 
132
- public all(): Promise<XyoPayload[]> | XyoPayload[] {
125
+ public all(): PromisableArray<XyoPayload> {
133
126
  try {
134
127
  return this.cache.dump().map((value) => value[1].value)
135
128
  } catch (ex) {
@@ -137,12 +130,10 @@ export class XyoMemoryArchivist extends XyoArchivist<XyoMemoryArchivistConfig> {
137
130
  }
138
131
  }
139
132
 
140
- public async commit(): Promise<XyoPayload[]> {
133
+ public async commit(): Promise<XyoBoundWitness> {
141
134
  try {
142
- const account = assertEx(this.account, 'Account is required for commit')
143
135
  const payloads = assertEx(await this.all(), 'Nothing to commit')
144
- const builder = new XyoBoundWitnessBuilder<XyoBoundWitness, XyoPayload>()
145
- const block = builder.payloads(payloads).witness(account).build()
136
+ const block = this.bindPayloads(payloads)
146
137
  await Promise.allSettled(
147
138
  compact(
148
139
  Object.values(this.parents?.commit ?? [])?.map(async (parent) => {
@@ -152,7 +143,7 @@ export class XyoMemoryArchivist extends XyoArchivist<XyoMemoryArchivistConfig> {
152
143
  ),
153
144
  )
154
145
  await this.clear()
155
- return payloads
146
+ return block
156
147
  } catch (ex) {
157
148
  throw new MemoryArchivistError('commit', ex, 'unexpected')
158
149
  }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @jest-environment jsdom
3
+ */
4
+
5
+ import { testArchivistAll, testArchivistRoundTrip } from './test.spec.test'
6
+ import { XyoStorageArchivist } from './XyoStorageArchivist'
7
+
8
+ testArchivistRoundTrip(new XyoStorageArchivist({ namespace: 'test', type: 'local' }), 'local')
9
+ testArchivistRoundTrip(new XyoStorageArchivist({ namespace: 'test', type: 'session' }), 'session')
10
+ testArchivistRoundTrip(new XyoStorageArchivist({ namespace: 'test', type: 'page' }), 'page')
11
+
12
+ testArchivistAll(new XyoStorageArchivist({ namespace: 'test', type: 'local' }), 'local')
13
+ testArchivistAll(new XyoStorageArchivist({ namespace: 'test', type: 'session' }), 'session')
14
+ testArchivistAll(new XyoStorageArchivist({ namespace: 'test', type: 'page' }), 'page')
@@ -0,0 +1,167 @@
1
+ import { assertEx } from '@xylabs/sdk-js'
2
+ import { XyoBoundWitness } from '@xyo-network/boundwitness'
3
+ import { XyoPayload, XyoPayloadWrapper } from '@xyo-network/payload'
4
+ import { PromisableArray } from '@xyo-network/promisable'
5
+ import compact from 'lodash/compact'
6
+ import store, { StoreBase } from 'store2'
7
+
8
+ import { XyoArchivistConfig } from './Config'
9
+ import { PartialArchivistConfig } from './PartialArchivistConfig'
10
+ import {
11
+ XyoArchivistAllQuerySchema,
12
+ XyoArchivistClearQuerySchema,
13
+ XyoArchivistCommitQuerySchema,
14
+ XyoArchivistDeleteQuerySchema,
15
+ XyoArchivistFindQuerySchema,
16
+ XyoArchivistInsertQuery,
17
+ XyoArchivistInsertQuerySchema,
18
+ } from './Queries'
19
+ import { XyoArchivist } from './XyoArchivist'
20
+ import { XyoPayloadFindFilter } from './XyoPayloadFindFilter'
21
+
22
+ export type XyoStorageArchivistConfigSchema = 'network.xyo.module.config.archivist.storage'
23
+ export const XyoStorageArchivistConfigSchema: XyoStorageArchivistConfigSchema = 'network.xyo.module.config.archivist.storage'
24
+
25
+ export type XyoStorageArchivistConfig = XyoArchivistConfig<{
26
+ schema: XyoStorageArchivistConfigSchema
27
+ type?: 'local' | 'session' | 'page'
28
+ namespace?: string
29
+ maxEntries?: number
30
+ maxEntrySize?: number
31
+ }>
32
+
33
+ class StorageArchivistError extends Error {
34
+ constructor(action: string, error: Error['cause'], message?: string) {
35
+ super(`Storage Archivist [${action}] failed${message ? ` (${message})` : ''}`, { cause: error })
36
+ }
37
+ }
38
+
39
+ export class XyoStorageArchivist extends XyoArchivist<XyoStorageArchivistConfig> {
40
+ public get type() {
41
+ return this.config?.type ?? 'local'
42
+ }
43
+
44
+ public get namespace() {
45
+ return this.config?.namespace ?? 'xyoarch'
46
+ }
47
+
48
+ public get maxEntries() {
49
+ return this.config?.maxEntries ?? 1000
50
+ }
51
+
52
+ public get maxEntrySize() {
53
+ return this.config?.maxEntries ?? 16000
54
+ }
55
+
56
+ public override queries() {
57
+ return [
58
+ XyoArchivistAllQuerySchema,
59
+ XyoArchivistDeleteQuerySchema,
60
+ XyoArchivistClearQuerySchema,
61
+ XyoArchivistFindQuerySchema,
62
+ XyoArchivistCommitQuerySchema,
63
+ ...super.queries(),
64
+ ]
65
+ }
66
+
67
+ private storage: StoreBase
68
+
69
+ constructor(config?: PartialArchivistConfig<XyoStorageArchivistConfig>) {
70
+ super({ ...config, schema: XyoStorageArchivistConfigSchema })
71
+ this.storage = store[this.type].namespace(this.namespace)
72
+ }
73
+
74
+ public delete(hashes: string[]): PromisableArray<boolean> {
75
+ try {
76
+ return hashes.map((hash) => {
77
+ this.storage.remove(hash)
78
+ return true
79
+ })
80
+ } catch (ex) {
81
+ throw new StorageArchivistError('delete', ex, 'unexpected')
82
+ }
83
+ }
84
+
85
+ public override clear(): void | Promise<void> {
86
+ try {
87
+ this.storage.clear()
88
+ } catch (ex) {
89
+ throw new StorageArchivistError('clear', ex, 'unexpected')
90
+ }
91
+ }
92
+
93
+ public async get(hashes: string[]): Promise<(XyoPayload | null)[]> {
94
+ try {
95
+ return await Promise.all(
96
+ hashes.map(async (hash) => {
97
+ const value = this.storage.get(hash)
98
+ return value ?? (await this.getFromParents(hash)) ?? null
99
+ }),
100
+ )
101
+ } catch (ex) {
102
+ throw new StorageArchivistError('get', ex, 'unexpected')
103
+ }
104
+ }
105
+
106
+ public async insert(payloads: XyoPayload[]): Promise<XyoBoundWitness> {
107
+ try {
108
+ const storedPayloads = payloads.map((payload) => {
109
+ const wrapper = new XyoPayloadWrapper(payload)
110
+ const hash = wrapper.hash
111
+ const value = JSON.stringify(wrapper.payload)
112
+ assertEx(value.length < this.maxEntrySize, `Payload too large [${wrapper.hash}, ${value.length}]`)
113
+ this.storage.set(hash, wrapper.payload)
114
+ return wrapper.payload
115
+ })
116
+ const boundwitness = this.bindPayloads(storedPayloads)
117
+ if (this.writeThrough) {
118
+ await this.writeToParents([boundwitness, ...storedPayloads])
119
+ }
120
+ return boundwitness
121
+ } catch (ex) {
122
+ throw new StorageArchivistError('insert', ex, 'unexpected')
123
+ }
124
+ }
125
+
126
+ public async find(filter: XyoPayloadFindFilter): Promise<XyoPayload[]> {
127
+ try {
128
+ const x = (await this.all()).filter((payload) => {
129
+ if (filter.schema && filter.schema !== payload.schema) {
130
+ return false
131
+ }
132
+ return true
133
+ })
134
+ return x
135
+ } catch (ex) {
136
+ throw new StorageArchivistError('find', ex, 'unexpected')
137
+ }
138
+ }
139
+
140
+ public all(): PromisableArray<XyoPayload> {
141
+ try {
142
+ return Object.entries(this.storage.getAll()).map(([, value]) => value)
143
+ } catch (ex) {
144
+ throw new StorageArchivistError('all', ex, 'unexpected')
145
+ }
146
+ }
147
+
148
+ public async commit(): Promise<XyoBoundWitness> {
149
+ try {
150
+ const payloads = await this.all()
151
+ assertEx(payloads.length > 0, 'Nothing to commit')
152
+ const block = this.bindPayloads(payloads)
153
+ await Promise.allSettled(
154
+ compact(
155
+ Object.values(this.parents?.commit ?? [])?.map(async (parent) => {
156
+ const query: XyoArchivistInsertQuery = { payloads: [block, ...payloads], schema: XyoArchivistInsertQuerySchema }
157
+ return await parent?.query(query)
158
+ }),
159
+ ),
160
+ )
161
+ await this.clear()
162
+ return block
163
+ } catch (ex) {
164
+ throw new StorageArchivistError('commit', ex, 'unexpected')
165
+ }
166
+ }
167
+ }
package/src/index.ts CHANGED
@@ -1,7 +1,10 @@
1
1
  export * from './Archivist'
2
2
  export * from './Config'
3
+ export * from './PartialArchivistConfig'
3
4
  export * from './Queries'
4
5
  export * from './XyoArchivist'
5
6
  export * from './XyoArchivistWrapper'
7
+ export * from './XyoCookieArchivist'
6
8
  export * from './XyoMemoryArchivist'
7
9
  export * from './XyoPayloadFindFilter'
10
+ export * from './XyoStorageArchivist'
@@ -0,0 +1 @@
1
+ export * from './testArchivist'
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @jest-environment jsdom
3
+ */
4
+
5
+ import { delay } from '@xylabs/delay'
6
+ import { XyoPayload, XyoPayloadWrapper } from '@xyo-network/payload'
7
+
8
+ import { XyoArchivist } from '../XyoArchivist'
9
+ import { XyoArchivistWrapper } from '../XyoArchivistWrapper'
10
+
11
+ export const testArchivistRoundTrip = (archivist: XyoArchivist, name: string) => {
12
+ test(`XyoArchivist [${name}]`, async () => {
13
+ const idPayload: XyoPayload<{ salt: string }> = {
14
+ salt: 'test',
15
+ schema: 'network.xyo.id',
16
+ }
17
+ const payloadWrapper = new XyoPayloadWrapper(idPayload)
18
+ const archivistWrapper = new XyoArchivistWrapper(archivist)
19
+ const insertResult = await archivistWrapper.insert([idPayload])
20
+ expect(insertResult).toBeDefined()
21
+ expect(insertResult.payload_hashes.find((hash) => hash === payloadWrapper.hash)).toBeDefined()
22
+ const getResult = await archivistWrapper.get([payloadWrapper.hash])
23
+ expect(getResult).toBeDefined()
24
+ expect(getResult.length).toBe(1)
25
+ const gottenPayload = getResult[0]
26
+ if (gottenPayload) {
27
+ const gottenPayloadWrapper = new XyoPayloadWrapper(gottenPayload)
28
+ expect(gottenPayloadWrapper.hash).toBe(payloadWrapper.hash)
29
+ }
30
+ })
31
+ }
32
+
33
+ export const testArchivistAll = (archivist: XyoArchivist, name: string) => {
34
+ test(`XyoArchivist [${name}]`, async () => {
35
+ const idPayload = {
36
+ salt: 'test',
37
+ schema: 'network.xyo.id',
38
+ }
39
+ const archivistWrapper = new XyoArchivistWrapper(archivist)
40
+ for (let x = 0; x < 10; x++) {
41
+ await archivistWrapper.insert([{ ...idPayload, salt: Date.now().toString() } as XyoPayload<{ salt: string }>])
42
+ await delay(10)
43
+ }
44
+ const getResult = await archivistWrapper.all()
45
+ expect(getResult).toBeDefined()
46
+ expect(getResult.length).toBe(11)
47
+ })
48
+ }