@tutti-os/workspace-file-reference 0.0.14 → 0.0.16
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/{chunk-7C3RZYQE.js → chunk-JURSITRX.js} +121 -3
- package/dist/chunk-JURSITRX.js.map +1 -0
- package/dist/{chunk-CD3YNHYJ.js → chunk-LJZYN4MH.js} +284 -39
- package/dist/chunk-LJZYN4MH.js.map +1 -0
- package/dist/contracts/index.d.ts +67 -4
- package/dist/core/index.d.ts +63 -3
- package/dist/core/index.js +7 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +7 -1
- package/dist/react/index.d.ts +76 -3
- package/dist/react/index.js +2 -2
- package/dist/{referenceSourceAggregator-yyyLVOPi.d.ts → referenceSourceAggregator-B8ATnJOZ.d.ts} +5 -0
- package/dist/ui/index.d.ts +38 -5
- package/dist/ui/index.js +964 -361
- package/dist/ui/index.js.map +1 -1
- package/package.json +6 -6
- package/dist/chunk-7C3RZYQE.js.map +0 -1
- package/dist/chunk-CD3YNHYJ.js.map +0 -1
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
nodeRefKey,
|
|
5
5
|
sortReferenceNodes,
|
|
6
6
|
uniqueWorkspaceFileReferences
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-JURSITRX.js";
|
|
8
8
|
|
|
9
9
|
// src/react/internal/reference/WorkspaceFileReferencePickerState.ts
|
|
10
10
|
var workspaceFileReferenceDefaultExpandedDepth = 4;
|
|
@@ -162,7 +162,15 @@ var defaultDirectoryPath = "/";
|
|
|
162
162
|
var defaultSearchDebounceMs = 180;
|
|
163
163
|
function createWorkspaceFileReferencePickerController(input) {
|
|
164
164
|
const searchDebounceMs = input.searchDebounceMs ?? defaultSearchDebounceMs;
|
|
165
|
-
let
|
|
165
|
+
let nextBrowseSeq = 0;
|
|
166
|
+
const latestBrowseSeqByKey = /* @__PURE__ */ new Map();
|
|
167
|
+
const stampBrowse = (seqKey) => {
|
|
168
|
+
const sequence = ++nextBrowseSeq;
|
|
169
|
+
latestBrowseSeqByKey.set(seqKey, sequence);
|
|
170
|
+
return sequence;
|
|
171
|
+
};
|
|
172
|
+
const isBrowseStale = (seqKey, sequence) => !retained || latestBrowseSeqByKey.get(seqKey) !== sequence;
|
|
173
|
+
const REVEAL_SEQ_KEY = "\0reveal";
|
|
166
174
|
let previewObjectUrl = null;
|
|
167
175
|
let previewSequence = 0;
|
|
168
176
|
let retained = false;
|
|
@@ -223,7 +231,7 @@ function createWorkspaceFileReferencePickerController(input) {
|
|
|
223
231
|
searchAbortController = null;
|
|
224
232
|
};
|
|
225
233
|
const cancelCurrentBrowse = () => {
|
|
226
|
-
|
|
234
|
+
latestBrowseSeqByKey.clear();
|
|
227
235
|
};
|
|
228
236
|
const cancelCurrentPreview = () => {
|
|
229
237
|
previewSequence += 1;
|
|
@@ -310,7 +318,8 @@ function createWorkspaceFileReferencePickerController(input) {
|
|
|
310
318
|
if (normalizedRoot && snapshot.directoryStateByPath[normalizedRoot]?.loaded) {
|
|
311
319
|
return;
|
|
312
320
|
}
|
|
313
|
-
const
|
|
321
|
+
const seqKey = normalizedRoot ?? "";
|
|
322
|
+
const sequence = stampBrowse(seqKey);
|
|
314
323
|
setSnapshot({
|
|
315
324
|
browseError: null,
|
|
316
325
|
isBrowseLoading: true
|
|
@@ -323,7 +332,7 @@ function createWorkspaceFileReferencePickerController(input) {
|
|
|
323
332
|
prefetchDepth: 4,
|
|
324
333
|
workspaceId: input.workspaceId
|
|
325
334
|
});
|
|
326
|
-
if (
|
|
335
|
+
if (isBrowseStale(seqKey, sequence)) {
|
|
327
336
|
return;
|
|
328
337
|
}
|
|
329
338
|
setSnapshot({
|
|
@@ -338,7 +347,7 @@ function createWorkspaceFileReferencePickerController(input) {
|
|
|
338
347
|
return;
|
|
339
348
|
}
|
|
340
349
|
const listing = await loadDirectoryListing(activeBrowseRootPath);
|
|
341
|
-
if (
|
|
350
|
+
if (isBrowseStale(seqKey, sequence) || !listing) {
|
|
342
351
|
return;
|
|
343
352
|
}
|
|
344
353
|
setSnapshot((current) => ({
|
|
@@ -356,7 +365,7 @@ function createWorkspaceFileReferencePickerController(input) {
|
|
|
356
365
|
isBrowseLoading: false
|
|
357
366
|
}));
|
|
358
367
|
} catch (error) {
|
|
359
|
-
if (
|
|
368
|
+
if (isBrowseStale(seqKey, sequence)) {
|
|
360
369
|
return;
|
|
361
370
|
}
|
|
362
371
|
setSnapshot({
|
|
@@ -373,7 +382,7 @@ function createWorkspaceFileReferencePickerController(input) {
|
|
|
373
382
|
if (!retained || snapshot.directoryStateByPath[folderKey]?.loaded || snapshot.directoryStateByPath[folderKey]?.loading) {
|
|
374
383
|
return;
|
|
375
384
|
}
|
|
376
|
-
const sequence =
|
|
385
|
+
const sequence = stampBrowse(folderKey);
|
|
377
386
|
setSnapshot((current) => ({
|
|
378
387
|
...current,
|
|
379
388
|
directoryStateByPath: {
|
|
@@ -388,7 +397,7 @@ function createWorkspaceFileReferencePickerController(input) {
|
|
|
388
397
|
}));
|
|
389
398
|
try {
|
|
390
399
|
const listing = await loadDirectoryListing(folderKey);
|
|
391
|
-
if (
|
|
400
|
+
if (isBrowseStale(folderKey, sequence) || !listing) {
|
|
392
401
|
return;
|
|
393
402
|
}
|
|
394
403
|
setSnapshot((current) => ({
|
|
@@ -404,7 +413,7 @@ function createWorkspaceFileReferencePickerController(input) {
|
|
|
404
413
|
}
|
|
405
414
|
}));
|
|
406
415
|
} catch {
|
|
407
|
-
if (
|
|
416
|
+
if (isBrowseStale(folderKey, sequence)) {
|
|
408
417
|
return;
|
|
409
418
|
}
|
|
410
419
|
setSnapshot((current) => ({
|
|
@@ -438,12 +447,12 @@ function createWorkspaceFileReferencePickerController(input) {
|
|
|
438
447
|
}
|
|
439
448
|
const nextState = createReferencePreviewState(reference, target, preview);
|
|
440
449
|
if (!retained || sequence !== previewSequence) {
|
|
441
|
-
if (nextState.status === "image") {
|
|
450
|
+
if (nextState.status === "image" || nextState.status === "video") {
|
|
442
451
|
URL.revokeObjectURL(nextState.objectUrl);
|
|
443
452
|
}
|
|
444
453
|
return;
|
|
445
454
|
}
|
|
446
|
-
if (nextState.status === "image") {
|
|
455
|
+
if (nextState.status === "image" || nextState.status === "video") {
|
|
447
456
|
previewObjectUrl = nextState.objectUrl;
|
|
448
457
|
}
|
|
449
458
|
setSnapshot({
|
|
@@ -542,7 +551,7 @@ function createWorkspaceFileReferencePickerController(input) {
|
|
|
542
551
|
});
|
|
543
552
|
return null;
|
|
544
553
|
}
|
|
545
|
-
const sequence =
|
|
554
|
+
const sequence = stampBrowse(REVEAL_SEQ_KEY);
|
|
546
555
|
const loadedDirectories = {};
|
|
547
556
|
const expandedDirectories = {};
|
|
548
557
|
const directoryState = (path) => loadedDirectories[path] ?? snapshot.directoryStateByPath[path];
|
|
@@ -573,7 +582,7 @@ function createWorkspaceFileReferencePickerController(input) {
|
|
|
573
582
|
loading: false
|
|
574
583
|
};
|
|
575
584
|
}
|
|
576
|
-
if (
|
|
585
|
+
if (isBrowseStale(REVEAL_SEQ_KEY, sequence)) {
|
|
577
586
|
return null;
|
|
578
587
|
}
|
|
579
588
|
setSnapshot((current) => ({
|
|
@@ -661,6 +670,7 @@ function createReferencePreviewState(reference, target, preview) {
|
|
|
661
670
|
bytes: preview.bytes,
|
|
662
671
|
contentType: preview.contentType,
|
|
663
672
|
entry: reference,
|
|
673
|
+
renderHtml: true,
|
|
664
674
|
target: {
|
|
665
675
|
...target,
|
|
666
676
|
fileKind: preview.kind
|
|
@@ -677,6 +687,17 @@ function createReferencePreviewState(reference, target, preview) {
|
|
|
677
687
|
status: "image"
|
|
678
688
|
};
|
|
679
689
|
}
|
|
690
|
+
if (loadedState.status === "video") {
|
|
691
|
+
return {
|
|
692
|
+
objectUrl: URL.createObjectURL(
|
|
693
|
+
new Blob([loadedState.bytes], {
|
|
694
|
+
type: loadedState.contentType
|
|
695
|
+
})
|
|
696
|
+
),
|
|
697
|
+
reference,
|
|
698
|
+
status: "video"
|
|
699
|
+
};
|
|
700
|
+
}
|
|
680
701
|
if (loadedState.status === "text") {
|
|
681
702
|
return {
|
|
682
703
|
content: loadedState.content,
|
|
@@ -684,6 +705,13 @@ function createReferencePreviewState(reference, target, preview) {
|
|
|
684
705
|
status: "text"
|
|
685
706
|
};
|
|
686
707
|
}
|
|
708
|
+
if (loadedState.status === "html") {
|
|
709
|
+
return {
|
|
710
|
+
content: loadedState.content,
|
|
711
|
+
reference,
|
|
712
|
+
status: "html"
|
|
713
|
+
};
|
|
714
|
+
}
|
|
687
715
|
return {
|
|
688
716
|
maxSizeBytes: loadedState.maxSizeBytes,
|
|
689
717
|
reason: loadedState.reason,
|
|
@@ -899,6 +927,8 @@ var ROOT_CHILDREN_KEY = nodeRefKey({
|
|
|
899
927
|
nodeId: SOURCE_ROOT_NODE_ID
|
|
900
928
|
});
|
|
901
929
|
var defaultSearchDebounceMs2 = 180;
|
|
930
|
+
var SEARCH_PAGE_SIZE = 30;
|
|
931
|
+
var SEARCH_MAX_LIMIT = 200;
|
|
902
932
|
function emptyTabState(sourceId) {
|
|
903
933
|
return {
|
|
904
934
|
sourceId,
|
|
@@ -906,8 +936,13 @@ function emptyTabState(sourceId) {
|
|
|
906
936
|
childrenByKey: {},
|
|
907
937
|
mode: "browse",
|
|
908
938
|
searchQuery: "",
|
|
939
|
+
searchFilters: [],
|
|
940
|
+
searchScopeNodeId: null,
|
|
909
941
|
searchEntries: [],
|
|
910
942
|
searchNextCursor: null,
|
|
943
|
+
searchLimit: 0,
|
|
944
|
+
searchHasMore: false,
|
|
945
|
+
isSearchLoadingMore: false,
|
|
911
946
|
isSearchLoading: false,
|
|
912
947
|
searchError: null
|
|
913
948
|
};
|
|
@@ -925,8 +960,10 @@ function createReferenceSourcePickerController(input) {
|
|
|
925
960
|
const { aggregator, scope } = input;
|
|
926
961
|
const searchDebounceMs = input.searchDebounceMs ?? defaultSearchDebounceMs2;
|
|
927
962
|
let retained = false;
|
|
963
|
+
let tabsReady = Promise.resolve();
|
|
928
964
|
let tabsSequence = 0;
|
|
929
|
-
let
|
|
965
|
+
let nextBrowseSeq = 0;
|
|
966
|
+
const latestBrowseSeqByKey = /* @__PURE__ */ new Map();
|
|
930
967
|
let searchSequence = 0;
|
|
931
968
|
let searchAbortController = null;
|
|
932
969
|
let searchTimer = null;
|
|
@@ -987,7 +1024,9 @@ function createReferenceSourcePickerController(input) {
|
|
|
987
1024
|
if (options.append && !cursor) {
|
|
988
1025
|
return;
|
|
989
1026
|
}
|
|
990
|
-
const
|
|
1027
|
+
const seqKey = `${sourceId}\0${key}`;
|
|
1028
|
+
const sequence = ++nextBrowseSeq;
|
|
1029
|
+
latestBrowseSeqByKey.set(seqKey, sequence);
|
|
991
1030
|
setChildrenState(sourceId, key, { loading: true, error: null });
|
|
992
1031
|
try {
|
|
993
1032
|
const result = await aggregator.listChildren(
|
|
@@ -995,7 +1034,7 @@ function createReferenceSourcePickerController(input) {
|
|
|
995
1034
|
node ? node.ref : { sourceId, nodeId: SOURCE_ROOT_NODE_ID },
|
|
996
1035
|
{ cursor }
|
|
997
1036
|
);
|
|
998
|
-
if (!retained ||
|
|
1037
|
+
if (!retained || latestBrowseSeqByKey.get(seqKey) !== sequence) {
|
|
999
1038
|
return;
|
|
1000
1039
|
}
|
|
1001
1040
|
const prior = snapshot.bySource[sourceId]?.childrenByKey[key]?.entries ?? [];
|
|
@@ -1008,7 +1047,7 @@ function createReferenceSourcePickerController(input) {
|
|
|
1008
1047
|
error: null
|
|
1009
1048
|
});
|
|
1010
1049
|
} catch (error) {
|
|
1011
|
-
if (!retained ||
|
|
1050
|
+
if (!retained || latestBrowseSeqByKey.get(seqKey) !== sequence) {
|
|
1012
1051
|
return;
|
|
1013
1052
|
}
|
|
1014
1053
|
setChildrenState(sourceId, key, {
|
|
@@ -1073,7 +1112,7 @@ function createReferenceSourcePickerController(input) {
|
|
|
1073
1112
|
searchAbortController?.abort();
|
|
1074
1113
|
searchAbortController = null;
|
|
1075
1114
|
};
|
|
1076
|
-
const runSearch = async (sourceId, query) => {
|
|
1115
|
+
const runSearch = async (sourceId, query, filters, scopeNodeId, limit, loadingMore) => {
|
|
1077
1116
|
if (!retained) {
|
|
1078
1117
|
return;
|
|
1079
1118
|
}
|
|
@@ -1083,13 +1122,16 @@ function createReferenceSourcePickerController(input) {
|
|
|
1083
1122
|
searchAbortController = abortController;
|
|
1084
1123
|
updateTab(sourceId, (tab) => ({
|
|
1085
1124
|
...tab,
|
|
1086
|
-
isSearchLoading: true,
|
|
1125
|
+
...loadingMore ? { isSearchLoadingMore: true } : { isSearchLoading: true },
|
|
1087
1126
|
searchError: null
|
|
1088
1127
|
}));
|
|
1089
1128
|
try {
|
|
1090
1129
|
const result = await aggregator.search(scope, sourceId, {
|
|
1091
1130
|
query,
|
|
1092
|
-
|
|
1131
|
+
limit,
|
|
1132
|
+
signal: abortController.signal,
|
|
1133
|
+
...filters.length > 0 ? { filters } : {},
|
|
1134
|
+
...scopeNodeId == null ? {} : { withinNodeId: scopeNodeId }
|
|
1093
1135
|
});
|
|
1094
1136
|
if (!retained || sequence !== searchSequence) {
|
|
1095
1137
|
return;
|
|
@@ -1097,8 +1139,12 @@ function createReferenceSourcePickerController(input) {
|
|
|
1097
1139
|
updateTab(sourceId, (tab) => ({
|
|
1098
1140
|
...tab,
|
|
1099
1141
|
isSearchLoading: false,
|
|
1142
|
+
isSearchLoadingMore: false,
|
|
1100
1143
|
searchEntries: sortReferenceNodes(result.entries),
|
|
1101
1144
|
searchNextCursor: result.nextCursor ?? null,
|
|
1145
|
+
searchLimit: limit,
|
|
1146
|
+
// 本页返回数达到请求上限、且未触全局上限 → 认为可能还有更多(增长式分页启发式)。
|
|
1147
|
+
searchHasMore: result.entries.length >= limit && limit < SEARCH_MAX_LIMIT,
|
|
1102
1148
|
searchError: null
|
|
1103
1149
|
}));
|
|
1104
1150
|
} catch (error) {
|
|
@@ -1108,7 +1154,9 @@ function createReferenceSourcePickerController(input) {
|
|
|
1108
1154
|
updateTab(sourceId, (tab) => ({
|
|
1109
1155
|
...tab,
|
|
1110
1156
|
isSearchLoading: false,
|
|
1111
|
-
|
|
1157
|
+
isSearchLoadingMore: false,
|
|
1158
|
+
// 加载更多失败时保留已有结果,仅新查询失败才清空。
|
|
1159
|
+
...loadingMore ? {} : { searchEntries: [], searchHasMore: false },
|
|
1112
1160
|
searchError: normalizeError(error, "reference search failed")
|
|
1113
1161
|
}));
|
|
1114
1162
|
} finally {
|
|
@@ -1144,18 +1192,32 @@ function createReferenceSourcePickerController(input) {
|
|
|
1144
1192
|
await walk(folder);
|
|
1145
1193
|
return files;
|
|
1146
1194
|
};
|
|
1147
|
-
const scheduleSearch = (sourceId, query) => {
|
|
1195
|
+
const scheduleSearch = (sourceId, query, filters, scopeNodeId) => {
|
|
1148
1196
|
clearSearchTimer();
|
|
1149
|
-
if (!retained || !query) {
|
|
1197
|
+
if (!retained || !query && filters.length === 0) {
|
|
1150
1198
|
return;
|
|
1151
1199
|
}
|
|
1152
1200
|
if (searchDebounceMs <= 0) {
|
|
1153
|
-
void runSearch(
|
|
1201
|
+
void runSearch(
|
|
1202
|
+
sourceId,
|
|
1203
|
+
query,
|
|
1204
|
+
filters,
|
|
1205
|
+
scopeNodeId,
|
|
1206
|
+
SEARCH_PAGE_SIZE,
|
|
1207
|
+
false
|
|
1208
|
+
);
|
|
1154
1209
|
return;
|
|
1155
1210
|
}
|
|
1156
1211
|
searchTimer = setTimeout(() => {
|
|
1157
1212
|
searchTimer = null;
|
|
1158
|
-
void runSearch(
|
|
1213
|
+
void runSearch(
|
|
1214
|
+
sourceId,
|
|
1215
|
+
query,
|
|
1216
|
+
filters,
|
|
1217
|
+
scopeNodeId,
|
|
1218
|
+
SEARCH_PAGE_SIZE,
|
|
1219
|
+
false
|
|
1220
|
+
);
|
|
1159
1221
|
}, searchDebounceMs);
|
|
1160
1222
|
};
|
|
1161
1223
|
return {
|
|
@@ -1170,17 +1232,17 @@ function createReferenceSourcePickerController(input) {
|
|
|
1170
1232
|
return;
|
|
1171
1233
|
}
|
|
1172
1234
|
retained = true;
|
|
1173
|
-
|
|
1235
|
+
tabsReady = loadTabs();
|
|
1174
1236
|
},
|
|
1175
1237
|
close() {
|
|
1176
1238
|
retained = false;
|
|
1177
1239
|
cancelSearch();
|
|
1178
|
-
|
|
1240
|
+
latestBrowseSeqByKey.clear();
|
|
1179
1241
|
tabsSequence += 1;
|
|
1180
1242
|
},
|
|
1181
1243
|
reset() {
|
|
1182
1244
|
cancelSearch();
|
|
1183
|
-
|
|
1245
|
+
latestBrowseSeqByKey.clear();
|
|
1184
1246
|
tabsSequence += 1;
|
|
1185
1247
|
setSnapshot({
|
|
1186
1248
|
isLoadingTabs: false,
|
|
@@ -1192,17 +1254,77 @@ function createReferenceSourcePickerController(input) {
|
|
|
1192
1254
|
});
|
|
1193
1255
|
},
|
|
1194
1256
|
setActiveSource(sourceId) {
|
|
1195
|
-
if (!snapshot.tabs.some((
|
|
1257
|
+
if (!snapshot.tabs.some((tab) => tab.sourceId === sourceId)) {
|
|
1196
1258
|
return;
|
|
1197
1259
|
}
|
|
1260
|
+
const prevTab = snapshot.activeSourceId ? snapshot.bySource[snapshot.activeSourceId] : void 0;
|
|
1261
|
+
const carriedQuery = prevTab?.searchQuery ?? "";
|
|
1262
|
+
const carriedFilters = prevTab?.searchFilters ?? [];
|
|
1263
|
+
const trimmed = carriedQuery.trim();
|
|
1198
1264
|
cancelSearch();
|
|
1199
1265
|
setSnapshot({ activeSourceId: sourceId });
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1266
|
+
if (trimmed === "" && carriedFilters.length === 0) {
|
|
1267
|
+
updateTab(
|
|
1268
|
+
sourceId,
|
|
1269
|
+
(tab) => tab.mode === "browse" && tab.searchQuery === "" && tab.searchFilters.length === 0 ? tab : {
|
|
1270
|
+
...tab,
|
|
1271
|
+
mode: "browse",
|
|
1272
|
+
searchQuery: "",
|
|
1273
|
+
searchFilters: [],
|
|
1274
|
+
searchEntries: [],
|
|
1275
|
+
searchHasMore: false,
|
|
1276
|
+
isSearchLoading: false,
|
|
1277
|
+
isSearchLoadingMore: false,
|
|
1278
|
+
searchError: null
|
|
1279
|
+
}
|
|
1280
|
+
);
|
|
1204
1281
|
ensureRootLoaded(sourceId);
|
|
1282
|
+
return;
|
|
1205
1283
|
}
|
|
1284
|
+
const nextScopeNodeId = snapshot.bySource[sourceId]?.searchScopeNodeId ?? null;
|
|
1285
|
+
updateTab(sourceId, (tab) => ({
|
|
1286
|
+
...tab,
|
|
1287
|
+
searchQuery: carriedQuery,
|
|
1288
|
+
searchFilters: carriedFilters,
|
|
1289
|
+
searchScopeNodeId: nextScopeNodeId,
|
|
1290
|
+
mode: "search",
|
|
1291
|
+
// 沿用旧结果直到新结果就绪,避免切源瞬间闪空。
|
|
1292
|
+
isSearchLoading: true,
|
|
1293
|
+
searchError: null
|
|
1294
|
+
}));
|
|
1295
|
+
scheduleSearch(sourceId, trimmed, carriedFilters, nextScopeNodeId);
|
|
1296
|
+
},
|
|
1297
|
+
async locatePath(target) {
|
|
1298
|
+
await tabsReady;
|
|
1299
|
+
if (!retained) {
|
|
1300
|
+
return [];
|
|
1301
|
+
}
|
|
1302
|
+
const refs = await aggregator.locateTarget(
|
|
1303
|
+
scope,
|
|
1304
|
+
target.sourceId,
|
|
1305
|
+
target.params
|
|
1306
|
+
);
|
|
1307
|
+
if (!refs || refs.length === 0) {
|
|
1308
|
+
return [];
|
|
1309
|
+
}
|
|
1310
|
+
const path = [];
|
|
1311
|
+
let parent = {
|
|
1312
|
+
sourceId: target.sourceId,
|
|
1313
|
+
nodeId: SOURCE_ROOT_NODE_ID
|
|
1314
|
+
};
|
|
1315
|
+
for (const ref of refs) {
|
|
1316
|
+
const { entries } = await aggregator.listChildren(scope, parent);
|
|
1317
|
+
const targetKey = nodeRefKey(ref);
|
|
1318
|
+
const node = entries.find(
|
|
1319
|
+
(entry) => nodeRefKey(entry.ref) === targetKey
|
|
1320
|
+
);
|
|
1321
|
+
if (!node) {
|
|
1322
|
+
break;
|
|
1323
|
+
}
|
|
1324
|
+
path.push(node);
|
|
1325
|
+
parent = ref;
|
|
1326
|
+
}
|
|
1327
|
+
return path;
|
|
1206
1328
|
},
|
|
1207
1329
|
ensureChildren(node) {
|
|
1208
1330
|
const sourceId = node ? node.ref.sourceId : snapshot.activeSourceId;
|
|
@@ -1221,6 +1343,24 @@ function createReferenceSourcePickerController(input) {
|
|
|
1221
1343
|
}
|
|
1222
1344
|
ensureRootLoaded(sourceId);
|
|
1223
1345
|
},
|
|
1346
|
+
expandNode(node) {
|
|
1347
|
+
if (node.kind !== "folder") {
|
|
1348
|
+
return;
|
|
1349
|
+
}
|
|
1350
|
+
const sourceId = node.ref.sourceId;
|
|
1351
|
+
const key = nodeRefKey(node.ref);
|
|
1352
|
+
updateTab(
|
|
1353
|
+
sourceId,
|
|
1354
|
+
(tab) => tab.expandedKeys[key] === true ? tab : {
|
|
1355
|
+
...tab,
|
|
1356
|
+
expandedKeys: { ...tab.expandedKeys, [key]: true }
|
|
1357
|
+
}
|
|
1358
|
+
);
|
|
1359
|
+
const childState = snapshot.bySource[sourceId]?.childrenByKey[key];
|
|
1360
|
+
if (!childState?.loaded && !childState?.loading) {
|
|
1361
|
+
void loadChildren(sourceId, node, { append: false });
|
|
1362
|
+
}
|
|
1363
|
+
},
|
|
1224
1364
|
toggleNode(node) {
|
|
1225
1365
|
if (node.kind !== "folder") {
|
|
1226
1366
|
return;
|
|
@@ -1245,26 +1385,108 @@ function createReferenceSourcePickerController(input) {
|
|
|
1245
1385
|
}
|
|
1246
1386
|
void loadChildren(sourceId, node, { append: true });
|
|
1247
1387
|
},
|
|
1248
|
-
|
|
1388
|
+
loadMoreSourceRoot(sourceId) {
|
|
1389
|
+
if (!sourceId) {
|
|
1390
|
+
return;
|
|
1391
|
+
}
|
|
1392
|
+
void loadChildren(sourceId, null, { append: true });
|
|
1393
|
+
},
|
|
1394
|
+
setSearchQuery(query, scopeNodeId = null) {
|
|
1249
1395
|
const sourceId = snapshot.activeSourceId;
|
|
1250
1396
|
if (!sourceId) {
|
|
1251
1397
|
return;
|
|
1252
1398
|
}
|
|
1399
|
+
const filters = snapshot.bySource[sourceId]?.searchFilters ?? [];
|
|
1253
1400
|
const trimmed = query.trim();
|
|
1254
|
-
const nextMode = trimmed ? "search" : "browse";
|
|
1401
|
+
const nextMode = trimmed || filters.length > 0 ? "search" : "browse";
|
|
1255
1402
|
updateTab(sourceId, (tab) => ({
|
|
1256
1403
|
...tab,
|
|
1257
1404
|
searchQuery: query,
|
|
1405
|
+
searchScopeNodeId: scopeNodeId,
|
|
1258
1406
|
mode: nextMode,
|
|
1259
|
-
|
|
1407
|
+
// 进入搜索:立刻置 loading(搜索是 debounce 的,否则键入到取数之间会先渲染空态,
|
|
1408
|
+
// 造成「空态 → spinner → 结果」闪烁)。保留上次 searchEntries,细化关键词时沿用旧结果而非闪空。
|
|
1409
|
+
...nextMode === "browse" ? { isSearchLoading: false, searchEntries: [], searchError: null } : { isSearchLoading: true, searchError: null }
|
|
1260
1410
|
}));
|
|
1261
1411
|
if (nextMode === "search") {
|
|
1262
|
-
scheduleSearch(sourceId, trimmed);
|
|
1412
|
+
scheduleSearch(sourceId, trimmed, filters, scopeNodeId);
|
|
1263
1413
|
} else {
|
|
1264
1414
|
cancelSearch();
|
|
1265
1415
|
ensureRootLoaded(sourceId);
|
|
1266
1416
|
}
|
|
1267
1417
|
},
|
|
1418
|
+
setSearchFilters(filters, scopeNodeId = null) {
|
|
1419
|
+
const sourceId = snapshot.activeSourceId;
|
|
1420
|
+
if (!sourceId) {
|
|
1421
|
+
return;
|
|
1422
|
+
}
|
|
1423
|
+
const tab = snapshot.bySource[sourceId];
|
|
1424
|
+
const trimmed = tab?.searchQuery.trim() ?? "";
|
|
1425
|
+
const scopeId = scopeNodeId ?? tab?.searchScopeNodeId ?? null;
|
|
1426
|
+
const nextMode = trimmed || filters.length > 0 ? "search" : "browse";
|
|
1427
|
+
updateTab(sourceId, (current) => ({
|
|
1428
|
+
...current,
|
|
1429
|
+
searchFilters: filters,
|
|
1430
|
+
searchScopeNodeId: scopeId,
|
|
1431
|
+
mode: nextMode,
|
|
1432
|
+
...nextMode === "browse" ? { isSearchLoading: false, searchEntries: [], searchError: null } : { isSearchLoading: true, searchError: null }
|
|
1433
|
+
}));
|
|
1434
|
+
if (nextMode === "search") {
|
|
1435
|
+
scheduleSearch(sourceId, trimmed, filters, scopeId);
|
|
1436
|
+
} else {
|
|
1437
|
+
cancelSearch();
|
|
1438
|
+
ensureRootLoaded(sourceId);
|
|
1439
|
+
}
|
|
1440
|
+
},
|
|
1441
|
+
setSearchScope(scopeNodeId) {
|
|
1442
|
+
const sourceId = snapshot.activeSourceId;
|
|
1443
|
+
if (!sourceId) {
|
|
1444
|
+
return;
|
|
1445
|
+
}
|
|
1446
|
+
const tab = snapshot.bySource[sourceId];
|
|
1447
|
+
if (!tab || tab.searchScopeNodeId === scopeNodeId) {
|
|
1448
|
+
return;
|
|
1449
|
+
}
|
|
1450
|
+
updateTab(sourceId, (current) => ({
|
|
1451
|
+
...current,
|
|
1452
|
+
searchScopeNodeId: scopeNodeId
|
|
1453
|
+
}));
|
|
1454
|
+
const trimmed = tab.searchQuery.trim();
|
|
1455
|
+
const filters = tab.searchFilters;
|
|
1456
|
+
if (tab.mode === "search" && (trimmed || filters.length > 0)) {
|
|
1457
|
+
scheduleSearch(sourceId, trimmed, filters, scopeNodeId);
|
|
1458
|
+
}
|
|
1459
|
+
},
|
|
1460
|
+
loadMoreSearch() {
|
|
1461
|
+
const sourceId = snapshot.activeSourceId;
|
|
1462
|
+
if (!sourceId) {
|
|
1463
|
+
return;
|
|
1464
|
+
}
|
|
1465
|
+
const tab = snapshot.bySource[sourceId];
|
|
1466
|
+
if (!tab || tab.mode !== "search" || !tab.searchHasMore || tab.isSearchLoadingMore) {
|
|
1467
|
+
return;
|
|
1468
|
+
}
|
|
1469
|
+
const trimmed = tab.searchQuery.trim();
|
|
1470
|
+
if (!trimmed && tab.searchFilters.length === 0) {
|
|
1471
|
+
return;
|
|
1472
|
+
}
|
|
1473
|
+
const nextLimit = Math.min(
|
|
1474
|
+
(tab.searchLimit || SEARCH_PAGE_SIZE) + SEARCH_PAGE_SIZE,
|
|
1475
|
+
SEARCH_MAX_LIMIT
|
|
1476
|
+
);
|
|
1477
|
+
if (nextLimit <= tab.searchLimit) {
|
|
1478
|
+
return;
|
|
1479
|
+
}
|
|
1480
|
+
clearSearchTimer();
|
|
1481
|
+
void runSearch(
|
|
1482
|
+
sourceId,
|
|
1483
|
+
trimmed,
|
|
1484
|
+
tab.searchFilters,
|
|
1485
|
+
tab.searchScopeNodeId,
|
|
1486
|
+
nextLimit,
|
|
1487
|
+
true
|
|
1488
|
+
);
|
|
1489
|
+
},
|
|
1268
1490
|
toggleSelection(node) {
|
|
1269
1491
|
const key = nodeRefKey(node.ref);
|
|
1270
1492
|
setSnapshot((current) => {
|
|
@@ -1306,6 +1528,29 @@ function createReferenceSourcePickerController(input) {
|
|
|
1306
1528
|
}
|
|
1307
1529
|
}
|
|
1308
1530
|
return resolved;
|
|
1531
|
+
},
|
|
1532
|
+
async confirmGrouped() {
|
|
1533
|
+
const files = [];
|
|
1534
|
+
const bundles = [];
|
|
1535
|
+
const seenPaths = /* @__PURE__ */ new Set();
|
|
1536
|
+
const pushFile = (ref) => {
|
|
1537
|
+
if (seenPaths.has(ref.path)) {
|
|
1538
|
+
return;
|
|
1539
|
+
}
|
|
1540
|
+
seenPaths.add(ref.path);
|
|
1541
|
+
files.push(ref);
|
|
1542
|
+
};
|
|
1543
|
+
for (const node of snapshot.selection) {
|
|
1544
|
+
const source = aggregator.getLoadedSource(node.ref.sourceId);
|
|
1545
|
+
const navigable = node.kind === "folder" && (source?.capabilities.navigable ?? false);
|
|
1546
|
+
if (!navigable) {
|
|
1547
|
+
pushFile(aggregator.resolveSelection(node));
|
|
1548
|
+
continue;
|
|
1549
|
+
}
|
|
1550
|
+
const handle = source?.describeReferenceHandle?.(node) ?? null;
|
|
1551
|
+
bundles.push({ root: node, handle });
|
|
1552
|
+
}
|
|
1553
|
+
return { files, bundles };
|
|
1309
1554
|
}
|
|
1310
1555
|
};
|
|
1311
1556
|
}
|
|
@@ -1328,4 +1573,4 @@ export {
|
|
|
1328
1573
|
ROOT_CHILDREN_KEY,
|
|
1329
1574
|
createReferenceSourcePickerController
|
|
1330
1575
|
};
|
|
1331
|
-
//# sourceMappingURL=chunk-
|
|
1576
|
+
//# sourceMappingURL=chunk-LJZYN4MH.js.map
|