buckyos 0.7.138 → 0.7.140
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/cli/core/app.ts +4 -0
- package/cli/dist/cli.mjs +545 -124
- package/cli/dist/cli.mjs.map +1 -1
- package/cli/modules/aiws.ts +294 -0
- package/cli/modules/executor.ts +98 -0
- package/cli/version.ts +1 -1
- package/dist/aiworkspace_client.d.ts +91 -0
- package/dist/aiworkspace_client.d.ts.map +1 -0
- package/dist/app-frame.cjs +1 -1
- package/dist/app-frame.cjs.map +1 -1
- package/dist/app-frame.d.ts +103 -3
- package/dist/app-frame.d.ts.map +1 -1
- package/dist/app-frame.mjs +189 -8
- package/dist/app-frame.mjs.map +1 -1
- package/dist/browser.cjs +1 -1
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.ts +2 -0
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.mjs +7 -3
- package/dist/browser.mjs.map +1 -1
- package/dist/content.cjs +1 -1
- package/dist/content.cjs.map +1 -1
- package/dist/content.d.ts +18 -0
- package/dist/content.d.ts.map +1 -1
- package/dist/content.mjs +61 -1
- package/dist/content.mjs.map +1 -1
- package/dist/executor_client-978a8e1b.js +13 -0
- package/dist/executor_client-978a8e1b.js.map +1 -0
- package/dist/{ndm_proxy-6b03b9ec.mjs → executor_client-d2c9e854.mjs} +848 -247
- package/dist/executor_client-d2c9e854.mjs.map +1 -0
- package/dist/executor_client.d.ts +138 -0
- package/dist/executor_client.d.ts.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +12 -3
- package/dist/index.mjs.map +1 -1
- package/dist/internal/hash_worker.d.ts +2 -1
- package/dist/internal/hash_worker.d.ts.map +1 -1
- package/dist/internal/tus_client.d.ts +3 -0
- package/dist/internal/tus_client.d.ts.map +1 -1
- package/dist/ndm_client.d.ts +56 -7
- package/dist/ndm_client.d.ts.map +1 -1
- package/dist/{ndn_types-ac9c1e48.mjs → ndn_types-dcb74613.mjs} +3 -3
- package/dist/{ndn_types-ac9c1e48.mjs.map → ndn_types-dcb74613.mjs.map} +1 -1
- package/dist/nfsp.cjs +1 -1
- package/dist/nfsp.cjs.map +1 -1
- package/dist/nfsp.d.ts +16 -0
- package/dist/nfsp.d.ts.map +1 -1
- package/dist/nfsp.mjs +6 -0
- package/dist/nfsp.mjs.map +1 -1
- package/dist/node.cjs +1 -1
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.ts +2 -0
- package/dist/node.d.ts.map +1 -1
- package/dist/node.mjs +7 -3
- package/dist/node.mjs.map +1 -1
- package/dist/provision.mjs +1 -1
- package/dist/runtime.d.ts +2 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/sdk_core.d.ts +4 -0
- package/dist/sdk_core.d.ts.map +1 -1
- package/dist/{tus_client-19baa342.mjs → tus_client-8fd4d937.mjs} +40 -2
- package/dist/tus_client-8fd4d937.mjs.map +1 -0
- package/dist/{tus_client-2b915a81.js → tus_client-a2f73d53.js} +4 -4
- package/dist/tus_client-a2f73d53.js.map +1 -0
- package/package.json +1 -1
- package/dist/ndm_proxy-67651066.js +0 -13
- package/dist/ndm_proxy-67651066.js.map +0 -1
- package/dist/ndm_proxy-6b03b9ec.mjs.map +0 -1
- package/dist/tus_client-19baa342.mjs.map +0 -1
- package/dist/tus_client-2b915a81.js.map +0 -1
|
@@ -35,7 +35,7 @@ var __privateMethod = (obj, member, method) => {
|
|
|
35
35
|
return method;
|
|
36
36
|
};
|
|
37
37
|
var _listener, _listeners, _cancelled, _allowInsecure, _gzip, _headers, _method, _timeout, _url, _body, _bodyType, _creds, _preflight, _process, _retry, _signal, _throttle, _getUrlFunc, _send, send_fn, _statusCode, _statusMessage, _headers2, _body2, _request, _error, _names, _data, _dataLength, _writeData, writeData_fn, _data2, _offset, _bytesRead, _parent, _maxInflation, _incrementBytesRead, incrementBytesRead_fn, _peekBytes, peekBytes_fn, _r, _s, _v, _networkV, _privateKey, _options, _type, _to, _data3, _nonce, _gasLimit, _gasPrice, _maxPriorityFeePerGas, _maxFeePerGas, _value, _chainId, _sig, _accessList, _maxFeePerBlobGas, _blobVersionedHashes, _kzg, _blobs, _auths, _blobWrapperVersion, _getSerialized, getSerialized_fn, _types, _fullTypes, _encoderCache, _getEncoder, getEncoder_fn, _offset2, _tokens, _subTokenString, subTokenString_fn, _walkAsync, walkAsync_fn, _getCoder, getCoder_fn, _errors, _events, _functions, _abiCoder, _getFunction, getFunction_fn, _getEvent, getEvent_fn, _transactions, _logs, _startBlock, _iface, _iface2, _filter, _a, _supports2544, _resolver, _fetch, fetch_fn, _getResolver, getResolver_fn, _url2, _processFunc, _name, _chainId2, _plugins, _provider, _poller, _interval, _blockNumber, _poll, poll_fn, _provider2, _poll2, _running, _tag, _lastBlock, _filter2, _hash, _provider3, _filter3, _poller2, _running2, _blockNumber2, _poll3, poll_fn2, _subs, _plugins2, _pausedState, _destroyed, _networkPromise, _anyNetwork, _performCache, _lastBlockNumber, _nextTimer, _timers, _disableCcipRead, _requestRate, _requestTimes, _options2, _getDelay, getDelay_fn, _perform, perform_fn, _call, call_fn, _checkNetwork, checkNetwork_fn, _getAccountValue, getAccountValue_fn, _getBlock, getBlock_fn, _hasSub, hasSub_fn, _getSub, getSub_fn, _throwUnsupported, throwUnsupported_fn, _provider4, _filterIdPromise, _poller3, _running3, _network, _hault, _poll4, poll_fn3, _teardown, teardown_fn, _event, _options3, _nextId, _payloads, _drainTimer, _notReady, _network2, _pendingDetectNetwork, _scheduleDrain, scheduleDrain_fn, _pollingInterval, _connect, _signingKey, _data4, _checksum, _words, _loadWords, loadWords_fn, _account, account_fn, _fromSeed, fromSeed_fn, _fromAccount, fromAccount_fn;
|
|
38
|
-
import { v as DID, w as getBrowserIdentityRaw, x as clearBrowserUserInfo, y as saveBrowserIdentity, z as saveBrowserUserInfo, A as getBrowserUserInfo, B as clearBrowserIdentity, q as parseBuckyOSOwnerDocument, h as hashPassword, C as saveLocalAccountInfo, E as cleanLocalAccountInfo, F as canonicalize, G as signJwtEdDSA,
|
|
38
|
+
import { v as DID, w as getBrowserIdentityRaw, x as clearBrowserUserInfo, y as saveBrowserIdentity, z as saveBrowserUserInfo, A as getBrowserUserInfo, B as clearBrowserIdentity, q as parseBuckyOSOwnerDocument, h as hashPassword, C as saveLocalAccountInfo, E as cleanLocalAccountInfo, F as canonicalize, G as signJwtEdDSA, H as ChunkId, I as sha256Bytes, J as FileObject, O as ObjId, K as DirObject, S as SimpleChunkList } from "./ndn_types-dcb74613.mjs";
|
|
39
39
|
class RPCError extends Error {
|
|
40
40
|
constructor(message, code, data) {
|
|
41
41
|
super(message);
|
|
@@ -323,6 +323,91 @@ function buildJumpUrl(action, params, jumpBase = DEFAULT_JUMP_BASE_URL) {
|
|
|
323
323
|
const fragment = new URLSearchParams(params).toString();
|
|
324
324
|
return `${base.origin}${path}${fragment ? `#${fragment}` : ""}`;
|
|
325
325
|
}
|
|
326
|
+
const AIWORKSPACE_SERVICE_NAME = "aiworkspace";
|
|
327
|
+
class AiwsFailure extends Error {
|
|
328
|
+
constructor(error) {
|
|
329
|
+
super(`${error.code}${error.sub_code ? `/${error.sub_code}` : ""}: ${error.detail}`);
|
|
330
|
+
this.name = "AiwsFailure";
|
|
331
|
+
this.code = error.code;
|
|
332
|
+
this.subCode = error.sub_code;
|
|
333
|
+
this.data = error.data;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
class AiWorkspaceClient {
|
|
337
|
+
constructor(rpcClient) {
|
|
338
|
+
this.rpcClient = rpcClient;
|
|
339
|
+
}
|
|
340
|
+
async call(method, params) {
|
|
341
|
+
const raw = await this.rpcClient.call(method, params);
|
|
342
|
+
if (raw && typeof raw === "object" && raw.ok === false)
|
|
343
|
+
throw new AiwsFailure(raw.error);
|
|
344
|
+
return raw;
|
|
345
|
+
}
|
|
346
|
+
// ---- workspace
|
|
347
|
+
list() {
|
|
348
|
+
return this.call("ws.list", {});
|
|
349
|
+
}
|
|
350
|
+
info(workspace_id) {
|
|
351
|
+
return this.call("ws.get_info", { workspace_id });
|
|
352
|
+
}
|
|
353
|
+
getUserState(workspace_id) {
|
|
354
|
+
return this.call("ws.get_user_state", { workspace_id });
|
|
355
|
+
}
|
|
356
|
+
setUserState(workspace_id, entries, expect) {
|
|
357
|
+
return this.call("ws.set_user_state", { workspace_id, entries, ...expect ? { expect } : {} });
|
|
358
|
+
}
|
|
359
|
+
// ---- document
|
|
360
|
+
resolve(workspace_id, reference) {
|
|
361
|
+
return this.call("doc.resolve", { workspace_id, reference });
|
|
362
|
+
}
|
|
363
|
+
resolvePath(workspace_id, path) {
|
|
364
|
+
return this.call("doc.resolve", { workspace_id, path });
|
|
365
|
+
}
|
|
366
|
+
read(workspace_id, entity_id, selector) {
|
|
367
|
+
return this.call("doc.read", { workspace_id, entity_id, ...selector ? { selector } : {} });
|
|
368
|
+
}
|
|
369
|
+
query(workspace_id, params) {
|
|
370
|
+
return this.call("doc.query", { workspace_id, ...params });
|
|
371
|
+
}
|
|
372
|
+
outline(workspace_id) {
|
|
373
|
+
return this.call("doc.outline", { workspace_id });
|
|
374
|
+
}
|
|
375
|
+
prepare(workspace_id, request) {
|
|
376
|
+
return this.rpcClient.call("doc.prepare", { workspace_id, ...request });
|
|
377
|
+
}
|
|
378
|
+
/** The three-state commit result (`status: accepted | conflict | rejected`), never thrown. */
|
|
379
|
+
commit(workspace_id, request) {
|
|
380
|
+
return this.rpcClient.call("doc.commit", { workspace_id, ...request });
|
|
381
|
+
}
|
|
382
|
+
getSubmission(workspace_id, epoch, idempotency_key) {
|
|
383
|
+
return this.call("doc.get_submission", { workspace_id, epoch, idempotency_key });
|
|
384
|
+
}
|
|
385
|
+
// ---- runs (M3 executor protocol)
|
|
386
|
+
runStart(workspace_id, program, params, idempotency_key) {
|
|
387
|
+
return this.call("proc.start", { workspace_id, program, params, idempotency_key });
|
|
388
|
+
}
|
|
389
|
+
runGet(workspace_id, run_id, choices) {
|
|
390
|
+
return this.call("proc.get", { workspace_id, run_id, ...choices ? { choices } : {} });
|
|
391
|
+
}
|
|
392
|
+
runList(workspace_id, wish_id, limit) {
|
|
393
|
+
return this.call("proc.list", { workspace_id, ...wish_id ? { wish_id } : {}, ...limit ? { limit } : {} });
|
|
394
|
+
}
|
|
395
|
+
runClaim(workspace_id, run_id, claim_token, executor) {
|
|
396
|
+
return this.call("proc.claim", { workspace_id, run_id, claim_token, ...executor ? { executor } : {} });
|
|
397
|
+
}
|
|
398
|
+
runHeartbeat(workspace_id, run_id, attempt, progress) {
|
|
399
|
+
return this.call("proc.heartbeat", { workspace_id, run_id, attempt, ...progress ? { progress } : {} });
|
|
400
|
+
}
|
|
401
|
+
runReport(workspace_id, report) {
|
|
402
|
+
return this.call("proc.report", { workspace_id, ...report });
|
|
403
|
+
}
|
|
404
|
+
runApply(workspace_id, run_id, plan_digest, session_id) {
|
|
405
|
+
return this.call("proc.apply", { workspace_id, run_id, plan_digest, ...session_id ? { session_id } : {} });
|
|
406
|
+
}
|
|
407
|
+
runCancel(workspace_id, run_id) {
|
|
408
|
+
return this.call("proc.cancel", { workspace_id, run_id });
|
|
409
|
+
}
|
|
410
|
+
}
|
|
326
411
|
function serializeAuthTarget(target) {
|
|
327
412
|
if (!target || typeof target !== "object") {
|
|
328
413
|
throw new RPCError("verify-hub auth target is required");
|
|
@@ -3453,6 +3538,9 @@ class BuckyOSRuntime {
|
|
|
3453
3538
|
getAiccClient() {
|
|
3454
3539
|
return new AiccClient(this.getServiceRpcClient("aicc"));
|
|
3455
3540
|
}
|
|
3541
|
+
getAiWorkspaceClient() {
|
|
3542
|
+
return new AiWorkspaceClient(this.getServiceRpcClient(AIWORKSPACE_SERVICE_NAME));
|
|
3543
|
+
}
|
|
3456
3544
|
getMsgQueueClient() {
|
|
3457
3545
|
return new MsgQueueClient(this.getServiceRpcClient("kmsg"));
|
|
3458
3546
|
}
|
|
@@ -5392,6 +5480,12 @@ class BuckyOSSDK {
|
|
|
5392
5480
|
}
|
|
5393
5481
|
return this.currentRuntime.getAiccClient();
|
|
5394
5482
|
}
|
|
5483
|
+
getAiWorkspaceClient() {
|
|
5484
|
+
if (this.currentRuntime == null) {
|
|
5485
|
+
throw new Error("BuckyOS WebSDK is not initialized,call initBuckyOS first");
|
|
5486
|
+
}
|
|
5487
|
+
return this.currentRuntime.getAiWorkspaceClient();
|
|
5488
|
+
}
|
|
5395
5489
|
getMsgQueueClient() {
|
|
5396
5490
|
if (this.currentRuntime == null) {
|
|
5397
5491
|
throw new Error("BuckyOS WebSDK is not initialized,call initBuckyOS first");
|
|
@@ -5584,6 +5678,7 @@ function createSDKModule(target) {
|
|
|
5584
5678
|
getTaskManagerClient: sdk.getTaskManagerClient.bind(sdk),
|
|
5585
5679
|
getWorkflowClient: sdk.getWorkflowClient.bind(sdk),
|
|
5586
5680
|
getAiccClient: sdk.getAiccClient.bind(sdk),
|
|
5681
|
+
getAiWorkspaceClient: sdk.getAiWorkspaceClient.bind(sdk),
|
|
5587
5682
|
getMsgQueueClient: sdk.getMsgQueueClient.bind(sdk),
|
|
5588
5683
|
getMsgCenterClient: sdk.getMsgCenterClient.bind(sdk),
|
|
5589
5684
|
getRepoClient: sdk.getRepoClient.bind(sdk)
|
|
@@ -22178,7 +22273,7 @@ class AbstractProvider {
|
|
|
22178
22273
|
request.body = { data, sender };
|
|
22179
22274
|
}
|
|
22180
22275
|
this.emit("debug", { action: "sendCcipReadFetchRequest", request, index: i, urls });
|
|
22181
|
-
let
|
|
22276
|
+
let errorMessage2 = "unknown error";
|
|
22182
22277
|
let resp;
|
|
22183
22278
|
try {
|
|
22184
22279
|
resp = await request.send();
|
|
@@ -22194,13 +22289,13 @@ class AbstractProvider {
|
|
|
22194
22289
|
return result.data;
|
|
22195
22290
|
}
|
|
22196
22291
|
if (result.message) {
|
|
22197
|
-
|
|
22292
|
+
errorMessage2 = result.message;
|
|
22198
22293
|
}
|
|
22199
22294
|
this.emit("debug", { action: "receiveCcipReadFetchError", request, result });
|
|
22200
22295
|
} catch (error) {
|
|
22201
22296
|
}
|
|
22202
|
-
assert(resp.statusCode < 400 || resp.statusCode >= 500, `response not found during CCIP fetch: ${
|
|
22203
|
-
errorMessages.push(
|
|
22297
|
+
assert(resp.statusCode < 400 || resp.statusCode >= 500, `response not found during CCIP fetch: ${errorMessage2}`, "OFFCHAIN_FAULT", { reason: "404_MISSING_RESOURCE", transaction: tx, info: { url, errorMessage: errorMessage2 } });
|
|
22298
|
+
errorMessages.push(errorMessage2);
|
|
22204
22299
|
}
|
|
22205
22300
|
assert(false, `error encountered during CCIP fetch: ${errorMessages.map((m) => JSON.stringify(m)).join(", ")}`, "OFFCHAIN_FAULT", {
|
|
22206
22301
|
reason: "500_SERVER_ERROR",
|
|
@@ -27581,7 +27676,9 @@ function getWorkerBlobUrl() {
|
|
|
27581
27676
|
function isHashWorkerAvailable() {
|
|
27582
27677
|
return typeof Worker !== "undefined" && typeof Blob !== "undefined" && typeof URL !== "undefined" && typeof URL.createObjectURL === "function" && typeof crypto !== "undefined" && typeof crypto.subtle !== "undefined";
|
|
27583
27678
|
}
|
|
27584
|
-
function hashFileInWorker(file, chunkSize) {
|
|
27679
|
+
function hashFileInWorker(file, chunkSize, signal) {
|
|
27680
|
+
let cancel = () => {
|
|
27681
|
+
};
|
|
27585
27682
|
let progressCb = null;
|
|
27586
27683
|
let cumulativeBytes = 0;
|
|
27587
27684
|
const chunks = [];
|
|
@@ -27593,6 +27690,16 @@ function hashFileInWorker(file, chunkSize) {
|
|
|
27593
27690
|
reject(new Error("Failed to create hash worker"));
|
|
27594
27691
|
return;
|
|
27595
27692
|
}
|
|
27693
|
+
cancel = () => {
|
|
27694
|
+
worker.terminate();
|
|
27695
|
+
signal == null ? void 0 : signal.removeEventListener("abort", cancel);
|
|
27696
|
+
reject(new Error("Hash cancelled"));
|
|
27697
|
+
};
|
|
27698
|
+
if (signal == null ? void 0 : signal.aborted) {
|
|
27699
|
+
cancel();
|
|
27700
|
+
return;
|
|
27701
|
+
}
|
|
27702
|
+
signal == null ? void 0 : signal.addEventListener("abort", cancel, { once: true });
|
|
27596
27703
|
worker.onmessage = (e) => {
|
|
27597
27704
|
const msg = e.data;
|
|
27598
27705
|
if (msg.type === "chunk") {
|
|
@@ -27607,14 +27714,17 @@ function hashFileInWorker(file, chunkSize) {
|
|
|
27607
27714
|
if (progressCb)
|
|
27608
27715
|
progressCb(cumulativeBytes);
|
|
27609
27716
|
} else if (msg.type === "done") {
|
|
27717
|
+
signal == null ? void 0 : signal.removeEventListener("abort", cancel);
|
|
27610
27718
|
worker.terminate();
|
|
27611
27719
|
resolve(chunks);
|
|
27612
27720
|
} else if (msg.type === "error") {
|
|
27721
|
+
signal == null ? void 0 : signal.removeEventListener("abort", cancel);
|
|
27613
27722
|
worker.terminate();
|
|
27614
27723
|
reject(new Error(msg.message ?? "Worker hash error"));
|
|
27615
27724
|
}
|
|
27616
27725
|
};
|
|
27617
27726
|
worker.onerror = (err) => {
|
|
27727
|
+
signal == null ? void 0 : signal.removeEventListener("abort", cancel);
|
|
27618
27728
|
worker.terminate();
|
|
27619
27729
|
reject(new Error(err.message ?? "Worker error"));
|
|
27620
27730
|
};
|
|
@@ -27622,6 +27732,7 @@ function hashFileInWorker(file, chunkSize) {
|
|
|
27622
27732
|
});
|
|
27623
27733
|
return {
|
|
27624
27734
|
result,
|
|
27735
|
+
cancel: () => cancel(),
|
|
27625
27736
|
onProgress(cb) {
|
|
27626
27737
|
progressCb = cb;
|
|
27627
27738
|
}
|
|
@@ -27664,6 +27775,7 @@ const browserProvider = {
|
|
|
27664
27775
|
},
|
|
27665
27776
|
pickFiles(options) {
|
|
27666
27777
|
return new Promise((resolve, reject) => {
|
|
27778
|
+
var _a2, _b;
|
|
27667
27779
|
const input = document.createElement("input");
|
|
27668
27780
|
input.type = "file";
|
|
27669
27781
|
if (options.mode === "single_dir") {
|
|
@@ -27679,27 +27791,44 @@ const browserProvider = {
|
|
|
27679
27791
|
input.accept = options.accept.join(",");
|
|
27680
27792
|
}
|
|
27681
27793
|
let settled = false;
|
|
27682
|
-
|
|
27794
|
+
const cleanup = () => {
|
|
27795
|
+
var _a3;
|
|
27796
|
+
window.removeEventListener("focus", onFocus);
|
|
27797
|
+
(_a3 = options.signal) == null ? void 0 : _a3.removeEventListener("abort", onAbort);
|
|
27798
|
+
};
|
|
27799
|
+
const fail2 = (error) => {
|
|
27683
27800
|
if (settled)
|
|
27684
27801
|
return;
|
|
27685
27802
|
settled = true;
|
|
27803
|
+
cleanup();
|
|
27804
|
+
reject(error);
|
|
27805
|
+
};
|
|
27806
|
+
const onAbort = () => fail2(new NdmError("USER_CANCELLED", "Import cancelled"));
|
|
27807
|
+
const onFocus = () => {
|
|
27808
|
+
setTimeout(() => {
|
|
27809
|
+
if (!settled)
|
|
27810
|
+
fail2(new NdmError("USER_CANCELLED", "User cancelled file selection"));
|
|
27811
|
+
}, 500);
|
|
27812
|
+
};
|
|
27813
|
+
input.addEventListener("change", () => {
|
|
27814
|
+
if (settled)
|
|
27815
|
+
return;
|
|
27686
27816
|
const files = input.files;
|
|
27687
27817
|
if (!files || files.length === 0) {
|
|
27688
|
-
|
|
27818
|
+
fail2(new NdmError(options.mode === "single_dir" ? "EMPTY_DIRECTORY_UNAVAILABLE" : "USER_CANCELLED", options.mode === "single_dir" ? "FileList cannot represent an empty directory; use a directory-tree provider" : "No files selected"));
|
|
27689
27819
|
return;
|
|
27690
27820
|
}
|
|
27821
|
+
settled = true;
|
|
27822
|
+
cleanup();
|
|
27691
27823
|
resolve(Array.from(files));
|
|
27692
27824
|
});
|
|
27693
|
-
|
|
27694
|
-
setTimeout(() => {
|
|
27695
|
-
if (!settled) {
|
|
27696
|
-
settled = true;
|
|
27697
|
-
reject(new NdmError("USER_CANCELLED", "User cancelled file selection"));
|
|
27698
|
-
}
|
|
27699
|
-
window.removeEventListener("focus", onFocus);
|
|
27700
|
-
}, 500);
|
|
27701
|
-
};
|
|
27825
|
+
input.addEventListener("cancel", onAbort);
|
|
27702
27826
|
window.addEventListener("focus", onFocus);
|
|
27827
|
+
if ((_a2 = options.signal) == null ? void 0 : _a2.aborted) {
|
|
27828
|
+
onAbort();
|
|
27829
|
+
return;
|
|
27830
|
+
}
|
|
27831
|
+
(_b = options.signal) == null ? void 0 : _b.addEventListener("abort", onAbort, { once: true });
|
|
27703
27832
|
input.click();
|
|
27704
27833
|
});
|
|
27705
27834
|
}
|
|
@@ -27772,7 +27901,8 @@ async function callStoreApi(methodName, requestBody, options) {
|
|
|
27772
27901
|
method: "POST",
|
|
27773
27902
|
headers,
|
|
27774
27903
|
body: JSON.stringify(requestBody),
|
|
27775
|
-
credentials: (options == null ? void 0 : options.credentials) ?? "include"
|
|
27904
|
+
credentials: (options == null ? void 0 : options.credentials) ?? "include",
|
|
27905
|
+
signal: options == null ? void 0 : options.signal
|
|
27776
27906
|
});
|
|
27777
27907
|
if (response.status === 204) {
|
|
27778
27908
|
await ((_a2 = response.body) == null ? void 0 : _a2.cancel());
|
|
@@ -27806,7 +27936,8 @@ async function getZoneGatewayJson(pathWithQuery, options) {
|
|
|
27806
27936
|
const response = await fetcher(`${endpoint}${pathWithQuery}`, {
|
|
27807
27937
|
method: "GET",
|
|
27808
27938
|
headers,
|
|
27809
|
-
credentials: (options == null ? void 0 : options.credentials) ?? "include"
|
|
27939
|
+
credentials: (options == null ? void 0 : options.credentials) ?? "include",
|
|
27940
|
+
signal: options == null ? void 0 : options.signal
|
|
27810
27941
|
});
|
|
27811
27942
|
const contentType = response.headers.get("content-type") ?? "";
|
|
27812
27943
|
const isJsonResponse = contentType.includes("application/json");
|
|
@@ -27911,7 +28042,8 @@ async function debugDumpExpandState$1(request, options) {
|
|
|
27911
28042
|
async function anchorState$1(request, options) {
|
|
27912
28043
|
return callStoreApi("anchor_state", request, options);
|
|
27913
28044
|
}
|
|
27914
|
-
async function materializeFile(file, chunkSize = DEFAULT_CHUNK_SIZE) {
|
|
28045
|
+
async function materializeFile(file, chunkSize = DEFAULT_CHUNK_SIZE, signal) {
|
|
28046
|
+
throwIfCancelled(signal);
|
|
27915
28047
|
const fileSize = file.size;
|
|
27916
28048
|
const chunks = [];
|
|
27917
28049
|
if (fileSize <= chunkSize) {
|
|
@@ -27921,12 +28053,14 @@ async function materializeFile(file, chunkSize = DEFAULT_CHUNK_SIZE) {
|
|
|
27921
28053
|
const chunkIdStr = chunkId.toString();
|
|
27922
28054
|
chunks.push({ chunkId: chunkIdStr, offset: 0, length: buf.length, uploaded: false });
|
|
27923
28055
|
const fileObj2 = new FileObject(file.name, fileSize, chunkIdStr);
|
|
27924
|
-
const [objId2] = fileObj2.genObjId();
|
|
27925
|
-
|
|
28056
|
+
const [objId2, objData2] = fileObj2.genObjId();
|
|
28057
|
+
throwIfCancelled(signal);
|
|
28058
|
+
return { objectId: objId2.toString(), chunks, fileObject: fileObj2.toJSON(), objects: [{ obj_id: objId2.toString(), obj_data: objData2 }] };
|
|
27926
28059
|
}
|
|
27927
28060
|
const chunkList = new SimpleChunkList();
|
|
27928
28061
|
let offset = 0;
|
|
27929
28062
|
while (offset < fileSize) {
|
|
28063
|
+
throwIfCancelled(signal);
|
|
27930
28064
|
const end = Math.min(offset + chunkSize, fileSize);
|
|
27931
28065
|
const slice = new Uint8Array(await file.slice(offset, end).arrayBuffer());
|
|
27932
28066
|
const hash2 = sha256Bytes(slice);
|
|
@@ -27935,29 +28069,42 @@ async function materializeFile(file, chunkSize = DEFAULT_CHUNK_SIZE) {
|
|
|
27935
28069
|
chunks.push({ chunkId: chunkId.toString(), offset, length: slice.length, uploaded: false });
|
|
27936
28070
|
offset = end;
|
|
27937
28071
|
}
|
|
27938
|
-
const [chunkListObjId] = chunkList.genObjId();
|
|
28072
|
+
const [chunkListObjId, chunkListData] = chunkList.genObjId();
|
|
27939
28073
|
const fileObj = new FileObject(file.name, fileSize, chunkListObjId.toString());
|
|
27940
|
-
const [objId] = fileObj.genObjId();
|
|
27941
|
-
|
|
27942
|
-
|
|
27943
|
-
|
|
27944
|
-
|
|
27945
|
-
|
|
28074
|
+
const [objId, objData] = fileObj.genObjId();
|
|
28075
|
+
throwIfCancelled(signal);
|
|
28076
|
+
return { objectId: objId.toString(), chunks, fileObject: fileObj.toJSON(), objects: [
|
|
28077
|
+
{ obj_id: chunkListObjId.toString(), obj_data: chunkListData },
|
|
28078
|
+
{ obj_id: objId.toString(), obj_data: objData }
|
|
28079
|
+
] };
|
|
28080
|
+
}
|
|
28081
|
+
async function materializeFileViaWorker(file, onHashProgress, chunkSize = DEFAULT_CHUNK_SIZE, signal) {
|
|
28082
|
+
if (!isHashWorkerAvailable() || file.size === 0) {
|
|
28083
|
+
const result = await materializeFile(file, chunkSize, signal);
|
|
28084
|
+
onHashProgress == null ? void 0 : onHashProgress(file.size);
|
|
28085
|
+
return result;
|
|
27946
28086
|
}
|
|
27947
28087
|
let hashResults;
|
|
28088
|
+
let timer;
|
|
28089
|
+
const worker = hashFileInWorker(file, chunkSize, signal);
|
|
27948
28090
|
try {
|
|
27949
|
-
|
|
27950
|
-
|
|
27951
|
-
session.onProgress(onHashProgress);
|
|
27952
|
-
}
|
|
27953
|
-
const WORKER_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
28091
|
+
if (onHashProgress)
|
|
28092
|
+
worker.onProgress(onHashProgress);
|
|
27954
28093
|
const timeout = new Promise((_, reject) => {
|
|
27955
|
-
setTimeout(() =>
|
|
28094
|
+
timer = setTimeout(() => {
|
|
28095
|
+
worker.cancel();
|
|
28096
|
+
reject(new Error("hash worker timeout"));
|
|
28097
|
+
}, 5 * 60 * 1e3);
|
|
27956
28098
|
});
|
|
27957
|
-
hashResults = await Promise.race([
|
|
28099
|
+
hashResults = await Promise.race([worker.result, timeout]);
|
|
27958
28100
|
} catch {
|
|
27959
|
-
|
|
28101
|
+
throwIfCancelled(signal);
|
|
28102
|
+
return materializeFile(file, chunkSize, signal);
|
|
28103
|
+
} finally {
|
|
28104
|
+
if (timer)
|
|
28105
|
+
clearTimeout(timer);
|
|
27960
28106
|
}
|
|
28107
|
+
throwIfCancelled(signal);
|
|
27961
28108
|
const fileSize = file.size;
|
|
27962
28109
|
const chunks = [];
|
|
27963
28110
|
if (hashResults.length === 1) {
|
|
@@ -27966,8 +28113,9 @@ async function materializeFileViaWorker(file, onHashProgress, chunkSize = DEFAUL
|
|
|
27966
28113
|
const chunkIdStr = chunkId.toString();
|
|
27967
28114
|
chunks.push({ chunkId: chunkIdStr, offset: 0, length: r.length, uploaded: false });
|
|
27968
28115
|
const fileObj2 = new FileObject(file.name, fileSize, chunkIdStr);
|
|
27969
|
-
const [objId2] = fileObj2.genObjId();
|
|
27970
|
-
|
|
28116
|
+
const [objId2, objData2] = fileObj2.genObjId();
|
|
28117
|
+
throwIfCancelled(signal);
|
|
28118
|
+
return { objectId: objId2.toString(), chunks, fileObject: fileObj2.toJSON(), objects: [{ obj_id: objId2.toString(), obj_data: objData2 }] };
|
|
27971
28119
|
}
|
|
27972
28120
|
const chunkList = new SimpleChunkList();
|
|
27973
28121
|
for (const r of hashResults) {
|
|
@@ -27975,10 +28123,14 @@ async function materializeFileViaWorker(file, onHashProgress, chunkSize = DEFAUL
|
|
|
27975
28123
|
chunkList.appendChunk(chunkId);
|
|
27976
28124
|
chunks.push({ chunkId: chunkId.toString(), offset: r.offset, length: r.length, uploaded: false });
|
|
27977
28125
|
}
|
|
27978
|
-
const [chunkListObjId] = chunkList.genObjId();
|
|
28126
|
+
const [chunkListObjId, chunkListData] = chunkList.genObjId();
|
|
27979
28127
|
const fileObj = new FileObject(file.name, fileSize, chunkListObjId.toString());
|
|
27980
|
-
const [objId] = fileObj.genObjId();
|
|
27981
|
-
|
|
28128
|
+
const [objId, objData] = fileObj.genObjId();
|
|
28129
|
+
throwIfCancelled(signal);
|
|
28130
|
+
return { objectId: objId.toString(), chunks, fileObject: fileObj.toJSON(), objects: [
|
|
28131
|
+
{ obj_id: chunkListObjId.toString(), obj_data: chunkListData },
|
|
28132
|
+
{ obj_id: objId.toString(), obj_data: objData }
|
|
28133
|
+
] };
|
|
27982
28134
|
}
|
|
27983
28135
|
function buildFileObjectFromContentId(name, size, contentId) {
|
|
27984
28136
|
const fileObj = new FileObject(name, size, contentId);
|
|
@@ -28000,27 +28152,21 @@ function resolveImportLookupEndpoint() {
|
|
|
28000
28152
|
return void 0;
|
|
28001
28153
|
}
|
|
28002
28154
|
async function tryCalculateQcidFromFile(file) {
|
|
28003
|
-
|
|
28004
|
-
if (fileSize < MIN_QCID_FILE_SIZE) {
|
|
28005
|
-
return null;
|
|
28006
|
-
}
|
|
28007
|
-
const beginBytes = new Uint8Array(await file.slice(0, QCID_HASH_PIECE_SIZE).arrayBuffer());
|
|
28008
|
-
const midOffset = Math.floor(fileSize / 2);
|
|
28009
|
-
const midBytes = new Uint8Array(
|
|
28010
|
-
await file.slice(midOffset, midOffset + QCID_HASH_PIECE_SIZE).arrayBuffer()
|
|
28011
|
-
);
|
|
28012
|
-
const combined = new Uint8Array(beginBytes.length + midBytes.length);
|
|
28013
|
-
combined.set(beginBytes, 0);
|
|
28014
|
-
combined.set(midBytes, beginBytes.length);
|
|
28015
|
-
const hash2 = sha256Bytes(combined);
|
|
28016
|
-
return ChunkId.fromMixHashResult(fileSize, hash2, "qcid").toString();
|
|
28155
|
+
return file.size < MIN_QCID_FILE_SIZE ? null : calculateQcidFromFile(file);
|
|
28017
28156
|
}
|
|
28018
28157
|
async function calculateQcidFromFile(file) {
|
|
28019
|
-
const
|
|
28020
|
-
|
|
28021
|
-
|
|
28158
|
+
const fileSize = file.size;
|
|
28159
|
+
let sampled;
|
|
28160
|
+
if (fileSize < MIN_QCID_FILE_SIZE) {
|
|
28161
|
+
sampled = new Uint8Array(await file.arrayBuffer());
|
|
28162
|
+
} else {
|
|
28163
|
+
sampled = new Uint8Array(QCID_HASH_PIECE_SIZE * 3);
|
|
28164
|
+
const offsets = [0, Math.floor((fileSize - QCID_HASH_PIECE_SIZE) / 2), fileSize - QCID_HASH_PIECE_SIZE];
|
|
28165
|
+
for (let index = 0; index < offsets.length; index++) {
|
|
28166
|
+
sampled.set(new Uint8Array(await file.slice(offsets[index], offsets[index] + QCID_HASH_PIECE_SIZE).arrayBuffer()), index * QCID_HASH_PIECE_SIZE);
|
|
28167
|
+
}
|
|
28022
28168
|
}
|
|
28023
|
-
return qcid;
|
|
28169
|
+
return ChunkId.fromMixHashResult(fileSize, sha256Bytes(sampled), "qcid").toString();
|
|
28024
28170
|
}
|
|
28025
28171
|
function extractLookupContentId(response, quickHash) {
|
|
28026
28172
|
const body = response;
|
|
@@ -28046,81 +28192,75 @@ function extractLookupContentId(response, quickHash) {
|
|
|
28046
28192
|
}
|
|
28047
28193
|
return void 0;
|
|
28048
28194
|
}
|
|
28049
|
-
async function lookupFileByQcid(file) {
|
|
28050
|
-
const endpoint = resolveImportLookupEndpoint();
|
|
28051
|
-
if (!endpoint)
|
|
28195
|
+
async function lookupFileByQcid(file, options, warnings) {
|
|
28196
|
+
const endpoint = options.endpoint ?? resolveImportLookupEndpoint();
|
|
28197
|
+
if (!endpoint)
|
|
28052
28198
|
return null;
|
|
28053
|
-
}
|
|
28054
28199
|
const qcid = await tryCalculateQcidFromFile(file);
|
|
28055
|
-
|
|
28200
|
+
throwIfCancelled(options.signal);
|
|
28201
|
+
if (!qcid)
|
|
28056
28202
|
return null;
|
|
28057
|
-
|
|
28058
|
-
|
|
28059
|
-
|
|
28060
|
-
|
|
28061
|
-
|
|
28062
|
-
|
|
28063
|
-
|
|
28064
|
-
|
|
28065
|
-
}
|
|
28066
|
-
);
|
|
28067
|
-
const contentId = extractLookupContentId(response, qcid);
|
|
28068
|
-
if (!contentId) {
|
|
28069
|
-
continue;
|
|
28070
|
-
}
|
|
28071
|
-
return {
|
|
28072
|
-
...buildFileObjectFromContentId(file.name, file.size, contentId),
|
|
28073
|
-
locality: "store"
|
|
28074
|
-
};
|
|
28075
|
-
} catch (error) {
|
|
28076
|
-
if (error instanceof NdmStoreApiError && error.status === 404) {
|
|
28077
|
-
continue;
|
|
28078
|
-
}
|
|
28203
|
+
try {
|
|
28204
|
+
const response = await lookupObject({ scope: "app", quick_hash: qcid }, { ...options, endpoint });
|
|
28205
|
+
if (response.reusable !== true || !("state" in response) || !["completed", "same_as", "local_link"].includes(response.state))
|
|
28206
|
+
return null;
|
|
28207
|
+
if (response.chunk_size !== file.size)
|
|
28208
|
+
return null;
|
|
28209
|
+
const contentId = extractLookupContentId(response, qcid);
|
|
28210
|
+
if (!contentId || !(ObjId.fromString(contentId).isChunk() || ObjId.fromString(contentId).isChunkList()) || contentId.startsWith("qcid:"))
|
|
28079
28211
|
return null;
|
|
28212
|
+
return { ...buildFileObjectFromContentId(file.name, file.size, contentId), locality: "store", qcid };
|
|
28213
|
+
} catch (error) {
|
|
28214
|
+
throwIfCancelled(options.signal);
|
|
28215
|
+
if (!(error instanceof NdmStoreApiError && error.status === 404)) {
|
|
28216
|
+
warnings.push(`QCID lookup for ${file.name}: ${errorMessage(error)}`);
|
|
28080
28217
|
}
|
|
28218
|
+
return null;
|
|
28081
28219
|
}
|
|
28082
|
-
|
|
28220
|
+
}
|
|
28221
|
+
function validateName(name) {
|
|
28222
|
+
if (!name || name === "." || name === ".." || /[\\/\x00-\x1f]/.test(name) || /^[a-z]:/i.test(name)) {
|
|
28223
|
+
throw new NdmError("INVALID_IMPORT_PATH", `Invalid file or directory name: ${name}`);
|
|
28224
|
+
}
|
|
28225
|
+
}
|
|
28226
|
+
function validatePath(path) {
|
|
28227
|
+
const parts = path.split("/");
|
|
28228
|
+
parts.forEach(validateName);
|
|
28229
|
+
return parts;
|
|
28083
28230
|
}
|
|
28084
28231
|
function buildDirTree(files, fileObjects) {
|
|
28085
|
-
|
|
28086
|
-
|
|
28087
|
-
const
|
|
28088
|
-
|
|
28089
|
-
|
|
28090
|
-
|
|
28091
|
-
|
|
28092
|
-
|
|
28093
|
-
|
|
28094
|
-
|
|
28095
|
-
|
|
28096
|
-
|
|
28097
|
-
|
|
28098
|
-
|
|
28099
|
-
|
|
28100
|
-
|
|
28101
|
-
|
|
28102
|
-
|
|
28103
|
-
|
|
28104
|
-
|
|
28105
|
-
|
|
28106
|
-
|
|
28107
|
-
|
|
28108
|
-
|
|
28109
|
-
|
|
28110
|
-
|
|
28111
|
-
children: []
|
|
28112
|
-
};
|
|
28113
|
-
dirMap.set(dirPath, dir);
|
|
28114
|
-
currentDir.children.push(dir);
|
|
28232
|
+
if (files.length === 0)
|
|
28233
|
+
throw new NdmError("EMPTY_DIRECTORY_UNAVAILABLE", "FileList cannot represent an empty directory; use importDirectory with directory nodes");
|
|
28234
|
+
const paths = files.map((file) => validatePath(file.webkitRelativePath || file.name));
|
|
28235
|
+
if (paths.some((parts) => parts.length < 2 || parts[0] !== paths[0][0])) {
|
|
28236
|
+
throw new NdmError("INVALID_IMPORT_PATH", "Folder selection must contain one root directory in webkitRelativePath");
|
|
28237
|
+
}
|
|
28238
|
+
const root = { kind: "dir", objectId: "", name: paths[0][0], children: [] };
|
|
28239
|
+
for (let index = 0; index < paths.length; index++) {
|
|
28240
|
+
const parts = paths[index].slice(1);
|
|
28241
|
+
let dir = root;
|
|
28242
|
+
for (let i = 0; i < parts.length; i++) {
|
|
28243
|
+
const name = parts[i];
|
|
28244
|
+
const existing = dir.children.find((child) => child.name === name);
|
|
28245
|
+
if (i === parts.length - 1) {
|
|
28246
|
+
if (existing)
|
|
28247
|
+
throw new NdmError("IMPORT_PATH_CONFLICT", `Duplicate file or directory: ${paths[index].join("/")}`);
|
|
28248
|
+
if (name !== fileObjects[index].name)
|
|
28249
|
+
throw new NdmError("INVALID_IMPORT_PATH", "Relative path basename must match File.name");
|
|
28250
|
+
dir.children.push(fileObjects[index]);
|
|
28251
|
+
} else {
|
|
28252
|
+
if ((existing == null ? void 0 : existing.kind) === "file")
|
|
28253
|
+
throw new NdmError("IMPORT_PATH_CONFLICT", `File used as directory: ${name}`);
|
|
28254
|
+
const child = existing ?? { kind: "dir", objectId: "", name, relativePath: parts.slice(0, i + 1).join("/"), children: [] };
|
|
28255
|
+
if (!existing)
|
|
28256
|
+
dir.children.push(child);
|
|
28257
|
+
dir = child;
|
|
28115
28258
|
}
|
|
28116
|
-
currentDir = dir;
|
|
28117
28259
|
}
|
|
28118
|
-
currentDir.children.push(fileObj);
|
|
28119
28260
|
}
|
|
28120
|
-
computeDirObjectIds(root);
|
|
28121
28261
|
return root;
|
|
28122
28262
|
}
|
|
28123
|
-
function computeDirObjectIds(dir) {
|
|
28263
|
+
function computeDirObjectIds(dir, manifest) {
|
|
28124
28264
|
const ndnDir = new DirObject(dir.name);
|
|
28125
28265
|
if (dir.children) {
|
|
28126
28266
|
for (const child of dir.children) {
|
|
@@ -28130,13 +28270,14 @@ function computeDirObjectIds(dir) {
|
|
|
28130
28270
|
}
|
|
28131
28271
|
ndnDir.addFile(child.name, child._ndnFileObject, child.size);
|
|
28132
28272
|
} else {
|
|
28133
|
-
const childState = computeDirObjectIds(child);
|
|
28273
|
+
const childState = computeDirObjectIds(child, manifest);
|
|
28134
28274
|
ndnDir.addDirectory(child.name, ObjId.fromString(childState.objectId), childState.totalSize);
|
|
28135
28275
|
}
|
|
28136
28276
|
}
|
|
28137
28277
|
}
|
|
28138
|
-
const [objId] = ndnDir.genObjId();
|
|
28278
|
+
const [objId, objData] = ndnDir.genObjId();
|
|
28139
28279
|
dir.objectId = objId.toString();
|
|
28280
|
+
manifest.set(dir.objectId, { obj_id: dir.objectId, obj_data: objData });
|
|
28140
28281
|
return {
|
|
28141
28282
|
objectId: dir.objectId,
|
|
28142
28283
|
totalSize: ndnDir.total_size,
|
|
@@ -28225,18 +28366,63 @@ function collectSummary(items) {
|
|
|
28225
28366
|
return { totalObjects: totalFiles + totalDirs, totalFiles, totalDirs, totalBytes };
|
|
28226
28367
|
}
|
|
28227
28368
|
async function pickupAndImport(options) {
|
|
28369
|
+
const provider = options.provider ?? currentProvider;
|
|
28370
|
+
const caps = provider.getCapabilities();
|
|
28371
|
+
if (options.mode === "single_dir" && !caps.canPickDirectory)
|
|
28372
|
+
throw new NdmError("DIRECTORY_NOT_SUPPORTED");
|
|
28373
|
+
if (options.mode === "mixed" && !caps.canPickMixed)
|
|
28374
|
+
throw new NdmError("MODE_NOT_SUPPORTED_IN_RUNTIME");
|
|
28375
|
+
throwIfCancelled(options.signal);
|
|
28376
|
+
const files = await provider.pickFiles(options);
|
|
28377
|
+
return importFiles(files, options);
|
|
28378
|
+
}
|
|
28379
|
+
async function importFiles(selectedFiles, options) {
|
|
28380
|
+
return importSelectedFiles(selectedFiles, options);
|
|
28381
|
+
}
|
|
28382
|
+
async function importDirectory(tree, options = {}) {
|
|
28383
|
+
return importSelectedFiles([], { ...options, mode: "single_dir" }, tree);
|
|
28384
|
+
}
|
|
28385
|
+
async function importSelectedFiles(selectedFiles, options, tree) {
|
|
28228
28386
|
var _a2;
|
|
28229
|
-
|
|
28230
|
-
|
|
28231
|
-
|
|
28232
|
-
|
|
28233
|
-
|
|
28234
|
-
|
|
28235
|
-
|
|
28236
|
-
|
|
28237
|
-
|
|
28238
|
-
|
|
28239
|
-
|
|
28387
|
+
throwIfCancelled(options.signal);
|
|
28388
|
+
const files = [...selectedFiles];
|
|
28389
|
+
const treePaths = [];
|
|
28390
|
+
if (tree) {
|
|
28391
|
+
const walk = (dir, parent) => {
|
|
28392
|
+
validateName(dir.name);
|
|
28393
|
+
const names = /* @__PURE__ */ new Set();
|
|
28394
|
+
for (const child of dir.children) {
|
|
28395
|
+
const name = child.kind === "file" ? child.file.name : child.name;
|
|
28396
|
+
validateName(name);
|
|
28397
|
+
if (names.has(name))
|
|
28398
|
+
throw new NdmError("IMPORT_PATH_CONFLICT", `Duplicate child: ${parent}/${name}`);
|
|
28399
|
+
names.add(name);
|
|
28400
|
+
if (child.kind === "file") {
|
|
28401
|
+
files.push(child.file);
|
|
28402
|
+
treePaths.push(`${parent}/${name}`);
|
|
28403
|
+
} else
|
|
28404
|
+
walk(child, `${parent}/${child.name}`);
|
|
28405
|
+
}
|
|
28406
|
+
};
|
|
28407
|
+
walk(tree, tree.name);
|
|
28408
|
+
}
|
|
28409
|
+
if (!tree && files.length === 0)
|
|
28410
|
+
throw new NdmError(options.mode === "single_dir" ? "EMPTY_DIRECTORY_UNAVAILABLE" : "USER_CANCELLED", options.mode === "single_dir" ? "FileList cannot represent empty directories; use importDirectory" : "No files selected");
|
|
28411
|
+
if (options.mode === "single_file" && files.length !== 1)
|
|
28412
|
+
throw new NdmError("INVALID_IMPORT_PATH", "single_file requires exactly one file");
|
|
28413
|
+
files.forEach((file) => {
|
|
28414
|
+
validateName(file.name);
|
|
28415
|
+
if (file.webkitRelativePath)
|
|
28416
|
+
validatePath(file.webkitRelativePath);
|
|
28417
|
+
});
|
|
28418
|
+
if (!tree && options.mode === "single_dir")
|
|
28419
|
+
buildDirTree(files, files.map((file) => ({ kind: "file", objectId: "", name: file.name, size: file.size })));
|
|
28420
|
+
const warnings = [];
|
|
28421
|
+
if (!tree && options.mode === "single_dir")
|
|
28422
|
+
warnings.push("FileList selections cannot preserve empty directories");
|
|
28423
|
+
const manifest = /* @__PURE__ */ new Map();
|
|
28424
|
+
const qcidLinks = [];
|
|
28425
|
+
const requestOptions = { endpoint: options.endpoint, sessionToken: options.sessionToken, fetcher: options.fetcher, headers: options.headers, signal: options.signal };
|
|
28240
28426
|
const fileObjects = [];
|
|
28241
28427
|
const objectStates = /* @__PURE__ */ new Map();
|
|
28242
28428
|
let allFilesAlreadyStored = true;
|
|
@@ -28244,11 +28430,12 @@ async function pickupAndImport(options) {
|
|
|
28244
28430
|
const fileCount = files.length;
|
|
28245
28431
|
for (let fi = 0; fi < files.length; fi++) {
|
|
28246
28432
|
const file = files[fi];
|
|
28247
|
-
|
|
28433
|
+
throwIfCancelled(options.signal);
|
|
28434
|
+
const relativePath = treePaths[fi] || file.webkitRelativePath || void 0;
|
|
28248
28435
|
if (onProgress) {
|
|
28249
28436
|
onProgress({ phase: "qcid_lookup", fileIndex: fi, fileCount, fileName: file.name, fileTotalBytes: file.size });
|
|
28250
28437
|
}
|
|
28251
|
-
const lookupHit = await lookupFileByQcid(file);
|
|
28438
|
+
const lookupHit = await lookupFileByQcid(file, requestOptions, warnings);
|
|
28252
28439
|
let materialized = null;
|
|
28253
28440
|
if (!lookupHit) {
|
|
28254
28441
|
if (onProgress) {
|
|
@@ -28258,12 +28445,25 @@ async function pickupAndImport(options) {
|
|
|
28258
28445
|
file,
|
|
28259
28446
|
onProgress ? (bytesHashed) => {
|
|
28260
28447
|
onProgress({ phase: "materializing", fileIndex: fi, fileCount, fileName: file.name, bytesProcessed: bytesHashed, fileTotalBytes: file.size });
|
|
28261
|
-
} : void 0
|
|
28448
|
+
} : void 0,
|
|
28449
|
+
DEFAULT_CHUNK_SIZE,
|
|
28450
|
+
options.signal
|
|
28262
28451
|
);
|
|
28263
28452
|
}
|
|
28264
28453
|
const objectId = (lookupHit == null ? void 0 : lookupHit.objectId) ?? materialized.objectId;
|
|
28265
28454
|
const fileObject = (lookupHit == null ? void 0 : lookupHit.fileObject) ?? materialized.fileObject;
|
|
28266
28455
|
const chunks = lookupHit ? [] : materialized.chunks;
|
|
28456
|
+
if (materialized)
|
|
28457
|
+
for (const object2 of materialized.objects)
|
|
28458
|
+
manifest.set(object2.obj_id, object2);
|
|
28459
|
+
else {
|
|
28460
|
+
const [, objData] = new FileObject(file.name, file.size, fileObject.content).genObjId();
|
|
28461
|
+
manifest.set(objectId, { obj_id: objectId, obj_data: objData });
|
|
28462
|
+
}
|
|
28463
|
+
const qcid = (lookupHit == null ? void 0 : lookupHit.qcid) ?? await tryCalculateQcidFromFile(file);
|
|
28464
|
+
if (qcid)
|
|
28465
|
+
qcidLinks.push({ qcid, content_id: fileObject.content, size: file.size });
|
|
28466
|
+
throwIfCancelled(options.signal);
|
|
28267
28467
|
const imported = {
|
|
28268
28468
|
kind: "file",
|
|
28269
28469
|
objectId,
|
|
@@ -28306,7 +28506,10 @@ async function pickupAndImport(options) {
|
|
|
28306
28506
|
let items;
|
|
28307
28507
|
let selection;
|
|
28308
28508
|
if (options.mode === "single_dir") {
|
|
28309
|
-
|
|
28509
|
+
let index = 0;
|
|
28510
|
+
const rebuild = (node) => ({ kind: "dir", name: node.name, objectId: "", children: node.children.map((child) => child.kind === "file" ? fileObjects[index++] : rebuild(child)) });
|
|
28511
|
+
const dirObj = tree ? rebuild(tree) : buildDirTree(files, fileObjects);
|
|
28512
|
+
computeDirObjectIds(dirObj, manifest);
|
|
28310
28513
|
items = [dirObj];
|
|
28311
28514
|
selection = dirObj;
|
|
28312
28515
|
} else {
|
|
@@ -28319,32 +28522,35 @@ async function pickupAndImport(options) {
|
|
|
28319
28522
|
}
|
|
28320
28523
|
const summary = collectSummary(items);
|
|
28321
28524
|
const sessionId = generateSessionId();
|
|
28322
|
-
|
|
28323
|
-
|
|
28324
|
-
materializationStatus = "all_in_store";
|
|
28325
|
-
} else if (caps.canUseNDMCache) {
|
|
28326
|
-
materializationStatus = "on_cache";
|
|
28327
|
-
}
|
|
28328
|
-
const uploadStatus = materializationStatus === "all_in_store" ? "not_required" : "not_started";
|
|
28525
|
+
const materializationStatus = allFilesAlreadyStored ? "all_in_store" : "ok";
|
|
28526
|
+
const uploadStatus = "not_started";
|
|
28329
28527
|
const session = {
|
|
28330
28528
|
sessionId,
|
|
28331
28529
|
items,
|
|
28332
28530
|
materializationStatus,
|
|
28333
28531
|
uploadStatus,
|
|
28334
28532
|
summary,
|
|
28335
|
-
objectStates
|
|
28533
|
+
objectStates,
|
|
28534
|
+
objectStatus: "pending",
|
|
28535
|
+
warnings,
|
|
28536
|
+
manifest,
|
|
28537
|
+
qcidLinks,
|
|
28538
|
+
requestOptions,
|
|
28539
|
+
transmittedBytes: 0
|
|
28336
28540
|
};
|
|
28337
28541
|
sessionRegistry.set(sessionId, session);
|
|
28338
28542
|
const snapshot = {
|
|
28339
28543
|
sessionId,
|
|
28340
28544
|
selection,
|
|
28341
28545
|
items,
|
|
28546
|
+
objectStatus: "pending",
|
|
28547
|
+
warnings,
|
|
28342
28548
|
materializationStatus,
|
|
28343
28549
|
uploadStatus,
|
|
28344
28550
|
summary
|
|
28345
28551
|
};
|
|
28346
28552
|
if (options.autoStartUpload && uploadStatus === "not_started") {
|
|
28347
|
-
startUpload(sessionId).catch(() => {
|
|
28553
|
+
startUpload(sessionId, { endpoint: options.endpoint, sessionToken: options.sessionToken, fetcher: options.fetcher, headers: options.headers, signal: options.signal }).catch(() => {
|
|
28348
28554
|
});
|
|
28349
28555
|
snapshot.uploadStatus = "uploading";
|
|
28350
28556
|
}
|
|
@@ -28358,21 +28564,27 @@ async function getImportSessionStatus(sessionId) {
|
|
|
28358
28564
|
const perObjectProgress = {};
|
|
28359
28565
|
let uploadedBytes = 0;
|
|
28360
28566
|
let uploadedObjects = 0;
|
|
28361
|
-
|
|
28362
|
-
|
|
28363
|
-
|
|
28364
|
-
|
|
28365
|
-
|
|
28366
|
-
|
|
28367
|
-
|
|
28368
|
-
|
|
28369
|
-
|
|
28370
|
-
|
|
28371
|
-
|
|
28567
|
+
const collect = (items) => {
|
|
28568
|
+
for (const item of items) {
|
|
28569
|
+
if (item.kind === "dir") {
|
|
28570
|
+
collect(item.children ?? []);
|
|
28571
|
+
continue;
|
|
28572
|
+
}
|
|
28573
|
+
const state = session.objectStates.get(item.objectId);
|
|
28574
|
+
perObjectProgress[item.objectId] = { objectId: item.objectId, uploadedBytes: state.uploadedBytes, totalBytes: state.size, state: state.state };
|
|
28575
|
+
uploadedBytes += state.uploadedBytes;
|
|
28576
|
+
if (state.state === "completed")
|
|
28577
|
+
uploadedObjects++;
|
|
28578
|
+
}
|
|
28579
|
+
};
|
|
28580
|
+
collect(session.items);
|
|
28372
28581
|
return {
|
|
28373
28582
|
sessionId,
|
|
28374
28583
|
materializationStatus: session.materializationStatus,
|
|
28375
28584
|
uploadStatus: session.uploadStatus,
|
|
28585
|
+
objectStatus: session.objectStatus,
|
|
28586
|
+
error: session.error,
|
|
28587
|
+
warnings: [...session.warnings],
|
|
28376
28588
|
summary: session.summary,
|
|
28377
28589
|
progress: {
|
|
28378
28590
|
uploadedBytes,
|
|
@@ -28388,6 +28600,10 @@ async function getUploadProgress(sessionId) {
|
|
|
28388
28600
|
const result = {
|
|
28389
28601
|
sessionId,
|
|
28390
28602
|
uploadStatus: status.uploadStatus,
|
|
28603
|
+
objectStatus: status.objectStatus,
|
|
28604
|
+
error: status.error,
|
|
28605
|
+
warnings: status.warnings,
|
|
28606
|
+
transmittedBytes: requireSession(sessionId).transmittedBytes,
|
|
28391
28607
|
totalBytes: status.progress.totalBytes,
|
|
28392
28608
|
uploadedBytes: status.progress.uploadedBytes,
|
|
28393
28609
|
totalObjects: status.progress.totalObjects,
|
|
@@ -28405,13 +28621,13 @@ async function getUploadProgress(sessionId) {
|
|
|
28405
28621
|
}
|
|
28406
28622
|
return result;
|
|
28407
28623
|
}
|
|
28408
|
-
async function uploadChunkViaTus(endpoint, file, chunkInfo, chunkIndex,
|
|
28624
|
+
async function uploadChunkViaTus(endpoint, file, chunkInfo, chunkIndex, fileHash, sessionToken, extraHeaders, onProgress, signal) {
|
|
28409
28625
|
const slice = file.slice(chunkInfo.offset, chunkInfo.offset + chunkInfo.length);
|
|
28410
28626
|
const chunkData = new Uint8Array(await slice.arrayBuffer());
|
|
28411
|
-
const logicalPath =
|
|
28627
|
+
const logicalPath = chunkInfo.chunkId;
|
|
28412
28628
|
let tusModule;
|
|
28413
28629
|
try {
|
|
28414
|
-
tusModule = await import("./tus_client-
|
|
28630
|
+
tusModule = await import("./tus_client-8fd4d937.mjs");
|
|
28415
28631
|
} catch (error) {
|
|
28416
28632
|
const message = error instanceof Error ? error.message : String(error);
|
|
28417
28633
|
throw new NdmError("UPLOAD_FAILED", `Failed to load tus-js-client: ${message}`);
|
|
@@ -28424,12 +28640,12 @@ async function uploadChunkViaTus(endpoint, file, chunkInfo, chunkIndex, appId, f
|
|
|
28424
28640
|
const blob = new Blob([chunkData]);
|
|
28425
28641
|
const upload = new tusModule.Upload(blob, {
|
|
28426
28642
|
endpoint: `${endpoint}/ndm/v1/uploads`,
|
|
28427
|
-
|
|
28643
|
+
...typeof XMLHttpRequest === "undefined" ? { httpStack: tusModule.fetchHttpStack } : {},
|
|
28644
|
+
headers: { ...extraHeaders, ...sessionToken ? { Authorization: `Bearer ${sessionToken}` } : {} },
|
|
28428
28645
|
chunkSize: chunkData.length,
|
|
28429
28646
|
retryDelays: [0, 1e3, 3e3, 5e3],
|
|
28430
28647
|
storeFingerprintForResuming: false,
|
|
28431
28648
|
metadata: {
|
|
28432
|
-
app_id: appId,
|
|
28433
28649
|
logical_path: logicalPath,
|
|
28434
28650
|
file_name: file.name,
|
|
28435
28651
|
file_size: String(file.size),
|
|
@@ -28443,109 +28659,209 @@ async function uploadChunkViaTus(endpoint, file, chunkInfo, chunkIndex, appId, f
|
|
|
28443
28659
|
},
|
|
28444
28660
|
onSuccess: () => {
|
|
28445
28661
|
onProgress(chunkData.length);
|
|
28662
|
+
signal == null ? void 0 : signal.removeEventListener("abort", onAbort);
|
|
28446
28663
|
resolve(chunkInfo.chunkId);
|
|
28447
28664
|
},
|
|
28448
28665
|
onError: (error) => {
|
|
28666
|
+
signal == null ? void 0 : signal.removeEventListener("abort", onAbort);
|
|
28449
28667
|
reject(new NdmError("UPLOAD_FAILED", error.message));
|
|
28450
28668
|
}
|
|
28451
28669
|
});
|
|
28452
|
-
|
|
28453
|
-
|
|
28454
|
-
|
|
28455
|
-
|
|
28456
|
-
|
|
28457
|
-
}
|
|
28670
|
+
const onAbort = () => {
|
|
28671
|
+
void Promise.resolve(upload.abort(true)).catch(() => void 0);
|
|
28672
|
+
reject(new NdmError("USER_CANCELLED", "Upload cancelled"));
|
|
28673
|
+
};
|
|
28674
|
+
signal == null ? void 0 : signal.addEventListener("abort", onAbort, { once: true });
|
|
28458
28675
|
upload.start();
|
|
28459
28676
|
});
|
|
28460
28677
|
}
|
|
28461
|
-
|
|
28678
|
+
function errorMessage(error) {
|
|
28679
|
+
return error instanceof Error ? error.message : String(error);
|
|
28680
|
+
}
|
|
28681
|
+
function throwIfCancelled(signal) {
|
|
28682
|
+
if (signal == null ? void 0 : signal.aborted)
|
|
28683
|
+
throw new NdmError("USER_CANCELLED", "Import cancelled");
|
|
28684
|
+
}
|
|
28685
|
+
function requireSession(sessionId) {
|
|
28462
28686
|
const session = sessionRegistry.get(sessionId);
|
|
28463
|
-
if (!session)
|
|
28687
|
+
if (!session)
|
|
28464
28688
|
throw new NdmError("SESSION_NOT_FOUND", `Session ${sessionId} not found`);
|
|
28465
|
-
|
|
28466
|
-
|
|
28467
|
-
|
|
28468
|
-
|
|
28469
|
-
|
|
28470
|
-
|
|
28471
|
-
}
|
|
28472
|
-
if (session.materializationStatus === "all_in_store") {
|
|
28473
|
-
session.uploadStatus = "not_required";
|
|
28689
|
+
return session;
|
|
28690
|
+
}
|
|
28691
|
+
async function startUpload(sessionId, options = {}) {
|
|
28692
|
+
var _a2;
|
|
28693
|
+
const session = requireSession(sessionId);
|
|
28694
|
+
if (session.objectStatus === "ready" || session.uploadPromise)
|
|
28474
28695
|
return getImportSessionStatus(sessionId);
|
|
28475
|
-
|
|
28696
|
+
const concurrency = options.concurrency ?? 3;
|
|
28697
|
+
if (!Number.isInteger(concurrency) || concurrency < 1)
|
|
28698
|
+
throw new NdmError("UPLOAD_FAILED", "concurrency must be a positive integer");
|
|
28699
|
+
throwIfCancelled(options.signal);
|
|
28700
|
+
session.requestOptions = { ...session.requestOptions, ...Object.fromEntries(Object.entries({ endpoint: options.endpoint, sessionToken: options.sessionToken, fetcher: options.fetcher, headers: options.headers }).filter(([, value]) => value !== void 0)) };
|
|
28701
|
+
const endpoint = session.requestOptions.endpoint ?? resolveImportLookupEndpoint();
|
|
28702
|
+
if (!endpoint)
|
|
28703
|
+
throw new NdmError("STORE_API_ENDPOINT_REQUIRED", "Pass endpoint or initialize the SDK before uploading");
|
|
28704
|
+
session.requestOptions.endpoint = normalizeEndpoint$1(endpoint);
|
|
28705
|
+
session.abortController = new AbortController();
|
|
28706
|
+
const cancel = () => {
|
|
28707
|
+
var _a3;
|
|
28708
|
+
return (_a3 = session.abortController) == null ? void 0 : _a3.abort();
|
|
28709
|
+
};
|
|
28710
|
+
(_a2 = options.signal) == null ? void 0 : _a2.addEventListener("abort", cancel, { once: true });
|
|
28711
|
+
session.requestOptions.signal = session.abortController.signal;
|
|
28476
28712
|
session.uploadStatus = "uploading";
|
|
28713
|
+
session.objectStatus = "pending";
|
|
28714
|
+
session.error = void 0;
|
|
28715
|
+
session.onProgress = options.onProgress;
|
|
28477
28716
|
session.uploadStartTime = Date.now();
|
|
28478
|
-
session.
|
|
28479
|
-
|
|
28480
|
-
|
|
28481
|
-
|
|
28482
|
-
|
|
28483
|
-
|
|
28484
|
-
|
|
28485
|
-
}
|
|
28486
|
-
|
|
28487
|
-
|
|
28717
|
+
session.uploadPromise = doUpload(session, concurrency).catch((error) => {
|
|
28718
|
+
var _a3;
|
|
28719
|
+
session.error = errorMessage(error);
|
|
28720
|
+
const cancelled = (_a3 = session.abortController) == null ? void 0 : _a3.signal.aborted;
|
|
28721
|
+
session.uploadStatus = cancelled ? "cancelled" : "failed";
|
|
28722
|
+
session.objectStatus = cancelled ? "cancelled" : "failed";
|
|
28723
|
+
throw error;
|
|
28724
|
+
}).finally(() => {
|
|
28725
|
+
var _a3;
|
|
28726
|
+
session.uploadPromise = void 0;
|
|
28727
|
+
(_a3 = options.signal) == null ? void 0 : _a3.removeEventListener("abort", cancel);
|
|
28728
|
+
emitProgress(session);
|
|
28488
28729
|
});
|
|
28730
|
+
void session.uploadPromise.catch(() => void 0);
|
|
28489
28731
|
return getImportSessionStatus(sessionId);
|
|
28490
28732
|
}
|
|
28491
|
-
async function
|
|
28492
|
-
|
|
28493
|
-
|
|
28494
|
-
|
|
28495
|
-
|
|
28496
|
-
|
|
28497
|
-
|
|
28498
|
-
|
|
28499
|
-
|
|
28500
|
-
|
|
28501
|
-
|
|
28502
|
-
|
|
28503
|
-
|
|
28504
|
-
|
|
28505
|
-
|
|
28506
|
-
|
|
28507
|
-
|
|
28508
|
-
|
|
28509
|
-
|
|
28510
|
-
|
|
28511
|
-
|
|
28512
|
-
|
|
28513
|
-
|
|
28514
|
-
|
|
28515
|
-
|
|
28516
|
-
|
|
28517
|
-
|
|
28518
|
-
}
|
|
28519
|
-
});
|
|
28520
|
-
}
|
|
28733
|
+
async function ensureUploaded(sessionId, options = {}) {
|
|
28734
|
+
await startUpload(sessionId, options);
|
|
28735
|
+
const session = requireSession(sessionId);
|
|
28736
|
+
await session.uploadPromise;
|
|
28737
|
+
if (session.objectStatus !== "ready")
|
|
28738
|
+
throw new NdmError("OBJECT_NOT_READY", session.error ?? "Objects are not ready");
|
|
28739
|
+
return getImportSessionStatus(sessionId);
|
|
28740
|
+
}
|
|
28741
|
+
function cancelImportSession(sessionId) {
|
|
28742
|
+
var _a2;
|
|
28743
|
+
const session = requireSession(sessionId);
|
|
28744
|
+
if (session.objectStatus === "ready")
|
|
28745
|
+
return;
|
|
28746
|
+
(_a2 = session.abortController) == null ? void 0 : _a2.abort();
|
|
28747
|
+
session.uploadStatus = "cancelled";
|
|
28748
|
+
session.objectStatus = "cancelled";
|
|
28749
|
+
}
|
|
28750
|
+
function releaseImportSession(sessionId) {
|
|
28751
|
+
const session = requireSession(sessionId);
|
|
28752
|
+
cancelImportSession(sessionId);
|
|
28753
|
+
sessionRegistry.delete(sessionId);
|
|
28754
|
+
const release = (items) => items.forEach((item) => {
|
|
28755
|
+
if (item.kind === "dir")
|
|
28756
|
+
release(item.children ?? []);
|
|
28757
|
+
else {
|
|
28758
|
+
delete item._file;
|
|
28759
|
+
delete item._ndnFileObject;
|
|
28521
28760
|
}
|
|
28522
|
-
next();
|
|
28523
28761
|
});
|
|
28762
|
+
release(session.items);
|
|
28524
28763
|
}
|
|
28525
|
-
|
|
28526
|
-
|
|
28527
|
-
|
|
28528
|
-
|
|
28529
|
-
|
|
28530
|
-
|
|
28531
|
-
await uploadChunkViaTus(
|
|
28532
|
-
endpoint,
|
|
28533
|
-
state.file,
|
|
28534
|
-
chunk,
|
|
28535
|
-
chunkIndex,
|
|
28536
|
-
"default",
|
|
28537
|
-
state.objectId,
|
|
28538
|
-
await sessionToken(),
|
|
28539
|
-
(uploaded) => {
|
|
28540
|
-
const prevChunkBytes = state.chunks.filter((c) => c !== chunk && c.uploaded).reduce((sum, c) => sum + c.length, 0);
|
|
28541
|
-
state.uploadedBytes = prevChunkBytes + uploaded;
|
|
28542
|
-
},
|
|
28543
|
-
(_a2 = session.abortController) == null ? void 0 : _a2.signal
|
|
28544
|
-
);
|
|
28545
|
-
chunk.uploaded = true;
|
|
28764
|
+
function emitProgress(session) {
|
|
28765
|
+
if (session.onProgress && sessionRegistry.has(session.sessionId)) {
|
|
28766
|
+
void getUploadProgress(session.sessionId).then((progress) => {
|
|
28767
|
+
var _a2;
|
|
28768
|
+
return (_a2 = session.onProgress) == null ? void 0 : _a2.call(session, progress);
|
|
28769
|
+
}).catch(() => void 0);
|
|
28546
28770
|
}
|
|
28547
|
-
|
|
28548
|
-
|
|
28771
|
+
}
|
|
28772
|
+
async function doUpload(session, concurrency) {
|
|
28773
|
+
var _a2;
|
|
28774
|
+
const states = [...session.objectStates.values()];
|
|
28775
|
+
const chunkTasks = /* @__PURE__ */ new Map();
|
|
28776
|
+
let index = 0;
|
|
28777
|
+
let failure;
|
|
28778
|
+
const workers = Array.from({ length: Math.min(concurrency, states.length) }, async () => {
|
|
28779
|
+
var _a3, _b;
|
|
28780
|
+
while (index < states.length && !failure) {
|
|
28781
|
+
const state = states[index++];
|
|
28782
|
+
try {
|
|
28783
|
+
throwIfCancelled((_a3 = session.abortController) == null ? void 0 : _a3.signal);
|
|
28784
|
+
if (state.state === "completed")
|
|
28785
|
+
continue;
|
|
28786
|
+
state.state = "uploading";
|
|
28787
|
+
for (const [chunkIndex, chunk] of state.chunks.entries()) {
|
|
28788
|
+
throwIfCancelled((_b = session.abortController) == null ? void 0 : _b.signal);
|
|
28789
|
+
if (chunk.uploaded)
|
|
28790
|
+
continue;
|
|
28791
|
+
let task = chunkTasks.get(chunk.chunkId);
|
|
28792
|
+
if (!task) {
|
|
28793
|
+
task = uploadMissingChunk(session, state, chunk, chunkIndex);
|
|
28794
|
+
chunkTasks.set(chunk.chunkId, task);
|
|
28795
|
+
}
|
|
28796
|
+
await task;
|
|
28797
|
+
chunk.uploaded = true;
|
|
28798
|
+
state.uploadedBytes = state.chunks.filter((c) => c.uploaded).reduce((sum, c) => sum + c.length, 0);
|
|
28799
|
+
emitProgress(session);
|
|
28800
|
+
}
|
|
28801
|
+
state.uploadedBytes = state.size;
|
|
28802
|
+
state.state = "completed";
|
|
28803
|
+
} catch (error) {
|
|
28804
|
+
state.state = "failed";
|
|
28805
|
+
failure = error;
|
|
28806
|
+
}
|
|
28807
|
+
}
|
|
28808
|
+
});
|
|
28809
|
+
await Promise.all(workers);
|
|
28810
|
+
if (failure)
|
|
28811
|
+
throw failure;
|
|
28812
|
+
throwIfCancelled((_a2 = session.abortController) == null ? void 0 : _a2.signal);
|
|
28813
|
+
session.objectStatus = "finalizing";
|
|
28814
|
+
emitProgress(session);
|
|
28815
|
+
const options = session.requestOptions;
|
|
28816
|
+
const token = options.sessionToken !== void 0 ? options.sessionToken : await getActiveSessionToken();
|
|
28817
|
+
const response = await (options.fetcher ?? defaultStoreFetcher)(`${options.endpoint}/ndm/v1/import/finalize`, {
|
|
28818
|
+
method: "POST",
|
|
28819
|
+
credentials: "include",
|
|
28820
|
+
signal: options.signal,
|
|
28821
|
+
headers: { ...options.headers, "Content-Type": "application/json", ...token ? { Authorization: `Bearer ${token}` } : {} },
|
|
28822
|
+
body: JSON.stringify({ objects: [...session.manifest.values()], roots: session.items.map((item) => item.objectId), qcid_links: session.qcidLinks })
|
|
28823
|
+
});
|
|
28824
|
+
const body = await response.json();
|
|
28825
|
+
if (!response.ok)
|
|
28826
|
+
throw new NdmStoreApiError(response.status, body.error, body.message ?? "Object registration failed", body);
|
|
28827
|
+
throwIfCancelled(options.signal);
|
|
28828
|
+
if (Array.isArray(body.warnings))
|
|
28829
|
+
session.warnings.push(...body.warnings.map(String));
|
|
28830
|
+
if (body.ready !== true || !Array.isArray(body.roots) || session.items.some((item) => !body.roots.some((root) => root.obj_id === item.objectId && root.ready === true))) {
|
|
28831
|
+
throw new NdmError("OBJECT_NOT_READY", "NDM did not confirm all root objects and their dependencies are ready");
|
|
28832
|
+
}
|
|
28833
|
+
session.objectStatus = "ready";
|
|
28834
|
+
session.uploadStatus = session.transmittedBytes === 0 ? "not_required" : "completed";
|
|
28835
|
+
session.materializationStatus = "all_in_store";
|
|
28836
|
+
emitProgress(session);
|
|
28837
|
+
}
|
|
28838
|
+
async function uploadMissingChunk(session, state, chunk, chunkIndex) {
|
|
28839
|
+
var _a2, _b;
|
|
28840
|
+
try {
|
|
28841
|
+
const found = await lookupObject({ scope: "app", quick_hash: chunk.chunkId }, session.requestOptions);
|
|
28842
|
+
if (found.reusable === true && "state" in found && ["completed", "same_as", "local_link"].includes(found.state) && found.chunk_size === chunk.length)
|
|
28843
|
+
return;
|
|
28844
|
+
} catch (error) {
|
|
28845
|
+
throwIfCancelled((_a2 = session.abortController) == null ? void 0 : _a2.signal);
|
|
28846
|
+
if (!(error instanceof NdmStoreApiError && error.status === 404))
|
|
28847
|
+
session.warnings.push(`Chunk lookup: ${errorMessage(error)}`);
|
|
28848
|
+
}
|
|
28849
|
+
const token = session.requestOptions.sessionToken !== void 0 ? session.requestOptions.sessionToken : await getActiveSessionToken();
|
|
28850
|
+
await uploadChunkViaTus(
|
|
28851
|
+
session.requestOptions.endpoint,
|
|
28852
|
+
state.file,
|
|
28853
|
+
chunk,
|
|
28854
|
+
chunkIndex,
|
|
28855
|
+
state.objectId,
|
|
28856
|
+
token,
|
|
28857
|
+
session.requestOptions.headers,
|
|
28858
|
+
(uploaded) => {
|
|
28859
|
+
state.uploadedBytes = state.chunks.filter((c) => c.uploaded).reduce((sum, c) => sum + c.length, 0) + uploaded;
|
|
28860
|
+
emitProgress(session);
|
|
28861
|
+
},
|
|
28862
|
+
(_b = session.abortController) == null ? void 0 : _b.signal
|
|
28863
|
+
);
|
|
28864
|
+
session.transmittedBytes += chunk.length;
|
|
28549
28865
|
}
|
|
28550
28866
|
const ndm_client = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
28551
28867
|
__proto__: null,
|
|
@@ -28555,7 +28871,9 @@ const ndm_client = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
|
|
|
28555
28871
|
anchorState: anchorState$1,
|
|
28556
28872
|
applyEdge: applyEdge$1,
|
|
28557
28873
|
calculateQcidFromFile,
|
|
28874
|
+
cancelImportSession,
|
|
28558
28875
|
debugDumpExpandState: debugDumpExpandState$1,
|
|
28876
|
+
ensureUploaded,
|
|
28559
28877
|
forcedGcUntil: forcedGcUntil$1,
|
|
28560
28878
|
fsAcquire: fsAcquire$1,
|
|
28561
28879
|
fsAnchorState: fsAnchorState$1,
|
|
@@ -28567,6 +28885,8 @@ const ndm_client = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
|
|
|
28567
28885
|
getObject: getObject$1,
|
|
28568
28886
|
getUploadProgress,
|
|
28569
28887
|
haveChunk: haveChunk$1,
|
|
28888
|
+
importDirectory,
|
|
28889
|
+
importFiles,
|
|
28570
28890
|
isObjectExist: isObjectExist$1,
|
|
28571
28891
|
isObjectStored: isObjectStored$1,
|
|
28572
28892
|
lookupObject,
|
|
@@ -28577,6 +28897,7 @@ const ndm_client = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
|
|
|
28577
28897
|
putObject: putObject$1,
|
|
28578
28898
|
queryChunkState: queryChunkState$1,
|
|
28579
28899
|
queryObjectById: queryObjectById$1,
|
|
28900
|
+
releaseImportSession,
|
|
28580
28901
|
removeChunk: removeChunk$1,
|
|
28581
28902
|
removeObject: removeObject$1,
|
|
28582
28903
|
setImportProvider,
|
|
@@ -29134,6 +29455,279 @@ const ndm_proxy = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePro
|
|
|
29134
29455
|
unpin,
|
|
29135
29456
|
unpinOwner
|
|
29136
29457
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
29458
|
+
class ExecutorClient {
|
|
29459
|
+
constructor(serviceUrl, token = null, options = {}) {
|
|
29460
|
+
this.rpc = new kRPCClient(serviceUrl, token, null, options);
|
|
29461
|
+
}
|
|
29462
|
+
syncSessionToken(token) {
|
|
29463
|
+
this.rpc.setSessionToken(token);
|
|
29464
|
+
}
|
|
29465
|
+
createDevice(input) {
|
|
29466
|
+
return this.rpc.call("executor.device.create", input);
|
|
29467
|
+
}
|
|
29468
|
+
listDevices() {
|
|
29469
|
+
return this.rpc.call("executor.device.list", {});
|
|
29470
|
+
}
|
|
29471
|
+
issueAccess(executor_id, expires_at_ms) {
|
|
29472
|
+
return this.rpc.call("executor.device.issue", { executor_id, expires_at_ms });
|
|
29473
|
+
}
|
|
29474
|
+
revokeAccess(executor_id) {
|
|
29475
|
+
return this.rpc.call("executor.device.revoke", { executor_id });
|
|
29476
|
+
}
|
|
29477
|
+
deleteDevice(executor_id) {
|
|
29478
|
+
return this.rpc.call("executor.device.delete", { executor_id });
|
|
29479
|
+
}
|
|
29480
|
+
listOnline() {
|
|
29481
|
+
return this.rpc.call("executor.online.list", {});
|
|
29482
|
+
}
|
|
29483
|
+
async *watchOnline(signal, intervalMs = 5e3) {
|
|
29484
|
+
if (intervalMs < 250)
|
|
29485
|
+
throw new Error("Watch interval must be at least 250 ms");
|
|
29486
|
+
let previous = "";
|
|
29487
|
+
while (!(signal == null ? void 0 : signal.aborted)) {
|
|
29488
|
+
const { executors } = await this.listOnline();
|
|
29489
|
+
const next = JSON.stringify(executors);
|
|
29490
|
+
if (next !== previous) {
|
|
29491
|
+
previous = next;
|
|
29492
|
+
yield executors;
|
|
29493
|
+
}
|
|
29494
|
+
await new Promise((resolve) => {
|
|
29495
|
+
const done = () => {
|
|
29496
|
+
clearTimeout(timer);
|
|
29497
|
+
signal == null ? void 0 : signal.removeEventListener("abort", done);
|
|
29498
|
+
resolve();
|
|
29499
|
+
};
|
|
29500
|
+
const timer = setTimeout(done, intervalMs);
|
|
29501
|
+
signal == null ? void 0 : signal.addEventListener("abort", done, { once: true });
|
|
29502
|
+
if (signal == null ? void 0 : signal.aborted)
|
|
29503
|
+
done();
|
|
29504
|
+
});
|
|
29505
|
+
}
|
|
29506
|
+
}
|
|
29507
|
+
openRoute(target) {
|
|
29508
|
+
return this.rpc.call("executor.stream.open", {
|
|
29509
|
+
executor_id: target.executor_id,
|
|
29510
|
+
generation: target.generation,
|
|
29511
|
+
profile_id: target.profile_id
|
|
29512
|
+
});
|
|
29513
|
+
}
|
|
29514
|
+
async connect(target, sessionToken, runtimeId, runId) {
|
|
29515
|
+
const route = await this.openRoute(target);
|
|
29516
|
+
return ExecutorCommandStream.connect(route, target, sessionToken, runtimeId, runId);
|
|
29517
|
+
}
|
|
29518
|
+
}
|
|
29519
|
+
class ExecutorStreamError extends Error {
|
|
29520
|
+
constructor(message, code = "unavailable", effectUnknown = false) {
|
|
29521
|
+
super(message);
|
|
29522
|
+
this.code = code;
|
|
29523
|
+
this.effectUnknown = effectUnknown;
|
|
29524
|
+
this.name = "ExecutorStreamError";
|
|
29525
|
+
}
|
|
29526
|
+
}
|
|
29527
|
+
function encodeExecutorControl(message) {
|
|
29528
|
+
const payload = new TextEncoder().encode(JSON.stringify(message));
|
|
29529
|
+
if (payload.length > 1024 * 1024)
|
|
29530
|
+
throw new Error("Executor control frame exceeds 1 MiB");
|
|
29531
|
+
const frame = new Uint8Array(5 + payload.length);
|
|
29532
|
+
frame[0] = 1;
|
|
29533
|
+
new DataView(frame.buffer).setUint32(1, payload.length);
|
|
29534
|
+
frame.set(payload, 5);
|
|
29535
|
+
return frame;
|
|
29536
|
+
}
|
|
29537
|
+
class ExecutorCommandStream {
|
|
29538
|
+
constructor(socket, target, runId) {
|
|
29539
|
+
this.socket = socket;
|
|
29540
|
+
this.target = target;
|
|
29541
|
+
this.runId = runId;
|
|
29542
|
+
this.buffer = new Uint8Array();
|
|
29543
|
+
this.sequence = 0;
|
|
29544
|
+
this.pending = /* @__PURE__ */ new Map();
|
|
29545
|
+
this.closed = false;
|
|
29546
|
+
socket.binaryType = "arraybuffer";
|
|
29547
|
+
socket.onmessage = (event) => {
|
|
29548
|
+
if (!(event.data instanceof ArrayBuffer)) {
|
|
29549
|
+
this.fail(new ExecutorStreamError("Expected binary Command Stream"));
|
|
29550
|
+
return;
|
|
29551
|
+
}
|
|
29552
|
+
try {
|
|
29553
|
+
this.receive(new Uint8Array(event.data));
|
|
29554
|
+
} catch {
|
|
29555
|
+
this.fail(new ExecutorStreamError("Invalid Command Stream frame", "protocol"));
|
|
29556
|
+
}
|
|
29557
|
+
};
|
|
29558
|
+
socket.onclose = () => this.fail(new ExecutorStreamError("Executor disconnected; query the persisted operation locator before taking further action", "unavailable", true));
|
|
29559
|
+
socket.onerror = () => this.fail(new ExecutorStreamError("Executor transport failed", "unavailable", true));
|
|
29560
|
+
}
|
|
29561
|
+
static async connect(route, target, token, runtimeId, runId) {
|
|
29562
|
+
if (route.executor_id !== target.executor_id || route.generation !== target.generation || route.profile_id !== target.profile_id || route.expires_at_ms <= Date.now()) {
|
|
29563
|
+
throw new ExecutorStreamError("Route does not match the requested active executor", "stale_target");
|
|
29564
|
+
}
|
|
29565
|
+
const url = new URL(route.ws_url);
|
|
29566
|
+
if (url.protocol !== "wss:" && !(url.protocol === "ws:" && ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname))) {
|
|
29567
|
+
throw new ExecutorStreamError("Executor routes require WSS");
|
|
29568
|
+
}
|
|
29569
|
+
if (url.username || url.password || url.hash)
|
|
29570
|
+
throw new ExecutorStreamError("Invalid executor route URL");
|
|
29571
|
+
const socket = new WebSocket(url);
|
|
29572
|
+
await new Promise((resolve, reject) => {
|
|
29573
|
+
const timer = setTimeout(() => {
|
|
29574
|
+
socket.close();
|
|
29575
|
+
reject(new ExecutorStreamError("Route authentication timed out"));
|
|
29576
|
+
}, 1e4);
|
|
29577
|
+
socket.onopen = () => socket.send(JSON.stringify({ ticket: route.ticket }));
|
|
29578
|
+
socket.onmessage = (event) => {
|
|
29579
|
+
try {
|
|
29580
|
+
if (typeof event.data !== "string" || JSON.parse(event.data).ready !== true)
|
|
29581
|
+
throw new Error();
|
|
29582
|
+
clearTimeout(timer);
|
|
29583
|
+
resolve();
|
|
29584
|
+
} catch {
|
|
29585
|
+
clearTimeout(timer);
|
|
29586
|
+
socket.close();
|
|
29587
|
+
reject(new ExecutorStreamError("Route authentication failed"));
|
|
29588
|
+
}
|
|
29589
|
+
};
|
|
29590
|
+
socket.onerror = socket.onclose = () => {
|
|
29591
|
+
clearTimeout(timer);
|
|
29592
|
+
reject(new ExecutorStreamError("Unable to connect executor route"));
|
|
29593
|
+
};
|
|
29594
|
+
});
|
|
29595
|
+
const client = new ExecutorCommandStream(socket, target, runId);
|
|
29596
|
+
try {
|
|
29597
|
+
const login = await client.request("login", { v: 1, token, profile: target.profile_id, client: { runtime_id: runtimeId, run_id: runId } });
|
|
29598
|
+
if (login.type !== "login_ok" || login.store_id !== target.store_id)
|
|
29599
|
+
throw new ExecutorStreamError("Executor ledger changed", "store_mismatch");
|
|
29600
|
+
return client;
|
|
29601
|
+
} catch (error) {
|
|
29602
|
+
client.close();
|
|
29603
|
+
throw error;
|
|
29604
|
+
}
|
|
29605
|
+
}
|
|
29606
|
+
receive(bytes2) {
|
|
29607
|
+
const merged = new Uint8Array(this.buffer.length + bytes2.length);
|
|
29608
|
+
merged.set(this.buffer);
|
|
29609
|
+
merged.set(bytes2, this.buffer.length);
|
|
29610
|
+
this.buffer = merged;
|
|
29611
|
+
while (this.buffer.length >= 5) {
|
|
29612
|
+
const length = new DataView(this.buffer.buffer, this.buffer.byteOffset).getUint32(1);
|
|
29613
|
+
if (length > 1024 * 1024 || ![1, 2].includes(this.buffer[0]))
|
|
29614
|
+
throw new Error();
|
|
29615
|
+
if (this.buffer.length < length + 5)
|
|
29616
|
+
return;
|
|
29617
|
+
const kind = this.buffer[0];
|
|
29618
|
+
const payload = this.buffer.slice(5, length + 5);
|
|
29619
|
+
this.buffer = this.buffer.slice(length + 5);
|
|
29620
|
+
if (kind !== 1)
|
|
29621
|
+
continue;
|
|
29622
|
+
const reply = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(payload));
|
|
29623
|
+
if (reply.type === "closing") {
|
|
29624
|
+
this.fail(new ExecutorStreamError("Executor stopped accepting requests"));
|
|
29625
|
+
return;
|
|
29626
|
+
}
|
|
29627
|
+
const pending = reply.request_id && this.pending.get(reply.request_id);
|
|
29628
|
+
if (!pending)
|
|
29629
|
+
continue;
|
|
29630
|
+
this.pending.delete(reply.request_id);
|
|
29631
|
+
clearTimeout(pending.timer);
|
|
29632
|
+
if (reply.error)
|
|
29633
|
+
pending.reject(new ExecutorStreamError(reply.error.message, reply.error.code, reply.error.effect_unknown));
|
|
29634
|
+
else
|
|
29635
|
+
pending.resolve(reply);
|
|
29636
|
+
}
|
|
29637
|
+
}
|
|
29638
|
+
fail(error) {
|
|
29639
|
+
if (this.closed)
|
|
29640
|
+
return;
|
|
29641
|
+
this.closed = true;
|
|
29642
|
+
for (const item of this.pending.values()) {
|
|
29643
|
+
clearTimeout(item.timer);
|
|
29644
|
+
item.reject(error);
|
|
29645
|
+
}
|
|
29646
|
+
this.pending.clear();
|
|
29647
|
+
this.socket.close();
|
|
29648
|
+
}
|
|
29649
|
+
close() {
|
|
29650
|
+
this.fail(new ExecutorStreamError("Executor stream closed", "unavailable", true));
|
|
29651
|
+
}
|
|
29652
|
+
request(type, params = {}, timeoutMs = 4e4) {
|
|
29653
|
+
if (this.closed)
|
|
29654
|
+
return Promise.reject(new ExecutorStreamError("Executor stream is closed"));
|
|
29655
|
+
const request_id = `q${++this.sequence}`;
|
|
29656
|
+
return new Promise((resolve, reject) => {
|
|
29657
|
+
const timer = setTimeout(() => {
|
|
29658
|
+
this.pending.delete(request_id);
|
|
29659
|
+
reject(new ExecutorStreamError("Executor response timed out; query operation before retrying", "unavailable", true));
|
|
29660
|
+
}, timeoutMs);
|
|
29661
|
+
this.pending.set(request_id, { resolve, reject, timer });
|
|
29662
|
+
try {
|
|
29663
|
+
this.socket.send(encodeExecutorControl({ ...params, type, request_id }));
|
|
29664
|
+
} catch {
|
|
29665
|
+
clearTimeout(timer);
|
|
29666
|
+
this.pending.delete(request_id);
|
|
29667
|
+
reject(new ExecutorStreamError("Unable to send request", "unavailable", true));
|
|
29668
|
+
}
|
|
29669
|
+
});
|
|
29670
|
+
}
|
|
29671
|
+
operation(locator) {
|
|
29672
|
+
if (locator.executor_id !== this.target.executor_id || locator.store_id !== this.target.store_id || locator.profile_id !== this.target.profile_id) {
|
|
29673
|
+
throw new ExecutorStreamError("Operation locator belongs to another executor, profile or ledger", "store_mismatch");
|
|
29674
|
+
}
|
|
29675
|
+
return { store_id: locator.store_id, op_id: locator.op_id, run_id: locator.run_id, call_id: locator.call_id };
|
|
29676
|
+
}
|
|
29677
|
+
fresh(locator) {
|
|
29678
|
+
if (locator.generation !== this.target.generation)
|
|
29679
|
+
throw new ExecutorStreamError("Cannot dispatch an old operation to a new connection generation", "stale_target");
|
|
29680
|
+
return this.operation(locator);
|
|
29681
|
+
}
|
|
29682
|
+
async describe(workdir) {
|
|
29683
|
+
const reply = await this.request("describe", { workdir });
|
|
29684
|
+
const described = reply.target;
|
|
29685
|
+
if (reply.type !== "describe_ok" || (described == null ? void 0 : described.executor_id) !== this.target.executor_id || (described == null ? void 0 : described.node_did) || (described == null ? void 0 : described.profile_id) !== this.target.profile_id || (described == null ? void 0 : described.store_id) !== this.target.store_id) {
|
|
29686
|
+
throw new ExecutorStreamError("Executor describe target changed", "stale_target");
|
|
29687
|
+
}
|
|
29688
|
+
return reply;
|
|
29689
|
+
}
|
|
29690
|
+
exec(locator, cmd, cwd, env_overrides = {}, execution_timeout_ms = 6e4) {
|
|
29691
|
+
return this.request("exec", { ...this.fresh(locator), cmd, cwd, env_overrides, execution_timeout_ms });
|
|
29692
|
+
}
|
|
29693
|
+
read(locator, path) {
|
|
29694
|
+
return this.request("read", { ...this.fresh(locator), path, offset: 0 });
|
|
29695
|
+
}
|
|
29696
|
+
edit(locator, path, edits) {
|
|
29697
|
+
return this.request("edit", { ...this.fresh(locator), path, edits });
|
|
29698
|
+
}
|
|
29699
|
+
async write(locator, path, content, mode = "replace") {
|
|
29700
|
+
const operation = this.fresh(locator);
|
|
29701
|
+
const id2 = new TextEncoder().encode(locator.op_id);
|
|
29702
|
+
if (id2.length === 0 || id2.length > 128)
|
|
29703
|
+
throw new Error("Invalid operation ID");
|
|
29704
|
+
const hash2 = Array.from(new Uint8Array(await crypto.subtle.digest("SHA-256", content))).map((value) => value.toString(16).padStart(2, "0")).join("");
|
|
29705
|
+
const accepted = this.request("write", { ...operation, path, mode, content_length: content.length, content_hash: `sha256:${hash2}` });
|
|
29706
|
+
for (let offset = 0; offset < content.length; offset += 16384) {
|
|
29707
|
+
const chunk = content.subarray(offset, offset + 16384);
|
|
29708
|
+
const frame = new Uint8Array(16 + id2.length + chunk.length);
|
|
29709
|
+
const view = new DataView(frame.buffer);
|
|
29710
|
+
frame[0] = 2;
|
|
29711
|
+
view.setUint32(1, frame.length - 5);
|
|
29712
|
+
frame[5] = 4;
|
|
29713
|
+
view.setBigUint64(6, BigInt(offset));
|
|
29714
|
+
view.setUint16(14, id2.length);
|
|
29715
|
+
frame.set(id2, 16);
|
|
29716
|
+
frame.set(chunk, 16 + id2.length);
|
|
29717
|
+
this.socket.send(frame);
|
|
29718
|
+
}
|
|
29719
|
+
this.socket.send(encodeExecutorControl({ type: "upload_end", request_id: `end${++this.sequence}`, op_id: locator.op_id }));
|
|
29720
|
+
return accepted;
|
|
29721
|
+
}
|
|
29722
|
+
query(locator, channel, offset = 0, wait_ms = 0) {
|
|
29723
|
+
this.operation(locator);
|
|
29724
|
+
return this.request("query", { store_id: locator.store_id, op_id: locator.op_id, channel, offset, max_bytes: 262144, wait_ms });
|
|
29725
|
+
}
|
|
29726
|
+
cancel(locator) {
|
|
29727
|
+
this.operation(locator);
|
|
29728
|
+
return this.request("cancel", { store_id: locator.store_id, op_id: locator.op_id });
|
|
29729
|
+
}
|
|
29730
|
+
}
|
|
29137
29731
|
export {
|
|
29138
29732
|
CONTACT_TAG_HOMESTATION_FOLLOWING as $,
|
|
29139
29733
|
NOTIFY_ACTION_DISMISS as A,
|
|
@@ -29302,6 +29896,13 @@ export {
|
|
|
29302
29896
|
BnsTxExecutorError as c5,
|
|
29303
29897
|
walletUserHasSnAccount as c6,
|
|
29304
29898
|
BnsTxExecutor as c7,
|
|
29899
|
+
ExecutorClient as c8,
|
|
29900
|
+
ExecutorStreamError as c9,
|
|
29901
|
+
encodeExecutorControl as ca,
|
|
29902
|
+
ExecutorCommandStream as cb,
|
|
29903
|
+
AIWORKSPACE_SERVICE_NAME as cc,
|
|
29904
|
+
AiwsFailure as cd,
|
|
29905
|
+
AiWorkspaceClient as ce,
|
|
29305
29906
|
BS_SERVICE_TASK_MANAGER as d,
|
|
29306
29907
|
getActiveRuntimeType as e,
|
|
29307
29908
|
getActiveZoneGatewayOrigin as f,
|
|
@@ -29326,4 +29927,4 @@ export {
|
|
|
29326
29927
|
NOTIFY_TEXT_CONTROL_ID as y,
|
|
29327
29928
|
NOTIFY_ACTION_ANSWER as z
|
|
29328
29929
|
};
|
|
29329
|
-
//# sourceMappingURL=
|
|
29930
|
+
//# sourceMappingURL=executor_client-d2c9e854.mjs.map
|