nolo-cli 0.49.1 → 0.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/{_executeModel-KE4PQSZ3.js → _executeModel-JKEH7ACW.js} +48 -42
  2. package/{action-IU6ON7ZB.js → action-VSG2IYP3.js} +8 -8
  3. package/{addContentAction-5V5CCI3I.js → addContentAction-2HJJITDI.js} +8 -7
  4. package/{addDialogAgentAction-KF3KZZNZ.js → addDialogAgentAction-7BSQVVL5.js} +10 -9
  5. package/{agentDeleteCommand-Z67TJG3W.js → agentDeleteCommand-SVXKS5SC.js} +30 -28
  6. package/{agentEmailCommands-7LPIK7JE.js → agentEmailCommands-WN7QBTP3.js} +57 -52
  7. package/{agentListCommands-5J2IM3IT.js → agentListCommands-2BEBOQIG.js} +42 -33
  8. package/{agentMachineCommands-YXH6FXUQ.js → agentMachineCommands-WALP3ONU.js} +30 -28
  9. package/{agentRecordCommands-GZLCDVUS.js → agentRecordCommands-E652SW57.js} +55 -50
  10. package/{agentRunCommand-WYH5Q54Q.js → agentRunCommand-6VXWXKCS.js} +60 -53
  11. package/{agentRunControl-4GHHSXFZ.js → agentRunControl-LJVFDJGU.js} +3 -1
  12. package/{agentRuntimeLocal-A6EF3RUY.js → agentRuntimeLocal-SBG7BDFQ.js} +30 -26
  13. package/{agentSlice-ARTDF6VD.js → agentSlice-3WYXIGEO.js} +8 -8
  14. package/{agentSuperviseCommands-VB6BUS5H.js → agentSuperviseCommands-F3RFAL7K.js} +2 -2
  15. package/{appDeleteCommands-V2B7ZCLC.js → appDeleteCommands-NTUNMEXY.js} +31 -29
  16. package/{appDeployCommands-AXQU44RD.js → appDeployCommands-DISWXRTL.js} +31 -29
  17. package/{appDeployStatusCommands-FWGSC2UM.js → appDeployStatusCommands-IKRA6B6F.js} +31 -29
  18. package/{appGetCommands-67R3RFZK.js → appGetCommands-UMOP2DFV.js} +31 -29
  19. package/{appListCommands-TTASJPGV.js → appListCommands-ZKFD2AKS.js} +31 -29
  20. package/{authCommand-QOPOEYEK.js → authCommand-BS3CQC6I.js} +11 -11
  21. package/{chatQueueReduxAdapter-6CAHUQ4O.js → chatQueueReduxAdapter-A3YH4MT4.js} +24 -21
  22. package/{chunk-76UA7376.js → chunk-273FJUYI.js} +6 -6
  23. package/{chunk-7CH6U3FL.js → chunk-2GRGFCF6.js} +2 -4
  24. package/{chunk-T27IEBNQ.js → chunk-2QDDKFG5.js} +74 -1
  25. package/{chunk-IRJVFYOH.js → chunk-2TLYVDTN.js} +321 -1100
  26. package/{chunk-6BYAXNH5.js → chunk-3QOCS5IF.js} +11 -2
  27. package/chunk-6IGD47IC.js +19 -0
  28. package/{chunk-GFD7TIZU.js → chunk-6TUT5ZJD.js} +4 -6
  29. package/chunk-6YTOJY35.js +352 -0
  30. package/{chunk-B54WOZ77.js → chunk-7H7GQL6V.js} +2 -2
  31. package/{chunk-OYNDYVSE.js → chunk-B45YNDAE.js} +1 -1
  32. package/{chunk-UQWFIWHX.js → chunk-BKIDF5LV.js} +1 -1
  33. package/{chunk-5XCW6RQG.js → chunk-BUBPRCIU.js} +1 -1
  34. package/chunk-BYXBJQAS.js +0 -0
  35. package/{chunk-X7S7OFUX.js → chunk-CEVCRRHU.js} +4 -4
  36. package/{chunk-SP3DPVBH.js → chunk-DEIGUGP6.js} +2 -2
  37. package/{chunk-V2IPBG5U.js → chunk-DGEPT6FH.js} +1 -1
  38. package/{chunk-3AOLVADY.js → chunk-DVINR3PL.js} +1 -1
  39. package/{chunk-NN3AMBY3.js → chunk-DXOELY7S.js} +64 -69
  40. package/{chunk-OFZPJ3NT.js → chunk-E4MARS3Q.js} +1 -1
  41. package/{chunk-QUCSAM43.js → chunk-EAYBPWHX.js} +87 -66
  42. package/{chunk-DQLYEGP7.js → chunk-EGVY3GMT.js} +1 -1
  43. package/{chunk-2JYSSXLY.js → chunk-EJFW7TRP.js} +5 -26
  44. package/{chunk-HPZL4IBN.js → chunk-FGRCSLPV.js} +34 -45
  45. package/{chunk-WL3UOGYO.js → chunk-G4WSLTQF.js} +31 -97
  46. package/{chunk-HR5XDXYM.js → chunk-G5SQVIFZ.js} +3 -3
  47. package/{chunk-J3UALFHL.js → chunk-GHE5XMVR.js} +1 -1
  48. package/{chunk-6SMMK7MD.js → chunk-GKB4AZKV.js} +440 -2981
  49. package/{chunk-IKSFDJXB.js → chunk-GKNGRBE6.js} +150 -27
  50. package/{chunk-Q24S4NDF.js → chunk-HQTK2SFT.js} +1 -1
  51. package/{chunk-GDGIEGHV.js → chunk-IPTZ5TVU.js} +7 -6
  52. package/{chunk-4RXXP6WD.js → chunk-J7KDNHUO.js} +5 -64
  53. package/{chunk-QDHZCAH3.js → chunk-KNQ5LYVZ.js} +57 -2
  54. package/{chunk-VRJUIUIY.js → chunk-KVVNC5V3.js} +2 -2
  55. package/{chunk-CVT7L2WZ.js → chunk-LVCAWHI5.js} +4 -4
  56. package/{chunk-WX5E6HZS.js → chunk-N6SLQMSA.js} +6 -6
  57. package/{chunk-SQTVMYMU.js → chunk-NTZO3KX2.js} +3 -3
  58. package/{chunk-LGUQHYAL.js → chunk-O5FLGN2L.js} +3 -2
  59. package/{chunk-WKOEOQCI.js → chunk-OSUZKICS.js} +1600 -190
  60. package/{chunk-EXDR5D6X.js → chunk-Q2QN2RHG.js} +7 -7
  61. package/{chunk-L3JWI7WX.js → chunk-QOKAKDPE.js} +15 -11
  62. package/{chunk-757BGY6Y.js → chunk-RFYXK6KI.js} +1 -1
  63. package/chunk-RQSN75DW.js +1766 -0
  64. package/{chunk-HCMFFI2G.js → chunk-S3JNURSO.js} +2 -2
  65. package/{chunk-YZ2WE6CW.js → chunk-SAJSBPI2.js} +2 -2
  66. package/{chunk-WHVQA7PJ.js → chunk-SCBBGS2N.js} +23 -5
  67. package/chunk-SGSJBBKP.js +297 -0
  68. package/{chunk-GFUOVFQA.js → chunk-TUBNQ3OF.js} +2 -2
  69. package/{chunk-BANYWEYY.js → chunk-TY3ADTX5.js} +1 -1
  70. package/chunk-UAD2WT54.js +64 -0
  71. package/{chunk-SW7RCUGA.js → chunk-UEV5WVQV.js} +3 -3
  72. package/{chunk-EURF2SV6.js → chunk-UMCMW5R3.js} +51 -34
  73. package/{chunk-K524MUQC.js → chunk-VFDRZHPM.js} +16 -16
  74. package/{chunk-5WADL4O7.js → chunk-W22UTILW.js} +3 -3
  75. package/{chunk-IKTHA3JH.js → chunk-WERPP2S7.js} +2 -2
  76. package/{chunk-GBADO3SM.js → chunk-WSUHBABG.js} +1 -1
  77. package/{chunk-U5Z7LFZF.js → chunk-X3OGKR5Q.js} +4 -4
  78. package/{chunk-AVKUDHJO.js → chunk-X5LRMXTS.js} +10 -10
  79. package/{chunk-DIQCV4FR.js → chunk-X665UCNM.js} +1 -1
  80. package/{chunk-HCBQVVFZ.js → chunk-X7P6EJUY.js} +4 -4
  81. package/{chunk-HHBXCRJS.js → chunk-XOJRZUPF.js} +4 -4
  82. package/{chunk-MRWGHF56.js → chunk-YDH3FDFQ.js} +12 -356
  83. package/{chunk-TNPCQNGQ.js → chunk-YEFRCO5N.js} +4 -9
  84. package/{chunk-RO2IUWZE.js → chunk-YUKTCDVN.js} +1 -1
  85. package/{chunk-56W233KG.js → chunk-YWY25N4V.js} +1 -1
  86. package/{chunk-RU5D3B22.js → chunk-ZDS63Y4O.js} +2 -2
  87. package/chunk-ZJ7UHBJS.js +89 -0
  88. package/{chunk-SG65C33A.js → chunk-ZLMG6NRV.js} +4 -4
  89. package/{codingSkills-BYQI6EPT.js → codingSkills-FQPCEIWL.js} +2 -2
  90. package/contentThunks-J33BZB3E.js +71 -0
  91. package/{createAgentAutomationAction-7BBF5YXN.js → createAgentAutomationAction-HTMTGX6Q.js} +25 -21
  92. package/{createDialogAction-B5URPHP4.js → createDialogAction-WYQBSN6A.js} +27 -23
  93. package/{createPageAction-ISJKM5Q3.js → createPageAction-ICRRK3SA.js} +27 -22
  94. package/{dbSlice-FWF5F4L7.js → dbSlice-YORO4VL4.js} +6 -6
  95. package/{deleteFile-NPZ64DFN.js → deleteFile-JYKRT7C3.js} +4 -4
  96. package/{dialogCommands-XHH4MVA4.js → dialogCommands-FRSIAPKY.js} +31 -29
  97. package/{dialogSlice-NRAN5X7F.js → dialogSlice-5KPVIAWH.js} +24 -21
  98. package/{docCreateCommands-FUN2Z7HQ.js → docCreateCommands-DBRJMPDX.js} +30 -28
  99. package/{docDeleteCommands-OZDPFXPF.js → docDeleteCommands-BCYPLWXN.js} +31 -29
  100. package/{docReadCommands-FIPK7LE3.js → docReadCommands-L5JX4Q7G.js} +30 -28
  101. package/{docStore-LUS7SWC3.js → docStore-34NXLCEO.js} +8 -33
  102. package/{docUpdateCommands-BZ5GKAN4.js → docUpdateCommands-RELG7XJD.js} +30 -28
  103. package/fetchMessages-KZQVBXKY.js +1 -1
  104. package/{getPricing-HAU62AFM.js → getPricing-FM7TJZFV.js} +4 -4
  105. package/{handleSendMessageAction-RA4OD2ZH.js → handleSendMessageAction-MEYK7RPD.js} +25 -22
  106. package/index.js +64 -64
  107. package/{machineCommands-WDAYEFBE.js → machineCommands-YSXTOWHQ.js} +59 -54
  108. package/{machineWsRunDispatch-TPQ2FQVS.js → machineWsRunDispatch-DNAYOPQT.js} +54 -49
  109. package/memberThunks-KVPBG4V7.js +638 -0
  110. package/{models-4QF4BJVY.js → models-CW5EL6Z7.js} +2 -2
  111. package/package.json +2 -3
  112. package/{read-J7RVVCHH.js → read-NIOV5F7W.js} +4 -4
  113. package/{readDocTool-G2WBM4IH.js → readDocTool-ULKJ5BEM.js} +1 -1
  114. package/{readlineWorkspace-HN44KGIF.js → readlineWorkspace-KZ3LPQG2.js} +829 -393
  115. package/{removeDialogAgentAction-RMPISD42.js → removeDialogAgentAction-JGSCPML3.js} +12 -11
  116. package/{runAgentClientLoop-ZYUI22EA.js → runAgentClientLoop-O2AUHIJT.js} +46 -40
  117. package/{setDialogExtraReferencesAction-7BUTHDAL.js → setDialogExtraReferencesAction-CORU64NM.js} +9 -8
  118. package/{setPrimaryDialogAgentAction-WCYIBGZ4.js → setPrimaryDialogAgentAction-5VS2VKLZ.js} +12 -11
  119. package/{settingSlice-7NN2MI6Y.js → settingSlice-3GNGTC2T.js} +7 -7
  120. package/{skillDiscovery-COX56OBO.js → skillDiscovery-CYUCJMAG.js} +3 -3
  121. package/{spaceCommands-OJ2567D4.js → spaceCommands-OI7RIB2T.js} +30 -28
  122. package/{streamAgentChatTurn-FNFMMGNN.js → streamAgentChatTurn-TA3PGS6C.js} +61 -54
  123. package/{switchDialogAgentAction-WGMMQHDI.js → switchDialogAgentAction-LP433X4D.js} +10 -9
  124. package/{tableCommands-P2TXJ3CF.js → tableCommands-R6WFRDYF.js} +1 -1
  125. package/{toolApiClient-B2MFXMEG.js → toolApiClient-53U4UDFF.js} +3 -2
  126. package/{tools-QCDR3UMD.js → tools-6ZPQ75XA.js} +37 -32
  127. package/{tuiSummaryLlmCaller-LCGT62QC.js → tuiSummaryLlmCaller-YKYQB4ZL.js} +17 -15
  128. package/{updateDialogTitleAction-Y3OGJWDB.js → updateDialogTitleAction-LRJ7NSOS.js} +26 -22
  129. package/chunk-EUG45QJR.js +0 -6104
  130. package/spaceSlice-F7JCOZEF.js +0 -127
  131. package/{chunk-NQ4N4IGO.js → chunk-CS6TCJ7E.js} +3 -3
@@ -1,25 +1,21 @@
1
+ import {
2
+ getCurrentSpaceId,
3
+ getCurrentSpaceIdRaw,
4
+ updateCurrentSpaceIfMatch
5
+ } from "./chunk-ZJ7UHBJS.js";
1
6
  import {
2
7
  deleteDialog,
3
8
  toast
4
- } from "./chunk-EURF2SV6.js";
5
- import {
6
- deleteServerSyncedCredential
7
- } from "./chunk-WX5E6HZS.js";
9
+ } from "./chunk-UMCMW5R3.js";
8
10
  import {
9
11
  require_date_fns
10
12
  } from "./chunk-M76ECQRD.js";
11
13
  import {
12
14
  require_react
13
- } from "./chunk-MRWGHF56.js";
14
- import {
15
- createFileCredentialBroker
16
- } from "./chunk-NQ4N4IGO.js";
17
- import {
18
- toErrorMessage
19
- } from "./chunk-HNMXYYJR.js";
15
+ } from "./chunk-YDH3FDFQ.js";
20
16
  import {
21
17
  isSystemAdmin
22
- } from "./chunk-X7S7OFUX.js";
18
+ } from "./chunk-CEVCRRHU.js";
23
19
  import {
24
20
  asRecordOrEmpty
25
21
  } from "./chunk-KX6YBIHG.js";
@@ -27,52 +23,39 @@ import {
27
23
  UNCATEGORIZED_ID,
28
24
  addContentAction,
29
25
  checkSpaceMembership,
26
+ localSpaceAuthorityPatchStamp
27
+ } from "./chunk-J7KDNHUO.js";
28
+ import {
30
29
  createSpaceKey,
31
- localSpaceAuthorityPatchStamp,
32
30
  normalizeSpaceId
33
- } from "./chunk-4RXXP6WD.js";
31
+ } from "./chunk-UAD2WT54.js";
34
32
  import {
35
33
  patch,
36
34
  read,
37
35
  readAndWait,
38
36
  remove,
39
37
  resolveFileCategory,
40
- selectById,
41
- selectEntities,
42
- toTimestampMs,
43
38
  uploadFileAction,
44
39
  upsertSSREntity,
45
40
  write
46
- } from "./chunk-76UA7376.js";
41
+ } from "./chunk-273FJUYI.js";
47
42
  import {
48
- DB_PREFIX,
49
43
  SEPARATOR,
50
- TYPE_STORAGE_PREFIXES,
51
44
  createKey,
52
45
  fileKey,
53
46
  isAgentKey,
54
- isAppKey,
55
- isDialogKey,
56
- isFileKey,
57
47
  isPageKey,
58
- isTableMetaKey,
59
- isTaskKey,
60
48
  metaKey,
61
49
  rowKey,
62
50
  splitKey,
63
- toTrimmedString,
64
51
  ulid
65
52
  } from "./chunk-SVEUG45B.js";
66
53
  import {
67
54
  asOptionalFiniteNumber
68
55
  } from "./chunk-WWC7I6TA.js";
69
56
  import {
70
- asNonEmptyStringArray,
71
57
  asTrimmedNonEmptyStringArray
72
58
  } from "./chunk-I42VC5KR.js";
73
- import {
74
- readAction
75
- } from "./chunk-2JYSSXLY.js";
76
59
  import {
77
60
  extractUserId
78
61
  } from "./chunk-BJIRLHJR.js";
@@ -80,31 +63,20 @@ import {
80
63
  DEVICE_LOCAL_OWNER_ID,
81
64
  asyncThunkCreator,
82
65
  buildCreateSlice,
66
+ createAsyncThunk,
83
67
  getRuntimeServerContext,
84
- isDeviceLocalOwnerId,
85
68
  isDeviceLocalSpaceBody,
86
- isDeviceLocalSpaceMembership,
87
- resolveEffectiveSpaceActorId,
88
- resolveRecordOwnerUserId,
89
69
  resolveReplicationServers,
90
70
  scheduleDeleteReplication,
91
71
  scheduleWriteReplication,
92
- selectIdentityUserId,
93
- selectRuntimeSnapshot
94
- } from "./chunk-HHBXCRJS.js";
72
+ selectIdentityUserId
73
+ } from "./chunk-XOJRZUPF.js";
95
74
  import {
96
- createClientLogger,
97
- fetchFromServer,
98
- getAllServers,
99
- logger
100
- } from "./chunk-L3JWI7WX.js";
75
+ createClientLogger
76
+ } from "./chunk-QOKAKDPE.js";
101
77
  import {
102
- buildTombstoneRecord,
103
- isTombstoneRecord
78
+ buildTombstoneRecord
104
79
  } from "./chunk-GBRG75BQ.js";
105
- import {
106
- isRecord
107
- } from "./chunk-KUG52IAP.js";
108
80
  import {
109
81
  asTrimmedString
110
82
  } from "./chunk-3EUW3WEO.js";
@@ -112,8 +84,8 @@ import {
112
84
  asOptionalPositiveFiniteNumber
113
85
  } from "./chunk-U6VC4MU4.js";
114
86
  import {
115
- API_ENDPOINTS
116
- } from "./chunk-LCBAMY2M.js";
87
+ isRecord
88
+ } from "./chunk-KUG52IAP.js";
117
89
  import {
118
90
  asOptionalTrimmedString
119
91
  } from "./chunk-G3SUCT4W.js";
@@ -235,550 +207,9 @@ var require_html_parse_stringify = __commonJS({
235
207
  }
236
208
  });
237
209
 
238
- // packages/create/space/category/categoryActions.ts
239
- import { ulid as ulid2 } from "ulid";
240
-
241
- // packages/create/space/spaceCurrentStore.ts
242
- var import_react = __toESM(require_react(), 1);
243
- var VIEW_MODE_STORAGE_KEY = "nolo-space-view-mode";
244
- var readStoredViewMode = () => {
245
- try {
246
- if (typeof window === "undefined") return "all";
247
- return window.localStorage.getItem(VIEW_MODE_STORAGE_KEY) === "categories" ? "categories" : "all";
248
- } catch {
249
- return "all";
250
- }
251
- };
252
- var writeStoredViewMode = (mode) => {
253
- try {
254
- if (typeof window === "undefined") return;
255
- window.localStorage.setItem(VIEW_MODE_STORAGE_KEY, mode);
256
- } catch {
257
- }
258
- };
259
- var createInitialState = () => ({
260
- currentSpaceId: null,
261
- currentSpace: null,
262
- viewMode: readStoredViewMode()
263
- });
264
- var state = createInitialState();
265
- var listeners = /* @__PURE__ */ new Set();
266
- var version = 0;
267
- var notify = () => {
268
- version += 1;
269
- for (const listener of listeners) {
270
- try {
271
- listener();
272
- } catch {
273
- }
274
- }
275
- };
276
- function getCurrentSpaceId() {
277
- return state.viewMode === "all" ? null : state.currentSpaceId;
278
- }
279
- function getCurrentSpaceIdRaw() {
280
- return state.currentSpaceId;
281
- }
282
- function getCurrentSpaceRaw() {
283
- return state.currentSpace;
284
- }
285
- function getViewMode() {
286
- return state.viewMode;
287
- }
288
- function setViewMode(mode) {
289
- if (state.viewMode === mode) return;
290
- state = { ...state, viewMode: mode };
291
- writeStoredViewMode(mode);
292
- notify();
293
- }
294
- function setCurrentSpace(space) {
295
- state = { ...state, currentSpace: space };
296
- notify();
297
- }
298
- function setCurrentSpaceBoth(spaceId, space) {
299
- state = { ...state, currentSpaceId: spaceId, currentSpace: space };
300
- notify();
301
- }
302
- function updateCurrentSpaceIfMatch(spaceId, space) {
303
- const currentId = state.currentSpaceId;
304
- if (currentId && normalizeSpaceId(currentId) === normalizeSpaceId(spaceId)) {
305
- state = { ...state, currentSpace: space };
306
- notify();
307
- }
308
- }
309
- function resetSpaceCurrentState() {
310
- state = { currentSpaceId: null, currentSpace: null, viewMode: "all" };
311
- writeStoredViewMode("all");
312
- notify();
313
- }
314
- function appendDialogContentEntry(dialogKey, title, timestamp) {
315
- if (!state.currentSpace) return;
316
- state = {
317
- ...state,
318
- currentSpace: {
319
- ...state.currentSpace,
320
- contents: {
321
- ...state.currentSpace.contents ?? {},
322
- [dialogKey]: {
323
- title,
324
- type: "dialog",
325
- contentKey: dialogKey,
326
- pinned: false,
327
- createdAt: timestamp,
328
- updatedAt: timestamp
329
- }
330
- },
331
- updatedAt: timestamp
332
- }
333
- };
334
- notify();
335
- }
336
-
337
- // packages/create/space/spaceCollapsedState.ts
338
- var SPACE_COLLAPSE_STORAGE_PREFIX = "space-collapsed-categories:";
339
- var normalizeCollapsedCategories = (value) => {
340
- const entries = Object.entries(asRecordOrEmpty(value)).filter(
341
- ([key, collapsed]) => typeof key === "string" && typeof collapsed === "boolean"
342
- );
343
- return Object.fromEntries(entries);
344
- };
345
- var storageKeyForSpace = (spaceId) => `${SPACE_COLLAPSE_STORAGE_PREFIX}${spaceId}`;
346
- var readStoredCollapsedCategories = (spaceId, storage) => {
347
- if (!spaceId || !storage) return {};
348
- try {
349
- const raw = storage.getItem(storageKeyForSpace(spaceId));
350
- if (!raw) return { [UNCATEGORIZED_ID]: false };
351
- return normalizeCollapsedCategories(JSON.parse(raw));
352
- } catch (error) {
353
- console.warn("[Space] \u8BFB\u53D6\u5206\u7C7B\u6298\u53E0\u72B6\u6001\u5931\u8D25:", error);
354
- return {};
355
- }
356
- };
357
- var writeStoredCollapsedCategories = (spaceId, collapsedCategories, storage) => {
358
- if (!spaceId || !storage) return;
359
- try {
360
- storage.setItem(
361
- storageKeyForSpace(spaceId),
362
- JSON.stringify(normalizeCollapsedCategories(collapsedCategories))
363
- );
364
- } catch (error) {
365
- console.warn("[Space] \u4FDD\u5B58\u5206\u7C7B\u6298\u53E0\u72B6\u6001\u5931\u8D25:", error);
366
- }
367
- };
368
-
369
- // packages/create/space/spaceUiStore.ts
370
- var import_react2 = __toESM(require_react(), 1);
371
- var DEFAULT_COLLAPSED_CATEGORIES = {
372
- [UNCATEGORIZED_ID]: false
373
- };
374
- var FAVORITES_COLLAPSED_STORAGE_KEY = "nolo-sidebar-favorites-collapsed";
375
- var readStoredFavoritesCollapsed = () => {
376
- try {
377
- if (typeof window === "undefined") return false;
378
- return window.localStorage.getItem(FAVORITES_COLLAPSED_STORAGE_KEY) === "1";
379
- } catch {
380
- return false;
381
- }
382
- };
383
- var writeStoredFavoritesCollapsed = (collapsed) => {
384
- try {
385
- if (typeof window === "undefined") return;
386
- window.localStorage.setItem(
387
- FAVORITES_COLLAPSED_STORAGE_KEY,
388
- collapsed ? "1" : "0"
389
- );
390
- } catch {
391
- }
392
- };
393
- var createInitialState2 = () => ({
394
- favoritesCollapsed: readStoredFavoritesCollapsed(),
395
- collapsedCategories: {},
396
- collapsedCategoriesSpaceId: null
397
- });
398
- var state2 = createInitialState2();
399
- var listeners2 = /* @__PURE__ */ new Set();
400
- var version2 = 0;
401
- var notify2 = () => {
402
- version2 += 1;
403
- for (const listener of listeners2) {
404
- try {
405
- listener();
406
- } catch {
407
- }
408
- }
409
- };
410
- function getCollapsedCategories() {
411
- return state2.collapsedCategories;
412
- }
413
- function setCollapsedCategories(categories, spaceId) {
414
- state2 = {
415
- ...state2,
416
- collapsedCategories: categories,
417
- collapsedCategoriesSpaceId: spaceId
418
- };
419
- notify2();
420
- }
421
- function toggleCategoryCollapse(categoryId) {
422
- const current = state2.collapsedCategories[categoryId] ?? (DEFAULT_COLLAPSED_CATEGORIES[categoryId] ?? true);
423
- state2 = {
424
- ...state2,
425
- collapsedCategories: {
426
- ...state2.collapsedCategories,
427
- [categoryId]: !current
428
- }
429
- };
430
- notify2();
431
- }
432
- function expandCategoryInCollapsed(categoryId, spaceId) {
433
- if (!categoryId || categoryId === UNCATEGORIZED_ID) return;
434
- state2 = {
435
- ...state2,
436
- collapsedCategories: {
437
- ...state2.collapsedCategories,
438
- [categoryId]: false
439
- }
440
- };
441
- if (typeof window !== "undefined") {
442
- writeStoredCollapsedCategories(
443
- spaceId,
444
- state2.collapsedCategories,
445
- window.localStorage
446
- );
447
- }
448
- notify2();
449
- }
450
- function resetSpaceUiState() {
451
- state2 = {
452
- favoritesCollapsed: false,
453
- collapsedCategories: {},
454
- collapsedCategoriesSpaceId: null
455
- };
456
- writeStoredFavoritesCollapsed(false);
457
- notify2();
458
- }
459
-
460
- // packages/create/space/category/categoryActions.ts
461
- var createCategoryActions = (create) => ({
462
- // --- Regular Reducers ---
463
- /**
464
- * (新增) 从持久化存储中水合分类的折叠状态
465
- */
466
- hydrateCollapsedCategories: create.reducer(
467
- (state6, action) => {
468
- setCollapsedCategories(
469
- normalizeCollapsedCategories(action.payload),
470
- getCurrentSpaceIdRaw()
471
- );
472
- }
473
- ),
474
- // --- Async Thunks ---
475
- /**
476
- * 批量切换所有分类的折叠状态,并持久化到本地
477
- */
478
- setAllCategoriesCollapsed: create.asyncThunk(
479
- async (input, thunkAPI) => {
480
- const { getState } = thunkAPI;
481
- const rootState = getState();
482
- const spaceId = input.spaceId || getCurrentSpaceId();
483
- if (!spaceId) throw new Error("\u65E0\u6CD5\u5207\u6362\u6298\u53E0\u72B6\u6001\uFF1A\u6CA1\u6709\u6D3B\u52A8\u7684\u7A7A\u95F4\u3002");
484
- const currentSpace = getCurrentSpaceRaw();
485
- const categoryIds = currentSpace?.categories ? Object.keys(currentSpace.categories) : [];
486
- categoryIds.push(UNCATEGORIZED_ID);
487
- const collapsedCategories = {};
488
- categoryIds.forEach((id) => {
489
- collapsedCategories[id] = input.collapsed;
490
- });
491
- if (typeof window !== "undefined") {
492
- writeStoredCollapsedCategories(
493
- spaceId,
494
- collapsedCategories,
495
- window.localStorage
496
- );
497
- }
498
- setCollapsedCategories(collapsedCategories, spaceId);
499
- return collapsedCategories;
500
- },
501
- {
502
- rejected: (state6, action) => {
503
- console.error("\u6279\u91CF\u5207\u6362\u5206\u7C7B\u6298\u53E0\u72B6\u6001\u5931\u8D25:", action.error.message);
504
- }
505
- }
506
- ),
507
- /**
508
- * 切换单个分类的折叠状态,并持久化存储。
509
- * 直接使用当前激活的 spaceId,无需外部传入。
510
- */
511
- toggleCategoryCollapse: create.asyncThunk(
512
- async (input, thunkAPI) => {
513
- const { getState } = thunkAPI;
514
- const { categoryId } = input;
515
- const rootState = getState();
516
- const spaceId = getCurrentSpaceId();
517
- if (!spaceId) throw new Error("\u65E0\u6CD5\u5207\u6362\u6298\u53E0\u72B6\u6001\uFF1A\u6CA1\u6709\u6D3B\u52A8\u7684\u7A7A\u95F4\u3002");
518
- if (!categoryId) throw new Error("\u65E0\u6548\u7684\u5206\u7C7BID\u3002");
519
- const defaultCollapsed = DEFAULT_COLLAPSED_CATEGORIES[categoryId] ?? true;
520
- const currentCollapsedCategories = getCollapsedCategories();
521
- const isCurrentlyCollapsed = currentCollapsedCategories[categoryId] ?? defaultCollapsed;
522
- const newCollapsedState = !isCurrentlyCollapsed;
523
- const collapsedCategories = {
524
- ...currentCollapsedCategories,
525
- [categoryId]: newCollapsedState
526
- };
527
- if (typeof window !== "undefined") {
528
- writeStoredCollapsedCategories(
529
- spaceId,
530
- collapsedCategories,
531
- window.localStorage
532
- );
533
- }
534
- toggleCategoryCollapse(categoryId);
535
- return collapsedCategories;
536
- },
537
- {
538
- rejected: (state6, action) => {
539
- console.error("\u5207\u6362\u5206\u7C7B\u6298\u53E0\u72B6\u6001\u5931\u8D25:", action.error.message);
540
- }
541
- }
542
- ),
543
- /**
544
- * 添加新分类
545
- */
546
- addCategory: create.asyncThunk(
547
- async (input, thunkAPI) => {
548
- const { spaceId: inputSpaceId, name, categoryId, order } = input;
549
- const { dispatch, getState } = thunkAPI;
550
- const rootState = getState();
551
- const spaceId = inputSpaceId || getCurrentSpaceId();
552
- if (!spaceId) {
553
- throw new Error("\u65E0\u6CD5\u6DFB\u52A0\u5206\u7C7B\uFF1A\u672A\u9009\u62E9\u5F53\u524D\u7A7A\u95F4\u4E14\u672A\u63D0\u4F9B\u7A7A\u95F4 ID\u3002");
554
- }
555
- const currentUserId = selectIdentityUserId(rootState);
556
- if (!currentUserId) throw new Error("User is not logged in.");
557
- if (!name.trim()) {
558
- throw new Error("\u65E0\u6548\u7684\u5206\u7C7B\u540D\u79F0\u3002");
559
- }
560
- const spaceKey = createSpaceKey.space(spaceId);
561
- const spaceData = await dispatch(read({
562
- dbKey: spaceKey
563
- })).unwrap();
564
- checkSpaceMembership(spaceData, currentUserId);
565
- const newCategoryId = categoryId || ulid2();
566
- if (spaceData.categories?.[newCategoryId]) {
567
- throw new Error(`\u5206\u7C7B ID "${newCategoryId}" \u5DF2\u5B58\u5728\u3002`);
568
- }
569
- const existingValidCategories = spaceData.categories ? Object.values(spaceData.categories).filter(Boolean) : [];
570
- const finalOrder = typeof order === "number" ? order : existingValidCategories.length;
571
- const nowISO = (/* @__PURE__ */ new Date()).toISOString();
572
- const newCategory = {
573
- name: name.trim(),
574
- order: finalOrder,
575
- updatedAt: nowISO
576
- };
577
- const updatedSpaceData = await dispatch(
578
- patch({
579
- dbKey: spaceKey,
580
- changes: {
581
- categories: { [newCategoryId]: newCategory },
582
- updatedAt: nowISO
583
- }
584
- })
585
- ).unwrap();
586
- const currentCollapsedCategories = getCollapsedCategories();
587
- const collapsedCategories = {
588
- ...currentCollapsedCategories,
589
- [newCategoryId]: false
590
- };
591
- if (typeof window !== "undefined") {
592
- writeStoredCollapsedCategories(
593
- spaceId,
594
- collapsedCategories,
595
- window.localStorage
596
- );
597
- }
598
- expandCategoryInCollapsed(newCategoryId, spaceId);
599
- return { spaceId, updatedSpaceData, newCategoryId, collapsedCategories };
600
- },
601
- {
602
- fulfilled: (state6, action) => {
603
- if (getCurrentSpaceIdRaw() === action.payload.spaceId) {
604
- updateCurrentSpaceIfMatch(action.payload.spaceId, action.payload.updatedSpaceData);
605
- }
606
- }
607
- }
608
- ),
609
- /**
610
- * 删除单个分类
611
- */
612
- deleteCategory: create.asyncThunk(
613
- async (input, thunkAPI) => {
614
- const { categoryId, spaceId } = input;
615
- const { dispatch, getState } = thunkAPI;
616
- const rootState = getState();
617
- const currentUserId = selectIdentityUserId(rootState);
618
- if (!currentUserId) throw new Error("User is not logged in.");
619
- if (!categoryId.trim()) throw new Error("\u65E0\u6548\u7684 categoryId\u3002");
620
- const spaceKey = createSpaceKey.space(spaceId);
621
- const spaceData = await dispatch(read({
622
- dbKey: spaceKey
623
- })).unwrap();
624
- checkSpaceMembership(spaceData, currentUserId);
625
- if (!spaceData?.categories?.[categoryId]) {
626
- throw new Error("\u6307\u5B9A\u7684\u5206\u7C7B\u4E0D\u5B58\u5728\u6216\u5DF2\u88AB\u5220\u9664\u3002");
627
- }
628
- const nowISO = (/* @__PURE__ */ new Date()).toISOString();
629
- const changes = {
630
- categories: { [categoryId]: null },
631
- updatedAt: nowISO
632
- };
633
- if (spaceData.contents) {
634
- const contentsPatch = {};
635
- let contentsChanged = false;
636
- for (const key in spaceData.contents) {
637
- if (spaceData.contents[key]?.categoryId === categoryId) {
638
- contentsPatch[key] = {
639
- categoryId: null,
640
- updatedAt: nowISO
641
- };
642
- contentsChanged = true;
643
- }
644
- }
645
- if (contentsChanged) changes.contents = contentsPatch;
646
- }
647
- const updatedSpaceData = await dispatch(
648
- patch({ dbKey: spaceKey, changes })
649
- ).unwrap();
650
- const collapsedCategories = { ...getCollapsedCategories() };
651
- delete collapsedCategories[categoryId];
652
- setCollapsedCategories(collapsedCategories, spaceId);
653
- if (typeof window !== "undefined") {
654
- writeStoredCollapsedCategories(
655
- spaceId,
656
- collapsedCategories,
657
- window.localStorage
658
- );
659
- }
660
- return { spaceId, updatedSpaceData, collapsedCategories };
661
- },
662
- {
663
- fulfilled: (state6, action) => {
664
- if (getCurrentSpaceIdRaw() === action.payload.spaceId) {
665
- updateCurrentSpaceIfMatch(action.payload.spaceId, action.payload.updatedSpaceData);
666
- }
667
- }
668
- }
669
- ),
670
- /**
671
- * 修改分类名称
672
- */
673
- updateCategoryName: create.asyncThunk(
674
- async (input, thunkAPI) => {
675
- const { spaceId, categoryId, name } = input;
676
- const { dispatch, getState } = thunkAPI;
677
- const currentUserId = selectIdentityUserId(getState());
678
- if (!currentUserId) throw new Error("User is not logged in.");
679
- if (!categoryId.trim()) throw new Error("\u65E0\u6548\u7684 categoryId\u3002");
680
- const trimmedName = name.trim();
681
- if (!trimmedName) throw new Error("\u5206\u7C7B\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A\u6216\u4EC5\u5305\u542B\u7A7A\u683C\u3002");
682
- const spaceKey = createSpaceKey.space(spaceId);
683
- const spaceData = await dispatch(read({
684
- dbKey: spaceKey
685
- })).unwrap();
686
- checkSpaceMembership(spaceData, currentUserId);
687
- const existingCategory = spaceData.categories?.[categoryId];
688
- if (!existingCategory) {
689
- throw new Error("\u6307\u5B9A\u7684\u5206\u7C7B\u4E0D\u5B58\u5728\u3002");
690
- }
691
- const nowISO = (/* @__PURE__ */ new Date()).toISOString();
692
- const changes = {
693
- categories: {
694
- [categoryId]: {
695
- ...existingCategory,
696
- name: trimmedName,
697
- updatedAt: nowISO
698
- }
699
- },
700
- updatedAt: nowISO
701
- };
702
- const updatedSpaceData = await dispatch(
703
- patch({ dbKey: spaceKey, changes })
704
- ).unwrap();
705
- return { spaceId, updatedSpaceData };
706
- },
707
- {
708
- fulfilled: (state6, action) => {
709
- if (getCurrentSpaceIdRaw() === action.payload.spaceId) {
710
- updateCurrentSpaceIfMatch(action.payload.spaceId, action.payload.updatedSpaceData);
711
- }
712
- }
713
- }
714
- ),
715
- /**
716
- * 重新排序分类
717
- */
718
- reorderCategories: create.asyncThunk(
719
- async (input, thunkAPI) => {
720
- const { spaceId, sortedCategoryIds } = input;
721
- const { dispatch, getState } = thunkAPI;
722
- const stateRoot = getState();
723
- const currentUserId = selectIdentityUserId(stateRoot);
724
- if (!currentUserId) {
725
- throw new Error("User is not logged in.");
726
- }
727
- if (!Array.isArray(sortedCategoryIds)) {
728
- throw new Error(
729
- "Invalid sortedCategoryIds provided: must be an array."
730
- );
731
- }
732
- const spaceKey = createSpaceKey.space(spaceId);
733
- const spaceData = await dispatch(read({
734
- dbKey: spaceKey
735
- })).unwrap();
736
- checkSpaceMembership(spaceData, currentUserId);
737
- if (!spaceData.categories || Object.keys(spaceData.categories).length === 0) {
738
- return { spaceId, updatedSpaceData: spaceData };
739
- }
740
- const nowISO = (/* @__PURE__ */ new Date()).toISOString();
741
- const currentCategories = spaceData.categories;
742
- const updatedCategoriesChanges = {};
743
- let hasValidChanges = false;
744
- sortedCategoryIds.forEach((catId, index) => {
745
- const existingCategory = currentCategories[catId];
746
- if (existingCategory) {
747
- updatedCategoriesChanges[catId] = {
748
- ...existingCategory,
749
- order: index,
750
- updatedAt: nowISO
751
- };
752
- if (existingCategory.order !== index) {
753
- hasValidChanges = true;
754
- }
755
- }
756
- });
757
- if (!hasValidChanges) {
758
- return { spaceId, updatedSpaceData: spaceData };
759
- }
760
- const changes = {
761
- categories: updatedCategoriesChanges,
762
- updatedAt: nowISO
763
- };
764
- const updatedSpaceData = await dispatch(
765
- patch({ dbKey: spaceKey, changes })
766
- ).unwrap();
767
- return { spaceId, updatedSpaceData };
768
- },
769
- {
770
- fulfilled: (state6, action) => {
771
- if (getCurrentSpaceIdRaw() === action.payload.spaceId) {
772
- updateCurrentSpaceIfMatch(action.payload.spaceId, action.payload.updatedSpaceData);
773
- }
774
- }
775
- }
776
- )
777
- });
778
-
779
210
  // packages/render/table/tableSlice.ts
780
211
  var import_date_fns2 = __toESM(require_date_fns(), 1);
781
- import { ulid as ulid4 } from "ulid";
212
+ import { ulid as ulid3 } from "ulid";
782
213
 
783
214
  // packages/render/table/fetchAndCacheTableRows.ts
784
215
  var getRowTimestamp = (row) => {
@@ -1133,7 +564,7 @@ function addColumnOptionInMeta(meta, input, deps) {
1133
564
 
1134
565
  // packages/render/table/createTableAction.ts
1135
566
  var import_date_fns = __toESM(require_date_fns(), 1);
1136
- import { ulid as ulid3 } from "ulid";
567
+ import { ulid as ulid2 } from "ulid";
1137
568
 
1138
569
  // node_modules/i18next/dist/esm/i18next.js
1139
570
  var isString = (obj) => typeof obj === "string";
@@ -3509,10 +2940,10 @@ var loadNamespaces = instance.loadNamespaces;
3509
2940
  var loadLanguages = instance.loadLanguages;
3510
2941
 
3511
2942
  // node_modules/react-i18next/dist/es/Trans.js
3512
- var import_react5 = __toESM(require_react(), 1);
2943
+ var import_react3 = __toESM(require_react(), 1);
3513
2944
 
3514
2945
  // node_modules/react-i18next/dist/es/TransWithoutContext.js
3515
- var import_react3 = __toESM(require_react(), 1);
2946
+ var import_react = __toESM(require_react(), 1);
3516
2947
  var import_html_parse_stringify = __toESM(require_html_parse_stringify(), 1);
3517
2948
 
3518
2949
  // node_modules/react-i18next/dist/es/unescape.js
@@ -3568,7 +2999,7 @@ var setI18n = (instance2) => {
3568
2999
  };
3569
3000
 
3570
3001
  // node_modules/react-i18next/dist/es/context.js
3571
- var import_react4 = __toESM(require_react(), 1);
3002
+ var import_react2 = __toESM(require_react(), 1);
3572
3003
 
3573
3004
  // node_modules/react-i18next/dist/es/initReactI18next.js
3574
3005
  var initReactI18next = {
@@ -3580,22 +3011,22 @@ var initReactI18next = {
3580
3011
  };
3581
3012
 
3582
3013
  // node_modules/react-i18next/dist/es/context.js
3583
- var I18nContext = (0, import_react4.createContext)();
3014
+ var I18nContext = (0, import_react2.createContext)();
3584
3015
 
3585
3016
  // node_modules/react-i18next/dist/es/useTranslation.js
3586
- var import_react6 = __toESM(require_react(), 1);
3017
+ var import_react4 = __toESM(require_react(), 1);
3587
3018
 
3588
3019
  // node_modules/react-i18next/dist/es/withTranslation.js
3589
- var import_react7 = __toESM(require_react(), 1);
3020
+ var import_react5 = __toESM(require_react(), 1);
3590
3021
 
3591
3022
  // node_modules/react-i18next/dist/es/I18nextProvider.js
3592
- var import_react8 = __toESM(require_react(), 1);
3023
+ var import_react6 = __toESM(require_react(), 1);
3593
3024
 
3594
3025
  // node_modules/react-i18next/dist/es/withSSR.js
3595
- var import_react10 = __toESM(require_react(), 1);
3026
+ var import_react8 = __toESM(require_react(), 1);
3596
3027
 
3597
3028
  // node_modules/react-i18next/dist/es/useSSR.js
3598
- var import_react9 = __toESM(require_react(), 1);
3029
+ var import_react7 = __toESM(require_react(), 1);
3599
3030
 
3600
3031
  // packages/app/i18n/i18n.base.ts
3601
3032
  var i18nBaseConfig = {
@@ -3646,7 +3077,7 @@ var normalizeColumns = (inputColumns) => {
3646
3077
  const name = c.name.trim();
3647
3078
  if (!name) return null;
3648
3079
  const col = {
3649
- id: asOptionalTrimmedString(c.id) ?? ulid3(),
3080
+ id: asOptionalTrimmedString(c.id) ?? ulid2(),
3650
3081
  name
3651
3082
  };
3652
3083
  const label = asOptionalTrimmedString(c.label);
@@ -3678,7 +3109,7 @@ var normalizeColumns = (inputColumns) => {
3678
3109
  }
3679
3110
  return DEFAULT_COLUMNS.map((c) => ({
3680
3111
  ...c,
3681
- id: ulid3()
3112
+ id: ulid2()
3682
3113
  }));
3683
3114
  };
3684
3115
  var normalizeStringArray = (value) => {
@@ -3717,11 +3148,11 @@ var createTableAction = async ({
3717
3148
  columns,
3718
3149
  withDefaultRows = true
3719
3150
  } = {}, { dispatch, getState }) => {
3720
- const state6 = getState();
3721
- const userId = selectIdentityUserId(state6);
3151
+ const state2 = getState();
3152
+ const userId = selectIdentityUserId(state2);
3722
3153
  if (!userId) throw new Error("User ID not found.");
3723
3154
  const spaceId = customSpaceId ?? getCurrentSpaceId();
3724
- const tableId = ulid3();
3155
+ const tableId = ulid2();
3725
3156
  const now = /* @__PURE__ */ new Date();
3726
3157
  const nowIso = (0, import_date_fns.formatISO)(now);
3727
3158
  const dbKey = metaKey(userId, tableId);
@@ -3848,8 +3279,8 @@ var deleteTableAction = async ({ dbKey }, {
3848
3279
  extra
3849
3280
  }) => {
3850
3281
  const { db } = extra;
3851
- const state6 = getState();
3852
- const { currentServer, syncServers } = getRuntimeServerContext(state6);
3282
+ const state2 = getState();
3283
+ const { currentServer, syncServers } = getRuntimeServerContext(state2);
3853
3284
  const { tenantId, tableId } = parseMetaKey(dbKey);
3854
3285
  const nowIso = (/* @__PURE__ */ new Date()).toISOString();
3855
3286
  const rowPrefix = createKey("row", tenantId, tableId, "");
@@ -3904,7 +3335,7 @@ var deleteTableAction = async ({ dbKey }, {
3904
3335
  syncServers,
3905
3336
  dbKey,
3906
3337
  deleteOptions: { type: "table" },
3907
- state: state6
3338
+ state: state2
3908
3339
  });
3909
3340
  return dbKey;
3910
3341
  };
@@ -3939,37 +3370,37 @@ var tableSlice = createSliceWithThunks({
3939
3370
  const { tenantId, tableId } = args;
3940
3371
  const dbKey = metaKey(tenantId, tableId);
3941
3372
  try {
3942
- const readAction2 = await dispatch(readAndWait(dbKey));
3943
- if (readAndWait.fulfilled.match(readAction2) && readAction2.payload) {
3944
- const meta = readAction2.payload;
3373
+ const readAction = await dispatch(readAndWait(dbKey));
3374
+ if (readAndWait.fulfilled.match(readAction) && readAction.payload) {
3375
+ const meta = readAction.payload;
3945
3376
  return meta;
3946
3377
  }
3947
- const msg = readAction2.payload?.message || `\u65E0\u6CD5\u52A0\u8F7D\u8868 ${tableId}`;
3378
+ const msg = readAction.payload?.message || `\u65E0\u6CD5\u52A0\u8F7D\u8868 ${tableId}`;
3948
3379
  return rejectWithValue(msg);
3949
3380
  } catch (e) {
3950
3381
  return rejectWithValue(e.message || `\u521D\u59CB\u5316\u8868 ${tableId} \u65F6\u51FA\u9519`);
3951
3382
  }
3952
3383
  },
3953
3384
  {
3954
- pending: (state6) => {
3955
- state6.isLoading = true;
3956
- state6.error = null;
3957
- state6.isInitialized = false;
3958
- state6.currentTable = null;
3959
- state6.rows = [];
3385
+ pending: (state2) => {
3386
+ state2.isLoading = true;
3387
+ state2.error = null;
3388
+ state2.isInitialized = false;
3389
+ state2.currentTable = null;
3390
+ state2.rows = [];
3960
3391
  },
3961
- fulfilled: (state6, action) => {
3962
- state6.isLoading = false;
3963
- state6.isInitialized = true;
3964
- state6.currentTable = action.payload;
3965
- state6.error = null;
3392
+ fulfilled: (state2, action) => {
3393
+ state2.isLoading = false;
3394
+ state2.isInitialized = true;
3395
+ state2.currentTable = action.payload;
3396
+ state2.error = null;
3966
3397
  },
3967
- rejected: (state6, action) => {
3968
- state6.isLoading = false;
3969
- state6.isInitialized = true;
3970
- state6.currentTable = null;
3971
- state6.error = action.payload || action.error.message || "\u521D\u59CB\u5316\u8868\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
3972
- state6.rows = [];
3398
+ rejected: (state2, action) => {
3399
+ state2.isLoading = false;
3400
+ state2.isInitialized = true;
3401
+ state2.currentTable = null;
3402
+ state2.error = action.payload || action.error.message || "\u521D\u59CB\u5316\u8868\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
3403
+ state2.rows = [];
3973
3404
  }
3974
3405
  }
3975
3406
  ),
@@ -3981,8 +3412,8 @@ var tableSlice = createSliceWithThunks({
3981
3412
  const { tenantId, tableId } = args;
3982
3413
  const { db } = extra;
3983
3414
  try {
3984
- const state6 = getState();
3985
- const { currentToken: token, remoteServers } = getRuntimeServerContext(state6);
3415
+ const state2 = getState();
3416
+ const { currentToken: token, remoteServers } = getRuntimeServerContext(state2);
3986
3417
  return await fetchAndCacheTableRows({
3987
3418
  db,
3988
3419
  tenantId,
@@ -3995,15 +3426,15 @@ var tableSlice = createSliceWithThunks({
3995
3426
  }
3996
3427
  },
3997
3428
  {
3998
- pending: (state6) => {
3999
- state6.error = null;
3429
+ pending: (state2) => {
3430
+ state2.error = null;
4000
3431
  },
4001
- fulfilled: (state6, action) => {
4002
- state6.rows = action.payload;
3432
+ fulfilled: (state2, action) => {
3433
+ state2.rows = action.payload;
4003
3434
  },
4004
- rejected: (state6, action) => {
4005
- state6.error = action.payload || action.error.message || "\u52A0\u8F7D\u8868\u884C\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
4006
- state6.rows = [];
3435
+ rejected: (state2, action) => {
3436
+ state2.error = action.payload || action.error.message || "\u52A0\u8F7D\u8868\u884C\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
3437
+ state2.rows = [];
4007
3438
  }
4008
3439
  }
4009
3440
  ),
@@ -4038,18 +3469,18 @@ var tableSlice = createSliceWithThunks({
4038
3469
  }
4039
3470
  },
4040
3471
  {
4041
- pending: (state6) => {
4042
- state6.error = null;
3472
+ pending: (state2) => {
3473
+ state2.error = null;
4043
3474
  },
4044
- fulfilled: (state6, action) => {
3475
+ fulfilled: (state2, action) => {
4045
3476
  const row = action.payload;
4046
- const meta = state6.currentTable;
3477
+ const meta = state2.currentTable;
4047
3478
  if (meta && row?.tenantId === meta.tenantId && row?.tableId === meta.tableId) {
4048
- state6.rows.push(row);
3479
+ state2.rows.push(row);
4049
3480
  }
4050
3481
  },
4051
- rejected: (state6, action) => {
4052
- state6.error = action.payload || action.error.message || "\u65B0\u589E\u8868\u884C\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
3482
+ rejected: (state2, action) => {
3483
+ state2.error = action.payload || action.error.message || "\u65B0\u589E\u8868\u884C\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
4053
3484
  }
4054
3485
  }
4055
3486
  ),
@@ -4059,8 +3490,8 @@ var tableSlice = createSliceWithThunks({
4059
3490
  deleteRow: create.asyncThunk(
4060
3491
  async (dbKey, { dispatch, getState, rejectWithValue, extra }) => {
4061
3492
  try {
4062
- const state6 = getState();
4063
- const row = state6.table.rows.find((item) => item?.dbKey === dbKey);
3493
+ const state2 = getState();
3494
+ const row = state2.table.rows.find((item) => item?.dbKey === dbKey);
4064
3495
  if (!row) {
4065
3496
  return rejectWithValue(`\u5F53\u524D\u8868\u4E2D\u627E\u4E0D\u5230\u8981\u5220\u9664\u7684\u884C\uFF1A${dbKey}`);
4066
3497
  }
@@ -4075,7 +3506,7 @@ var tableSlice = createSliceWithThunks({
4075
3506
  await extra.db.put(dbKey, tombstoneRow);
4076
3507
  }
4077
3508
  dispatch(upsertSSREntity(tombstoneRow));
4078
- const { currentServer, syncServers } = getRuntimeServerContext(state6);
3509
+ const { currentServer, syncServers } = getRuntimeServerContext(state2);
4079
3510
  const servers = resolveReplicationServers(currentServer, syncServers);
4080
3511
  scheduleWriteReplication(
4081
3512
  servers,
@@ -4083,7 +3514,7 @@ var tableSlice = createSliceWithThunks({
4083
3514
  data: tombstoneRow,
4084
3515
  customKey: dbKey
4085
3516
  },
4086
- state6
3517
+ state2
4087
3518
  );
4088
3519
  return dbKey;
4089
3520
  } catch (e) {
@@ -4091,15 +3522,15 @@ var tableSlice = createSliceWithThunks({
4091
3522
  }
4092
3523
  },
4093
3524
  {
4094
- pending: (state6) => {
4095
- state6.error = null;
3525
+ pending: (state2) => {
3526
+ state2.error = null;
4096
3527
  },
4097
- fulfilled: (state6, action) => {
3528
+ fulfilled: (state2, action) => {
4098
3529
  const dbKey = action.payload;
4099
- state6.rows = state6.rows.filter((row) => row.dbKey !== dbKey);
3530
+ state2.rows = state2.rows.filter((row) => row.dbKey !== dbKey);
4100
3531
  },
4101
- rejected: (state6, action) => {
4102
- state6.error = action.payload || action.error.message || "\u5220\u9664\u8868\u884C\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
3532
+ rejected: (state2, action) => {
3533
+ state2.error = action.payload || action.error.message || "\u5220\u9664\u8868\u884C\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
4103
3534
  }
4104
3535
  }
4105
3536
  ),
@@ -4109,19 +3540,19 @@ var tableSlice = createSliceWithThunks({
4109
3540
  deleteTable: create.asyncThunk(
4110
3541
  deleteTableAction,
4111
3542
  {
4112
- pending: (state6) => {
4113
- state6.error = null;
3543
+ pending: (state2) => {
3544
+ state2.error = null;
4114
3545
  },
4115
- fulfilled: (state6, action) => {
3546
+ fulfilled: (state2, action) => {
4116
3547
  const deletedKey = action.payload;
4117
- if (state6.currentTable?.dbKey === deletedKey) {
4118
- state6.currentTable = null;
4119
- state6.rows = [];
4120
- state6.isInitialized = false;
3548
+ if (state2.currentTable?.dbKey === deletedKey) {
3549
+ state2.currentTable = null;
3550
+ state2.rows = [];
3551
+ state2.isInitialized = false;
4121
3552
  }
4122
3553
  },
4123
- rejected: (state6, action) => {
4124
- state6.error = action.payload || action.error.message || "\u5220\u9664\u8868\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
3554
+ rejected: (state2, action) => {
3555
+ state2.error = action.payload || action.error.message || "\u5220\u9664\u8868\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
4125
3556
  }
4126
3557
  }
4127
3558
  ),
@@ -4131,15 +3562,15 @@ var tableSlice = createSliceWithThunks({
4131
3562
  addColumn: create.asyncThunk(
4132
3563
  async (args, { dispatch, getState, rejectWithValue }) => {
4133
3564
  const { tenantId, tableId, columnName } = args;
4134
- const state6 = getState().table;
4135
- const meta = state6.currentTable;
3565
+ const state2 = getState().table;
3566
+ const meta = state2.currentTable;
4136
3567
  if (!meta || meta.tenantId !== tenantId || meta.tableId !== tableId) {
4137
3568
  return rejectWithValue("\u5F53\u524D\u6CA1\u6709\u52A0\u8F7D\u5BF9\u5E94\u7684\u8868\u5B9A\u4E49");
4138
3569
  }
4139
3570
  const result = addColumnToMeta(
4140
3571
  meta,
4141
3572
  { columnName },
4142
- { id: ulid4(), nowIso: (0, import_date_fns2.formatISO)(/* @__PURE__ */ new Date()) }
3573
+ { id: ulid3(), nowIso: (0, import_date_fns2.formatISO)(/* @__PURE__ */ new Date()) }
4143
3574
  );
4144
3575
  if (!result.ok) {
4145
3576
  return rejectWithValue(result.error);
@@ -4157,15 +3588,15 @@ var tableSlice = createSliceWithThunks({
4157
3588
  }
4158
3589
  },
4159
3590
  {
4160
- pending: (state6) => {
4161
- state6.error = null;
3591
+ pending: (state2) => {
3592
+ state2.error = null;
4162
3593
  },
4163
- fulfilled: (state6, action) => {
4164
- state6.currentTable = action.payload;
4165
- state6.isInitialized = true;
3594
+ fulfilled: (state2, action) => {
3595
+ state2.currentTable = action.payload;
3596
+ state2.isInitialized = true;
4166
3597
  },
4167
- rejected: (state6, action) => {
4168
- state6.error = action.payload || action.error.message || "\u4E3A\u8868\u65B0\u589E\u5B57\u6BB5\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
3598
+ rejected: (state2, action) => {
3599
+ state2.error = action.payload || action.error.message || "\u4E3A\u8868\u65B0\u589E\u5B57\u6BB5\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
4169
3600
  }
4170
3601
  }
4171
3602
  ),
@@ -4175,14 +3606,14 @@ var tableSlice = createSliceWithThunks({
4175
3606
  deleteColumn: create.asyncThunk(
4176
3607
  async (args, { dispatch, getState, rejectWithValue }) => {
4177
3608
  const { tenantId, tableId, columnName } = args;
4178
- const state6 = getState().table;
4179
- const meta = state6.currentTable;
3609
+ const state2 = getState().table;
3610
+ const meta = state2.currentTable;
4180
3611
  if (!meta || meta.tenantId !== tenantId || meta.tableId !== tableId) {
4181
3612
  return rejectWithValue("\u5F53\u524D\u6CA1\u6709\u52A0\u8F7D\u5BF9\u5E94\u7684\u8868\u5B9A\u4E49");
4182
3613
  }
4183
3614
  const result = deleteColumnFromMeta(
4184
3615
  meta,
4185
- state6.rows,
3616
+ state2.rows,
4186
3617
  { columnName },
4187
3618
  { nowIso: (0, import_date_fns2.formatISO)(/* @__PURE__ */ new Date()) }
4188
3619
  );
@@ -4203,16 +3634,16 @@ var tableSlice = createSliceWithThunks({
4203
3634
  }
4204
3635
  },
4205
3636
  {
4206
- pending: (state6) => {
4207
- state6.error = null;
3637
+ pending: (state2) => {
3638
+ state2.error = null;
4208
3639
  },
4209
- fulfilled: (state6, action) => {
4210
- state6.currentTable = action.payload.meta;
4211
- state6.rows = action.payload.rows;
4212
- state6.isInitialized = true;
3640
+ fulfilled: (state2, action) => {
3641
+ state2.currentTable = action.payload.meta;
3642
+ state2.rows = action.payload.rows;
3643
+ state2.isInitialized = true;
4213
3644
  },
4214
- rejected: (state6, action) => {
4215
- state6.error = action.payload || action.error.message || "\u5220\u9664\u5B57\u6BB5\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
3645
+ rejected: (state2, action) => {
3646
+ state2.error = action.payload || action.error.message || "\u5220\u9664\u5B57\u6BB5\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
4216
3647
  }
4217
3648
  }
4218
3649
  ),
@@ -4222,8 +3653,8 @@ var tableSlice = createSliceWithThunks({
4222
3653
  reorderColumn: create.asyncThunk(
4223
3654
  async (args, { dispatch, getState, rejectWithValue }) => {
4224
3655
  const { tenantId, tableId, fromIndex, toIndex } = args;
4225
- const state6 = getState().table;
4226
- const meta = state6.currentTable;
3656
+ const state2 = getState().table;
3657
+ const meta = state2.currentTable;
4227
3658
  if (!meta || meta.tenantId !== tenantId || meta.tableId !== tableId) {
4228
3659
  return rejectWithValue("\u5F53\u524D\u6CA1\u6709\u52A0\u8F7D\u5BF9\u5E94\u7684\u8868\u5B9A\u4E49");
4229
3660
  }
@@ -4249,15 +3680,15 @@ var tableSlice = createSliceWithThunks({
4249
3680
  }
4250
3681
  },
4251
3682
  {
4252
- pending: (state6) => {
4253
- state6.error = null;
3683
+ pending: (state2) => {
3684
+ state2.error = null;
4254
3685
  },
4255
- fulfilled: (state6, action) => {
4256
- state6.currentTable = action.payload;
4257
- state6.isInitialized = true;
3686
+ fulfilled: (state2, action) => {
3687
+ state2.currentTable = action.payload;
3688
+ state2.isInitialized = true;
4258
3689
  },
4259
- rejected: (state6, action) => {
4260
- state6.error = action.payload || action.error.message || "\u8C03\u6574\u5217\u987A\u5E8F\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
3690
+ rejected: (state2, action) => {
3691
+ state2.error = action.payload || action.error.message || "\u8C03\u6574\u5217\u987A\u5E8F\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
4261
3692
  }
4262
3693
  }
4263
3694
  ),
@@ -4269,14 +3700,14 @@ var tableSlice = createSliceWithThunks({
4269
3700
  renameColumn: create.asyncThunk(
4270
3701
  async (args, { dispatch, getState, rejectWithValue }) => {
4271
3702
  const { tenantId, tableId, oldName, newName } = args;
4272
- const state6 = getState().table;
4273
- const meta = state6.currentTable;
3703
+ const state2 = getState().table;
3704
+ const meta = state2.currentTable;
4274
3705
  if (!meta || meta.tenantId !== tenantId || meta.tableId !== tableId) {
4275
3706
  return rejectWithValue("\u5F53\u524D\u6CA1\u6709\u52A0\u8F7D\u5BF9\u5E94\u7684\u8868\u5B9A\u4E49");
4276
3707
  }
4277
3708
  const result = renameColumnInMeta(
4278
3709
  meta,
4279
- state6.rows,
3710
+ state2.rows,
4280
3711
  { oldName, newName },
4281
3712
  { nowIso: (0, import_date_fns2.formatISO)(/* @__PURE__ */ new Date()) }
4282
3713
  );
@@ -4297,16 +3728,16 @@ var tableSlice = createSliceWithThunks({
4297
3728
  }
4298
3729
  },
4299
3730
  {
4300
- pending: (state6) => {
4301
- state6.error = null;
3731
+ pending: (state2) => {
3732
+ state2.error = null;
4302
3733
  },
4303
- fulfilled: (state6, action) => {
4304
- state6.currentTable = action.payload.meta;
4305
- state6.rows = action.payload.rows;
4306
- state6.isInitialized = true;
3734
+ fulfilled: (state2, action) => {
3735
+ state2.currentTable = action.payload.meta;
3736
+ state2.rows = action.payload.rows;
3737
+ state2.isInitialized = true;
4307
3738
  },
4308
- rejected: (state6, action) => {
4309
- state6.error = action.payload || action.error.message || "\u91CD\u547D\u540D\u5B57\u6BB5\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
3739
+ rejected: (state2, action) => {
3740
+ state2.error = action.payload || action.error.message || "\u91CD\u547D\u540D\u5B57\u6BB5\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
4310
3741
  }
4311
3742
  }
4312
3743
  ),
@@ -4318,8 +3749,8 @@ var tableSlice = createSliceWithThunks({
4318
3749
  renameColumnLabel: create.asyncThunk(
4319
3750
  async (args, { dispatch, getState, rejectWithValue }) => {
4320
3751
  const { tenantId, tableId, columnId, newLabel } = args;
4321
- const state6 = getState().table;
4322
- const meta = state6.currentTable;
3752
+ const state2 = getState().table;
3753
+ const meta = state2.currentTable;
4323
3754
  if (!meta || meta.tenantId !== tenantId || meta.tableId !== tableId) {
4324
3755
  return rejectWithValue("\u5F53\u524D\u6CA1\u6709\u52A0\u8F7D\u5BF9\u5E94\u7684\u8868\u5B9A\u4E49");
4325
3756
  }
@@ -4342,15 +3773,15 @@ var tableSlice = createSliceWithThunks({
4342
3773
  }
4343
3774
  },
4344
3775
  {
4345
- pending: (state6) => {
4346
- state6.error = null;
3776
+ pending: (state2) => {
3777
+ state2.error = null;
4347
3778
  },
4348
- fulfilled: (state6, action) => {
4349
- state6.currentTable = action.payload;
4350
- state6.isInitialized = true;
3779
+ fulfilled: (state2, action) => {
3780
+ state2.currentTable = action.payload;
3781
+ state2.isInitialized = true;
4351
3782
  },
4352
- rejected: (state6, action) => {
4353
- state6.error = action.payload || action.error.message || "\u91CD\u547D\u540D\u5B57\u6BB5\u663E\u793A\u540D\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
3783
+ rejected: (state2, action) => {
3784
+ state2.error = action.payload || action.error.message || "\u91CD\u547D\u540D\u5B57\u6BB5\u663E\u793A\u540D\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
4354
3785
  }
4355
3786
  }
4356
3787
  ),
@@ -4361,8 +3792,8 @@ var tableSlice = createSliceWithThunks({
4361
3792
  updateColumnWidth: create.asyncThunk(
4362
3793
  async (args, { dispatch, getState, rejectWithValue }) => {
4363
3794
  const { tenantId, tableId, columnId, width } = args;
4364
- const state6 = getState().table;
4365
- const meta = state6.currentTable;
3795
+ const state2 = getState().table;
3796
+ const meta = state2.currentTable;
4366
3797
  if (!meta || meta.tenantId !== tenantId || meta.tableId !== tableId) {
4367
3798
  return rejectWithValue("\u5F53\u524D\u6CA1\u6709\u52A0\u8F7D\u5BF9\u5E94\u7684\u8868\u5B9A\u4E49");
4368
3799
  }
@@ -4385,15 +3816,15 @@ var tableSlice = createSliceWithThunks({
4385
3816
  }
4386
3817
  },
4387
3818
  {
4388
- pending: (state6) => {
4389
- state6.error = null;
3819
+ pending: (state2) => {
3820
+ state2.error = null;
4390
3821
  },
4391
- fulfilled: (state6, action) => {
4392
- state6.currentTable = action.payload;
4393
- state6.isInitialized = true;
3822
+ fulfilled: (state2, action) => {
3823
+ state2.currentTable = action.payload;
3824
+ state2.isInitialized = true;
4394
3825
  },
4395
- rejected: (state6, action) => {
4396
- state6.error = action.payload || action.error.message || "\u66F4\u65B0\u5B57\u6BB5\u5BBD\u5EA6\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
3826
+ rejected: (state2, action) => {
3827
+ state2.error = action.payload || action.error.message || "\u66F4\u65B0\u5B57\u6BB5\u5BBD\u5EA6\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
4397
3828
  }
4398
3829
  }
4399
3830
  ),
@@ -4405,8 +3836,8 @@ var tableSlice = createSliceWithThunks({
4405
3836
  addColumnOption: create.asyncThunk(
4406
3837
  async (args, { dispatch, getState, rejectWithValue }) => {
4407
3838
  const { tenantId, tableId, columnId, option } = args;
4408
- const state6 = getState().table;
4409
- const meta = state6.currentTable;
3839
+ const state2 = getState().table;
3840
+ const meta = state2.currentTable;
4410
3841
  if (!meta || meta.tenantId !== tenantId || meta.tableId !== tableId) {
4411
3842
  return rejectWithValue("\u5F53\u524D\u6CA1\u6709\u52A0\u8F7D\u5BF9\u5E94\u7684\u8868\u5B9A\u4E49");
4412
3843
  }
@@ -4432,15 +3863,15 @@ var tableSlice = createSliceWithThunks({
4432
3863
  }
4433
3864
  },
4434
3865
  {
4435
- pending: (state6) => {
4436
- state6.error = null;
3866
+ pending: (state2) => {
3867
+ state2.error = null;
4437
3868
  },
4438
- fulfilled: (state6, action) => {
4439
- state6.currentTable = action.payload;
4440
- state6.isInitialized = true;
3869
+ fulfilled: (state2, action) => {
3870
+ state2.currentTable = action.payload;
3871
+ state2.isInitialized = true;
4441
3872
  },
4442
- rejected: (state6, action) => {
4443
- state6.error = action.payload || action.error.message || "\u65B0\u589E\u9009\u9879\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
3873
+ rejected: (state2, action) => {
3874
+ state2.error = action.payload || action.error.message || "\u65B0\u589E\u9009\u9879\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
4444
3875
  }
4445
3876
  }
4446
3877
  ),
@@ -4454,8 +3885,8 @@ var tableSlice = createSliceWithThunks({
4454
3885
  if (!trimmedName) {
4455
3886
  return rejectWithValue("\u8868\u540D\u4E0D\u80FD\u4E3A\u7A7A");
4456
3887
  }
4457
- const state6 = getState().table;
4458
- const meta = state6.currentTable;
3888
+ const state2 = getState().table;
3889
+ const meta = state2.currentTable;
4459
3890
  if (!meta || meta.tenantId !== tenantId || meta.tableId !== tableId) {
4460
3891
  return rejectWithValue("\u5F53\u524D\u6CA1\u6709\u52A0\u8F7D\u5BF9\u5E94\u7684\u8868\u5B9A\u4E49");
4461
3892
  }
@@ -4481,22 +3912,22 @@ var tableSlice = createSliceWithThunks({
4481
3912
  }
4482
3913
  },
4483
3914
  {
4484
- pending: (state6) => {
4485
- state6.error = null;
3915
+ pending: (state2) => {
3916
+ state2.error = null;
4486
3917
  },
4487
- fulfilled: (state6, action) => {
4488
- state6.currentTable = action.payload;
3918
+ fulfilled: (state2, action) => {
3919
+ state2.currentTable = action.payload;
4489
3920
  },
4490
- rejected: (state6, action) => {
4491
- state6.error = action.payload || action.error.message || "\u91CD\u547D\u540D\u8868\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
3921
+ rejected: (state2, action) => {
3922
+ state2.error = action.payload || action.error.message || "\u91CD\u547D\u540D\u8868\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
4492
3923
  }
4493
3924
  }
4494
3925
  ),
4495
3926
  updateTableIcon: create.asyncThunk(
4496
3927
  async (args, { dispatch, getState, rejectWithValue }) => {
4497
3928
  const { tenantId, tableId, icon } = args;
4498
- const state6 = getState().table;
4499
- const meta = state6.currentTable;
3929
+ const state2 = getState().table;
3930
+ const meta = state2.currentTable;
4500
3931
  if (!meta || meta.tenantId !== tenantId || meta.tableId !== tableId) {
4501
3932
  return rejectWithValue("\u5F53\u524D\u6CA1\u6709\u52A0\u8F7D\u5BF9\u5E94\u7684\u8868\u5B9A\u4E49");
4502
3933
  }
@@ -4522,14 +3953,14 @@ var tableSlice = createSliceWithThunks({
4522
3953
  }
4523
3954
  },
4524
3955
  {
4525
- pending: (state6) => {
4526
- state6.error = null;
3956
+ pending: (state2) => {
3957
+ state2.error = null;
4527
3958
  },
4528
- fulfilled: (state6, action) => {
4529
- state6.currentTable = action.payload;
3959
+ fulfilled: (state2, action) => {
3960
+ state2.currentTable = action.payload;
4530
3961
  },
4531
- rejected: (state6, action) => {
4532
- state6.error = action.payload || action.error.message || "\u66F4\u65B0\u8868\u683C\u56FE\u6807\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
3962
+ rejected: (state2, action) => {
3963
+ state2.error = action.payload || action.error.message || "\u66F4\u65B0\u8868\u683C\u56FE\u6807\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
4533
3964
  }
4534
3965
  }
4535
3966
  ),
@@ -4556,19 +3987,19 @@ var tableSlice = createSliceWithThunks({
4556
3987
  }
4557
3988
  },
4558
3989
  {
4559
- pending: (state6) => {
4560
- state6.error = null;
3990
+ pending: (state2) => {
3991
+ state2.error = null;
4561
3992
  },
4562
- fulfilled: (state6, action) => {
3993
+ fulfilled: (state2, action) => {
4563
3994
  const { dbKey, columnName, value, updatedAt } = action.payload;
4564
- const row = state6.rows.find((r) => r.dbKey === dbKey);
3995
+ const row = state2.rows.find((r) => r.dbKey === dbKey);
4565
3996
  if (row) {
4566
3997
  row[columnName] = value;
4567
3998
  row.updatedAt = updatedAt;
4568
3999
  }
4569
4000
  },
4570
- rejected: (state6, action) => {
4571
- state6.error = action.payload || action.error.message || "\u66F4\u65B0\u5355\u5143\u683C\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
4001
+ rejected: (state2, action) => {
4002
+ state2.error = action.payload || action.error.message || "\u66F4\u65B0\u5355\u5143\u683C\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
4572
4003
  }
4573
4004
  }
4574
4005
  ),
@@ -4576,12 +4007,12 @@ var tableSlice = createSliceWithThunks({
4576
4007
  * 5. 重置当前表状态
4577
4008
  * ------------------------------------*/
4578
4009
  setTableFocusContext: create.reducer(
4579
- (state6, action) => {
4580
- state6.focusContext = action.payload;
4010
+ (state2, action) => {
4011
+ state2.focusContext = action.payload;
4581
4012
  }
4582
4013
  ),
4583
- resetTable: create.reducer((state6) => {
4584
- Object.assign(state6, initialState);
4014
+ resetTable: create.reducer((state2) => {
4015
+ Object.assign(state2, initialState);
4585
4016
  })
4586
4017
  }),
4587
4018
  selectors: {
@@ -4659,11 +4090,11 @@ var ENTITY_DELETE_STRATEGIES = {
4659
4090
  await dispatch(deleteTable({ dbKey: key })).unwrap();
4660
4091
  },
4661
4092
  file: async (key, { thunkAPI }) => {
4662
- const { deleteFileAction } = await import("./deleteFile-NPZ64DFN.js");
4093
+ const { deleteFileAction } = await import("./deleteFile-JYKRT7C3.js");
4663
4094
  await deleteFileAction(key, thunkAPI);
4664
4095
  },
4665
4096
  image: async (key, { thunkAPI }) => {
4666
- const { deleteFileAction } = await import("./deleteFile-NPZ64DFN.js");
4097
+ const { deleteFileAction } = await import("./deleteFile-JYKRT7C3.js");
4667
4098
  await deleteFileAction(key, thunkAPI);
4668
4099
  },
4669
4100
  agent: async (key, { dispatch, userId, sourceServerOrigin }) => {
@@ -4759,7 +4190,7 @@ var deleteContentFromSpaceAction = async (input, thunkAPI) => {
4759
4190
  };
4760
4191
 
4761
4192
  // packages/create/space/content/moveContentAction.ts
4762
- var logger2 = createClientLogger("move-content");
4193
+ var logger = createClientLogger("move-content");
4763
4194
  var moveContentAction = async (input, thunkAPI) => {
4764
4195
  const {
4765
4196
  contentKey,
@@ -4768,18 +4199,18 @@ var moveContentAction = async (input, thunkAPI) => {
4768
4199
  targetCategoryId: rawTargetCategoryId
4769
4200
  } = input;
4770
4201
  const { dispatch, getState } = thunkAPI;
4771
- const state6 = getState();
4772
- const userId = selectIdentityUserId(state6);
4202
+ const state2 = getState();
4203
+ const userId = selectIdentityUserId(state2);
4773
4204
  const now = Date.now();
4774
- logger2.info({ ...input, userId }, "Initiating moveContentAction");
4205
+ logger.info({ ...input, userId }, "Initiating moveContentAction");
4775
4206
  if (sourceSpaceId === targetSpaceId) {
4776
- logger2.error("Source and target space IDs are the same.");
4207
+ logger.error("Source and target space IDs are the same.");
4777
4208
  throw new Error(
4778
4209
  "\u6E90\u7A7A\u95F4\u548C\u76EE\u6807\u7A7A\u95F4\u4E0D\u80FD\u76F8\u540C\u3002\u5982\u9700\u4FEE\u6539\u5206\u7C7B\uFF0C\u8BF7\u4F7F\u7528\u66F4\u65B0\u5206\u7C7B\u64CD\u4F5C\u3002"
4779
4210
  );
4780
4211
  }
4781
4212
  if (!contentKey || typeof contentKey !== "string" || contentKey.trim() === "") {
4782
- logger2.error("Invalid contentKey provided.");
4213
+ logger.error("Invalid contentKey provided.");
4783
4214
  throw new Error("\u65E0\u6548\u7684\u5185\u5BB9 Key\u3002");
4784
4215
  }
4785
4216
  let sourceSpaceData = null;
@@ -4791,7 +4222,7 @@ var moveContentAction = async (input, thunkAPI) => {
4791
4222
  try {
4792
4223
  const sourceSpaceKey = createSpaceKey.space(sourceSpaceId);
4793
4224
  const targetSpaceKey = createSpaceKey.space(targetSpaceId);
4794
- logger2.info(
4225
+ logger.info(
4795
4226
  { sourceSpaceKey, targetSpaceKey },
4796
4227
  "Reading source and target space data."
4797
4228
  );
@@ -4817,11 +4248,11 @@ var moveContentAction = async (input, thunkAPI) => {
4817
4248
  );
4818
4249
  }
4819
4250
  targetSpaceData = targetResult.value;
4820
- logger2.info("Checking permissions for source and target spaces.");
4251
+ logger.info("Checking permissions for source and target spaces.");
4821
4252
  checkSpaceMembership(sourceSpaceData, userId);
4822
4253
  checkSpaceMembership(targetSpaceData, userId);
4823
4254
  if (!sourceSpaceData.contents || !sourceSpaceData.contents[contentKey]) {
4824
- logger2.error(
4255
+ logger.error(
4825
4256
  { contentKey, sourceSpaceId },
4826
4257
  "Content key not found in source space contents."
4827
4258
  );
@@ -4831,7 +4262,7 @@ var moveContentAction = async (input, thunkAPI) => {
4831
4262
  }
4832
4263
  contentDataFromSource = sourceSpaceData.contents[contentKey];
4833
4264
  if (targetSpaceData.contents && targetSpaceData.contents[contentKey]) {
4834
- logger2.warn(
4265
+ logger.warn(
4835
4266
  { contentKey, targetSpaceId },
4836
4267
  "Content key already exists in target space. Overwriting."
4837
4268
  );
@@ -4841,7 +4272,7 @@ var moveContentAction = async (input, thunkAPI) => {
4841
4272
  if (targetSpaceData.categories?.[rawTargetCategoryId]) {
4842
4273
  categoryIdForTargetStorage = rawTargetCategoryId;
4843
4274
  } else {
4844
- logger2.warn(
4275
+ logger.warn(
4845
4276
  `Target category ${rawTargetCategoryId} not found in target space ${targetSpaceId}. Content will be uncategorized.`
4846
4277
  );
4847
4278
  categoryIdForTargetStorage = void 0;
@@ -4873,7 +4304,7 @@ var moveContentAction = async (input, thunkAPI) => {
4873
4304
  updatedAt: now,
4874
4305
  ...localSpaceAuthorityPatchStamp(targetSpaceData)
4875
4306
  };
4876
- logger2.info("Patching source and target space data.");
4307
+ logger.info("Patching source and target space data.");
4877
4308
  await Promise.all([
4878
4309
  dispatch(
4879
4310
  patch({ dbKey: sourceSpaceKey, changes: sourcePatchChanges })
@@ -4882,15 +4313,15 @@ var moveContentAction = async (input, thunkAPI) => {
4882
4313
  patch({ dbKey: targetSpaceKey, changes: targetPatchChanges })
4883
4314
  ).unwrap()
4884
4315
  ]);
4885
- logger2.info("Successfully patched both source and target spaces.");
4316
+ logger.info("Successfully patched both source and target spaces.");
4886
4317
  } catch (error) {
4887
- logger2.error(
4318
+ logger.error(
4888
4319
  { error: error.message, stack: error.stack },
4889
4320
  "Error during move content action execution."
4890
4321
  );
4891
4322
  overallError = error.message || "\u79FB\u52A8\u5185\u5BB9\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
4892
4323
  } finally {
4893
- logger2.info("Attempting to re-read final space data.");
4324
+ logger.info("Attempting to re-read final space data.");
4894
4325
  const sourceSpaceKey = createSpaceKey.space(sourceSpaceId);
4895
4326
  const targetSpaceKey = createSpaceKey.space(targetSpaceId);
4896
4327
  const [finalSourceResult, finalTargetResult] = await Promise.allSettled([
@@ -4904,7 +4335,7 @@ var moveContentAction = async (input, thunkAPI) => {
4904
4335
  if (finalSourceResult.status === "fulfilled") {
4905
4336
  finalSourceData = finalSourceResult.value;
4906
4337
  } else {
4907
- logger2.error(
4338
+ logger.error(
4908
4339
  { sourceSpaceId, reason: finalSourceResult.reason },
4909
4340
  "Failed to re-read final source space data."
4910
4341
  );
@@ -4912,12 +4343,12 @@ var moveContentAction = async (input, thunkAPI) => {
4912
4343
  if (finalTargetResult.status === "fulfilled") {
4913
4344
  finalTargetData = finalTargetResult.value;
4914
4345
  } else {
4915
- logger2.error(
4346
+ logger.error(
4916
4347
  { targetSpaceId, reason: finalTargetResult.reason },
4917
4348
  "Failed to re-read final target space data."
4918
4349
  );
4919
4350
  }
4920
- logger2.info(
4351
+ logger.info(
4921
4352
  {
4922
4353
  hasError: !!overallError,
4923
4354
  sourceReadSuccess: !!finalSourceData,
@@ -5123,8 +4554,8 @@ var updateContentPinnedAction = async (input, thunkAPI) => {
5123
4554
  var updateContentCategoryAction = async (input, thunkAPI) => {
5124
4555
  const { spaceId, contentKey, categoryId: targetContainerId } = input;
5125
4556
  const { dispatch, getState } = thunkAPI;
5126
- const state6 = getState();
5127
- const userId = selectIdentityUserId(state6);
4557
+ const state2 = getState();
4558
+ const userId = selectIdentityUserId(state2);
5128
4559
  if (!userId) {
5129
4560
  throw new Error("User is not logged in.");
5130
4561
  }
@@ -5220,17 +4651,17 @@ var updateContentCategoryAction = async (input, thunkAPI) => {
5220
4651
  };
5221
4652
 
5222
4653
  // packages/create/space/content/deleteMultipleContentAction.ts
5223
- var logger3 = createClientLogger("delete-multiple-content");
4654
+ var logger2 = createClientLogger("delete-multiple-content");
5224
4655
  var deleteMultipleContentAction = async (input, thunkAPI) => {
5225
4656
  const { contentKeys, spaceId } = input;
5226
4657
  if (!contentKeys || contentKeys.length === 0) {
5227
- logger3.warn("deleteMultipleContentAction called with no contentKeys.");
4658
+ logger2.warn("deleteMultipleContentAction called with no contentKeys.");
5228
4659
  return { spaceId, updatedSpaceData: null };
5229
4660
  }
5230
4661
  const { dispatch, getState } = thunkAPI;
5231
- const state6 = getState();
5232
- const userId = selectIdentityUserId(state6);
5233
- logger3.info(
4662
+ const state2 = getState();
4663
+ const userId = selectIdentityUserId(state2);
4664
+ logger2.info(
5234
4665
  { count: contentKeys.length, spaceId, userId },
5235
4666
  "Initiating deleteMultipleContentAction"
5236
4667
  );
@@ -5241,11 +4672,11 @@ var deleteMultipleContentAction = async (input, thunkAPI) => {
5241
4672
  })
5242
4673
  ).unwrap();
5243
4674
  if (!spaceData) {
5244
- logger3.error({ spaceKey }, "Space data not found for batch delete");
4675
+ logger2.error({ spaceKey }, "Space data not found for batch delete");
5245
4676
  throw new Error("\u7A7A\u95F4\u4E0D\u5B58\u5728");
5246
4677
  }
5247
4678
  if (!userId || !spaceData.members.includes(userId)) {
5248
- logger3.warn({ userId, spaceId }, "Unauthorized attempt for batch delete");
4679
+ logger2.warn({ userId, spaceId }, "Unauthorized attempt for batch delete");
5249
4680
  throw new Error("\u65E0\u6743\u4FEE\u6539\u6B64\u7A7A\u95F4");
5250
4681
  }
5251
4682
  const changes = {
@@ -5259,12 +4690,12 @@ var deleteMultipleContentAction = async (input, thunkAPI) => {
5259
4690
  };
5260
4691
  try {
5261
4692
  await dispatch(patch({ dbKey: spaceKey, changes })).unwrap();
5262
- logger3.info(
4693
+ logger2.info(
5263
4694
  { spaceKey, count: contentKeys.length },
5264
4695
  "Successfully batched patch to remove content references"
5265
4696
  );
5266
4697
  } catch (patchError) {
5267
- logger3.error(
4698
+ logger2.error(
5268
4699
  { error: patchError, spaceKey },
5269
4700
  "Failed to batch patch space data. Aborting."
5270
4701
  );
@@ -5276,9 +4707,9 @@ var deleteMultipleContentAction = async (input, thunkAPI) => {
5276
4707
  const results = await Promise.allSettled(removePromises);
5277
4708
  results.forEach((result, index) => {
5278
4709
  if (result.status === "fulfilled") {
5279
- logger3.info({ contentKey: contentKeys[index] }, "Entity removed");
4710
+ logger2.info({ contentKey: contentKeys[index] }, "Entity removed");
5280
4711
  } else {
5281
- logger3.error(
4712
+ logger2.error(
5282
4713
  { contentKey: contentKeys[index], error: result.reason },
5283
4714
  "Failed to remove an entity"
5284
4715
  );
@@ -5289,7 +4720,7 @@ var deleteMultipleContentAction = async (input, thunkAPI) => {
5289
4720
  dbKey: spaceKey
5290
4721
  })
5291
4722
  ).unwrap();
5292
- logger3.info({ spaceId }, "Finished batch delete and refetched space data.");
4723
+ logger2.info({ spaceId }, "Finished batch delete and refetched space data.");
5293
4724
  return {
5294
4725
  spaceId,
5295
4726
  updatedSpaceData: finalSpaceData
@@ -5300,8 +4731,8 @@ var deleteMultipleContentAction = async (input, thunkAPI) => {
5300
4731
  var uploadAndAddFileToSpaceAction = async (payload, thunkAPI) => {
5301
4732
  const { spaceId, file, categoryId } = payload;
5302
4733
  const { dispatch, getState } = thunkAPI;
5303
- const state6 = getState();
5304
- const userId = selectIdentityUserId(state6);
4734
+ const state2 = getState();
4735
+ const userId = selectIdentityUserId(state2);
5305
4736
  if (!userId) {
5306
4737
  console.warn("[uploadAndAddFileToSpace] Warning: No userId found in state. Uploading as anonymous/unknown might cause issues.");
5307
4738
  }
@@ -5356,2242 +4787,270 @@ var uploadAndAddFileToSpaceAction = async (payload, thunkAPI) => {
5356
4787
  }
5357
4788
  };
5358
4789
 
5359
- // packages/create/space/content/contentThunks.ts
5360
- var createContentThunks = (create) => ({
5361
- /**
5362
- * Add content into a space. When the content lands in a real category,
5363
- * force-expand that category (Redux + localStorage) so "create page"
5364
- * never leaves the new item trapped inside a default-collapsed section.
5365
- */
5366
- addContentToSpace: create.asyncThunk(
5367
- async (input, thunkAPI) => {
5368
- const result = await addContentAction(input, thunkAPI);
5369
- const rawCategoryId = asTrimmedString(input.categoryId);
5370
- const expandCategoryId = rawCategoryId && rawCategoryId !== UNCATEGORIZED_ID ? rawCategoryId : null;
5371
- if (expandCategoryId) {
5372
- const collapsedCategories = {
5373
- ...getCollapsedCategories(),
5374
- [expandCategoryId]: false
5375
- };
5376
- if (typeof window !== "undefined") {
5377
- writeStoredCollapsedCategories(
5378
- result.spaceId,
5379
- collapsedCategories,
5380
- window.localStorage
5381
- );
5382
- }
5383
- expandCategoryInCollapsed(expandCategoryId, result.spaceId);
5384
- return { ...result, expandCategoryId, collapsedCategories };
5385
- }
5386
- return { ...result, expandCategoryId: null };
5387
- },
5388
- {
5389
- fulfilled: (state6, action) => {
5390
- const { spaceId, updatedSpaceData } = action.payload;
5391
- const normalizedSpaceId = normalizeSpaceId(spaceId);
5392
- const rawSpaceId = getCurrentSpaceIdRaw();
5393
- const normalizedCurrentSpaceId = rawSpaceId ? normalizeSpaceId(rawSpaceId) : null;
5394
- if (normalizedCurrentSpaceId === normalizedSpaceId && updatedSpaceData) {
5395
- updateCurrentSpaceIfMatch(action.payload.spaceId, updatedSpaceData);
5396
- }
5397
- }
5398
- }
5399
- ),
5400
- moveContentToSpace: create.asyncThunk(moveContentAction, {
5401
- fulfilled: (_state, action) => {
5402
- const {
5403
- sourceSpaceId,
5404
- updatedSourceSpaceData,
5405
- targetSpaceId,
5406
- updatedTargetSpaceData
5407
- } = action.payload;
5408
- if (getCurrentSpaceIdRaw() === sourceSpaceId && updatedSourceSpaceData) {
5409
- updateCurrentSpaceIfMatch(sourceSpaceId, updatedSourceSpaceData);
5410
- }
5411
- if (getCurrentSpaceIdRaw() === targetSpaceId && updatedTargetSpaceData) {
5412
- updateCurrentSpaceIfMatch(targetSpaceId, updatedTargetSpaceData);
5413
- }
5414
- }
5415
- }),
5416
- deleteContentFromSpace: create.asyncThunk(deleteContentFromSpaceAction, {
5417
- fulfilled: (_state, action) => {
5418
- const { spaceId, updatedSpaceData } = action.payload;
5419
- const normalizedSpaceId = normalizeSpaceId(spaceId);
5420
- const rawSpaceId = getCurrentSpaceIdRaw();
5421
- const normalizedCurrentSpaceId = rawSpaceId ? normalizeSpaceId(rawSpaceId) : null;
5422
- if (normalizedCurrentSpaceId === normalizedSpaceId && updatedSpaceData) {
5423
- updateCurrentSpaceIfMatch(action.payload.spaceId, updatedSpaceData);
5424
- }
5425
- }
5426
- }),
5427
- // --- 新增: 批量删除内容的 Thunk ---
5428
- deleteMultipleContent: create.asyncThunk(deleteMultipleContentAction, {
5429
- fulfilled: (_state, action) => {
5430
- const normalizedSpaceId = normalizeSpaceId(action.payload.spaceId);
5431
- const rawSpaceId = getCurrentSpaceIdRaw();
5432
- const normalizedCurrentSpaceId = rawSpaceId ? normalizeSpaceId(rawSpaceId) : null;
5433
- if (normalizedCurrentSpaceId === normalizedSpaceId && action.payload.updatedSpaceData) {
5434
- updateCurrentSpaceIfMatch(action.payload.spaceId, action.payload.updatedSpaceData);
5435
- }
5436
- }
5437
- }),
5438
- uploadAndAddFileToSpace: create.asyncThunk(uploadAndAddFileToSpaceAction, {
5439
- fulfilled: (state6, action) => {
5440
- if (getCurrentSpaceIdRaw() === action.payload.spaceId) {
5441
- updateCurrentSpaceIfMatch(action.payload.spaceId, action.payload.updatedSpaceData);
5442
- }
5443
- }
5444
- }),
5445
- // --- 结束新增 ---
5446
- updateContentTitle: create.asyncThunk(updateContentTitleAction, {
5447
- fulfilled: (state6, action) => {
5448
- if (getCurrentSpaceIdRaw() === action.payload.spaceId) {
5449
- updateCurrentSpaceIfMatch(action.payload.spaceId, action.payload.updatedSpaceData);
5450
- }
5451
- },
5452
- rejected: (_state, action) => {
5453
- const message = action.error.message || "\u6807\u9898\u4FDD\u5B58\u5931\u8D25";
5454
- if (message.includes("\u65E0\u6CD5\u52A0\u8F7D\u7A7A\u95F4\u6570\u636E")) return;
5455
- toast.error(message);
5456
- }
5457
- }),
5458
- updateContentPinned: create.asyncThunk(updateContentPinnedAction, {
5459
- fulfilled: (state6, action) => {
5460
- if (action.payload.updatedSpaceData && getCurrentSpaceIdRaw() === action.payload.spaceId) {
5461
- updateCurrentSpaceIfMatch(action.payload.spaceId, action.payload.updatedSpaceData);
5462
- }
5463
- },
5464
- rejected: (_state, action) => {
5465
- toast.error(action.error.message || "\u7F6E\u9876\u72B6\u6001\u66F4\u65B0\u5931\u8D25");
5466
- }
5467
- }),
5468
- updateContentCategory: create.asyncThunk(updateContentCategoryAction, {
5469
- fulfilled: (state6, action) => {
5470
- if (getCurrentSpaceIdRaw() === action.payload.spaceId) {
5471
- updateCurrentSpaceIfMatch(action.payload.spaceId, action.payload.updatedSpaceData);
5472
- }
5473
- }
5474
- })
5475
- });
5476
-
5477
- // packages/create/space/spaceAccess.ts
5478
- var resolveSpaceRemoteServers = (state6) => {
5479
- const currentServer = typeof state6?.settings?.currentServer === "string" ? state6.settings.currentServer : void 0;
5480
- const syncServers = Array.isArray(state6?.settings?.syncServers) ? state6.settings.syncServers : void 0;
5481
- return getAllServers(currentServer, syncServers);
5482
- };
5483
- var selectSpaceRemoteAuth = (state6) => ({
5484
- token: state6?.auth?.currentToken ?? null,
5485
- userId: state6?.auth?.currentUser?.userId ?? null,
5486
- servers: resolveSpaceRemoteServers(state6)
5487
- });
5488
- var spaceListsUser = (spaceData, userId) => {
5489
- if (!spaceData || isTombstoneRecord(spaceData)) return false;
5490
- if (spaceData.ownerId === userId) return true;
5491
- return Array.isArray(spaceData.members) && spaceData.members.includes(userId);
4790
+ // packages/create/space/spaceCollapsedState.ts
4791
+ var SPACE_COLLAPSE_STORAGE_PREFIX = "space-collapsed-categories:";
4792
+ var normalizeCollapsedCategories = (value) => {
4793
+ const entries = Object.entries(asRecordOrEmpty(value)).filter(
4794
+ ([key, collapsed]) => typeof key === "string" && typeof collapsed === "boolean"
4795
+ );
4796
+ return Object.fromEntries(entries);
5492
4797
  };
5493
- var membershipBelongsToUser = (membership, userId) => !membership.userId || membership.userId === userId;
5494
- var membershipFetchCache = /* @__PURE__ */ new Map();
5495
- var MEMBERSHIP_FETCH_CACHE_TTL_MS = 3e4;
5496
- async function fetchMembershipsFromServer(server, token, userId, timeoutMs) {
5497
- if (!token) return { ok: false, memberships: [] };
5498
- const controller = new AbortController();
5499
- const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
4798
+ var storageKeyForSpace = (spaceId) => `${SPACE_COLLAPSE_STORAGE_PREFIX}${spaceId}`;
4799
+ var readStoredCollapsedCategories = (spaceId, storage) => {
4800
+ if (!spaceId || !storage) return {};
5500
4801
  try {
5501
- const response = await fetch(`${server}/rpc/getUserSpaceMemberships`, {
5502
- method: "POST",
5503
- headers: {
5504
- Authorization: `Bearer ${token}`,
5505
- "Content-Type": "application/json"
5506
- },
5507
- body: JSON.stringify({ userId }),
5508
- signal: controller.signal
5509
- });
5510
- clearTimeout(timeoutId);
5511
- if (!response.ok) {
5512
- console.error(
5513
- `Failed to fetch memberships from ${server}: ${response.statusText}`
5514
- );
5515
- return { ok: false, memberships: [] };
5516
- }
5517
- const data = await response.json();
5518
- return {
5519
- ok: true,
5520
- server,
5521
- memberships: Array.isArray(data) ? data : []
5522
- };
4802
+ const raw = storage.getItem(storageKeyForSpace(spaceId));
4803
+ if (!raw) return { [UNCATEGORIZED_ID]: false };
4804
+ return normalizeCollapsedCategories(JSON.parse(raw));
5523
4805
  } catch (error) {
5524
- clearTimeout(timeoutId);
5525
- console.error(`Error fetching memberships from ${server}:`, error);
5526
- return { ok: false, memberships: [] };
4806
+ console.warn("[Space] \u8BFB\u53D6\u5206\u7C7B\u6298\u53E0\u72B6\u6001\u5931\u8D25:", error);
4807
+ return {};
5527
4808
  }
5528
- }
5529
- var fetchRemoteUserSpaceMemberships = (server, token, userId, timeoutMs = 5e3) => {
5530
- const cacheKey = `${server}|${userId}`;
5531
- const cached = membershipFetchCache.get(cacheKey);
5532
- if (cached) return cached;
5533
- const promise = fetchMembershipsFromServer(server, token, userId, timeoutMs);
5534
- membershipFetchCache.set(cacheKey, promise);
5535
- promise.catch(() => {
5536
- }).finally(() => {
5537
- setTimeout(() => {
5538
- if (membershipFetchCache.get(cacheKey) === promise) {
5539
- membershipFetchCache.delete(cacheKey);
5540
- }
5541
- }, MEMBERSHIP_FETCH_CACHE_TTL_MS);
5542
- });
5543
- return promise;
5544
4809
  };
5545
- var fetchRemoteSpace = async (server, token, spaceId) => {
4810
+ var writeStoredCollapsedCategories = (spaceId, collapsedCategories, storage) => {
4811
+ if (!spaceId || !storage) return;
5546
4812
  try {
5547
- const space = await fetchFromServer(
5548
- server,
5549
- createSpaceKey.space(normalizeSpaceId(spaceId)),
5550
- token ?? void 0
4813
+ storage.setItem(
4814
+ storageKeyForSpace(spaceId),
4815
+ JSON.stringify(normalizeCollapsedCategories(collapsedCategories))
5551
4816
  );
5552
- return space && typeof space === "object" ? space : null;
5553
- } catch {
5554
- return null;
4817
+ } catch (error) {
4818
+ console.warn("[Space] \u4FDD\u5B58\u5206\u7C7B\u6298\u53E0\u72B6\u6001\u5931\u8D25:", error);
5555
4819
  }
5556
4820
  };
5557
- var hasActiveRemoteMembership = async (server, token, userId, spaceId) => {
5558
- const result = await fetchRemoteUserSpaceMemberships(server, token, userId);
5559
- if (!result.ok) return false;
5560
- const normalizedSpaceId = normalizeSpaceId(spaceId);
5561
- return result.memberships.some((membership) => {
5562
- const membershipSpaceId = typeof membership?.spaceId === "string" ? normalizeSpaceId(membership.spaceId) : "";
5563
- return membershipSpaceId === normalizedSpaceId && membershipBelongsToUser(membership, userId) && !isTombstoneRecord(membership);
5564
- });
4821
+
4822
+ // packages/create/space/spaceUiStore.ts
4823
+ var import_react9 = __toESM(require_react(), 1);
4824
+ var DEFAULT_COLLAPSED_CATEGORIES = {
4825
+ [UNCATEGORIZED_ID]: false
5565
4826
  };
5566
- var fetchAuthoritativeRemoteSpace = async ({
5567
- servers,
5568
- token,
5569
- userId,
5570
- spaceId
5571
- }) => {
5572
- const normalizedSpaceId = normalizeSpaceId(spaceId);
5573
- for (const server of servers) {
5574
- const space = await fetchRemoteSpace(server, token, normalizedSpaceId);
5575
- if (!space) continue;
5576
- if (!spaceListsUser(space, userId)) {
5577
- throw new Error(`Current user is not a member of space: ${normalizedSpaceId}`);
5578
- }
5579
- if (space.ownerId !== userId) {
5580
- const hasMembership = await hasActiveRemoteMembership(
5581
- server,
5582
- token,
5583
- userId,
5584
- normalizedSpaceId
5585
- );
5586
- if (!hasMembership) {
5587
- throw new Error(
5588
- `Current user has no active membership for space: ${normalizedSpaceId}`
5589
- );
5590
- }
4827
+ var FAVORITES_COLLAPSED_STORAGE_KEY = "nolo-sidebar-favorites-collapsed";
4828
+ var readStoredFavoritesCollapsed = () => {
4829
+ try {
4830
+ if (typeof window === "undefined") return false;
4831
+ return window.localStorage.getItem(FAVORITES_COLLAPSED_STORAGE_KEY) === "1";
4832
+ } catch {
4833
+ return false;
4834
+ }
4835
+ };
4836
+ var createInitialState = () => ({
4837
+ favoritesCollapsed: readStoredFavoritesCollapsed(),
4838
+ collapsedCategories: {},
4839
+ collapsedCategoriesSpaceId: null
4840
+ });
4841
+ var state = createInitialState();
4842
+ var listeners = /* @__PURE__ */ new Set();
4843
+ var version = 0;
4844
+ var notify = () => {
4845
+ version += 1;
4846
+ for (const listener of listeners) {
4847
+ try {
4848
+ listener();
4849
+ } catch {
5591
4850
  }
5592
- return space;
5593
4851
  }
5594
- return null;
5595
4852
  };
5596
-
5597
- // packages/create/space/member/isSpaceMembershipRemoteUnavailableError.ts
5598
- var SPACE_MEMBERSHIP_REMOTE_UNAVAILABLE = "space_membership_remote_unavailable";
5599
- var isSpaceMembershipRemoteUnavailableError = (error) => {
5600
- if (typeof error === "string") {
5601
- return error.includes(SPACE_MEMBERSHIP_REMOTE_UNAVAILABLE);
5602
- }
5603
- if (error instanceof Error) {
5604
- return error.message.includes(SPACE_MEMBERSHIP_REMOTE_UNAVAILABLE);
5605
- }
5606
- if (error && typeof error === "object" && "message" in error && typeof error.message === "string") {
5607
- return error.message.includes(
5608
- SPACE_MEMBERSHIP_REMOTE_UNAVAILABLE
4853
+ function getCollapsedCategories() {
4854
+ return state.collapsedCategories;
4855
+ }
4856
+ function setCollapsedCategories(categories, spaceId) {
4857
+ state = {
4858
+ ...state,
4859
+ collapsedCategories: categories,
4860
+ collapsedCategoriesSpaceId: spaceId
4861
+ };
4862
+ notify();
4863
+ }
4864
+ function toggleCategoryCollapse(categoryId) {
4865
+ const current = state.collapsedCategories[categoryId] ?? (DEFAULT_COLLAPSED_CATEGORIES[categoryId] ?? true);
4866
+ state = {
4867
+ ...state,
4868
+ collapsedCategories: {
4869
+ ...state.collapsedCategories,
4870
+ [categoryId]: !current
4871
+ }
4872
+ };
4873
+ notify();
4874
+ }
4875
+ function expandCategoryInCollapsed(categoryId, spaceId) {
4876
+ if (!categoryId || categoryId === UNCATEGORIZED_ID) return;
4877
+ state = {
4878
+ ...state,
4879
+ collapsedCategories: {
4880
+ ...state.collapsedCategories,
4881
+ [categoryId]: false
4882
+ }
4883
+ };
4884
+ if (typeof window !== "undefined") {
4885
+ writeStoredCollapsedCategories(
4886
+ spaceId,
4887
+ state.collapsedCategories,
4888
+ window.localStorage
5609
4889
  );
5610
4890
  }
5611
- return false;
5612
- };
4891
+ notify();
4892
+ }
5613
4893
 
5614
- // packages/create/space/member/fetchUserSpaceMembershipsAction.ts
5615
- var CONTENT_SPACE_RECOVERY_TYPES = [
5616
- "app" /* APP */,
5617
- "page" /* DOC */,
5618
- "dialog" /* DIALOG */,
5619
- "image" /* IMAGE */,
5620
- "file" /* FILE */,
5621
- "table" /* TABLE */,
5622
- "agent" /* AGENT */
5623
- ];
5624
- var readLocalSpaceData = async (db, spaceId) => {
4894
+ // packages/create/space/content/contentThunks.ts
4895
+ var syncCurrentSpaceIfNormalizedMatch = (spaceId, updatedSpaceData) => {
5625
4896
  const normalizedSpaceId = normalizeSpaceId(spaceId);
5626
- const spaceKey = createSpaceKey.space(normalizedSpaceId);
5627
- try {
5628
- return await db.get(spaceKey) ?? null;
5629
- } catch {
5630
- return null;
5631
- }
5632
- };
5633
- var membershipCheckUserId = (membership, activeUserId) => isDeviceLocalSpaceMembership(membership) ? DEVICE_LOCAL_OWNER_ID : activeUserId;
5634
- var buildLocalMembershipPreview = async (userId, db, memberships) => {
5635
- const preview = await Promise.all(
5636
- memberships.map(async (membership) => {
5637
- if (isTombstoneRecord(membership)) return null;
5638
- const checkUserId = membershipCheckUserId(membership, userId);
5639
- if (!membershipBelongsToUser(membership, checkUserId)) return null;
5640
- const normalizedSpaceId = normalizeSpaceId(membership.spaceId);
5641
- const localSpaceData = await readLocalSpaceData(db, normalizedSpaceId);
5642
- if (!localSpaceData || isTombstoneRecord(localSpaceData)) return null;
5643
- if (!spaceListsUser(localSpaceData, checkUserId)) return null;
5644
- return {
5645
- ...membership,
5646
- spaceId: normalizedSpaceId
4897
+ const rawSpaceId = getCurrentSpaceIdRaw();
4898
+ const normalizedCurrentSpaceId = rawSpaceId ? normalizeSpaceId(rawSpaceId) : null;
4899
+ if (normalizedCurrentSpaceId === normalizedSpaceId && updatedSpaceData) {
4900
+ updateCurrentSpaceIfMatch(spaceId, updatedSpaceData);
4901
+ }
4902
+ };
4903
+ var addContentToSpace = createAsyncThunk(
4904
+ "space/addContentToSpace",
4905
+ async (input, thunkAPI) => {
4906
+ const result = await addContentAction(input, thunkAPI);
4907
+ const rawCategoryId = asTrimmedString(input.categoryId);
4908
+ const expandCategoryId = rawCategoryId && rawCategoryId !== UNCATEGORIZED_ID ? rawCategoryId : null;
4909
+ if (expandCategoryId) {
4910
+ const collapsedCategories = {
4911
+ ...getCollapsedCategories(),
4912
+ [expandCategoryId]: false
5647
4913
  };
5648
- })
5649
- );
5650
- return preview.filter(
5651
- (membership) => !!membership
5652
- );
5653
- };
5654
- var fetchLocalForUser = async (userId, db) => {
5655
- try {
5656
- const memberships = [];
5657
- const prefix = `space-member-${userId}`;
5658
- let iterator = db.iterator({
5659
- gte: prefix,
5660
- lte: prefix + "\xFF"
5661
- });
5662
- if (iterator && typeof iterator.then === "function") {
5663
- iterator = await iterator;
5664
- }
5665
- for await (const [_, memberData] of iterator) {
5666
- if (memberData && typeof memberData === "object" && memberData.spaceId && !isTombstoneRecord(memberData)) {
5667
- memberships.push(memberData);
4914
+ if (typeof window !== "undefined") {
4915
+ writeStoredCollapsedCategories(
4916
+ result.spaceId,
4917
+ collapsedCategories,
4918
+ window.localStorage
4919
+ );
5668
4920
  }
4921
+ expandCategoryInCollapsed(expandCategoryId, result.spaceId);
4922
+ syncCurrentSpaceIfNormalizedMatch(
4923
+ result.spaceId,
4924
+ result.updatedSpaceData
4925
+ );
4926
+ return { ...result, expandCategoryId, collapsedCategories };
5669
4927
  }
5670
- return memberships;
5671
- } catch (error) {
5672
- console.error("Error fetching local memberships:", error);
5673
- return [];
4928
+ syncCurrentSpaceIfNormalizedMatch(result.spaceId, result.updatedSpaceData);
4929
+ return { ...result, expandCategoryId: null };
5674
4930
  }
5675
- };
5676
- var fetchLocalUnion = async (userId, db) => {
5677
- const deviceLocalRows = await fetchLocalForUser(DEVICE_LOCAL_OWNER_ID, db);
5678
- const taggedLocal = deviceLocalRows.map(
5679
- (membership) => ({
5680
- ...membership,
5681
- spaceId: normalizeSpaceId(membership.spaceId),
5682
- deviceLocal: true,
5683
- userId: membership.userId || DEVICE_LOCAL_OWNER_ID
5684
- })
5685
- );
5686
- if (isDeviceLocalOwnerId(userId)) {
5687
- return taggedLocal;
5688
- }
5689
- const accountRows = await fetchLocalForUser(userId, db);
5690
- const taggedAccount = accountRows.map(
5691
- (membership) => ({
5692
- ...membership,
5693
- spaceId: normalizeSpaceId(membership.spaceId),
5694
- deviceLocal: false
5695
- })
5696
- );
5697
- return [...taggedLocal, ...taggedAccount];
5698
- };
5699
- var fetchRemoteContentSpaceIds = async (server, userId, token) => {
5700
- try {
5701
- const queryParams = new URLSearchParams({ limit: "200" });
5702
- const headers = {
5703
- "Content-Type": "application/json"
5704
- };
5705
- const authToken = asTrimmedString(token);
5706
- if (authToken) {
5707
- headers.Authorization = `Bearer ${authToken}`;
4931
+ );
4932
+ var moveContentToSpace = createAsyncThunk(
4933
+ "space/moveContentToSpace",
4934
+ async (arg, thunkAPI) => {
4935
+ const payload = await moveContentAction(arg, thunkAPI);
4936
+ const {
4937
+ sourceSpaceId,
4938
+ updatedSourceSpaceData,
4939
+ targetSpaceId,
4940
+ updatedTargetSpaceData
4941
+ } = payload;
4942
+ if (getCurrentSpaceIdRaw() === sourceSpaceId && updatedSourceSpaceData) {
4943
+ updateCurrentSpaceIfMatch(sourceSpaceId, updatedSourceSpaceData);
5708
4944
  }
5709
- const response = await fetch(
5710
- `${server}${API_ENDPOINTS.DATABASE}/query/${encodeURIComponent(userId)}?${queryParams}`,
5711
- {
5712
- method: "POST",
5713
- headers,
5714
- body: JSON.stringify({
5715
- type: [...CONTENT_SPACE_RECOVERY_TYPES],
5716
- includeDeleted: true,
5717
- summary: true
5718
- })
5719
- }
5720
- );
5721
- if (!response.ok) return [];
5722
- const data = await response.json();
5723
- const records = Array.isArray(data?.data?.data) ? data.data.data : [];
5724
- return records.filter((record) => !isTombstoneRecord(record)).map(
5725
- (record) => typeof record?.spaceId === "string" ? normalizeSpaceId(record.spaceId) : ""
5726
- ).filter((spaceId) => spaceId.length > 0);
5727
- } catch {
5728
- return [];
4945
+ if (getCurrentSpaceIdRaw() === targetSpaceId && updatedTargetSpaceData) {
4946
+ updateCurrentSpaceIfMatch(targetSpaceId, updatedTargetSpaceData);
4947
+ }
4948
+ return payload;
5729
4949
  }
5730
- };
5731
- var recoverMembershipsFromContentSpaces = async ({
5732
- servers,
5733
- token,
5734
- userId,
5735
- knownSpaceIds
5736
- }) => {
5737
- const candidateSpaceIds = /* @__PURE__ */ new Set();
5738
- await Promise.all(
5739
- servers.map(async (server) => {
5740
- const spaceIds = await fetchRemoteContentSpaceIds(server, userId, token);
5741
- spaceIds.forEach((spaceId) => {
5742
- if (!knownSpaceIds.has(spaceId)) {
5743
- candidateSpaceIds.add(spaceId);
5744
- }
5745
- });
5746
- })
5747
- );
5748
- const results = await Promise.all(
5749
- [...candidateSpaceIds].map(async (spaceId) => {
5750
- try {
5751
- for (const server of servers) {
5752
- const remoteSpace = await fetchRemoteSpace(server, token, spaceId);
5753
- if (!spaceListsUser(remoteSpace, userId)) continue;
5754
- return {
5755
- userId,
5756
- spaceId,
5757
- spaceName: typeof remoteSpace?.name === "string" && remoteSpace.name.trim() ? remoteSpace.name : spaceId,
5758
- role: remoteSpace?.ownerId === userId ? "owner" /* OWNER */ : "member" /* MEMBER */,
5759
- joinedAt: remoteSpace?.updatedAt ?? remoteSpace?.createdAt ?? Date.now(),
5760
- sourceServer: server
5761
- };
5762
- }
5763
- } catch {
5764
- }
5765
- return null;
5766
- })
5767
- );
5768
- const recovered = results.filter(
5769
- (m) => m !== null
5770
- );
5771
- return recovered;
5772
- };
5773
- var fetchUserSpaceMembershipsAction = async (userId, thunkAPI) => {
5774
- const state6 = thunkAPI.getState();
5775
- const db = thunkAPI.extra.db;
5776
- const { token, servers } = selectSpaceRemoteAuth(state6);
5777
- const isLocalActor = isDeviceLocalOwnerId(userId);
5778
- const localMembershipsPromise = fetchLocalUnion(userId, db);
5779
- const remoteResultsPromise = isLocalActor ? Promise.resolve([]) : Promise.all(
5780
- servers.map(
5781
- (server) => fetchRemoteUserSpaceMemberships(server, token, userId)
5782
- )
5783
- );
5784
- const localMemberships = await localMembershipsPromise;
5785
- if (state6.space?.memberSpaces === null && localMemberships.length > 0) {
5786
- const localPreview = await buildLocalMembershipPreview(
5787
- userId,
5788
- db,
5789
- localMemberships
4950
+ );
4951
+ var deleteContentFromSpace = createAsyncThunk(
4952
+ "space/deleteContentFromSpace",
4953
+ async (arg, thunkAPI) => {
4954
+ const payload = await deleteContentFromSpaceAction(arg, thunkAPI);
4955
+ syncCurrentSpaceIfNormalizedMatch(
4956
+ payload.spaceId,
4957
+ payload.updatedSpaceData
5790
4958
  );
5791
- if (localPreview.length > 0) {
5792
- thunkAPI.dispatch?.({
5793
- type: "space/hydrateMemberSpacesFromLocal",
5794
- payload: localPreview
5795
- });
5796
- }
4959
+ return payload;
5797
4960
  }
5798
- const remoteResults = await remoteResultsPromise;
5799
- const successfulRemoteResults = remoteResults.filter((result) => result.ok);
5800
- const successfulRemoteMemberships = successfulRemoteResults.flatMap(
5801
- (result) => result.memberships.map((membership) => ({
5802
- ...membership,
5803
- sourceServer: result.server
5804
- }))
5805
- );
5806
- const hasSuccessfulRemoteFetch = successfulRemoteResults.length > 0;
5807
- const hasRemoteAuthority = !isLocalActor && !!token && servers.length > 0;
5808
- if (hasRemoteAuthority && !hasSuccessfulRemoteFetch) {
5809
- throw new Error(
5810
- `${SPACE_MEMBERSHIP_REMOTE_UNAVAILABLE}: unable to refresh memberships from ${servers.join(", ")}`
4961
+ );
4962
+ var deleteMultipleContent = createAsyncThunk(
4963
+ "space/deleteMultipleContent",
4964
+ async (arg, thunkAPI) => {
4965
+ const payload = await deleteMultipleContentAction(arg, thunkAPI);
4966
+ syncCurrentSpaceIfNormalizedMatch(
4967
+ payload.spaceId,
4968
+ payload.updatedSpaceData
5811
4969
  );
4970
+ return payload;
5812
4971
  }
5813
- const remoteSpaceIds = new Set(
5814
- successfulRemoteMemberships.map(
5815
- (membership) => normalizeSpaceId(membership.spaceId)
5816
- )
5817
- );
5818
- const filteredLocalMemberships = hasSuccessfulRemoteFetch ? (await Promise.all(
5819
- localMemberships.map(async (membership) => {
5820
- const normalizedSpaceId = normalizeSpaceId(membership.spaceId);
5821
- if (membership.deviceLocal || isDeviceLocalSpaceMembership(membership)) {
5822
- return {
5823
- ...membership,
5824
- spaceId: normalizedSpaceId,
5825
- deviceLocal: true
5826
- };
4972
+ );
4973
+ var uploadAndAddFileToSpace = createAsyncThunk(
4974
+ "space/uploadAndAddFileToSpace",
4975
+ async (arg, thunkAPI) => {
4976
+ const payload = await uploadAndAddFileToSpaceAction(arg, thunkAPI);
4977
+ if (getCurrentSpaceIdRaw() === payload.spaceId) {
4978
+ updateCurrentSpaceIfMatch(payload.spaceId, payload.updatedSpaceData);
4979
+ }
4980
+ return payload;
4981
+ }
4982
+ );
4983
+ var updateContentTitle = createAsyncThunk(
4984
+ "space/updateContentTitle",
4985
+ async (arg, thunkAPI) => {
4986
+ try {
4987
+ const payload = await updateContentTitleAction(arg, thunkAPI);
4988
+ if (getCurrentSpaceIdRaw() === payload.spaceId) {
4989
+ updateCurrentSpaceIfMatch(payload.spaceId, payload.updatedSpaceData);
5827
4990
  }
5828
- if (remoteSpaceIds.has(normalizedSpaceId)) {
5829
- return {
5830
- ...membership,
5831
- spaceId: normalizedSpaceId
5832
- };
4991
+ return payload;
4992
+ } catch (error) {
4993
+ const message = error?.message || "\u6807\u9898\u4FDD\u5B58\u5931\u8D25";
4994
+ if (!message.includes("\u65E0\u6CD5\u52A0\u8F7D\u7A7A\u95F4\u6570\u636E")) {
4995
+ toast.error(message);
5833
4996
  }
5834
- console.warn(
5835
- `[SpaceMembership] Membership missing from remote index, verifying space record: user=${userId}, spaceId=${normalizedSpaceId}`
4997
+ throw error;
4998
+ }
4999
+ }
5000
+ );
5001
+ var updateContentPinned = createAsyncThunk(
5002
+ "space/updateContentPinned",
5003
+ async (arg, thunkAPI) => {
5004
+ try {
5005
+ const payload = await updateContentPinnedAction(arg, thunkAPI);
5006
+ if (payload.updatedSpaceData && getCurrentSpaceIdRaw() === payload.spaceId) {
5007
+ updateCurrentSpaceIfMatch(payload.spaceId, payload.updatedSpaceData);
5008
+ }
5009
+ return payload;
5010
+ } catch (error) {
5011
+ toast.error(
5012
+ error?.message || "\u7F6E\u9876\u72B6\u6001\u66F4\u65B0\u5931\u8D25"
5836
5013
  );
5837
- return {
5838
- ...membership,
5839
- spaceId: normalizedSpaceId,
5840
- requiresRemoteSpaceVerification: true
5841
- };
5842
- })
5843
- )).filter((membership) => !!membership) : localMemberships.map((membership) => ({
5844
- ...membership,
5845
- spaceId: normalizeSpaceId(membership.spaceId)
5846
- }));
5847
- const verifyActiveSpaceMembership = async (membership) => {
5848
- if (isTombstoneRecord(membership)) return null;
5849
- const checkUserId = membershipCheckUserId(membership, userId);
5850
- if (!membershipBelongsToUser(membership, checkUserId)) return null;
5851
- const normalizedSpaceId = normalizeSpaceId(membership.spaceId);
5852
- const localSpaceData = await readLocalSpaceData(db, normalizedSpaceId);
5853
- const isDeviceLocal = membership.deviceLocal || isDeviceLocalSpaceMembership(membership);
5854
- if (isDeviceLocal) {
5855
- if (!localSpaceData || isTombstoneRecord(localSpaceData)) return null;
5856
- if (!spaceListsUser(localSpaceData, checkUserId)) {
5857
- return null;
5858
- }
5859
- const {
5860
- sourceServer: _s,
5861
- requiresRemoteSpaceVerification: _r,
5862
- deviceLocal: _d,
5863
- ...visible
5864
- } = membership;
5865
- return {
5866
- ...visible,
5867
- spaceId: normalizedSpaceId,
5868
- userId: DEVICE_LOCAL_OWNER_ID
5869
- };
5014
+ throw error;
5870
5015
  }
5871
- if (membership.sourceServer || membership.requiresRemoteSpaceVerification) {
5872
- if (localSpaceData && isTombstoneRecord(localSpaceData)) return null;
5873
- if (membership.sourceServer && !membership.requiresRemoteSpaceVerification) {
5874
- const { sourceServer: _ss, ...verifiedMembership } = membership;
5875
- return {
5876
- ...verifiedMembership,
5877
- spaceId: normalizedSpaceId
5878
- };
5879
- }
5880
- try {
5881
- const remoteSpaceServers = Array.from(
5882
- new Set(
5883
- [membership.sourceServer, ...servers].filter(
5884
- (server) => typeof server === "string" && server.length > 0
5885
- )
5886
- )
5887
- );
5888
- let remoteSpace = null;
5889
- for (const server of remoteSpaceServers) {
5890
- remoteSpace = await fetchRemoteSpace(
5891
- server,
5892
- token,
5893
- normalizedSpaceId
5894
- );
5895
- if (remoteSpace) break;
5896
- }
5897
- if (!spaceListsUser(remoteSpace, userId)) return null;
5898
- const {
5899
- requiresRemoteSpaceVerification,
5900
- deviceLocal: _dl,
5901
- ...verifiedMembership
5902
- } = membership;
5903
- return {
5904
- ...verifiedMembership,
5905
- spaceId: normalizedSpaceId
5906
- };
5907
- } catch {
5908
- return null;
5909
- }
5910
- }
5911
- if (localSpaceData) {
5912
- return !spaceListsUser(localSpaceData, userId) ? null : {
5913
- ...membership,
5914
- spaceId: normalizedSpaceId
5915
- };
5916
- }
5917
- if (!membership.sourceServer && servers.length === 0) {
5918
- return {
5919
- ...membership,
5920
- spaceId: normalizedSpaceId
5921
- };
5922
- }
5923
- try {
5924
- const remoteSpace = await readAction(
5925
- {
5926
- dbKey: createSpaceKey.space(normalizedSpaceId),
5927
- preferredServerOrigin: membership.sourceServer
5928
- },
5929
- thunkAPI
5930
- );
5931
- if (!spaceListsUser(remoteSpace, userId)) return null;
5932
- return {
5933
- ...membership,
5934
- spaceId: normalizedSpaceId
5935
- };
5936
- } catch {
5937
- return null;
5938
- }
5939
- };
5940
- const activeMemberships = (await Promise.all(
5941
- [...filteredLocalMemberships, ...successfulRemoteMemberships].map(
5942
- verifyActiveSpaceMembership
5943
- )
5944
- )).filter((membership) => !!membership);
5945
- const knownSpaceIds = new Set(
5946
- [
5947
- ...filteredLocalMemberships,
5948
- ...successfulRemoteMemberships,
5949
- ...activeMemberships
5950
- ].map((membership) => normalizeSpaceId(membership.spaceId))
5951
- );
5952
- if (hasRemoteAuthority && hasSuccessfulRemoteFetch && !isLocalActor) {
5953
- void recoverMembershipsFromContentSpaces({
5954
- servers,
5955
- token,
5956
- userId,
5957
- knownSpaceIds
5958
- }).then((rawRecovered) => {
5959
- const activeUserId = thunkAPI.getState()?.auth?.currentUser?.userId ?? null;
5960
- if (activeUserId !== userId) return;
5961
- if (rawRecovered.length === 0) return;
5962
- const cleaned = rawRecovered.map((membership) => {
5963
- const {
5964
- sourceServer: _ss,
5965
- requiresRemoteSpaceVerification: _rv,
5966
- deviceLocal: _dl,
5967
- ...visible
5968
- } = membership;
5969
- return { ...visible, spaceId: normalizeSpaceId(membership.spaceId) };
5970
- });
5971
- thunkAPI.dispatch?.({
5972
- type: "space/appendRecoveredMemberships",
5973
- payload: cleaned
5974
- });
5975
- }).catch(() => {
5976
- });
5977
- }
5978
- const membershipMap = /* @__PURE__ */ new Map();
5979
- const preferAccountOnCollision = (existing, next) => {
5980
- if (!existing) return next;
5981
- const existingLocal = isDeviceLocalSpaceMembership(existing);
5982
- const nextLocal = isDeviceLocalSpaceMembership(next);
5983
- if (existingLocal && !nextLocal) return next;
5984
- if (!existingLocal && nextLocal) return existing;
5985
- return next;
5986
- };
5987
- [...activeMemberships].forEach((membership) => {
5988
- const normalizedSpaceId = normalizeSpaceId(membership.spaceId);
5989
- const {
5990
- sourceServer: _sourceServer,
5991
- requiresRemoteSpaceVerification: _req,
5992
- deviceLocal: _deviceLocal,
5993
- ...visibleMembership
5994
- } = membership;
5995
- const cleaned = {
5996
- ...visibleMembership,
5997
- spaceId: normalizedSpaceId
5998
- };
5999
- const existing = membershipMap.get(normalizedSpaceId);
6000
- membershipMap.set(
6001
- normalizedSpaceId,
6002
- preferAccountOnCollision(existing, cleaned)
6003
- );
6004
- });
6005
- const finalMemberships = Array.from(membershipMap.values()).sort(
6006
- (a, b) => (b.joinedAt || 0) - (a.joinedAt || 0)
6007
- );
6008
- return finalMemberships;
6009
- };
6010
-
6011
- // packages/database/thunkApiTypes.ts
6012
- var dbThunkState = (thunkApi) => thunkApi.getState();
6013
- var dbThunkExtra = (thunkApi) => thunkApi.extra;
6014
-
6015
- // packages/create/space/member/addMemberAction.ts
6016
- var addMemberAction = async (input, thunkAPI) => {
6017
- const { spaceId, memberId, role = "member" /* MEMBER */ } = input;
6018
- const { dispatch } = thunkAPI;
6019
- const state6 = dbThunkState(thunkAPI);
6020
- const currentUserId = selectIdentityUserId(state6);
6021
- const { db } = dbThunkExtra(thunkAPI);
6022
- const resolvedMemberId = db ? await resolveMemberId(db, memberId) : memberId.trim();
6023
- const spaceKey = createSpaceKey.space(spaceId);
6024
- const spaceData = await dispatch(read({
6025
- dbKey: spaceKey
6026
- })).unwrap();
6027
- if (!spaceData) {
6028
- throw new Error("Space not found");
6029
- }
6030
- if (!currentUserId) {
6031
- throw new Error("User is not logged in.");
6032
- }
6033
- if (!spaceData.members.includes(currentUserId)) {
6034
- throw new Error("\u5F53\u524D\u7528\u6237\u4E0D\u662F\u7A7A\u95F4\u6210\u5458\uFF0C\u65E0\u6CD5\u6DFB\u52A0\u6210\u5458");
6035
- }
6036
- if (spaceData.members.includes(resolvedMemberId)) {
6037
- throw new Error("\u6210\u5458\u5DF2\u5B58\u5728");
6038
- }
6039
- const updatedSpaceData = {
6040
- ...spaceData,
6041
- members: [...spaceData.members, resolvedMemberId],
6042
- updatedAt: Date.now()
6043
- };
6044
- await dispatch(
6045
- write({ data: updatedSpaceData, customKey: spaceKey })
6046
- ).unwrap();
6047
- const now = Date.now();
6048
- const spaceMemberData = {
6049
- userId: resolvedMemberId,
6050
- role,
6051
- // 使用传入的 role,默认为 MEMBER
6052
- joinedAt: now,
6053
- updatedAt: now,
6054
- // 可选字段,初始化时设置为当前时间
6055
- spaceId,
6056
- spaceName: spaceData.name,
6057
- ownerId: spaceData.ownerId,
6058
- visibility: spaceData.visibility,
6059
- type: "space" /* SPACE */
6060
- // 添加 type 字段
6061
- };
6062
- const spaceMemberKey = createSpaceKey.member(resolvedMemberId, spaceId);
6063
- await dispatch(
6064
- write({
6065
- data: spaceMemberData,
6066
- customKey: spaceMemberKey
6067
- })
6068
- ).unwrap();
6069
- return { spaceId, updatedSpaceData };
6070
- };
6071
- async function resolveMemberId(db, identifier) {
6072
- const trimmed = identifier.trim();
6073
- let foundUserId = null;
6074
- let matchCount = 0;
6075
- try {
6076
- for await (const [key, value] of db.iterator({
6077
- gte: `${DB_PREFIX.USER}`,
6078
- lte: `${DB_PREFIX.USER}\uFFFF`
6079
- })) {
6080
- if (value.username === trimmed) {
6081
- foundUserId = key.slice(DB_PREFIX.USER.length);
6082
- matchCount++;
6083
- }
6084
- }
6085
- } catch (err2) {
6086
- logger.warn({ err: err2, identifier: trimmed }, "Failed to scan users by username");
6087
- }
6088
- if (matchCount > 1) {
6089
- throw new Error(
6090
- `\u627E\u5230\u591A\u4E2A\u7528\u6237\u540D\u4E3A ${trimmed} \u7684\u7528\u6237\uFF0C\u8BF7\u4F7F\u7528\u7528\u6237 ID \u9080\u8BF7`
6091
- );
6092
- }
6093
- if (matchCount === 1 && foundUserId) {
6094
- return foundUserId;
6095
- }
6096
- return trimmed;
6097
- }
6098
-
6099
- // packages/create/space/member/removeMemberAction.ts
6100
- var removeMemberAction = async (input, thunkAPI) => {
6101
- const { spaceId, memberId } = input;
6102
- const { dispatch, getState } = thunkAPI;
6103
- const state6 = getState();
6104
- const currentUserId = selectIdentityUserId(state6);
6105
- const spaceKey = createSpaceKey.space(spaceId);
6106
- const spaceData = await dispatch(read({
6107
- dbKey: spaceKey
6108
- })).unwrap();
6109
- if (!spaceData) {
6110
- throw new Error("Space not found");
6111
- }
6112
- if (spaceData.ownerId !== currentUserId) {
6113
- throw new Error("\u53EA\u6709\u7A7A\u95F4\u6240\u6709\u8005\u624D\u80FD\u5220\u9664\u6210\u5458");
6114
- }
6115
- if (!spaceData.members.includes(memberId)) {
6116
- throw new Error("\u5F85\u5220\u9664\u7684\u6210\u5458\u4E0D\u5B58\u5728");
6117
- }
6118
- const updatedSpaceData = {
6119
- ...spaceData,
6120
- members: spaceData.members.filter((id) => id !== memberId),
6121
- updatedAt: Date.now()
6122
- };
6123
- const memberKey = createSpaceKey.member(memberId, spaceId);
6124
- await Promise.all([
6125
- dispatch(write({ data: updatedSpaceData, customKey: spaceKey })).unwrap(),
6126
- dispatch(remove(memberKey)).unwrap()
6127
- // 使用 remove 替代 del
6128
- ]);
6129
- return { spaceId, updatedSpaceData };
6130
- };
6131
-
6132
- // packages/create/space/spaceMembershipStore.ts
6133
- var import_react11 = __toESM(require_react(), 1);
6134
- var createInitialState3 = () => ({
6135
- memberSpaces: null,
6136
- loading: false,
6137
- membershipStatus: "idle",
6138
- initialized: false
6139
- });
6140
- var state3 = createInitialState3();
6141
- var listeners3 = /* @__PURE__ */ new Set();
6142
- var version3 = 0;
6143
- var notify3 = () => {
6144
- version3 += 1;
6145
- for (const listener of listeners3) {
6146
- try {
6147
- listener();
6148
- } catch {
6149
- }
6150
- }
6151
- };
6152
- var getMembershipUpdatedAt = (space) => {
6153
- if (!space) return 0;
6154
- return toTimestampMs(
6155
- space.spaceUpdatedAt ?? space.memberUpdatedAt ?? space.updatedAt ?? space.createdAt ?? space.joinedAt
6156
- );
6157
- };
6158
- function dedupeMemberSpacesById(memberSpaces) {
6159
- const membershipMap = /* @__PURE__ */ new Map();
6160
- memberSpaces.forEach((space) => {
6161
- const prev = membershipMap.get(space.spaceId);
6162
- if (!prev || getMembershipUpdatedAt(space) >= getMembershipUpdatedAt(prev)) {
6163
- membershipMap.set(space.spaceId, space);
6164
- }
6165
- });
6166
- return Array.from(membershipMap.values());
6167
- }
6168
- function getAllMemberSpaces() {
6169
- const memberSpaces = dedupeMemberSpacesById(state3.memberSpaces || []);
6170
- return [...memberSpaces].sort((a, b) => {
6171
- return getMembershipUpdatedAt(b) - getMembershipUpdatedAt(a);
6172
- });
6173
- }
6174
- function setMemberSpaces(spaces) {
6175
- state3 = {
6176
- ...state3,
6177
- memberSpaces: spaces,
6178
- loading: false,
6179
- error: void 0,
6180
- membershipStatus: "fresh",
6181
- initialized: true
6182
- };
6183
- notify3();
6184
- }
6185
- function setMembershipLoading() {
6186
- state3 = { ...state3, loading: true, membershipStatus: "loading" };
6187
- notify3();
6188
- }
6189
- function setMembershipRejected(errorMessage, isRemoteUnavailable) {
6190
- const membershipStatus = isRemoteUnavailable ? "offline" : state3.membershipStatus === "loading" ? "idle" : state3.membershipStatus;
6191
- state3 = {
6192
- ...state3,
6193
- loading: false,
6194
- error: errorMessage,
6195
- membershipStatus
6196
- };
6197
- notify3();
6198
- }
6199
- function hydrateMemberSpacesFromLocal(spaces) {
6200
- if (state3.memberSpaces !== null || spaces.length === 0) return;
6201
- state3 = {
6202
- ...state3,
6203
- memberSpaces: dedupeMemberSpacesById(spaces),
6204
- loading: false
6205
- };
6206
- notify3();
6207
- }
6208
- function appendRecoveredMemberships(recovered) {
6209
- if (!recovered || recovered.length === 0) return;
6210
- if (state3.memberSpaces === null) {
6211
- state3 = {
6212
- ...state3,
6213
- memberSpaces: dedupeMemberSpacesById(recovered)
6214
- };
6215
- notify3();
6216
- return;
6217
- }
6218
- state3 = {
6219
- ...state3,
6220
- memberSpaces: dedupeMemberSpacesById([
6221
- ...state3.memberSpaces,
6222
- ...recovered
6223
- ]).sort((a, b) => toTimestampMs(b.joinedAt) - toTimestampMs(a.joinedAt))
6224
- };
6225
- notify3();
6226
- }
6227
- function setSpaceInitialized() {
6228
- state3 = { ...state3, initialized: true };
6229
- notify3();
6230
- }
6231
- function setMembershipLoaded() {
6232
- state3 = { ...state3, loading: false, error: void 0 };
6233
- notify3();
6234
- }
6235
- function addMemberSpace(space) {
6236
- const existing = state3.memberSpaces || [];
6237
- state3 = {
6238
- ...state3,
6239
- memberSpaces: dedupeMemberSpacesById([...existing, space])
6240
- };
6241
- notify3();
6242
- }
6243
- function removeMemberSpace(spaceId) {
6244
- if (!state3.memberSpaces) return;
6245
- const normalized = normalizeSpaceId(spaceId);
6246
- state3 = {
6247
- ...state3,
6248
- memberSpaces: state3.memberSpaces.filter(
6249
- (s) => normalizeSpaceId(s.spaceId) !== normalized
6250
- )
6251
- };
6252
- notify3();
6253
- }
6254
- function updateMemberSpaceName(spaceId, name) {
6255
- if (!state3.memberSpaces || !name) return;
6256
- state3 = {
6257
- ...state3,
6258
- memberSpaces: state3.memberSpaces.map(
6259
- (space) => space.spaceId === spaceId ? { ...space, spaceName: name } : space
6260
- )
6261
- };
6262
- notify3();
6263
- }
6264
- function resetSpaceMembershipState() {
6265
- state3 = createInitialState3();
6266
- notify3();
6267
- }
6268
-
6269
- // packages/create/space/member/memberThunks.ts
6270
- var createMemberThunks = (create) => ({
6271
- fetchUserSpaceMemberships: create.asyncThunk(
6272
- fetchUserSpaceMembershipsAction,
6273
- {
6274
- pending: (state6) => {
6275
- setMembershipLoading();
6276
- },
6277
- fulfilled: (state6, action) => {
6278
- setMemberSpaces(action.payload);
6279
- },
6280
- rejected: (state6, action) => {
6281
- setMembershipRejected(
6282
- action.error.message,
6283
- isSpaceMembershipRemoteUnavailableError(action.error)
6284
- );
6285
- }
6286
- }
6287
- ),
6288
- addMember: create.asyncThunk(addMemberAction, {
6289
- fulfilled: (state6, action) => {
6290
- if (getCurrentSpaceIdRaw() === action.payload.spaceId) {
6291
- updateCurrentSpaceIfMatch(action.payload.spaceId, action.payload.updatedSpaceData);
6292
- }
6293
- }
6294
- }),
6295
- removeMember: create.asyncThunk(removeMemberAction, {
6296
- fulfilled: (state6, action) => {
6297
- if (getCurrentSpaceIdRaw() === action.payload.spaceId) {
6298
- updateCurrentSpaceIfMatch(action.payload.spaceId, action.payload.updatedSpaceData);
6299
- }
6300
- }
6301
- })
6302
- });
6303
-
6304
- // packages/database/queryPrefixes.ts
6305
- function getUserDataPrefixes(type, userId) {
6306
- const normalizedType = toTrimmedString(type);
6307
- const normalizedUserId = toTrimmedString(userId);
6308
- if (!normalizedType || !normalizedUserId) return [];
6309
- const aliases = TYPE_STORAGE_PREFIXES[normalizedType] ?? [normalizedType];
6310
- const seen = /* @__PURE__ */ new Set();
6311
- const prefixes = [];
6312
- for (const raw of aliases) {
6313
- const alias = toTrimmedString(raw);
6314
- if (!alias) continue;
6315
- const prefix = `${alias}-${normalizedUserId}-`;
6316
- if (seen.has(prefix)) continue;
6317
- seen.add(prefix);
6318
- prefixes.push(prefix);
6319
- }
6320
- return prefixes;
6321
- }
6322
-
6323
- // packages/database/client/fetchUserData.ts
6324
- var attachQueriedKey = (key, value) => {
6325
- if (!value || typeof value !== "object") return value;
6326
- if (typeof value.dbKey === "string" && value.dbKey.trim().length > 0) {
6327
- return value;
6328
- }
6329
- return {
6330
- ...value,
6331
- dbKey: key
6332
- };
6333
- };
6334
- var normalizeTypeList = (types) => {
6335
- const raw = Array.isArray(types) ? types : [types];
6336
- const seen = /* @__PURE__ */ new Set();
6337
- const out = [];
6338
- for (const t2 of raw) {
6339
- const n = toTrimmedString(t2);
6340
- if (!n || seen.has(n)) continue;
6341
- seen.add(n);
6342
- out.push(n);
6343
- }
6344
- return out;
6345
- };
6346
- async function fetchUserData(db, types, userId, options = {}) {
6347
- const results = {};
6348
- const typeArray = normalizeTypeList(types);
6349
- const includeDeleted = options.includeDeleted === true;
6350
- try {
6351
- for (const type of typeArray) {
6352
- const byKey = /* @__PURE__ */ new Map();
6353
- const prefixes = getUserDataPrefixes(type, userId);
6354
- for (const prefix of prefixes) {
6355
- if (!prefix) continue;
6356
- let iterator = db.iterator({
6357
- gte: prefix,
6358
- lte: `${prefix}\uFFFF`
6359
- });
6360
- if (iterator && typeof iterator.then === "function") {
6361
- iterator = await iterator;
6362
- }
6363
- for await (const [key, value] of iterator) {
6364
- const keyStr = String(key);
6365
- if (byKey.has(keyStr)) continue;
6366
- const hydrated = attachQueriedKey(keyStr, value);
6367
- if (!hydrated) continue;
6368
- if (!includeDeleted && hydrated.deletedAt) continue;
6369
- byKey.set(keyStr, hydrated);
6370
- }
6371
- }
6372
- results[type] = [...byKey.values()];
6373
- }
6374
- if (Array.isArray(types)) {
6375
- return results;
6376
- }
6377
- const single = toTrimmedString(types);
6378
- return results[single] ?? [];
6379
- } catch (error) {
6380
- console.error("Query error:", error);
6381
- throw error;
6382
- }
6383
- }
6384
-
6385
- // packages/create/space/addSpaceAction.ts
6386
- import { ulid as ulid5 } from "ulid";
6387
- async function getUserDataOnce({
6388
- types,
6389
- userId,
6390
- limit,
6391
- isLoggedIn = false,
6392
- currentUserId,
6393
- db
6394
- }) {
6395
- try {
6396
- const typeArray = Array.isArray(types) ? types : [types];
6397
- const effectiveUserId = userId === "local" && isLoggedIn && currentUserId ? currentUserId : userId;
6398
- const localResults = await fetchUserData(db, typeArray, effectiveUserId);
6399
- const localData = Object.values(localResults).flat();
6400
- return { data: localData };
6401
- } catch (err2) {
6402
- const error = err2 instanceof Error ? err2 : new Error("Unknown error occurred");
6403
- return { data: [], error };
6404
- }
6405
- }
6406
- var targetTypes = ["dialog" /* DIALOG */, "page" /* DOC */];
6407
- var getCurrentPathForLog = () => typeof window !== "undefined" && typeof window.location?.pathname === "string" ? window.location.pathname : void 0;
6408
- var addSpaceAction = async (input, thunkAPI) => {
6409
- const {
6410
- name,
6411
- description = "",
6412
- boundFolder
6413
- } = input;
6414
- const visibility = input.visibility ?? "private" /* PRIVATE */;
6415
- const { dispatch, getState, extra } = thunkAPI;
6416
- const state6 = getState();
6417
- const accountUserId = selectIdentityUserId(state6);
6418
- const userId = resolveEffectiveSpaceActorId(accountUserId);
6419
- const spaceId = ulid5();
6420
- const now = Date.now();
6421
- const nowISO = new Date(now).toISOString();
6422
- const spaceData = {
6423
- id: spaceId,
6424
- name,
6425
- description,
6426
- boundFolder,
6427
- ownerId: userId,
6428
- userId,
6429
- visibility,
6430
- members: [userId],
6431
- categories: {},
6432
- contents: {},
6433
- createdAt: now,
6434
- updatedAt: now,
6435
- type: "space" /* SPACE */
6436
- };
6437
- const spaces = getAllMemberSpaces();
6438
- const hasSpaceForActor = spaces.some(
6439
- (membership) => {
6440
- if (isDeviceLocalOwnerId(userId)) {
6441
- return isDeviceLocalSpaceMembership(membership);
6442
- }
6443
- if (isDeviceLocalSpaceMembership(membership)) return false;
6444
- return membership.userId === userId || membership.ownerId === userId;
6445
- }
6446
- );
6447
- console.info("[space/create] addSpaceAction", {
6448
- userId,
6449
- name,
6450
- visibility,
6451
- boundFolder,
6452
- memberSpaceCount: spaces.length,
6453
- hasSpaceForActor,
6454
- currentPath: getCurrentPathForLog()
6455
- });
6456
- if (!hasSpaceForActor) {
6457
- const { data: oldItems = [] } = await getUserDataOnce({
6458
- types: targetTypes,
6459
- userId,
6460
- limit: 100,
6461
- db: extra.db
6462
- });
6463
- const hasOldSideData = oldItems.length > 0;
6464
- if (hasOldSideData) {
6465
- const contents = {};
6466
- const updatePromises = [];
6467
- for (const item of oldItems) {
6468
- if (!item.id || !item.type) continue;
6469
- const recordOwner = resolveRecordOwnerUserId(item);
6470
- if (recordOwner !== userId) continue;
6471
- const stableContentKey = typeof item.dbKey === "string" && item.dbKey.trim() ? item.dbKey : item.id;
6472
- contents[stableContentKey] = {
6473
- title: item.title || "",
6474
- type: item.type,
6475
- contentKey: stableContentKey,
6476
- categoryId: "",
6477
- pinned: false,
6478
- createdAt: item.createdAt ?? now,
6479
- updatedAt: item.updatedAt ?? now,
6480
- order: item.order
6481
- };
6482
- if (item.dbKey) {
6483
- updatePromises.push(
6484
- dispatch(
6485
- patch({
6486
- dbKey: item.dbKey,
6487
- changes: { spaceId, updatedAt: now }
6488
- })
6489
- )
6490
- );
6491
- }
6492
- }
6493
- spaceData.contents = contents;
6494
- await Promise.all(updatePromises);
6495
- }
6496
- }
6497
- const spaceKey = createSpaceKey.space(spaceId);
6498
- await dispatch(
6499
- write({ data: spaceData, customKey: spaceKey, userId })
6500
- ).unwrap();
6501
- const spaceMemberKey = createSpaceKey.member(userId, spaceId);
6502
- const spaceMemberData = {
6503
- dbKey: spaceMemberKey,
6504
- type: "space" /* SPACE */,
6505
- userId,
6506
- role: "owner" /* OWNER */,
6507
- joinedAt: now,
6508
- spaceId,
6509
- spaceName: name,
6510
- ownerId: userId,
6511
- visibility,
6512
- createdAt: nowISO,
6513
- updatedAt: nowISO
6514
- };
6515
- await dispatch(
6516
- write({ data: spaceMemberData, customKey: spaceMemberKey, userId })
6517
- ).unwrap();
6518
- return spaceMemberData;
6519
- };
6520
-
6521
- // packages/app/favorite/favoriteStore.ts
6522
- var import_react14 = __toESM(require_react());
6523
-
6524
- // packages/app/sessionSnapshot.ts
6525
- var import_react12 = __toESM(require_react());
6526
-
6527
- // packages/app/hooks/useHasMounted.ts
6528
- var import_react13 = __toESM(require_react());
6529
-
6530
- // packages/app/favorite/favoriteStore.ts
6531
- var createInitialState4 = () => ({
6532
- agentIds: [],
6533
- contentIds: [],
6534
- favoritedAtById: {},
6535
- initialized: false,
6536
- loading: false,
6537
- error: null
6538
- });
6539
- var state4 = createInitialState4();
6540
- var listeners4 = /* @__PURE__ */ new Set();
6541
- var version4 = 0;
6542
- var notify4 = () => {
6543
- version4 += 1;
6544
- for (const listener of listeners4) {
6545
- try {
6546
- listener();
6547
- } catch {
6548
- }
6549
- }
6550
- };
6551
- function removeFavoriteLocally(payload) {
6552
- const { targetType, id } = payload;
6553
- if (targetType === "agent") {
6554
- state4 = {
6555
- ...state4,
6556
- agentIds: state4.agentIds.filter((item) => item !== id),
6557
- favoritedAtById: { ...state4.favoritedAtById }
6558
- };
6559
- delete state4.favoritedAtById[id];
6560
- notify4();
6561
- return;
6562
- }
6563
- if (targetType === "doc" || targetType === "page" || targetType === "content") {
6564
- state4 = {
6565
- ...state4,
6566
- contentIds: state4.contentIds.filter((item) => item !== id),
6567
- favoritedAtById: { ...state4.favoritedAtById }
6568
- };
6569
- delete state4.favoritedAtById[id];
6570
- notify4();
6571
- }
6572
- }
6573
-
6574
- // packages/app/favorite/deletedFavoriteProjection.ts
6575
- var resolveDeletedFavoriteProjectionRemoval = (contentKey) => {
6576
- if (!contentKey) return null;
6577
- if (isAgentKey(contentKey)) {
6578
- return { targetType: "agent", id: contentKey };
6579
- }
6580
- if (isPageKey(contentKey) || isTableMetaKey(contentKey) || isFileKey(contentKey)) {
6581
- return { targetType: "content", id: contentKey };
6582
- }
6583
- return null;
6584
- };
6585
-
6586
- // packages/agent-runtime/deleteAgentLocalCredential.ts
6587
- var AGENT_LOCAL_CREDENTIAL_DELETE_FAILED_MESSAGE = "Agent was deleted, but local API key cleanup failed. You may remove the leftover credential manually if needed.";
6588
- var createAgentLocalCredentialBroker = createFileCredentialBroker;
6589
- function isPublicAgentProjectionKey(dbKey) {
6590
- const key = asTrimmedString(dbKey);
6591
- return key.startsWith("agent-pub-");
6592
- }
6593
- function extractAgentLocalCredentialRef(record) {
6594
- if (!record || typeof record !== "object") return null;
6595
- const value = record.credentialRef;
6596
- return asOptionalTrimmedString(value) ?? null;
6597
- }
6598
- async function deleteAgentLocalCredentialRef(credentialRef, options) {
6599
- const ref = asTrimmedString(credentialRef);
6600
- if (!ref) {
6601
- return { deleted: false, skipped: true };
6602
- }
6603
- try {
6604
- const factory = options?.brokerFactory ?? createAgentLocalCredentialBroker;
6605
- const broker = factory();
6606
- await broker.delete(ref);
6607
- return { deleted: true };
6608
- } catch {
6609
- return {
6610
- deleted: false,
6611
- warning: AGENT_LOCAL_CREDENTIAL_DELETE_FAILED_MESSAGE
6612
- };
6613
- }
6614
- }
6615
-
6616
- // packages/app/hooks/deleteDbKey.ts
6617
- var performDirectDelete = async (dispatch, getState, contentKey, preferredServerOrigin, includeAttachments) => {
6618
- if (isDialogKey(contentKey)) {
6619
- await dispatch(
6620
- deleteDialog({ dialogKey: contentKey, includeAttachments })
6621
- ).unwrap();
6622
- return;
6623
- }
6624
- if (isTableMetaKey(contentKey)) {
6625
- await dispatch(deleteTable({ dbKey: contentKey })).unwrap();
6626
- return;
6627
- }
6628
- if (isAgentKey(contentKey)) {
6629
- let credentialRef = null;
6630
- let credentialSynced = false;
6631
- if (!isPublicAgentProjectionKey(contentKey)) {
6632
- try {
6633
- let record = selectById(getState(), contentKey);
6634
- if (!record) {
6635
- try {
6636
- record = await dispatch(
6637
- read({
6638
- dbKey: contentKey,
6639
- preferredServerOrigin
6640
- })
6641
- ).unwrap();
6642
- } catch {
6643
- record = null;
6644
- }
6645
- }
6646
- credentialRef = extractAgentLocalCredentialRef(record);
6647
- if (record && typeof record === "object" && "credentialSynced" in record) {
6648
- credentialSynced = record.credentialSynced === true;
6649
- }
6650
- } catch {
6651
- credentialRef = null;
6652
- }
6653
- }
6654
- await dispatch(
6655
- remove({
6656
- dbKey: contentKey,
6657
- preferredServerOrigin
6658
- })
6659
- ).unwrap();
6660
- if (credentialRef) {
6661
- const cleanup = await deleteAgentLocalCredentialRef(credentialRef);
6662
- if (!cleanup.deleted && "warning" in cleanup) {
6663
- console.warn(
6664
- "[deleteDbKey] local API credential cleanup failed after agent delete:",
6665
- cleanup.warning
6666
- );
6667
- }
6668
- }
6669
- if (credentialRef && credentialSynced) {
6670
- try {
6671
- const { currentServer, currentToken } = selectRuntimeSnapshot(
6672
- getState()
6673
- );
6674
- if (currentServer && currentToken) {
6675
- await deleteServerSyncedCredential(
6676
- { currentServer, authToken: currentToken },
6677
- credentialRef
6678
- );
6679
- }
6680
- } catch {
6681
- }
6682
- }
6683
- return;
6684
- }
6685
- if (isAppKey(contentKey) || isPageKey(contentKey) || isFileKey(contentKey) || isTaskKey(contentKey)) {
6686
- await dispatch(
6687
- remove({
6688
- dbKey: contentKey,
6689
- preferredServerOrigin
6690
- })
6691
- ).unwrap();
6692
- }
6693
- };
6694
- var resolveDeleteInput = (input) => {
6695
- if (typeof input === "string" && input.trim()) {
6696
- return { contentKey: input };
6697
- }
6698
- if (input && typeof input === "object") {
6699
- const candidates = [input.contentKey, input.dbKey, input.key];
6700
- const preferredServerOrigin = asNonEmptyStringArray([
6701
- input.preferredServerOrigin,
6702
- input.serverOrigin
6703
- ])[0];
6704
- const inputSpaceId = typeof input.spaceId === "string" && input.spaceId.trim().length > 0 ? input.spaceId : null;
6705
- const includeAttachments = input.includeAttachments === true;
6706
- for (const candidate of candidates) {
6707
- if (typeof candidate === "string" && candidate.trim()) {
6708
- return {
6709
- contentKey: candidate,
6710
- preferredServerOrigin,
6711
- inputSpaceId,
6712
- includeAttachments
6713
- };
6714
- }
6715
- }
6716
- }
6717
- throw new Error("Invalid delete key");
6718
- };
6719
- var extractDeleteErrorMessage = (error, seen = /* @__PURE__ */ new Set(), depth = 0) => {
6720
- if (depth > 8) {
6721
- return null;
6722
- }
6723
- if (error instanceof Error && error.message.trim()) {
6724
- return error.message;
6725
- }
6726
- if (typeof error === "string" && error.trim()) {
6727
- return error;
6728
- }
6729
- if (!error || typeof error !== "object") {
6730
- return null;
6731
- }
6732
- if (seen.has(error)) {
6733
- return null;
6734
- }
6735
- seen.add(error);
6736
- const record = error;
6737
- const directKeys = ["message", "error", "detail", "title"];
6738
- for (const key of directKeys) {
6739
- const value = record[key];
6740
- if (typeof value === "string" && value.trim()) {
6741
- return value;
6742
- }
6743
- }
6744
- const nestedKeys = ["payload", "data", "cause"];
6745
- for (const key of nestedKeys) {
6746
- const message = extractDeleteErrorMessage(record[key], seen, depth + 1);
6747
- if (message) {
6748
- return message;
6749
- }
6750
- }
6751
- if (Array.isArray(record.errors)) {
6752
- const messages = record.errors.map((item) => extractDeleteErrorMessage(item, seen, depth + 1)).filter((item) => Boolean(item));
6753
- if (messages.length > 0) {
6754
- return messages.join("\n");
6755
- }
6756
- }
6757
- try {
6758
- const serialized = JSON.stringify(error);
6759
- if (serialized && serialized !== "{}") {
6760
- return serialized;
6761
- }
6762
- } catch {
6763
- return null;
6764
- }
6765
- return null;
6766
- };
6767
- var getDeleteErrorMessage = (error, fallback = "Delete failed") => {
6768
- return extractDeleteErrorMessage(error) ?? fallback;
6769
- };
6770
- var normalizeDeleteError = (error) => {
6771
- if (error instanceof Error && error.message.trim()) {
6772
- return error;
6773
- }
6774
- return new Error(getDeleteErrorMessage(error));
6775
- };
6776
- var deleteDbKey = (input, spaceId) => async (dispatch, getState) => {
6777
- try {
6778
- const {
6779
- contentKey,
6780
- preferredServerOrigin,
6781
- inputSpaceId,
6782
- includeAttachments
6783
- } = resolveDeleteInput(input);
6784
- const effectiveSpaceId = typeof spaceId === "string" && spaceId.trim().length > 0 ? spaceId : inputSpaceId ?? null;
6785
- await performDirectDelete(
6786
- dispatch,
6787
- getState,
6788
- contentKey,
6789
- preferredServerOrigin,
6790
- includeAttachments
6791
- );
6792
- const spaceIds = isAppKey(contentKey) ? /* @__PURE__ */ new Set([
6793
- effectiveSpaceId,
6794
- ...getAllMemberSpaces().map((space) => space.spaceId)
6795
- ]) : /* @__PURE__ */ new Set([effectiveSpaceId]);
6796
- await Promise.all(
6797
- [...spaceIds].filter((spaceId2) => Boolean(spaceId2)).map(
6798
- (spaceId2) => dispatch(
6799
- deleteContentFromSpace({
6800
- contentKey,
6801
- spaceId: spaceId2,
6802
- ...preferredServerOrigin ? { sourceServerOrigin: preferredServerOrigin } : {}
6803
- })
6804
- ).unwrap().catch((err2) => {
6805
- console.warn("[deleteDbKey] space cleanup failed (entity already tombstoned):", err2);
6806
- })
6807
- )
6808
- );
6809
- const favoriteProjectionRemoval = resolveDeletedFavoriteProjectionRemoval(contentKey);
6810
- if (favoriteProjectionRemoval) {
6811
- removeFavoriteLocally(favoriteProjectionRemoval);
6812
- }
6813
- if (typeof window !== "undefined") {
6814
- window.dispatchEvent(
6815
- new CustomEvent("nolo-user-data-updated", {
6816
- detail: { deletedDbKey: contentKey }
6817
- })
6818
- );
6819
- }
6820
- return true;
6821
- } catch (error) {
6822
- throw normalizeDeleteError(error);
6823
5016
  }
6824
- };
6825
-
6826
- // packages/create/space/deleteSpaceAction.ts
6827
- var getCurrentUserId = (state6) => asOptionalTrimmedString(selectIdentityUserId(state6)) ?? null;
6828
- var fetchSpaceData = async (spaceId, dispatch) => {
6829
- const spaceKey = createSpaceKey.space(spaceId);
6830
- try {
6831
- return await dispatch(read({
6832
- dbKey: spaceKey
6833
- })).unwrap();
6834
- } catch (error) {
6835
- console.warn(`Failed to read space ${spaceId}:`, error);
6836
- return void 0;
6837
- }
6838
- };
6839
- var checkOwnerPermission = (spaceData, accountUserId) => {
6840
- if (!spaceData) return;
6841
- if (isDeviceLocalSpaceBody(spaceData)) return;
6842
- if (!accountUserId) {
6843
- throw new Error("User is not logged in.");
6844
- }
6845
- if (spaceData.ownerId !== accountUserId) {
6846
- throw new Error("Only owner can delete space");
6847
- }
6848
- };
6849
- var deleteSpaceData = async (spaceId, dispatch) => {
6850
- const spaceKey = createSpaceKey.space(spaceId);
6851
- try {
6852
- await dispatch(remove(spaceKey)).unwrap();
6853
- } catch (error) {
6854
- console.warn(`Failed to delete space ${spaceId}:`, error);
6855
- }
6856
- };
6857
- var tombstoneLocalAuthorityRecord = async (dbKey, existing, dispatch) => {
6858
- const nowIso = (/* @__PURE__ */ new Date()).toISOString();
6859
- const base = existing && typeof existing === "object" ? { ...existing } : { dbKey };
6860
- const tombstone = buildTombstoneRecord(
6861
- {
6862
- ...base,
6863
- dbKey,
6864
- userId: DEVICE_LOCAL_OWNER_ID
6865
- },
6866
- nowIso
6867
- );
6868
- await dispatch(
6869
- write({
6870
- data: tombstone,
6871
- customKey: dbKey,
6872
- userId: DEVICE_LOCAL_OWNER_ID
6873
- })
6874
- ).unwrap();
6875
- };
6876
- var deleteLocalSpaceAuthority = async (spaceId, spaceData, dispatch) => {
6877
- const spaceKey = createSpaceKey.space(spaceId);
6878
- try {
6879
- await tombstoneLocalAuthorityRecord(
6880
- spaceKey,
6881
- spaceData && typeof spaceData === "object" ? spaceData : { dbKey: spaceKey },
6882
- dispatch
6883
- );
6884
- } catch (error) {
6885
- console.warn(`Failed to tombstone local space ${spaceId}:`, error);
6886
- throw error;
6887
- }
6888
- const memberIds = /* @__PURE__ */ new Set([
6889
- DEVICE_LOCAL_OWNER_ID,
6890
- ...asTrimmedNonEmptyStringArray(spaceData?.members)
6891
- ]);
6892
- for (const memberId of memberIds) {
6893
- const memberKey = createSpaceKey.member(memberId, spaceId);
6894
- let existingMember = null;
6895
- try {
6896
- existingMember = await dispatch(read({ dbKey: memberKey })).unwrap();
6897
- } catch {
6898
- existingMember = null;
6899
- }
6900
- try {
6901
- await tombstoneLocalAuthorityRecord(
6902
- memberKey,
6903
- existingMember ?? {
6904
- dbKey: memberKey,
6905
- type: "space" /* SPACE */,
6906
- userId: memberId,
6907
- spaceId: normalizeSpaceId(spaceId)
6908
- },
6909
- dispatch
6910
- );
6911
- } catch (err2) {
6912
- console.warn(
6913
- `Failed to tombstone local membership ${memberId} for space ${spaceId}:`,
6914
- err2
6915
- );
6916
- }
6917
- }
6918
- };
6919
- var deleteAllMembers = async (spaceData, spaceId, dispatch) => {
6920
- if (spaceData?.members) {
6921
- for (const memberId of spaceData.members) {
6922
- const memberKey = createSpaceKey.member(memberId, spaceId);
6923
- await dispatch(remove(memberKey)).unwrap().catch(
6924
- (err2) => console.warn(
6925
- `Failed to delete member ${memberId} for space ${spaceId}:`,
6926
- err2
6927
- )
6928
- );
6929
- }
6930
- }
6931
- };
6932
- var deleteCurrentUserMember = async (userId, spaceId, dispatch) => {
6933
- const currentUserMemberKey = createSpaceKey.member(userId, spaceId);
6934
- await dispatch(remove(currentUserMemberKey)).unwrap().catch(
6935
- (err2) => console.warn(
6936
- `Failed to delete member key for user ${userId} in space ${spaceId}:`,
6937
- err2
6938
- )
6939
- );
6940
- };
6941
- var resolveDeleteArgs = (input) => {
6942
- if (typeof input === "string") {
6943
- return { spaceId: input, strategy: "delete-space-only" };
6944
- }
6945
- return {
6946
- spaceId: input.spaceId,
6947
- strategy: input.strategy ?? "delete-space-only"
6948
- };
6949
- };
6950
- var isOwnedByUser = (entityKey, entity, userId) => {
6951
- if (!entityKey || !userId) return false;
6952
- const keyParts = splitKey(entityKey);
6953
- const keyedOwner = keyParts[1];
6954
- if ((isDialogKey(entityKey) || isPageKey(entityKey) || isFileKey(entityKey) || isTableMetaKey(entityKey)) && keyedOwner === userId) {
6955
- return true;
6956
- }
6957
- if ((isAgentKey(entityKey) || isAppKey(entityKey)) && entity?.userId === userId) {
6958
- return true;
6959
- }
6960
- if (entity?.tenantId === userId || entity?.userId === userId || entity?.ownerId === userId) {
6961
- return true;
6962
- }
6963
- return false;
6964
- };
6965
- var nextUpdatedAt = (entity) => {
6966
- const source = entity?.updatedAt ?? entity?.updated_at ?? entity?.createdAt ?? entity?.created ?? Date.now();
6967
- const timestamp = typeof source === "number" ? source : Date.parse(String(source)) || Date.now();
6968
- return new Date(Math.max(Date.now(), timestamp + 1)).toISOString();
6969
- };
6970
- var listSpaceEntities = async (spaceData, dispatch) => {
6971
- const results = [];
6972
- const contents = Object.values(spaceData?.contents ?? {}).filter(Boolean);
6973
- for (const item of contents) {
6974
- const entityKey = typeof item.contentKey === "string" ? item.contentKey : "";
6975
- if (!entityKey) continue;
6976
- let entity = null;
6977
- try {
6978
- entity = await dispatch(read({ dbKey: entityKey })).unwrap();
6979
- } catch {
6980
- entity = null;
6981
- }
6982
- results.push({ entityKey, entity });
6983
- }
6984
- return results;
6985
- };
6986
- var clearEntitySpaceIds = async (entities, dispatch) => {
6987
- await Promise.all(
6988
- entities.filter(({ entity }) => entity && typeof entity === "object").map(
6989
- ({ entityKey, entity }) => dispatch(
6990
- patch({
6991
- dbKey: entityKey,
6992
- changes: {
6993
- spaceId: null,
6994
- updatedAt: nextUpdatedAt(entity)
6995
- }
6996
- })
6997
- ).unwrap()
6998
- )
6999
- );
7000
- };
7001
- var deleteOwnedEntities = async (ownedEntities, dispatch) => {
7002
- for (const { entityKey } of ownedEntities) {
7003
- await dispatch(deleteDbKey(entityKey));
7004
- }
7005
- };
7006
- var deleteSpaceAction = async (input, thunkAPI) => {
7007
- const { dispatch, getState } = thunkAPI;
7008
- const { spaceId, strategy } = resolveDeleteArgs(input);
7009
- const accountUserId = getCurrentUserId(getState());
7010
- const spaceData = await fetchSpaceData(spaceId, dispatch);
7011
- const isLocalSpace = isDeviceLocalSpaceBody(spaceData);
7012
- if (!isLocalSpace) {
7013
- if (!accountUserId) {
7014
- throw new Error("User is not logged in.");
7015
- }
7016
- checkOwnerPermission(spaceData, accountUserId);
7017
- }
7018
- const ownershipUserId = isLocalSpace ? DEVICE_LOCAL_OWNER_ID : accountUserId;
7019
- if (spaceData && strategy !== "delete-space-only") {
7020
- const allEntities = await listSpaceEntities(spaceData, dispatch);
7021
- const ownedEntities = allEntities.filter(
7022
- ({ entityKey, entity }) => isOwnedByUser(entityKey, entity, ownershipUserId)
7023
- );
7024
- const unownedEntities = allEntities.filter(
7025
- ({ entityKey, entity }) => !isOwnedByUser(entityKey, entity, ownershipUserId)
7026
- );
7027
- if (strategy === "move-owned-to-all") {
7028
- await clearEntitySpaceIds(allEntities, dispatch);
7029
- } else if (strategy === "delete-owned-content") {
7030
- await deleteOwnedEntities(ownedEntities, dispatch);
7031
- await clearEntitySpaceIds(unownedEntities, dispatch);
7032
- }
7033
- }
7034
- if (isLocalSpace) {
7035
- await deleteLocalSpaceAuthority(spaceId, spaceData, dispatch);
7036
- } else {
7037
- await deleteSpaceData(spaceId, dispatch);
7038
- await deleteAllMembers(spaceData, spaceId, dispatch);
7039
- await deleteCurrentUserMember(accountUserId, spaceId, dispatch);
7040
- }
7041
- return { spaceId, strategy };
7042
- };
7043
-
7044
- // packages/create/space/fetchSpaceAction.ts
7045
- var fetchSpaceAction = async (input, thunkAPI) => {
7046
- const rawSpaceId = typeof input === "string" ? input : input?.spaceId;
7047
- const fresh = typeof input === "object" && input !== null ? !!input.fresh : false;
7048
- const { dispatch } = thunkAPI;
7049
- if (!rawSpaceId) {
7050
- throw new Error("spaceId is required");
7051
- }
7052
- const spaceId = normalizeSpaceId(rawSpaceId);
7053
- const spaceKey = createSpaceKey.space(spaceId);
7054
- const readSpace = async (dbKey) => {
7055
- try {
7056
- const { read: read2, readAndWait: readAndWait2 } = await import("./dbSlice-FWF5F4L7.js");
7057
- if (fresh) {
7058
- return await dispatch(readAndWait2(dbKey)).unwrap();
7059
- }
7060
- return await dispatch(
7061
- read2({
7062
- dbKey
7063
- })
7064
- ).unwrap();
7065
- } catch {
7066
- return null;
7067
- }
7068
- };
7069
- const readLocalSpaceBody = async () => {
7070
- let spaceData2 = await readSpace(spaceKey);
7071
- if (!spaceData2 && rawSpaceId !== spaceKey) {
7072
- spaceData2 = await readSpace(rawSpaceId);
7073
- }
7074
- if (!spaceData2 || isTombstoneRecord(spaceData2)) {
7075
- return null;
7076
- }
7077
- return spaceData2;
7078
- };
7079
- if (fresh) {
7080
- const localBody = await readLocalSpaceBody();
7081
- if (localBody && isDeviceLocalSpaceBody(localBody)) {
7082
- return { spaceId, spaceData: localBody };
7083
- }
7084
- const { token, userId, servers } = selectSpaceRemoteAuth(thunkAPI.getState());
7085
- if (token && userId && servers.length > 0) {
7086
- const remoteSpace = await fetchAuthoritativeRemoteSpace({
7087
- servers,
7088
- token,
7089
- userId,
7090
- spaceId
7091
- });
7092
- if (remoteSpace) return { spaceId, spaceData: remoteSpace };
7093
- throw new Error(`Space not found: ${spaceId}`);
7094
- }
7095
- if (localBody) {
7096
- return { spaceId, spaceData: localBody };
7097
- }
7098
- throw new Error(`Space not found: ${spaceId}`);
7099
- }
7100
- const spaceData = await readLocalSpaceBody();
7101
- if (!spaceData) {
7102
- throw new Error(`Space not found: ${spaceId}`);
7103
- }
7104
- return { spaceId, spaceData };
7105
- };
7106
-
7107
- // packages/create/space/updateSpaceAction.ts
7108
- var updateSpaceAction = async (input, thunkAPI) => {
7109
- const { spaceId, name, description, visibility, boundFolder } = input;
7110
- const { dispatch, getState } = thunkAPI;
7111
- const state6 = getState();
7112
- const userId = selectIdentityUserId(state6);
7113
- const spaceKey = createSpaceKey.space(spaceId);
7114
- let spaceData = null;
7115
- try {
7116
- spaceData = await dispatch(read({
7117
- dbKey: spaceKey
7118
- })).unwrap();
7119
- } catch (readError) {
7120
- throw new Error(
7121
- `\u65E0\u6CD5\u52A0\u8F7D\u7A7A\u95F4\u6570\u636E: ${spaceId}, \u539F\u56E0: ${toErrorMessage(readError)}`
7122
- );
7123
- }
7124
- if (!spaceData) {
7125
- throw new Error(`\u7A7A\u95F4\u4E0D\u5B58\u5728: ${spaceId}`);
7126
- }
7127
- if (!userId) {
7128
- throw new Error("\u7528\u6237\u672A\u767B\u5F55\uFF0C\u65E0\u6CD5\u66F4\u65B0\u7A7A\u95F4\u8BBE\u7F6E\u3002");
7129
- }
7130
- if (!spaceData.members || !spaceData.members.includes(userId)) {
7131
- throw new Error("\u5F53\u524D\u7528\u6237\u4E0D\u662F\u7A7A\u95F4\u6210\u5458\uFF0C\u65E0\u6CD5\u66F4\u65B0\u7A7A\u95F4\u8BBE\u7F6E\u3002");
7132
- }
7133
- const changes = {};
7134
- let hasChanges = false;
7135
- if (name !== void 0 && name !== spaceData.name) {
7136
- changes.name = name.trim();
7137
- hasChanges = true;
7138
- }
7139
- if (description !== void 0 && description !== spaceData.description) {
7140
- changes.description = description;
7141
- hasChanges = true;
7142
- }
7143
- if (visibility !== void 0 && visibility !== spaceData.visibility) {
7144
- changes.visibility = visibility;
7145
- hasChanges = true;
7146
- }
7147
- if (boundFolder !== void 0 && (boundFolder || void 0) !== (spaceData.boundFolder || void 0)) {
7148
- changes.boundFolder = boundFolder || void 0;
7149
- hasChanges = true;
7150
- }
7151
- if (!hasChanges) {
7152
- return { updatedSpace: spaceData, spaceId };
7153
- }
7154
- const now = Date.now();
7155
- changes.updatedAt = now;
7156
- let updatedSpaceData;
7157
- try {
7158
- updatedSpaceData = await dispatch(
7159
- patch({
7160
- dbKey: spaceKey,
7161
- changes
7162
- })
7163
- ).unwrap();
7164
- } catch (patchError) {
7165
- throw new Error(`\u66F4\u65B0\u7A7A\u95F4\u8BBE\u7F6E\u5931\u8D25: ${toErrorMessage(patchError)}`);
7166
- }
7167
- if (changes.name !== void 0) {
7168
- const memberKey = createSpaceKey.member(userId, spaceId);
7169
- try {
7170
- const memberData = await dispatch(
7171
- read({
7172
- dbKey: memberKey
7173
- })
7174
- ).unwrap();
7175
- if (memberData) {
7176
- const memberChanges = {
7177
- spaceName: changes.name,
7178
- updatedAt: now
7179
- // 为 member 数据也设置 updatedAt
7180
- };
7181
- await dispatch(
7182
- patch({
7183
- dbKey: memberKey,
7184
- changes: memberChanges
7185
- })
7186
- ).unwrap();
7187
- }
7188
- } catch (memberError) {
7189
- console.error(
7190
- `Failed to update member data ${memberKey} for space name change:`,
7191
- memberError
7192
- );
7193
- }
7194
- }
7195
- return {
7196
- updatedSpace: updatedSpaceData,
7197
- spaceId
7198
- };
7199
- };
7200
-
7201
- // packages/create/space/fetchSpaceSidebarStateAction.ts
7202
- var fetchSpaceSidebarStateAction = async (spaceId, thunkAPI) => {
7203
- const { dispatch, getState } = thunkAPI;
7204
- const normalizedSpaceId = normalizeSpaceId(spaceId);
7205
- return {
7206
- collapsedCategories: typeof window === "undefined" ? {} : readStoredCollapsedCategories(
7207
- normalizedSpaceId,
7208
- window.localStorage
7209
- )
7210
- };
7211
- };
7212
-
7213
- // packages/create/space/changeSpaceAction.ts
7214
- var getSpaceUpdatedAt = (space) => {
7215
- if (!space) return 0;
7216
- return toTimestampMs(space.updatedAt);
7217
- };
7218
- var changeSpaceAction = async (spaceId, thunkAPI) => {
7219
- const normalizedSpaceId = normalizeSpaceId(spaceId);
7220
- const sidebarPromise = fetchSpaceSidebarStateAction(
7221
- normalizedSpaceId,
7222
- thunkAPI
7223
- ).catch(() => ({ collapsedCategories: {} }));
7224
- let spaceData = null;
7225
- let usedLocal = false;
7226
- try {
7227
- const local = await fetchSpaceAction(
7228
- { spaceId: normalizedSpaceId, fresh: false },
7229
- thunkAPI
7230
- );
7231
- if (local?.spaceData) {
7232
- spaceData = local.spaceData;
7233
- usedLocal = true;
7234
- }
7235
- } catch {
7236
- }
7237
- if (!spaceData) {
7238
- const fresh = await fetchSpaceAction(
7239
- { spaceId: normalizedSpaceId, fresh: true },
7240
- thunkAPI
7241
- );
7242
- if (!fresh?.spaceData) {
7243
- throw new Error("\u7A7A\u95F4\u4E0D\u5B58\u5728\u6216\u52A0\u8F7D\u5931\u8D25");
7244
- }
7245
- spaceData = fresh.spaceData;
7246
- } else if (usedLocal) {
7247
- void fetchSpaceAction({ spaceId: normalizedSpaceId, fresh: true }, thunkAPI).then((result) => {
7248
- if (!result?.spaceData) return;
7249
- const state6 = thunkAPI.getState()?.space;
7250
- if (!state6) return;
7251
- if (normalizeSpaceId(state6.currentSpaceId || "") !== normalizedSpaceId) {
7252
- return;
7253
- }
7254
- if (getSpaceUpdatedAt(result.spaceData) < getSpaceUpdatedAt(state6.currentSpace)) {
7255
- return;
7256
- }
7257
- thunkAPI.dispatch({
7258
- type: "space/fetchSpace/fulfilled",
7259
- payload: {
7260
- spaceId: normalizedSpaceId,
7261
- spaceData: result.spaceData
7262
- },
7263
- meta: {
7264
- arg: { spaceId: normalizedSpaceId, fresh: true },
7265
- requestId: `changeSpace-revalidate-${normalizedSpaceId}`,
7266
- requestStatus: "fulfilled"
7267
- }
7268
- });
7269
- }).catch(() => {
7270
- });
7271
- }
7272
- const sidebarState = await sidebarPromise;
7273
- return {
7274
- spaceId: normalizedSpaceId,
7275
- spaceData,
7276
- sidebarState
7277
- };
7278
- };
7279
-
7280
- // packages/create/space/spaceThunks.ts
7281
- var createSpaceThunks = (create) => ({
7282
- fetchSpaceSidebarState: create.asyncThunk(fetchSpaceSidebarStateAction, {
7283
- fulfilled: (state6, action) => {
7284
- setCollapsedCategories(action.payload.collapsedCategories, getCurrentSpaceIdRaw());
7285
- },
7286
- rejected: (state6, action) => {
7287
- console.error("\u83B7\u53D6\u7A7A\u95F4\u4FA7\u8FB9\u680F\u72B6\u6001\u5931\u8D25:", action.error.message);
7288
- setCollapsedCategories({}, getCurrentSpaceIdRaw());
7289
- }
7290
- }),
7291
- changeSpace: create.asyncThunk(changeSpaceAction, {
7292
- pending: (state6, action) => {
7293
- const newSpaceId = normalizeSpaceId(action.meta.arg);
7294
- if (getCurrentSpaceIdRaw() !== newSpaceId) {
7295
- setMembershipLoading();
7296
- setCurrentSpace(null);
7297
- }
7298
- },
7299
- fulfilled: (state6, action) => {
7300
- setCurrentSpaceBoth(action.payload.spaceId, action.payload.spaceData);
7301
- setMembershipLoaded();
7302
- setCollapsedCategories(
7303
- action.payload.sidebarState?.collapsedCategories || {},
7304
- action.payload.spaceId
7305
- );
7306
- },
7307
- rejected: (state6, action) => {
7308
- setMembershipRejected(action.error.message || "\u5207\u6362\u7A7A\u95F4\u5931\u8D25", false);
7309
- setCurrentSpaceBoth(null, null);
7310
- setCollapsedCategories({}, null);
7311
- }
7312
- }),
7313
- addSpace: create.asyncThunk(addSpaceAction, {
7314
- pending: (state6) => {
7315
- setMembershipLoading();
7316
- },
7317
- fulfilled: (state6, action) => {
7318
- addMemberSpace(action.payload);
7319
- },
7320
- rejected: (state6, action) => {
7321
- setMembershipRejected(action.error.message, false);
7322
- }
7323
- }),
7324
- deleteSpace: create.asyncThunk(deleteSpaceAction, {
7325
- fulfilled: (state6, action) => {
7326
- const normalizedSpaceId = normalizeSpaceId(action.payload.spaceId);
7327
- const currentSpaceId = getCurrentSpaceIdRaw();
7328
- const normalizedCurrentSpaceId = currentSpaceId ? normalizeSpaceId(currentSpaceId) : null;
7329
- removeMemberSpace(normalizedSpaceId);
7330
- if (normalizedCurrentSpaceId === normalizedSpaceId) {
7331
- setCurrentSpaceBoth(null, null);
7332
- setCollapsedCategories({}, null);
7333
- setViewMode("all");
7334
- }
7335
- }
7336
- }),
7337
- updateSpace: create.asyncThunk(updateSpaceAction, {
7338
- fulfilled: (state6, action) => {
7339
- const { updatedSpace, spaceId } = action.payload;
7340
- updateCurrentSpaceIfMatch(spaceId, updatedSpace);
7341
- if (updatedSpace.name) {
7342
- updateMemberSpaceName(updatedSpace.id, updatedSpace.name);
7343
- }
7344
- }
7345
- }),
7346
- fetchSpace: create.asyncThunk(fetchSpaceAction, {
7347
- fulfilled: (state6, action) => {
7348
- const { spaceId, spaceData } = action.payload;
7349
- const currentSpaceId = getCurrentSpaceIdRaw();
7350
- if (!currentSpaceId || currentSpaceId === spaceId) {
7351
- setCurrentSpaceBoth(spaceId, spaceData);
7352
- setSpaceInitialized();
7353
- }
7354
- }
7355
- })
7356
- });
7357
-
7358
- // packages/create/space/spaceDialogStore.ts
7359
- var import_react15 = __toESM(require_react(), 1);
7360
- var createInitialState5 = () => ({
7361
- dialogStatuses: {},
7362
- dialogEventTimestamps: {},
7363
- dialogTitles: {},
7364
- unreadDialogIds: {}
7365
- });
7366
- var state5 = createInitialState5();
7367
- var listeners5 = /* @__PURE__ */ new Set();
7368
- var version5 = 0;
7369
- var notify5 = () => {
7370
- version5 += 1;
7371
- for (const listener of listeners5) {
7372
- try {
7373
- listener();
7374
- } catch {
5017
+ );
5018
+ var updateContentCategory = createAsyncThunk(
5019
+ "space/updateContentCategory",
5020
+ async (arg, thunkAPI) => {
5021
+ const payload = await updateContentCategoryAction(arg, thunkAPI);
5022
+ if (getCurrentSpaceIdRaw() === payload.spaceId) {
5023
+ updateCurrentSpaceIfMatch(payload.spaceId, payload.updatedSpaceData);
7375
5024
  }
5025
+ return payload;
7376
5026
  }
7377
- };
7378
- var nextDialogEventTimestamp = (prev, now = Date.now()) => Math.max(now, toTimestampMs(prev) + 1);
7379
- function applySpaceEventDialog(ev, now = Date.now()) {
7380
- if (ev.type === "dialog.created" && ev.dialogKey && ev.dialogId && ev.title) {
7381
- const ts = nextDialogEventTimestamp(state5.dialogEventTimestamps[ev.dialogId], now);
7382
- state5 = {
7383
- ...state5,
7384
- dialogStatuses: { ...state5.dialogStatuses, [ev.dialogId]: "running" },
7385
- dialogEventTimestamps: { ...state5.dialogEventTimestamps, [ev.dialogId]: ts },
7386
- dialogTitles: { ...state5.dialogTitles, [ev.dialogId]: ev.title },
7387
- unreadDialogIds: { ...state5.unreadDialogIds, [ev.dialogId]: false }
7388
- };
7389
- if (state5.unreadDialogIds[ev.dialogId] !== void 0) {
7390
- const next = { ...state5.unreadDialogIds };
7391
- delete next[ev.dialogId];
7392
- state5 = { ...state5, unreadDialogIds: next };
7393
- }
7394
- }
7395
- if (ev.type === "dialog.done" && ev.dialogId) {
7396
- const ts = nextDialogEventTimestamp(state5.dialogEventTimestamps[ev.dialogId], now);
7397
- state5 = {
7398
- ...state5,
7399
- dialogStatuses: { ...state5.dialogStatuses, [ev.dialogId]: "done" },
7400
- dialogEventTimestamps: { ...state5.dialogEventTimestamps, [ev.dialogId]: ts },
7401
- unreadDialogIds: { ...state5.unreadDialogIds, [ev.dialogId]: true }
7402
- };
7403
- }
7404
- if (ev.type === "dialog.failed" && ev.dialogId) {
7405
- const ts = nextDialogEventTimestamp(state5.dialogEventTimestamps[ev.dialogId], now);
7406
- state5 = {
7407
- ...state5,
7408
- dialogStatuses: { ...state5.dialogStatuses, [ev.dialogId]: "failed" },
7409
- dialogEventTimestamps: { ...state5.dialogEventTimestamps, [ev.dialogId]: ts },
7410
- unreadDialogIds: { ...state5.unreadDialogIds, [ev.dialogId]: true }
7411
- };
7412
- }
7413
- notify5();
7414
- }
7415
- function clearDialogUnread(dialogId) {
7416
- if (state5.unreadDialogIds[dialogId] === void 0) return;
7417
- const next = { ...state5.unreadDialogIds };
7418
- delete next[dialogId];
7419
- state5 = { ...state5, unreadDialogIds: next };
7420
- notify5();
7421
- }
7422
- function resetSpaceDialogState() {
7423
- state5 = createInitialState5();
7424
- notify5();
7425
- }
7426
-
7427
- // packages/create/space/spaceCurrentSelectors.ts
7428
- var getSpaceUpdatedAt2 = (space) => space ? Number(space.updatedAt) || 0 : 0;
7429
- function getCurrentSpace(entities) {
7430
- const spaceId = getCurrentSpaceId();
7431
- if (!spaceId) return null;
7432
- const stored = getCurrentSpaceRaw();
7433
- const entity = entities[createSpaceKey.space(spaceId)];
7434
- if (!stored) return entity ?? null;
7435
- if (!entity) return stored;
7436
- return getSpaceUpdatedAt2(entity) > getSpaceUpdatedAt2(stored) ? entity : stored;
7437
- }
7438
-
7439
- // packages/create/space/spaceSlice.ts
7440
- var createSliceWithThunks2 = buildCreateSlice({
7441
- creators: { asyncThunk: asyncThunkCreator }
7442
- });
7443
- var initialState2 = {};
7444
- var spaceSlice = createSliceWithThunks2({
7445
- name: "space",
7446
- initialState: initialState2,
7447
- reducers: (create) => ({
7448
- ...createSpaceThunks(create),
7449
- ...createCategoryActions(create),
7450
- ...createContentThunks(create),
7451
- ...createMemberThunks(create),
7452
- resetSpace: create.reducer((_state) => {
7453
- resetSpaceUiState();
7454
- resetSpaceDialogState();
7455
- resetSpaceMembershipState();
7456
- resetSpaceCurrentState();
7457
- }),
7458
- setViewMode: create.reducer((_state, action) => {
7459
- setViewMode(action.payload);
7460
- }),
7461
- hydrateMemberSpacesFromLocal: create.reducer((_state, action) => {
7462
- hydrateMemberSpacesFromLocal(action.payload);
7463
- }),
7464
- appendRecoveredMemberships: create.reducer((_state, action) => {
7465
- appendRecoveredMemberships(action.payload);
7466
- }),
7467
- markDialogRead: create.asyncThunk(
7468
- async (payload, thunkAPI) => {
7469
- if (payload.dialogKey) {
7470
- const { patch: patch2 } = await import("./dbSlice-FWF5F4L7.js");
7471
- try {
7472
- await thunkAPI.dispatch(
7473
- patch2({ dbKey: payload.dialogKey, changes: { unreadAt: null } })
7474
- ).unwrap();
7475
- } catch (error) {
7476
- console.warn("[space/markDialogRead] failed to clear unreadAt", payload.dialogKey, error);
7477
- }
7478
- }
7479
- return { dialogId: payload.dialogId };
7480
- },
7481
- {
7482
- pending: (_state, action) => clearDialogUnread(action.meta.arg.dialogId),
7483
- fulfilled: (_state, action) => clearDialogUnread(action.payload.dialogId)
7484
- }
7485
- ),
7486
- applySpaceEvent: create.reducer((_state, action) => {
7487
- const now = Date.now();
7488
- const ev = action.payload;
7489
- if (ev.type === "dialog.created" && ev.dialogKey && ev.dialogId && ev.title) {
7490
- appendDialogContentEntry(ev.dialogKey, ev.title, Math.max(now, 1));
7491
- }
7492
- applySpaceEventDialog(ev, now);
7493
- })
7494
- })
7495
- });
7496
- var {
7497
- toggleCategoryCollapse: toggleCategoryCollapse2,
7498
- setAllCategoriesCollapsed,
7499
- changeSpace,
7500
- addSpace,
7501
- deleteSpace,
7502
- updateSpace,
7503
- fetchSpace,
7504
- addCategory,
7505
- deleteCategory,
7506
- updateCategoryName,
7507
- reorderCategories,
7508
- addContentToSpace,
7509
- moveContentToSpace,
7510
- deleteContentFromSpace,
7511
- deleteMultipleContent,
7512
- updateContentTitle,
7513
- updateContentPinned,
7514
- updateContentCategory,
7515
- uploadAndAddFileToSpace,
7516
- fetchUserSpaceMemberships,
7517
- addMember,
7518
- removeMember,
7519
- fetchSpaceSidebarState,
7520
- applySpaceEvent,
7521
- markDialogRead,
7522
- resetSpace,
7523
- setViewMode: setViewMode2,
7524
- toggleFavoritesCollapse,
7525
- hydrateMemberSpacesFromLocal: hydrateMemberSpacesFromLocal2,
7526
- appendRecoveredMemberships: appendRecoveredMemberships2
7527
- } = spaceSlice.actions;
7528
- var selectCurrentSpaceId = (_state) => getCurrentSpaceId();
7529
- var selectCurrentSpace = (state6) => getCurrentSpace(selectEntities(state6));
7530
- var selectSpaceById = (state6, spaceId) => {
7531
- if (!spaceId) return null;
7532
- return selectEntities(state6)[createSpaceKey.space(spaceId)] || null;
7533
- };
7534
- var selectViewMode = (_state) => getViewMode();
7535
- var selectDialogStatusFromEntity = (dialogKey) => (state6) => selectEntities(state6)[dialogKey]?.status;
7536
- var selectIsDialogUnreadFromEntity = (dialogKey) => (state6) => {
7537
- const entity = selectEntities(state6)[dialogKey];
7538
- return typeof entity?.unreadAt === "number" && entity.unreadAt > 0;
7539
- };
7540
- var spaceSlice_default = spaceSlice.reducer;
5027
+ );
7541
5028
 
7542
5029
  export {
7543
5030
  instance,
7544
5031
  initReactI18next,
7545
5032
  i18nBaseConfig,
7546
- getCurrentSpaceId,
7547
- getCurrentSpaceIdRaw,
7548
- getViewMode,
7549
5033
  fetchAndCacheTableRows,
7550
5034
  client_default,
7551
5035
  createTable,
7552
5036
  addRow,
5037
+ deleteTable,
7553
5038
  loadTableRows,
7554
5039
  selectCurrentTable,
7555
5040
  selectTableRows,
7556
- dedupeMemberSpacesById,
7557
- getAllMemberSpaces,
7558
- fetchUserData,
7559
- deleteDbKey,
7560
- toggleCategoryCollapse2 as toggleCategoryCollapse,
7561
- setAllCategoriesCollapsed,
7562
- changeSpace,
7563
- addSpace,
7564
- deleteSpace,
7565
- updateSpace,
7566
- fetchSpace,
7567
- addCategory,
7568
- deleteCategory,
7569
- updateCategoryName,
7570
- reorderCategories,
5041
+ readStoredCollapsedCategories,
5042
+ writeStoredCollapsedCategories,
5043
+ DEFAULT_COLLAPSED_CATEGORIES,
5044
+ getCollapsedCategories,
5045
+ setCollapsedCategories,
5046
+ toggleCategoryCollapse,
5047
+ expandCategoryInCollapsed,
7571
5048
  addContentToSpace,
7572
5049
  moveContentToSpace,
7573
5050
  deleteContentFromSpace,
7574
5051
  deleteMultipleContent,
5052
+ uploadAndAddFileToSpace,
7575
5053
  updateContentTitle,
7576
5054
  updateContentPinned,
7577
- updateContentCategory,
7578
- uploadAndAddFileToSpace,
7579
- fetchUserSpaceMemberships,
7580
- addMember,
7581
- removeMember,
7582
- fetchSpaceSidebarState,
7583
- applySpaceEvent,
7584
- markDialogRead,
7585
- resetSpace,
7586
- setViewMode2 as setViewMode,
7587
- toggleFavoritesCollapse,
7588
- hydrateMemberSpacesFromLocal2 as hydrateMemberSpacesFromLocal,
7589
- appendRecoveredMemberships2 as appendRecoveredMemberships,
7590
- selectCurrentSpaceId,
7591
- selectCurrentSpace,
7592
- selectSpaceById,
7593
- selectViewMode,
7594
- selectDialogStatusFromEntity,
7595
- selectIsDialogUnreadFromEntity,
7596
- spaceSlice_default
5055
+ updateContentCategory
7597
5056
  };