@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.
- package/dist/cjs/Archivist/Api.d.ts +2 -1
- package/dist/cjs/Archivist/Api.js +3 -2
- package/dist/cjs/Archivist/Api.js.map +1 -1
- package/dist/cjs/Archivist/Node/Api.d.ts +28 -0
- package/dist/cjs/Archivist/Node/Api.js +74 -0
- package/dist/cjs/Archivist/Node/Api.js.map +1 -0
- package/dist/cjs/Archivist/Node/index.d.ts +1 -0
- package/dist/cjs/Archivist/Node/index.js +5 -0
- package/dist/cjs/Archivist/Node/index.js.map +1 -0
- package/dist/docs.json +4130 -4134
- package/dist/esm/Archivist/Api.d.ts +2 -1
- package/dist/esm/Archivist/Api.js +4 -3
- package/dist/esm/Archivist/Api.js.map +1 -1
- package/dist/esm/Archivist/Node/Api.d.ts +28 -0
- package/dist/esm/Archivist/Node/Api.js +67 -0
- package/dist/esm/Archivist/Node/Api.js.map +1 -0
- package/dist/esm/Archivist/Node/index.d.ts +1 -0
- package/dist/esm/Archivist/Node/index.js +2 -0
- package/dist/esm/Archivist/Node/index.js.map +1 -0
- package/package.json +3 -3
- package/src/Archivist/Api.spec.ts +1 -26
- package/src/Archivist/Api.ts +4 -3
- package/src/Archivist/Node/Api.spec.ts +141 -0
- package/src/Archivist/Node/Api.ts +75 -0
- package/src/Archivist/Node/index.ts +1 -0
|
@@ -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<
|
|
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
|
|
66
|
+
node(archive = 'temp') {
|
|
67
|
+
return new XyoArchivistNodeApi({
|
|
67
68
|
...this.config,
|
|
68
|
-
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":"AAAA,OAAO,EAAE,IAAI,EAAE,eAAe,EAA4C,MAAM,mBAAmB,CAAA;AAEnG,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEpC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAA;AAClD,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"Api.js","sourceRoot":"","sources":["../../../src/Archivist/Api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,eAAe,EAA4C,MAAM,mBAAmB,CAAA;AAEnG,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEpC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAA;AAClD,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAA;AAE5C,MAAM,OAAO,eAAgB,SAAQ,UAAU;IAE7C,IAAW,QAAQ;QACjB,IAAI,CAAC,SAAS;YACZ,IAAI,CAAC,SAAS;gBACd,IAAI,uBAAuB,CAAC;oBAC1B,GAAG,IAAI,CAAC,MAAM;oBACd,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,UAAU;iBAC7B,CAAC,CAAA;QACJ,OAAO,IAAI,CAAC,SAAS,CAAA;IACvB,CAAC;IAGD,IAAW,KAAK;QACd,IAAI,CAAC,MAAM;YACT,IAAI,CAAC,MAAM;gBACX,IAAI,YAAY,CAAY;oBAC1B,GAAG,IAAI,CAAC,MAAM;oBACd,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,QAAQ;iBAC3B,CAAC,CAAA;QACJ,OAAO,IAAI,CAAC,MAAM,CAAA;IACpB,CAAC;IAGD,IAAW,IAAI;QACb,IAAI,CAAC,KAAK;YACR,IAAI,CAAC,KAAK;gBACV,IAAI,UAAU,CAAC;oBACb,GAAG,IAAI,CAAC,MAAM;oBACd,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,OAAO;iBAC1B,CAAC,CAAA;QACJ,OAAO,IAAI,CAAC,KAAK,CAAA;IACnB,CAAC;IAEM,OAAO,CAAC,OAAO,GAAG,MAAM;QAC7B,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,EAAE,CAAA;QACzC,OAAO,IAAI,sBAAsB,CAAC;YAChC,GAAG,IAAI,CAAC,MAAM;YACd,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,WAAW,WAAW,GAAG;SAC5C,CAAC,CAAA;IACJ,CAAC;IAED,sCAAsC;IAC/B,MAAM,CAAC,OAAoB;QAChC,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAC9B,CAAC;IAEM,OAAO,CAAC,OAAoB;QACjC,OAAO,IAAI,aAAa,CAAC;YACvB,GAAG,IAAI,CAAC,MAAM;YACd,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,UAAU,IAAI,eAAe,CAAC,OAAO,CAAC,CAAC,GAAG,GAAG;SAChE,CAAC,CAAA;IACJ,CAAC;IAEM,IAAI,CAAC,IAAmB;QAC7B,MAAM,OAAO,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QAChE,OAAO,IAAI,YAAY,CAAa;YAClC,GAAG,IAAI,CAAC,MAAM;YACd,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,GAAG;SACrC,CAAC,CAAA;IACJ,CAAC;IAED;;;;OAIG;IACI,IAAI,CAA0F,OAAO,GAAG,MAAM;QACnH,OAAO,IAAI,mBAAmB,CAAQ;YACpC,GAAG,IAAI,CAAC,MAAM;YACd,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,GAAG,OAAO,GAAG;SAChC,CAAC,CAAA;IACJ,CAAC;IAQD,yCAAyC;IAClC,KAAK,CAAC,GAAG,CAAC,IAAmB,EAAE,YAAiC;QACrE,MAAM,OAAO,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QAChE,QAAQ,YAAY,EAAE;YACpB,KAAK,OAAO;gBACV,OAAO,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;YACtD;gBACE,OAAO,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;SACtD;IACH,CAAC;CACF"}
|
|
@@ -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 @@
|
|
|
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.
|
|
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.
|
|
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.
|
|
70
|
+
"version": "2.20.45",
|
|
71
71
|
"packageManager": "yarn@3.1.1"
|
|
72
72
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { XyoAccount, XyoBoundWitness, XyoBoundWitnessBuilder
|
|
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', () => {
|
package/src/Archivist/Api.ts
CHANGED
|
@@ -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<
|
|
79
|
-
return new
|
|
79
|
+
public node<TData extends XyoBoundWitness | XyoBoundWitness[] = XyoBoundWitness | XyoBoundWitness[]>(archive = 'temp') {
|
|
80
|
+
return new XyoArchivistNodeApi<TData>({
|
|
80
81
|
...this.config,
|
|
81
|
-
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'
|