@xyo-network/api 2.20.42 → 2.20.45

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.
@@ -6,6 +6,7 @@ import { XyoUserApi } from '../User';
6
6
  import { XyoAccountApi } from './Account';
7
7
  import { XyoArchivistArchiveApi } from './Archive';
8
8
  import { XyoArchivistArchivesApi } from './Archives';
9
+ import { XyoArchivistNodeApi } from './Node';
9
10
  export declare class XyoArchivistApi extends XyoApiBase {
10
11
  private _archives?;
11
12
  get archives(): XyoArchivistArchivesApi;
@@ -23,7 +24,7 @@ export declare class XyoArchivistApi extends XyoApiBase {
23
24
  * @param archive Optional, the archive to issue the requests against
24
25
  * @returns Confirmation for the request, as a BoundWitness, from the network Node
25
26
  */
26
- node<TResponse extends XyoBoundWitness, TData extends XyoBoundWitness = TResponse>(archive?: string): XyoApiSimple<TResponse, TData, Record<string, never>, import("../models/Api/Config").XyoApiConfig>;
27
+ node<TData extends XyoBoundWitness | XyoBoundWitness[] = XyoBoundWitness | XyoBoundWitness[]>(archive?: string): XyoArchivistNodeApi<TData, import("..").WithArchive<import("../models/Api/Config").XyoApiConfig>>;
27
28
  /** @deprecated use huri(huri) instead */
28
29
  get(huri: Huri | string): Promise<XyoApiResponseBody<XyoPayload>>;
29
30
  /** @deprecated use huri(huri) instead */
@@ -5,6 +5,7 @@ import { XyoUserApi } from '../User';
5
5
  import { XyoAccountApi } from './Account';
6
6
  import { XyoArchivistArchiveApi } from './Archive';
7
7
  import { XyoArchivistArchivesApi } from './Archives';
8
+ import { XyoArchivistNodeApi } from './Node';
8
9
  export class XyoArchivistApi extends XyoApiBase {
9
10
  get archives() {
10
11
  this._archives =
@@ -62,10 +63,10 @@ export class XyoArchivistApi extends XyoApiBase {
62
63
  * @param archive Optional, the archive to issue the requests against
63
64
  * @returns Confirmation for the request, as a BoundWitness, from the network Node
64
65
  */
65
- node(archive) {
66
- return new XyoApiSimple({
66
+ node(archive = 'temp') {
67
+ return new XyoArchivistNodeApi({
67
68
  ...this.config,
68
- root: archive ? `${this.root}${archive}/` : this.root,
69
+ root: `${this.root}${archive}/`,
69
70
  });
70
71
  }
71
72
  /** @deprecated use huri(huri) instead */
@@ -1 +1 @@
1
- {"version":3,"file":"Api.js","sourceRoot":"","sources":["../../../src/Archivist/Api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Api.js","sourceRoot":"","sources":["../../../src/Archivist/Api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { XyoBoundWitness, XyoPayload } from '@xyo-network/core';
2
+ import { XyoApiConfig } from '../../models';
3
+ import { XyoApiSimple, XyoApiSimpleQuery } from '../../Simple';
4
+ import { WithArchive } from '../../WithArchive';
5
+ export declare class XyoArchivistNodeApi<D extends XyoBoundWitness | XyoBoundWitness[] = XyoBoundWitness | XyoBoundWitness[], C extends WithArchive<XyoApiConfig> = WithArchive<XyoApiConfig>> extends XyoApiSimple<string[][], D, XyoApiSimpleQuery, C> {
6
+ /**
7
+ * Get the result of a previously issued query (if available)
8
+ * @param queryId Query ID from a previously issued query
9
+ * @returns The result of the query (if available)
10
+ */
11
+ result<T extends XyoPayload = XyoPayload>(queryId: string): XyoApiSimple<XyoPayload>;
12
+ /**
13
+ * Issue the supplied queries and wait (non-blocking) for the results
14
+ * @param data The queries to issue
15
+ * @param timeout The max time to wait for the query results
16
+ * @param retryInterval The interval to poll for query results
17
+ * @returns The results for the issued queries
18
+ */
19
+ performTransaction(data: D, timeout?: number, retryInterval?: number): Promise<import("../../models").XyoApiEnvelope<import("@xyo-network/core").XyoPayloadFull | undefined>[][]>;
20
+ /**
21
+ * Issue the supplied query and wait (non-blocking) for the result
22
+ * @param data The query to issue
23
+ * @param timeout The max time to wait for the query results
24
+ * @param retryInterval The interval to poll for query results
25
+ * @returns The result for the issued query
26
+ */
27
+ perform<T>(data: T, schema: string, timeout?: number, retryInterval?: number): Promise<import("../../models").XyoApiEnvelope<import("@xyo-network/core").XyoPayloadFull | undefined>>;
28
+ }
@@ -0,0 +1,67 @@
1
+ import { assertEx, delay } from '@xylabs/sdk-js';
2
+ import { XyoBoundWitnessBuilder, XyoPayloadBuilder } from '@xyo-network/core';
3
+ import { XyoApiSimple } from '../../Simple';
4
+ const getRequestStatuses = (results) => {
5
+ return results.flatMap((r) => r).map((r) => r?.[2]?.status);
6
+ };
7
+ const allRequestsSucceeded = (results) => {
8
+ return getRequestStatuses(results).every((status) => status === 200);
9
+ };
10
+ const anyRequestsFailed = (results) => {
11
+ return getRequestStatuses(results).every((status) => status > 399);
12
+ };
13
+ export class XyoArchivistNodeApi extends XyoApiSimple {
14
+ /**
15
+ * Get the result of a previously issued query (if available)
16
+ * @param queryId Query ID from a previously issued query
17
+ * @returns The result of the query (if available)
18
+ */
19
+ result(queryId) {
20
+ return new XyoApiSimple({
21
+ ...this.config,
22
+ root: `/query/${queryId}/`,
23
+ });
24
+ }
25
+ /**
26
+ * Issue the supplied queries and wait (non-blocking) for the results
27
+ * @param data The queries to issue
28
+ * @param timeout The max time to wait for the query results
29
+ * @param retryInterval The interval to poll for query results
30
+ * @returns The results for the issued queries
31
+ */
32
+ async performTransaction(data, timeout = 5000, retryInterval = 100) {
33
+ assertEx(timeout > 0, 'timeout must be positive');
34
+ assertEx(retryInterval > 0, 'retryInterval must be positive');
35
+ assertEx(timeout > retryInterval, 'timeout must be greater than retryInterval');
36
+ const ids = await this.post(data);
37
+ if (!ids?.length)
38
+ return [];
39
+ const loops = Math.floor(timeout / retryInterval);
40
+ let results = [];
41
+ for (let i = 0; i < loops; i++) {
42
+ await delay(retryInterval);
43
+ results = await Promise.all(ids?.map(async (bw) => await Promise.all(bw.map((p) => this.result(p).get('tuple')))));
44
+ if (allRequestsSucceeded(results))
45
+ break;
46
+ // TODO: More nuanced error handling of partial success/failure
47
+ if (anyRequestsFailed(results))
48
+ throw new Error('Request Error');
49
+ }
50
+ // Unpack results
51
+ return results.map((b) => b.map((p) => p[1]));
52
+ }
53
+ /**
54
+ * Issue the supplied query and wait (non-blocking) for the result
55
+ * @param data The query to issue
56
+ * @param timeout The max time to wait for the query results
57
+ * @param retryInterval The interval to poll for query results
58
+ * @returns The result for the issued query
59
+ */
60
+ async perform(data, schema, timeout = 5000, retryInterval = 100) {
61
+ const payload = new XyoPayloadBuilder({ schema }).fields(data).build();
62
+ const query = new XyoBoundWitnessBuilder({ inlinePayloads: true }).payload(payload).build();
63
+ const result = await this.performTransaction(query, timeout, retryInterval);
64
+ return result?.[0]?.[0];
65
+ }
66
+ }
67
+ //# sourceMappingURL=Api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Api.js","sourceRoot":"","sources":["../../../../src/Archivist/Node/Api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAmB,sBAAsB,EAAc,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAG1G,OAAO,EAAE,YAAY,EAAqB,MAAM,cAAc,CAAA;AAG9D,MAAM,kBAAkB,GAAG,CAAC,OAA4C,EAAY,EAAE;IACpF,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;AAC7D,CAAC,CAAA;AAED,MAAM,oBAAoB,GAAG,CAAC,OAA4C,EAAW,EAAE;IACrF,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,GAAG,CAAC,CAAA;AACtE,CAAC,CAAA;AAED,MAAM,iBAAiB,GAAG,CAAC,OAA4C,EAAW,EAAE;IAClF,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,GAAG,GAAG,CAAC,CAAA;AACpE,CAAC,CAAA;AAED,MAAM,OAAO,mBAGX,SAAQ,YAAiD;IACzD;;;;OAIG;IACI,MAAM,CAAoC,OAAe;QAC9D,OAAO,IAAI,YAAY,CAAI;YACzB,GAAG,IAAI,CAAC,MAAM;YACd,IAAI,EAAE,UAAU,OAAO,GAAG;SAC3B,CAAC,CAAA;IACJ,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,kBAAkB,CAAC,IAAO,EAAE,OAAO,GAAG,IAAI,EAAE,aAAa,GAAG,GAAG;QAC1E,QAAQ,CAAC,OAAO,GAAG,CAAC,EAAE,0BAA0B,CAAC,CAAA;QACjD,QAAQ,CAAC,aAAa,GAAG,CAAC,EAAE,gCAAgC,CAAC,CAAA;QAC7D,QAAQ,CAAC,OAAO,GAAG,aAAa,EAAE,4CAA4C,CAAC,CAAA;QAC/E,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACjC,IAAI,CAAC,GAAG,EAAE,MAAM;YAAE,OAAO,EAAE,CAAA;QAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,aAAa,CAAC,CAAA;QACjD,IAAI,OAAO,GAAG,EAAyC,CAAA;QACvD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;YAC9B,MAAM,KAAK,CAAC,aAAa,CAAC,CAAA;YAC1B,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YAClH,IAAI,oBAAoB,CAAC,OAAO,CAAC;gBAAE,MAAK;YACxC,+DAA+D;YAC/D,IAAI,iBAAiB,CAAC,OAAO,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAA;SACjE;QACD,iBAAiB;QACjB,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAC/C,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,OAAO,CAAI,IAAO,EAAE,MAAc,EAAE,OAAO,GAAG,IAAI,EAAE,aAAa,GAAG,GAAG;QAClF,MAAM,OAAO,GAAG,IAAI,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAA;QACtE,MAAM,KAAK,GAAG,IAAI,sBAAsB,CAAC,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAO,CAAA;QAChG,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,aAAa,CAAC,CAAA;QAC3E,OAAO,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IACzB,CAAC;CACF"}
@@ -0,0 +1 @@
1
+ export * from './Api';
@@ -0,0 +1,2 @@
1
+ export * from './Api';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/Archivist/Node/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAA"}
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "dependencies": {
12
12
  "@xylabs/sdk-js": "^2.5.7",
13
- "@xyo-network/core": "^2.20.42",
13
+ "@xyo-network/core": "^2.20.45",
14
14
  "axios": "^0.27.2",
15
15
  "pako": "^2.0.4",
16
16
  "uuid": "^8.3.2"
@@ -28,7 +28,7 @@
28
28
  "ethers": "^5.6.8",
29
29
  "license-checker": "^25.0.1",
30
30
  "tslib": "^2.4.0",
31
- "typescript": "^4.7.2"
31
+ "typescript": "^4.7.3"
32
32
  },
33
33
  "browser": "dist/esm/index.js",
34
34
  "docs": "dist/docs.json",
@@ -67,6 +67,6 @@
67
67
  },
68
68
  "sideEffects": true,
69
69
  "types": "dist/esm/index.d.ts",
70
- "version": "2.20.42",
70
+ "version": "2.20.45",
71
71
  "packageManager": "yarn@3.1.1"
72
72
  }
@@ -1,4 +1,4 @@
1
- import { XyoAccount, XyoBoundWitness, XyoBoundWitnessBuilder, XyoPayload, XyoPayloadBuilder } from '@xyo-network/core'
1
+ import { XyoAccount, XyoBoundWitness, XyoBoundWitnessBuilder } from '@xyo-network/core'
2
2
  import { config } from 'dotenv'
3
3
 
4
4
  import { XyoApiConfig, XyoApiError } from '../models'
@@ -56,31 +56,6 @@ describe('postBoundWitnesses', () => {
56
56
  })
57
57
  })
58
58
 
59
- describe('node', () => {
60
- describe('with archive', () => {
61
- it('calculates the correct path', () => {
62
- const api = new XyoArchivistApi(configData)
63
- const path = api.node().config.root
64
- expect(path).toBe('/')
65
- })
66
- })
67
- describe('without archive', () => {
68
- it('calculates the correct path', () => {
69
- const archive = 'foo'
70
- const api = new XyoArchivistApi(configData)
71
- const path = api.node(archive).config.root
72
- expect(path).toBe(`/${archive}/`)
73
- })
74
- it('posts to the root', () => {
75
- const api = new XyoArchivistApi(configData)
76
- const p: XyoPayload<{ foo: string }> = new XyoPayloadBuilder<XyoPayload<{ foo: string }>>({ schema: 'foo' }).fields({ foo: 'bar' }).build()
77
- const bw: XyoBoundWitness = new XyoBoundWitnessBuilder({ inlinePayloads: true }).payload(p).build()
78
- const path = api.node('foo').post(bw)
79
- expect(path).toBe('/foo/')
80
- })
81
- })
82
- })
83
-
84
59
  describeSkipIfNoToken('XyoArchivistApi', () => {
85
60
  describe('get', () => {
86
61
  it('returns a new XyoArchivistApi', () => {
@@ -7,6 +7,7 @@ import { XyoUserApi } from '../User'
7
7
  import { XyoAccountApi } from './Account'
8
8
  import { XyoArchivistArchiveApi } from './Archive'
9
9
  import { XyoArchivistArchivesApi } from './Archives'
10
+ import { XyoArchivistNodeApi } from './Node'
10
11
 
11
12
  export class XyoArchivistApi extends XyoApiBase {
12
13
  private _archives?: XyoArchivistArchivesApi
@@ -75,10 +76,10 @@ export class XyoArchivistApi extends XyoApiBase {
75
76
  * @param archive Optional, the archive to issue the requests against
76
77
  * @returns Confirmation for the request, as a BoundWitness, from the network Node
77
78
  */
78
- public node<TResponse extends XyoBoundWitness, TData extends XyoBoundWitness = TResponse>(archive?: string) {
79
- return new XyoApiSimple<TResponse, TData>({
79
+ public node<TData extends XyoBoundWitness | XyoBoundWitness[] = XyoBoundWitness | XyoBoundWitness[]>(archive = 'temp') {
80
+ return new XyoArchivistNodeApi<TData>({
80
81
  ...this.config,
81
- root: archive ? `${this.root}${archive}/` : this.root,
82
+ root: `${this.root}${archive}/`,
82
83
  })
83
84
  }
84
85
 
@@ -0,0 +1,141 @@
1
+ import { assertEx, delay } from '@xylabs/sdk-js'
2
+ import { XyoBoundWitness, XyoBoundWitnessBuilder, XyoPayload, XyoPayloadBuilder } from '@xyo-network/core'
3
+ import { v4 } from 'uuid'
4
+
5
+ import { XyoApiConfig, XyoApiEnvelope } from '../../models'
6
+ import { XyoArchivistApi } from '../Api'
7
+
8
+ const config: XyoApiConfig = {
9
+ apiDomain: process.env.API_DOMAIN || 'http://localhost:8080',
10
+ }
11
+
12
+ const schema = 'network.xyo.debug'
13
+
14
+ const getQuery = (count = 1): XyoBoundWitness => {
15
+ const payloads = [] as XyoPayload[]
16
+ for (let i = 0; i < count; i++) {
17
+ payloads.push(new XyoPayloadBuilder({ schema }).fields({ nonce: v4() }).build())
18
+ }
19
+ return new XyoBoundWitnessBuilder({ inlinePayloads: true }).payloads(payloads).build()
20
+ }
21
+
22
+ const issueQuery = async (query: XyoBoundWitness = getQuery()): Promise<string> => {
23
+ const api = new XyoArchivistApi(config)
24
+ const response = await api.node('temp').post(query)
25
+ const id = response?.[0]?.[0]
26
+ expect(id).toBeDefined()
27
+ return assertEx(id)
28
+ }
29
+
30
+ const validateAllResponseSchemas = (response: XyoApiEnvelope<XyoPayload | undefined>[][]): boolean => {
31
+ return response
32
+ .flatMap((r) => r)
33
+ .map((r) => (r as unknown as XyoPayload)?.schema)
34
+ .every((s) => s === schema)
35
+ }
36
+
37
+ describe('XyoArchivistNodeApi', () => {
38
+ describe('node', () => {
39
+ describe('without archive supplied', () => {
40
+ it('calculates the correct path', () => {
41
+ const api = new XyoArchivistApi(config)
42
+ const path = api.node().config.root
43
+ expect(path).toBe('/temp/')
44
+ })
45
+ })
46
+ describe('with archive supplied', () => {
47
+ const archive = 'foo'
48
+ it('calculates the correct path', () => {
49
+ const api = new XyoArchivistApi(config)
50
+ const path = api.node(archive).config.root
51
+ expect(path).toBe(`/${archive}/`)
52
+ })
53
+ })
54
+ })
55
+ describe('queryResult', () => {
56
+ let id = '123456789'
57
+ describe('with valid query id', () => {
58
+ beforeEach(async () => {
59
+ id = await issueQuery()
60
+ })
61
+ it('returns the query result', async () => {
62
+ const api = new XyoArchivistApi(config)
63
+ await delay(1000)
64
+ const [_, payload, response] = await api.node().result(id).get('tuple')
65
+ expect(_).toBeUndefined()
66
+ expect(payload).toBeDefined()
67
+ expect((payload as unknown as XyoPayload).schema).toBe(schema)
68
+ expect(response.status).toBe(200)
69
+ })
70
+ })
71
+ describe('without archive supplied', () => {
72
+ it('calculates the correct path', () => {
73
+ const api = new XyoArchivistApi(config)
74
+ const path = api.node().result(id).config.root
75
+ expect(path).toBe(`/query/${id}/`)
76
+ })
77
+ })
78
+ describe('with archive supplied', () => {
79
+ const archive = 'foo'
80
+ it('calculates the correct path', () => {
81
+ const api = new XyoArchivistApi(config)
82
+ const path = api.node(archive).result(id).config.root
83
+ expect(path).toBe(`/query/${id}/`)
84
+ })
85
+ })
86
+ })
87
+ describe('perform', () => {
88
+ it('creates and issues the query and returns the result', async () => {
89
+ const api = new XyoArchivistApi(config)
90
+ const response = await api.node().perform({ nonce: v4() }, schema)
91
+ expect(response).toBeDefined()
92
+ expect((response as unknown as XyoPayload).schema).toBe(schema)
93
+ })
94
+ })
95
+ describe('performTransaction', () => {
96
+ describe('with a single BoundWitness', () => {
97
+ describe('with a single Payload', () => {
98
+ it('issues the query and returns the result', async () => {
99
+ const api = new XyoArchivistApi(config)
100
+ const query = [getQuery()]
101
+ const response = await api.node().performTransaction(query)
102
+ expect(response).toBeDefined()
103
+ expect(Array.isArray(response)).toBeTruthy()
104
+ expect(validateAllResponseSchemas(response)).toBeTruthy()
105
+ })
106
+ })
107
+ describe('with a multiple Payloads', () => {
108
+ it('issues the query and returns the result', async () => {
109
+ const api = new XyoArchivistApi(config)
110
+ const query = [getQuery(2)]
111
+ const response = await api.node().performTransaction(query)
112
+ expect(response).toBeDefined()
113
+ expect(Array.isArray(response)).toBeTruthy()
114
+ expect(validateAllResponseSchemas(response)).toBeTruthy()
115
+ })
116
+ })
117
+ })
118
+ describe('with a multiple BoundWitnesses', () => {
119
+ describe('with a single Payload', () => {
120
+ it('issues the query and returns the result', async () => {
121
+ const api = new XyoArchivistApi(config)
122
+ const query = [getQuery(), getQuery()]
123
+ const response = await api.node().performTransaction(query)
124
+ expect(response).toBeDefined()
125
+ expect(Array.isArray(response)).toBeTruthy()
126
+ expect(validateAllResponseSchemas(response)).toBeTruthy()
127
+ })
128
+ })
129
+ describe('with a multiple Payloads', () => {
130
+ it('issues the query and returns the result', async () => {
131
+ const api = new XyoArchivistApi(config)
132
+ const query = [getQuery(2), getQuery(2)]
133
+ const response = await api.node().performTransaction(query)
134
+ expect(response).toBeDefined()
135
+ expect(Array.isArray(response)).toBeTruthy()
136
+ expect(validateAllResponseSchemas(response)).toBeTruthy()
137
+ })
138
+ })
139
+ })
140
+ })
141
+ })
@@ -0,0 +1,75 @@
1
+ import { assertEx, delay } from '@xylabs/sdk-js'
2
+ import { XyoBoundWitness, XyoBoundWitnessBuilder, XyoPayload, XyoPayloadBuilder } from '@xyo-network/core'
3
+
4
+ import { XyoApiConfig, XyoApiResponseTuple } from '../../models'
5
+ import { XyoApiSimple, XyoApiSimpleQuery } from '../../Simple'
6
+ import { WithArchive } from '../../WithArchive'
7
+
8
+ const getRequestStatuses = (results: XyoApiResponseTuple<XyoPayload>[][]): number[] => {
9
+ return results.flatMap((r) => r).map((r) => r?.[2]?.status)
10
+ }
11
+
12
+ const allRequestsSucceeded = (results: XyoApiResponseTuple<XyoPayload>[][]): boolean => {
13
+ return getRequestStatuses(results).every((status) => status === 200)
14
+ }
15
+
16
+ const anyRequestsFailed = (results: XyoApiResponseTuple<XyoPayload>[][]): boolean => {
17
+ return getRequestStatuses(results).every((status) => status > 399)
18
+ }
19
+
20
+ export class XyoArchivistNodeApi<
21
+ D extends XyoBoundWitness | XyoBoundWitness[] = XyoBoundWitness | XyoBoundWitness[],
22
+ C extends WithArchive<XyoApiConfig> = WithArchive<XyoApiConfig>
23
+ > extends XyoApiSimple<string[][], D, XyoApiSimpleQuery, C> {
24
+ /**
25
+ * Get the result of a previously issued query (if available)
26
+ * @param queryId Query ID from a previously issued query
27
+ * @returns The result of the query (if available)
28
+ */
29
+ public result<T extends XyoPayload = XyoPayload>(queryId: string): XyoApiSimple<XyoPayload> {
30
+ return new XyoApiSimple<T>({
31
+ ...this.config,
32
+ root: `/query/${queryId}/`,
33
+ })
34
+ }
35
+
36
+ /**
37
+ * Issue the supplied queries and wait (non-blocking) for the results
38
+ * @param data The queries to issue
39
+ * @param timeout The max time to wait for the query results
40
+ * @param retryInterval The interval to poll for query results
41
+ * @returns The results for the issued queries
42
+ */
43
+ public async performTransaction(data: D, timeout = 5000, retryInterval = 100) {
44
+ assertEx(timeout > 0, 'timeout must be positive')
45
+ assertEx(retryInterval > 0, 'retryInterval must be positive')
46
+ assertEx(timeout > retryInterval, 'timeout must be greater than retryInterval')
47
+ const ids = await this.post(data)
48
+ if (!ids?.length) return []
49
+ const loops = Math.floor(timeout / retryInterval)
50
+ let results = [] as XyoApiResponseTuple<XyoPayload>[][]
51
+ for (let i = 0; i < loops; i++) {
52
+ await delay(retryInterval)
53
+ results = await Promise.all(ids?.map(async (bw) => await Promise.all(bw.map((p) => this.result(p).get('tuple')))))
54
+ if (allRequestsSucceeded(results)) break
55
+ // TODO: More nuanced error handling of partial success/failure
56
+ if (anyRequestsFailed(results)) throw new Error('Request Error')
57
+ }
58
+ // Unpack results
59
+ return results.map((b) => b.map((p) => p[1]))
60
+ }
61
+
62
+ /**
63
+ * Issue the supplied query and wait (non-blocking) for the result
64
+ * @param data The query to issue
65
+ * @param timeout The max time to wait for the query results
66
+ * @param retryInterval The interval to poll for query results
67
+ * @returns The result for the issued query
68
+ */
69
+ public async perform<T>(data: T, schema: string, timeout = 5000, retryInterval = 100) {
70
+ const payload = new XyoPayloadBuilder({ schema }).fields(data).build()
71
+ const query = new XyoBoundWitnessBuilder({ inlinePayloads: true }).payload(payload).build() as D
72
+ const result = await this.performTransaction(query, timeout, retryInterval)
73
+ return result?.[0]?.[0]
74
+ }
75
+ }
@@ -0,0 +1 @@
1
+ export * from './Api'