@vertexvis/api-client-node 0.20.9 → 0.21.0
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/api.d.ts +43 -1
- package/dist/cjs/api.js +176 -88
- package/dist/cjs/client/helpers/scene-items.d.ts +21 -0
- package/dist/cjs/client/helpers/scene-items.js +40 -1
- package/dist/cjs/client/helpers/scenes.d.ts +21 -38
- package/dist/cjs/client/helpers/scenes.js +231 -192
- package/dist/cjs/client/utils.d.ts +8 -1
- package/dist/cjs/client/utils.js +21 -2
- package/dist/cjs/client/version.d.ts +1 -1
- package/dist/cjs/client/version.js +1 -1
- package/dist/esm/api.d.ts +43 -1
- package/dist/esm/api.js +176 -88
- package/dist/esm/client/helpers/scene-items.d.ts +21 -0
- package/dist/esm/client/helpers/scene-items.js +38 -1
- package/dist/esm/client/helpers/scenes.d.ts +21 -38
- package/dist/esm/client/helpers/scenes.js +229 -188
- package/dist/esm/client/utils.d.ts +8 -1
- package/dist/esm/client/utils.js +18 -1
- package/dist/esm/client/version.d.ts +1 -1
- package/dist/esm/client/version.js +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
import { CreateSceneItemRequest, SceneItem } from '../../index';
|
|
2
2
|
import { BaseReq, Polling } from '../index';
|
|
3
|
+
export declare enum SceneItemErrorStatus {
|
|
4
|
+
NotFound = "404",
|
|
5
|
+
ServerError = "500"
|
|
6
|
+
}
|
|
7
|
+
export declare enum SceneItemErrorCode {
|
|
8
|
+
NotFound = "NotFound",
|
|
9
|
+
ServerError = "ServerError"
|
|
10
|
+
}
|
|
11
|
+
export declare enum SceneItemErrorSourcePointer {
|
|
12
|
+
Parent = "/body/data/attributes/parent",
|
|
13
|
+
SourcePart = "/body/data/relationships/source/data"
|
|
14
|
+
}
|
|
15
|
+
export declare enum SceneItemSystemMetadata {
|
|
16
|
+
IsMissingGeometry = "VERTEX_IS_MISSING_GEOMETRY",
|
|
17
|
+
MissingGeometrySetId = "VERTEX_MISSING_GEOMETRY_SET_ID",
|
|
18
|
+
MissingPartRevisionId = "VERTEX_MISSING_PART_REVISION_ID",
|
|
19
|
+
MissingSuppliedPartId = "VERTEX_MISSING_SUPPLIED_PART_ID",
|
|
20
|
+
MissingSuppliedPartRevisionId = "VERTEX_MISSING_SUPPLIED_PART_REVISION_ID"
|
|
21
|
+
}
|
|
3
22
|
/**
|
|
4
23
|
* Create scene item arguments.
|
|
5
24
|
*/
|
|
@@ -17,3 +36,5 @@ export interface CreateSceneItemReq extends BaseReq {
|
|
|
17
36
|
* @param args - The {@link CreateSceneItemReq}.
|
|
18
37
|
*/
|
|
19
38
|
export declare function createSceneItem({ client, createSceneItemReq, onMsg, polling, sceneId, verbose, }: CreateSceneItemReq): Promise<SceneItem>;
|
|
39
|
+
export declare function isPartNotFoundError(e: unknown): boolean;
|
|
40
|
+
export declare function isParentNotFoundError(e: unknown): boolean;
|
|
@@ -9,8 +9,31 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.createSceneItem = void 0;
|
|
12
|
+
exports.isParentNotFoundError = exports.isPartNotFoundError = exports.createSceneItem = exports.SceneItemSystemMetadata = exports.SceneItemErrorSourcePointer = exports.SceneItemErrorCode = exports.SceneItemErrorStatus = void 0;
|
|
13
13
|
const index_1 = require("../index");
|
|
14
|
+
var SceneItemErrorStatus;
|
|
15
|
+
(function (SceneItemErrorStatus) {
|
|
16
|
+
SceneItemErrorStatus["NotFound"] = "404";
|
|
17
|
+
SceneItemErrorStatus["ServerError"] = "500";
|
|
18
|
+
})(SceneItemErrorStatus = exports.SceneItemErrorStatus || (exports.SceneItemErrorStatus = {}));
|
|
19
|
+
var SceneItemErrorCode;
|
|
20
|
+
(function (SceneItemErrorCode) {
|
|
21
|
+
SceneItemErrorCode["NotFound"] = "NotFound";
|
|
22
|
+
SceneItemErrorCode["ServerError"] = "ServerError";
|
|
23
|
+
})(SceneItemErrorCode = exports.SceneItemErrorCode || (exports.SceneItemErrorCode = {}));
|
|
24
|
+
var SceneItemErrorSourcePointer;
|
|
25
|
+
(function (SceneItemErrorSourcePointer) {
|
|
26
|
+
SceneItemErrorSourcePointer["Parent"] = "/body/data/attributes/parent";
|
|
27
|
+
SceneItemErrorSourcePointer["SourcePart"] = "/body/data/relationships/source/data";
|
|
28
|
+
})(SceneItemErrorSourcePointer = exports.SceneItemErrorSourcePointer || (exports.SceneItemErrorSourcePointer = {}));
|
|
29
|
+
var SceneItemSystemMetadata;
|
|
30
|
+
(function (SceneItemSystemMetadata) {
|
|
31
|
+
SceneItemSystemMetadata["IsMissingGeometry"] = "VERTEX_IS_MISSING_GEOMETRY";
|
|
32
|
+
SceneItemSystemMetadata["MissingGeometrySetId"] = "VERTEX_MISSING_GEOMETRY_SET_ID";
|
|
33
|
+
SceneItemSystemMetadata["MissingPartRevisionId"] = "VERTEX_MISSING_PART_REVISION_ID";
|
|
34
|
+
SceneItemSystemMetadata["MissingSuppliedPartId"] = "VERTEX_MISSING_SUPPLIED_PART_ID";
|
|
35
|
+
SceneItemSystemMetadata["MissingSuppliedPartRevisionId"] = "VERTEX_MISSING_SUPPLIED_PART_REVISION_ID";
|
|
36
|
+
})(SceneItemSystemMetadata = exports.SceneItemSystemMetadata || (exports.SceneItemSystemMetadata = {}));
|
|
14
37
|
/**
|
|
15
38
|
* Create a scene item.
|
|
16
39
|
*
|
|
@@ -38,3 +61,19 @@ function createSceneItem({ client, createSceneItemReq, onMsg = console.log, poll
|
|
|
38
61
|
});
|
|
39
62
|
}
|
|
40
63
|
exports.createSceneItem = createSceneItem;
|
|
64
|
+
function isPartNotFoundError(e) {
|
|
65
|
+
return ((0, index_1.defined)(e) &&
|
|
66
|
+
(0, index_1.isApiError)(e) &&
|
|
67
|
+
e.code === SceneItemErrorCode.NotFound &&
|
|
68
|
+
e.source !== undefined &&
|
|
69
|
+
e.source.pointer === SceneItemErrorSourcePointer.SourcePart);
|
|
70
|
+
}
|
|
71
|
+
exports.isPartNotFoundError = isPartNotFoundError;
|
|
72
|
+
function isParentNotFoundError(e) {
|
|
73
|
+
return ((0, index_1.defined)(e) &&
|
|
74
|
+
(0, index_1.isApiError)(e) &&
|
|
75
|
+
e.code === SceneItemErrorCode.NotFound &&
|
|
76
|
+
e.source !== undefined &&
|
|
77
|
+
e.source.pointer === SceneItemErrorSourcePointer.Parent);
|
|
78
|
+
}
|
|
79
|
+
exports.isParentNotFoundError = isParentNotFoundError;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { AxiosResponse } from 'axios';
|
|
2
|
+
import { Limit } from 'p-limit';
|
|
3
|
+
import { RelationshipData } from '../../index';
|
|
2
4
|
import { ApiError, BatchOperation, CreateSceneItemRequest, CreateSceneItemRequestData, CreateSceneRequest, Failure, QueuedJob, Scene, SceneData, UpdateSceneRequestDataAttributes } from '../../index';
|
|
3
5
|
import { BaseReq, DeleteReq, Polling, RenderImageReq, VertexClient } from '../index';
|
|
4
6
|
export interface CreateSceneAndSceneItemsReq extends BaseReq {
|
|
@@ -17,35 +19,23 @@ export interface CreateSceneAndSceneItemsReq extends BaseReq {
|
|
|
17
19
|
/** Whether or not to return queued scene items. */
|
|
18
20
|
readonly returnQueued?: boolean;
|
|
19
21
|
}
|
|
20
|
-
export interface CreateSceneAndSceneItemsReqEXPERIMENTAL extends BaseReq {
|
|
21
|
-
/** A list of {@link CreateSceneItemRequest}. */
|
|
22
|
-
readonly createSceneItemReqs: Array<Array<CreateSceneItemRequest>>;
|
|
23
|
-
/** Function returning a {@link CreateSceneRequest}. */
|
|
24
|
-
readonly createSceneReq: () => CreateSceneRequest;
|
|
25
|
-
/** Whether or not to fail if any scene item fails initial validation. */
|
|
26
|
-
readonly failFast?: boolean;
|
|
27
|
-
/** How many requests to run in parallel. */
|
|
28
|
-
readonly parallelism: number;
|
|
29
|
-
/** {@link Polling} */
|
|
30
|
-
readonly polling?: Polling;
|
|
31
|
-
/** Callback with total number of requests and number complete. */
|
|
32
|
-
onProgress?: (complete: number, total: number) => void;
|
|
33
|
-
/** Whether or not to return queued scene items. */
|
|
34
|
-
readonly returnQueued?: boolean;
|
|
35
|
-
}
|
|
36
22
|
export interface CreateSceneAndSceneItemsRes {
|
|
37
|
-
readonly errors: QueuedSceneItem[];
|
|
38
|
-
readonly scene: Scene;
|
|
39
|
-
/** Only populated if `returnQueued` is true in request. */
|
|
40
|
-
readonly queued: QueuedSceneItem[];
|
|
41
|
-
}
|
|
42
|
-
export interface CreateSceneAndSceneItemsResEXPERIMENTAL {
|
|
43
23
|
readonly errors: QueuedBatchOps[];
|
|
44
|
-
readonly scene
|
|
24
|
+
readonly scene?: Scene;
|
|
45
25
|
readonly sceneItemErrors: SceneItemError[];
|
|
46
26
|
/** Only populated if `returnQueued` is true in request. */
|
|
47
27
|
readonly queued: QueuedBatchOps[];
|
|
48
28
|
}
|
|
29
|
+
export interface CreateSceneItemBatchReq extends CreateSceneItemsReq {
|
|
30
|
+
/** {@link Polling} */
|
|
31
|
+
readonly polling?: Polling;
|
|
32
|
+
}
|
|
33
|
+
export interface CreateSceneItemBatchRes {
|
|
34
|
+
batchOps: QueuedBatchOps[];
|
|
35
|
+
batchErrors: QueuedBatchOps[];
|
|
36
|
+
itemErrors: SceneItemError[];
|
|
37
|
+
itemResults: SceneItemResult[];
|
|
38
|
+
}
|
|
49
39
|
export interface CreateSceneItemsReq extends Base {
|
|
50
40
|
/** A list of {@link CreateSceneItemRequest}. */
|
|
51
41
|
readonly createSceneItemReqs: CreateSceneItemRequest[];
|
|
@@ -53,14 +43,10 @@ export interface CreateSceneItemsReq extends Base {
|
|
|
53
43
|
readonly failFast: boolean;
|
|
54
44
|
/** Callback with total number of requests and number complete. */
|
|
55
45
|
readonly onProgress?: (complete: number, total: number) => void;
|
|
56
|
-
/**
|
|
57
|
-
readonly
|
|
46
|
+
/** Limit for requests to run in parallel. */
|
|
47
|
+
readonly limit: Limit;
|
|
58
48
|
}
|
|
59
49
|
export interface CreateSceneItemsRes {
|
|
60
|
-
readonly leaves: number;
|
|
61
|
-
readonly queuedSceneItems: QueuedSceneItem[];
|
|
62
|
-
}
|
|
63
|
-
export interface CreateSceneItemsResEXPERIMENTAL {
|
|
64
50
|
readonly chunks: number;
|
|
65
51
|
readonly queuedBatchOps: QueuedBatchOps[];
|
|
66
52
|
}
|
|
@@ -71,6 +57,11 @@ export interface QueuedBatchOps {
|
|
|
71
57
|
export interface SceneItemError {
|
|
72
58
|
readonly req: CreateSceneItemRequestData;
|
|
73
59
|
readonly res?: ApiError;
|
|
60
|
+
placeholderItem?: RelationshipData;
|
|
61
|
+
}
|
|
62
|
+
export interface SceneItemResult {
|
|
63
|
+
readonly req: CreateSceneItemRequestData;
|
|
64
|
+
readonly res: RelationshipData | ApiError;
|
|
74
65
|
}
|
|
75
66
|
/**
|
|
76
67
|
* Poll scene ready arguments.
|
|
@@ -104,15 +95,7 @@ export declare function createSceneAndSceneItems({ client, createSceneItemReqs,
|
|
|
104
95
|
/**
|
|
105
96
|
* Create scene items within a scene.
|
|
106
97
|
*/
|
|
107
|
-
export declare function createSceneItems({ client, createSceneItemReqs, failFast,
|
|
108
|
-
/**
|
|
109
|
-
* Create a scene with scene items using experimental strategy.
|
|
110
|
-
*/
|
|
111
|
-
export declare function createSceneAndSceneItemsEXPERIMENTAL({ client, createSceneItemReqs, createSceneReq, failFast, onMsg, onProgress, parallelism, polling, returnQueued, verbose, }: CreateSceneAndSceneItemsReqEXPERIMENTAL): Promise<CreateSceneAndSceneItemsResEXPERIMENTAL>;
|
|
112
|
-
/**
|
|
113
|
-
* Create scene items within a scene.
|
|
114
|
-
*/
|
|
115
|
-
export declare function createSceneItemsEXPERIMENTAL({ client, createSceneItemReqs, failFast, parallelism, sceneId, }: CreateSceneItemsReq): Promise<CreateSceneItemsResEXPERIMENTAL>;
|
|
98
|
+
export declare function createSceneItems({ client, createSceneItemReqs, failFast, limit, sceneId, }: CreateSceneItemsReq): Promise<CreateSceneItemsRes>;
|
|
116
99
|
/**
|
|
117
100
|
* Delete all scenes.
|
|
118
101
|
*
|
|
@@ -12,246 +12,285 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.updateScene = exports.renderScene = exports.pollSceneReady = exports.deleteAllScenes = exports.
|
|
15
|
+
exports.updateScene = exports.renderScene = exports.pollSceneReady = exports.deleteAllScenes = exports.createSceneItems = exports.createSceneAndSceneItems = void 0;
|
|
16
16
|
const p_limit_1 = __importDefault(require("p-limit"));
|
|
17
17
|
const process_1 = require("process");
|
|
18
18
|
const index_1 = require("../../index");
|
|
19
19
|
const index_2 = require("../index");
|
|
20
20
|
const utils_1 = require("../utils");
|
|
21
21
|
const queued_jobs_1 = require("./queued-jobs");
|
|
22
|
-
const
|
|
22
|
+
const defaultPolling = { intervalMs: 200, maxAttempts: 4500 }; // 15 minute timeout for batch completions
|
|
23
|
+
const sceneReadyPolling = { intervalMs: 1000, maxAttempts: 3600 }; // one hour timeout for scene state ready
|
|
23
24
|
/**
|
|
24
25
|
* Create a scene with scene items.
|
|
25
26
|
*/
|
|
26
|
-
function createSceneAndSceneItems({ client, createSceneItemReqs, createSceneReq, failFast = false, onMsg = console.log, onProgress, parallelism, polling =
|
|
27
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
28
|
-
const scene = (yield client.scenes.createScene({ createSceneRequest: createSceneReq() })).data;
|
|
29
|
-
const sceneId = scene.data.id;
|
|
30
|
-
const createRes = yield createSceneItems({
|
|
31
|
-
client,
|
|
32
|
-
createSceneItemReqs,
|
|
33
|
-
failFast,
|
|
34
|
-
onProgress,
|
|
35
|
-
parallelism,
|
|
36
|
-
sceneId,
|
|
37
|
-
});
|
|
38
|
-
const { a: queuedItems, b: errors } = (0, index_2.partition)(createRes.queuedSceneItems, (i) => (0, index_2.isQueuedJob)(i.res));
|
|
39
|
-
const queued = returnQueued ? createRes.queuedSceneItems : [];
|
|
40
|
-
if (queuedItems.length === 0 || errors.length === createRes.leaves) {
|
|
41
|
-
return { errors, queued, scene };
|
|
42
|
-
}
|
|
43
|
-
if (verbose)
|
|
44
|
-
onMsg(`Polling for completed scene-items...`);
|
|
45
|
-
const limit = (0, p_limit_1.default)(Math.min(parallelism, 20));
|
|
46
|
-
const cnt = queuedItems.length;
|
|
47
|
-
const step = Math.floor(cnt / ((PollPercentage / 100) * cnt));
|
|
48
|
-
const qis = [];
|
|
49
|
-
// Poll for percentage of items starting at end of `queuedItems` array
|
|
50
|
-
for (let i = 0; i < cnt; i += step)
|
|
51
|
-
qis.push(queuedItems[cnt - i - 1]);
|
|
52
|
-
function poll({ req, res }) {
|
|
53
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
54
|
-
const r = yield (0, queued_jobs_1.pollQueuedJob)({
|
|
55
|
-
id: res.data.id,
|
|
56
|
-
getQueuedJob: (id, cancelToken) => client.sceneItems.getQueuedSceneItem({ id }, { cancelToken }),
|
|
57
|
-
allow404: true,
|
|
58
|
-
limit,
|
|
59
|
-
polling,
|
|
60
|
-
});
|
|
61
|
-
if ((0, queued_jobs_1.isPollError)(r.res)) {
|
|
62
|
-
failFast ? (0, queued_jobs_1.throwOnError)(r) : errors.push({ req, res: r.res });
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
yield Promise.all(qis.map((is) => limit(poll, is)));
|
|
67
|
-
if (verbose)
|
|
68
|
-
onMsg(`Committing scene and polling until ready...`);
|
|
69
|
-
yield updateScene({
|
|
70
|
-
attributes: { state: index_1.UpdateSceneRequestDataAttributesStateEnum.Commit },
|
|
71
|
-
client,
|
|
72
|
-
sceneId,
|
|
73
|
-
});
|
|
74
|
-
yield pollSceneReady({ client, id: sceneId, onMsg, polling, verbose });
|
|
75
|
-
if (verbose)
|
|
76
|
-
onMsg(`Fitting scene's camera to scene-items...`);
|
|
77
|
-
const updated = (yield updateScene({
|
|
78
|
-
attributes: { camera: { type: index_1.CameraFitTypeEnum.FitVisibleSceneItems } },
|
|
79
|
-
client,
|
|
80
|
-
sceneId,
|
|
81
|
-
})).scene;
|
|
82
|
-
return { errors, queued, scene: updated };
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
exports.createSceneAndSceneItems = createSceneAndSceneItems;
|
|
86
|
-
/**
|
|
87
|
-
* Create scene items within a scene.
|
|
88
|
-
*/
|
|
89
|
-
function createSceneItems({ client, createSceneItemReqs, failFast, onProgress, parallelism, sceneId, }) {
|
|
90
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
91
|
-
const limit = (0, p_limit_1.default)(parallelism);
|
|
92
|
-
let complete = 0;
|
|
93
|
-
let leaves = 0;
|
|
94
|
-
const queuedSceneItems = yield Promise.all(createSceneItemReqs.map((r) => limit((req) => __awaiter(this, void 0, void 0, function* () {
|
|
95
|
-
var _a;
|
|
96
|
-
let res;
|
|
97
|
-
try {
|
|
98
|
-
if ((0, index_2.defined)(req.data.attributes.source) ||
|
|
99
|
-
(0, index_2.defined)(req.data.relationships.source)) {
|
|
100
|
-
leaves++;
|
|
101
|
-
}
|
|
102
|
-
res = (yield client.sceneItems.createSceneItem({
|
|
103
|
-
id: sceneId,
|
|
104
|
-
createSceneItemRequest: req,
|
|
105
|
-
})).data;
|
|
106
|
-
}
|
|
107
|
-
catch (error) {
|
|
108
|
-
if (!failFast && (0, index_2.hasVertexError)(error)) {
|
|
109
|
-
res = (_a = error.vertexError) === null || _a === void 0 ? void 0 : _a.res;
|
|
110
|
-
}
|
|
111
|
-
else
|
|
112
|
-
throw error;
|
|
113
|
-
}
|
|
114
|
-
if (onProgress != null) {
|
|
115
|
-
complete += 1;
|
|
116
|
-
onProgress(complete, createSceneItemReqs.length);
|
|
117
|
-
}
|
|
118
|
-
return { req, res };
|
|
119
|
-
}), r)));
|
|
120
|
-
return { leaves, queuedSceneItems };
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
exports.createSceneItems = createSceneItems;
|
|
124
|
-
/**
|
|
125
|
-
* Create a scene with scene items using experimental strategy.
|
|
126
|
-
*/
|
|
127
|
-
function createSceneAndSceneItemsEXPERIMENTAL({ client, createSceneItemReqs, createSceneReq, failFast = false, onMsg = console.log, onProgress, parallelism, polling = { intervalMs: index_2.PollIntervalMs, maxAttempts: index_2.MaxAttempts }, returnQueued = false, verbose, }) {
|
|
27
|
+
function createSceneAndSceneItems({ client, createSceneItemReqs, createSceneReq, failFast = false, onMsg = console.log, onProgress, parallelism, polling = defaultPolling, returnQueued = false, verbose, }) {
|
|
128
28
|
return __awaiter(this, void 0, void 0, function* () {
|
|
29
|
+
const limit = (0, p_limit_1.default)(Math.min(parallelism, 100));
|
|
129
30
|
const startTime = process_1.hrtime.bigint();
|
|
130
31
|
if (verbose)
|
|
131
32
|
onMsg(`Creating scene...`);
|
|
132
33
|
const scene = (yield client.scenes.createScene({ createSceneRequest: createSceneReq() })).data;
|
|
133
34
|
const sceneId = scene.data.id;
|
|
35
|
+
if (verbose)
|
|
36
|
+
onMsg(`Scene ID: ${sceneId}`);
|
|
134
37
|
if (verbose)
|
|
135
38
|
onMsg(`Creating scene items...`);
|
|
136
39
|
let itemCount = 0;
|
|
137
|
-
let
|
|
138
|
-
let
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
40
|
+
let createFailed = false;
|
|
41
|
+
let sceneResult;
|
|
42
|
+
const reqMap = new Map();
|
|
43
|
+
// create parent map and set ordinals based on request order
|
|
44
|
+
createSceneItemReqs.forEach((req) => {
|
|
45
|
+
var _a, _b, _c;
|
|
46
|
+
const reqParent = (_c = (_a = req.data.attributes.parent) !== null && _a !== void 0 ? _a : (_b = req.data.relationships.parent) === null || _b === void 0 ? void 0 : _b.data.id) !== null && _c !== void 0 ? _c : '';
|
|
47
|
+
if (!reqMap.has(reqParent)) {
|
|
48
|
+
reqMap.set(reqParent, []);
|
|
49
|
+
}
|
|
50
|
+
const siblings = reqMap.get(reqParent);
|
|
51
|
+
if (req.data.attributes.ordinal == null) {
|
|
52
|
+
req.data.attributes.ordinal = siblings === null || siblings === void 0 ? void 0 : siblings.length;
|
|
53
|
+
}
|
|
54
|
+
siblings === null || siblings === void 0 ? void 0 : siblings.push(req);
|
|
55
|
+
});
|
|
56
|
+
// sort all scene item requests into depth sorted array of arrays
|
|
57
|
+
const depthSortedItems = [];
|
|
58
|
+
// fetch list of scene items with no parent (root items)
|
|
59
|
+
let nextChildren = reqMap.get('') || [];
|
|
60
|
+
reqMap.delete('');
|
|
61
|
+
while (nextChildren.length > 0) {
|
|
62
|
+
depthSortedItems.push(nextChildren);
|
|
63
|
+
nextChildren = nextChildren.flatMap((req) => {
|
|
64
|
+
if (req.data.attributes.suppliedId &&
|
|
65
|
+
reqMap.has(req.data.attributes.suppliedId)) {
|
|
66
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
67
|
+
const children = reqMap.get(req.data.attributes.suppliedId);
|
|
68
|
+
reqMap.delete(req.data.attributes.suppliedId);
|
|
69
|
+
return children;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
return [];
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
let resultQueuedOps = [];
|
|
77
|
+
let resultBatchErrors = [];
|
|
78
|
+
let resultItemErrors = [];
|
|
79
|
+
// if we had any scene item requests with invalid parents,
|
|
80
|
+
// add error entries indicating so.
|
|
81
|
+
reqMap.forEach((children) => {
|
|
82
|
+
children.forEach((childItem) => {
|
|
83
|
+
resultItemErrors.push({
|
|
84
|
+
req: childItem.data,
|
|
85
|
+
res: {
|
|
86
|
+
status: '404',
|
|
87
|
+
code: 'NotFound',
|
|
88
|
+
title: 'The requested resource was not found.',
|
|
89
|
+
source: { pointer: '/body/data/attributes/parent' },
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
let depth = 0;
|
|
95
|
+
for (depth; depth < depthSortedItems.length; depth++) {
|
|
96
|
+
const createItemReqs = depthSortedItems[depth];
|
|
142
97
|
itemCount += createItemReqs.length;
|
|
143
98
|
if (verbose)
|
|
144
99
|
onMsg(`Creating ${createItemReqs.length} scene items at depth ${depth}...`);
|
|
145
100
|
// Await is used intentionally to defer loop iteration
|
|
146
101
|
// until all scene items have been created at each depth.
|
|
102
|
+
const { batchOps: queuedBatchOps, batchErrors: queuedBatchErrors, itemErrors: batchItemErrors, } =
|
|
147
103
|
// eslint-disable-next-line no-await-in-loop
|
|
148
|
-
|
|
104
|
+
yield createSceneItemBatch({
|
|
149
105
|
client,
|
|
150
106
|
createSceneItemReqs: createItemReqs,
|
|
151
107
|
failFast,
|
|
152
108
|
onProgress,
|
|
153
|
-
|
|
109
|
+
limit,
|
|
154
110
|
sceneId,
|
|
111
|
+
polling,
|
|
155
112
|
});
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
if (errors.length) {
|
|
159
|
-
batchErrors = batchErrors.concat(errors);
|
|
160
|
-
if (verbose)
|
|
161
|
-
onMsg(`WARNING: ${errors.length} scene item batch errors at depth ${depth}.`);
|
|
162
|
-
}
|
|
163
|
-
// Nothing succeeded, return early as something is likely wrong
|
|
164
|
-
if (queuedOps.length === 0 || errors.length === createRes.chunks) {
|
|
165
|
-
return {
|
|
166
|
-
errors,
|
|
167
|
-
queued: returnQueued ? createRes.queuedBatchOps : [],
|
|
168
|
-
scene,
|
|
169
|
-
sceneItemErrors: [],
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
const limit = (0, p_limit_1.default)(Math.min(parallelism, 20));
|
|
173
|
-
function poll({ ops, res, }) {
|
|
174
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
175
|
-
const r = yield (0, queued_jobs_1.pollQueuedJob)({
|
|
176
|
-
id: res.data.id,
|
|
177
|
-
getQueuedJob: (id, cancelToken) => client.batches.getQueuedBatch({ id }, { cancelToken }),
|
|
178
|
-
allow404: true,
|
|
179
|
-
limit,
|
|
180
|
-
polling,
|
|
181
|
-
});
|
|
182
|
-
if ((0, queued_jobs_1.isPollError)(r.res)) {
|
|
183
|
-
failFast ? (0, queued_jobs_1.throwOnError)(r) : errors.push({ ops, res: r.res });
|
|
184
|
-
}
|
|
185
|
-
return r;
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
// eslint-disable-next-line no-await-in-loop
|
|
189
|
-
const batchRes = yield Promise.all(queuedOps.map((is) => limit(poll, is)));
|
|
190
|
-
const batchItemErrors = batchRes
|
|
191
|
-
.flatMap((b, i) => (0, queued_jobs_1.isBatch)(b.res)
|
|
192
|
-
? b.res['vertexvis/batch:results'].map((r, j) => (0, utils_1.isApiError)(r)
|
|
193
|
-
? { req: queuedOps[i].ops[j].data, res: r }
|
|
194
|
-
: undefined)
|
|
195
|
-
: [])
|
|
196
|
-
.filter(index_2.defined);
|
|
113
|
+
resultQueuedOps = resultQueuedOps.concat(queuedBatchOps);
|
|
114
|
+
resultBatchErrors = resultBatchErrors.concat(queuedBatchErrors);
|
|
197
115
|
if (batchItemErrors.length) {
|
|
198
|
-
sceneItemErrors = sceneItemErrors.concat(batchItemErrors);
|
|
199
116
|
if (verbose)
|
|
200
117
|
onMsg(`WARNING: ${batchItemErrors.length} scene item creation errors at depth ${depth}.`);
|
|
118
|
+
resultItemErrors = resultItemErrors.concat(batchItemErrors);
|
|
119
|
+
if (failFast) {
|
|
120
|
+
createFailed = true;
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
// evaluate item errors and generate retry list
|
|
125
|
+
const retryErrors = batchItemErrors.filter((v) => (0, index_2.isPartNotFoundError)(v.res));
|
|
126
|
+
const retries = retryErrors.map((itemError) => {
|
|
127
|
+
var _a, _b, _c, _d, _e, _f;
|
|
128
|
+
const item = itemError.req;
|
|
129
|
+
return {
|
|
130
|
+
data: {
|
|
131
|
+
type: 'scene-item',
|
|
132
|
+
attributes: Object.assign(Object.assign({}, item.attributes), { metadata: Object.assign(Object.assign({}, item.attributes.metadata), { [index_2.SceneItemSystemMetadata.IsMissingGeometry]: toMetadataOrUndefined('1'), [index_2.SceneItemSystemMetadata.MissingGeometrySetId]: toMetadataOrUndefined((_a = item.relationships.source) === null || _a === void 0 ? void 0 : _a.data.id, ((_b = item.relationships.source) === null || _b === void 0 ? void 0 : _b.data.type) === 'geometry-set'), [index_2.SceneItemSystemMetadata.MissingPartRevisionId]: toMetadataOrUndefined((_c = item.relationships.source) === null || _c === void 0 ? void 0 : _c.data.id, ((_d = item.relationships.source) === null || _d === void 0 ? void 0 : _d.data.type) === 'part-revision'), [index_2.SceneItemSystemMetadata.MissingSuppliedPartId]: toMetadataOrUndefined((_e = item.attributes.source) === null || _e === void 0 ? void 0 : _e.suppliedPartId), [index_2.SceneItemSystemMetadata.MissingSuppliedPartRevisionId]: toMetadataOrUndefined((_f = item.attributes.source) === null || _f === void 0 ? void 0 : _f.suppliedRevisionId) }), source: undefined }),
|
|
133
|
+
relationships: Object.assign(Object.assign({}, item.relationships), { source: undefined }),
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
});
|
|
137
|
+
if (retries.length > 0) {
|
|
138
|
+
onMsg(`Creating ${retries.length} placeholder scene items at depth ${depth}.`);
|
|
139
|
+
// wait for placeholders to be created
|
|
140
|
+
const { itemResults: placeholderItemResults } =
|
|
141
|
+
// eslint-disable-next-line no-await-in-loop
|
|
142
|
+
yield createSceneItemBatch({
|
|
143
|
+
client,
|
|
144
|
+
createSceneItemReqs: retries,
|
|
145
|
+
failFast,
|
|
146
|
+
onProgress,
|
|
147
|
+
limit,
|
|
148
|
+
sceneId,
|
|
149
|
+
polling,
|
|
150
|
+
});
|
|
151
|
+
// attach placeholder references to item errors
|
|
152
|
+
placeholderItemResults.forEach((resultItem, i) => {
|
|
153
|
+
if ((0, utils_1.isSceneItemRelationship)(resultItem.res)) {
|
|
154
|
+
retryErrors[i].placeholderItem = resultItem.res;
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
201
159
|
}
|
|
202
160
|
}
|
|
203
|
-
if (
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
onMsg(` Batch errors: ${batchErrors.length}`);
|
|
161
|
+
if (createFailed) {
|
|
162
|
+
if (verbose) {
|
|
163
|
+
onMsg(`Scene item creation failed in ${(0, utils_1.formatTime)(Number(process_1.hrtime.bigint() - startTime) / 1000000000)} at depth ${depth}.`);
|
|
207
164
|
}
|
|
208
|
-
|
|
209
|
-
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
if (verbose) {
|
|
168
|
+
onMsg(`Scene item creation completed in ${(0, utils_1.formatTime)(Number(process_1.hrtime.bigint() - startTime) / 1000000000)} for ${itemCount} scene items with max depth of ${depthSortedItems.length - 1}.`);
|
|
169
|
+
if (resultBatchErrors.length) {
|
|
170
|
+
onMsg(`Batch errors: ${resultBatchErrors.length}`);
|
|
171
|
+
}
|
|
172
|
+
if (resultItemErrors.length) {
|
|
173
|
+
onMsg(`Scene item errors: ${resultItemErrors.length}`);
|
|
174
|
+
}
|
|
210
175
|
}
|
|
176
|
+
if (verbose)
|
|
177
|
+
onMsg(`Committing scene and polling until ready...`);
|
|
178
|
+
yield updateScene({
|
|
179
|
+
attributes: { state: index_1.UpdateSceneRequestDataAttributesStateEnum.Commit },
|
|
180
|
+
client,
|
|
181
|
+
sceneId,
|
|
182
|
+
});
|
|
183
|
+
yield pollSceneReady({
|
|
184
|
+
client,
|
|
185
|
+
id: sceneId,
|
|
186
|
+
onMsg,
|
|
187
|
+
polling: sceneReadyPolling,
|
|
188
|
+
verbose,
|
|
189
|
+
});
|
|
190
|
+
if (verbose)
|
|
191
|
+
onMsg(`Fitting scene's camera to scene items...`);
|
|
192
|
+
sceneResult = (yield updateScene({
|
|
193
|
+
attributes: {
|
|
194
|
+
camera: { type: index_1.CameraFitTypeEnum.FitVisibleSceneItems },
|
|
195
|
+
},
|
|
196
|
+
client,
|
|
197
|
+
sceneId,
|
|
198
|
+
})).scene;
|
|
211
199
|
}
|
|
212
|
-
if (verbose)
|
|
213
|
-
onMsg(`Committing scene and polling until ready...`);
|
|
214
|
-
yield updateScene({
|
|
215
|
-
attributes: { state: index_1.UpdateSceneRequestDataAttributesStateEnum.Commit },
|
|
216
|
-
client,
|
|
217
|
-
sceneId,
|
|
218
|
-
});
|
|
219
|
-
yield pollSceneReady({ client, id: sceneId, onMsg, polling, verbose });
|
|
220
|
-
if (verbose)
|
|
221
|
-
onMsg(`Fitting scene's camera to scene items...`);
|
|
222
|
-
const sceneResult = (yield updateScene({
|
|
223
|
-
attributes: {
|
|
224
|
-
camera: { type: index_1.CameraFitTypeEnum.FitVisibleSceneItems },
|
|
225
|
-
},
|
|
226
|
-
client,
|
|
227
|
-
sceneId,
|
|
228
|
-
})).scene;
|
|
229
200
|
if (verbose) {
|
|
230
|
-
|
|
231
|
-
const h = Math.floor(seconds / 3600);
|
|
232
|
-
const m = Math.floor((seconds % 3600) / 60);
|
|
233
|
-
const s = Math.round(seconds % 60);
|
|
234
|
-
return [h, m > 9 ? m : h ? '0' + m : m || '0', s > 9 ? s : '0' + s]
|
|
235
|
-
.filter(Boolean)
|
|
236
|
-
.join(':');
|
|
237
|
-
};
|
|
238
|
-
onMsg(`Scene creation completed in ${formatTime(Number(process_1.hrtime.bigint() - startTime) / 1000000000)}.`);
|
|
201
|
+
onMsg(`Scene creation completed in ${(0, utils_1.formatTime)(Number(process_1.hrtime.bigint() - startTime) / 1000000000)}.`);
|
|
239
202
|
}
|
|
240
203
|
return {
|
|
241
|
-
errors:
|
|
242
|
-
queued:
|
|
204
|
+
errors: resultBatchErrors,
|
|
205
|
+
queued: returnQueued ? resultQueuedOps : [],
|
|
243
206
|
scene: sceneResult,
|
|
244
|
-
sceneItemErrors,
|
|
207
|
+
sceneItemErrors: resultItemErrors,
|
|
245
208
|
};
|
|
246
209
|
});
|
|
247
210
|
}
|
|
248
|
-
exports.
|
|
211
|
+
exports.createSceneAndSceneItems = createSceneAndSceneItems;
|
|
212
|
+
/**
|
|
213
|
+
* Helper function for building a metadata string object.
|
|
214
|
+
*
|
|
215
|
+
* @param value Value to convert to metadata object
|
|
216
|
+
* @param condition Setting to `false` will cause result to be `undefined`
|
|
217
|
+
* @returns Instance of a `MetadataValue` object
|
|
218
|
+
*/
|
|
219
|
+
function toMetadataOrUndefined(value, condition = true) {
|
|
220
|
+
return condition && (0, index_2.defined)(value)
|
|
221
|
+
? {
|
|
222
|
+
type: 'string',
|
|
223
|
+
value,
|
|
224
|
+
}
|
|
225
|
+
: // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
226
|
+
undefined;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* This async function takes a long list of create scene item data and handles
|
|
230
|
+
* batch based scene item creation. Batch operation results and errors are
|
|
231
|
+
* returned to the caller.
|
|
232
|
+
*/
|
|
233
|
+
const createSceneItemBatch = ({ client, createSceneItemReqs: createItemReqs, failFast, onProgress, limit, sceneId, polling = { intervalMs: index_2.PollIntervalMs, maxAttempts: index_2.MaxAttempts }, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
234
|
+
let batchErrors = [];
|
|
235
|
+
let itemErrors = [];
|
|
236
|
+
let itemResults = [];
|
|
237
|
+
const createRes = yield createSceneItems({
|
|
238
|
+
client,
|
|
239
|
+
createSceneItemReqs: createItemReqs,
|
|
240
|
+
failFast,
|
|
241
|
+
onProgress,
|
|
242
|
+
limit,
|
|
243
|
+
sceneId,
|
|
244
|
+
});
|
|
245
|
+
const { a: batchOps, b: errors } = (0, index_2.partition)(createRes.queuedBatchOps, (i) => (0, index_2.isQueuedJob)(i.res));
|
|
246
|
+
if (errors.length) {
|
|
247
|
+
batchErrors = batchErrors.concat(errors);
|
|
248
|
+
}
|
|
249
|
+
// Nothing succeeded, return early as something is likely wrong
|
|
250
|
+
if (batchOps.length === 0 || errors.length === createRes.chunks) {
|
|
251
|
+
return { batchOps, batchErrors, itemErrors, itemResults };
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
function poll({ ops, res, }) {
|
|
255
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
256
|
+
const r = yield (0, queued_jobs_1.pollQueuedJob)({
|
|
257
|
+
id: res.data.id,
|
|
258
|
+
getQueuedJob: (id, cancelToken) => client.batches.getQueuedBatch({ id }, { cancelToken }),
|
|
259
|
+
allow404: true,
|
|
260
|
+
limit,
|
|
261
|
+
polling,
|
|
262
|
+
});
|
|
263
|
+
if ((0, queued_jobs_1.isPollError)(r.res)) {
|
|
264
|
+
failFast ? (0, queued_jobs_1.throwOnError)(r) : errors.push({ ops, res: r.res });
|
|
265
|
+
}
|
|
266
|
+
return r;
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
// eslint-disable-next-line no-await-in-loop
|
|
270
|
+
const batchRes = yield Promise.all(batchOps.map((is) => limit(poll, is)));
|
|
271
|
+
itemResults = batchRes.flatMap((b, i) => (0, queued_jobs_1.isBatch)(b.res)
|
|
272
|
+
? b.res['vertexvis/batch:results'].map((r, j) => {
|
|
273
|
+
return { req: batchOps[i].ops[j].data, res: r };
|
|
274
|
+
})
|
|
275
|
+
: []);
|
|
276
|
+
itemErrors = itemErrors.concat(itemResults.filter((resultItem) => (0, utils_1.isApiError)(resultItem.res)));
|
|
277
|
+
}
|
|
278
|
+
// if the full batch failed add batch item error for each item
|
|
279
|
+
errors.forEach((error) => {
|
|
280
|
+
console.log(error);
|
|
281
|
+
error.ops.forEach((op) => {
|
|
282
|
+
// `error.res` guaranteed to be non-null due to `isApiError()` condition above
|
|
283
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
284
|
+
itemErrors.push({ req: op.data, res: error.res });
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
return { batchOps, batchErrors, itemErrors, itemResults };
|
|
288
|
+
});
|
|
249
289
|
/**
|
|
250
290
|
* Create scene items within a scene.
|
|
251
291
|
*/
|
|
252
|
-
function
|
|
292
|
+
function createSceneItems({ client, createSceneItemReqs, failFast, limit, sceneId, }) {
|
|
253
293
|
return __awaiter(this, void 0, void 0, function* () {
|
|
254
|
-
const limit = (0, p_limit_1.default)(parallelism);
|
|
255
294
|
const batchSize = 500;
|
|
256
295
|
const opChunks = (0, utils_1.arrayChunked)(createSceneItemReqs.map((req) => ({
|
|
257
296
|
data: req.data,
|
|
@@ -281,7 +320,7 @@ function createSceneItemsEXPERIMENTAL({ client, createSceneItemReqs, failFast, p
|
|
|
281
320
|
return { chunks: opChunks.length, queuedBatchOps };
|
|
282
321
|
});
|
|
283
322
|
}
|
|
284
|
-
exports.
|
|
323
|
+
exports.createSceneItems = createSceneItems;
|
|
285
324
|
/**
|
|
286
325
|
* Delete all scenes.
|
|
287
326
|
*
|