nolo-cli 0.67.0-alpha.1 → 0.68.0-alpha.1

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 (59) hide show
  1. package/{_executeModel-C5K4UL5I.js → _executeModel-XCNYHC6S.js} +13 -13
  2. package/{agentDeleteCommand-7RESZDRC.js → agentDeleteCommand-Z3DTLQEG.js} +5 -5
  3. package/{agentEmailCommands-KES5FG2E.js → agentEmailCommands-DFK2MIXR.js} +14 -14
  4. package/{agentListCommands-VFBLREFU.js → agentListCommands-FSX7RY7U.js} +5 -5
  5. package/{agentMachineCommands-UJ77TKWZ.js → agentMachineCommands-FYPV45TJ.js} +6 -6
  6. package/{agentRecordCommands-MZBPYUGL.js → agentRecordCommands-SXOCVBX7.js} +14 -14
  7. package/{agentRunCommand-R3RWG53B.js → agentRunCommand-XISX4ICI.js} +14 -14
  8. package/{agentRuntimeLocal-BD7R3OJL.js → agentRuntimeLocal-2ENB2B2Z.js} +5 -5
  9. package/{agentSlice-UP66DIC2.js → agentSlice-QLZWET7H.js} +1 -1
  10. package/{appDeleteCommands-X3UF4ZHF.js → appDeleteCommands-XKAUWKUI.js} +5 -5
  11. package/{appDeployCommands-MFHLJIYZ.js → appDeployCommands-SNXZY5IX.js} +5 -5
  12. package/{appDeployStatusCommands-BGXSUHY6.js → appDeployStatusCommands-NXUJ6LXS.js} +5 -5
  13. package/{appGetCommands-KEA6FZTF.js → appGetCommands-DNRYKGOK.js} +5 -5
  14. package/{appListCommands-CZGMZW3L.js → appListCommands-URESGUKU.js} +5 -5
  15. package/{chatQueueReduxAdapter-VVXE2NXW.js → chatQueueReduxAdapter-FNXZNIAT.js} +4 -4
  16. package/{chunk-HQ3ZLBSI.js → chunk-2XENHR3P.js} +96 -0
  17. package/{chunk-TDTSQVDX.js → chunk-3E67YXGD.js} +85 -88
  18. package/{chunk-RCNQCXPM.js → chunk-5JTJG4OG.js} +115 -121
  19. package/{chunk-MN2XJEWL.js → chunk-7NG5APVZ.js} +16 -133
  20. package/{chunk-UZXOOSHF.js → chunk-AUA5DTWI.js} +15 -14
  21. package/{chunk-HPRMNGAM.js → chunk-IX6H4NKR.js} +1 -1
  22. package/{chunk-UBWLW3KY.js → chunk-IY2BLZKO.js} +3 -3
  23. package/{chunk-5DUAG5G7.js → chunk-K4326DRU.js} +202 -11729
  24. package/{chunk-AVJQ4TDL.js → chunk-K5YS7FAN.js} +1 -1
  25. package/{chunk-TTTW4DIT.js → chunk-LNOW66U4.js} +6 -6
  26. package/{chunk-NFTTUZ3L.js → chunk-LTLZPAO7.js} +1 -1
  27. package/{chunk-QPXRNDI3.js → chunk-MIN5X7GI.js} +2 -2
  28. package/{chunk-OHJWIXXW.js → chunk-RLZ6HZSX.js} +3 -3
  29. package/{chunk-BG7ZGBKH.js → chunk-SM4ED2LZ.js} +4 -4
  30. package/{chunk-FPT2E44F.js → chunk-VHADFQCI.js} +2 -2
  31. package/{chunk-UNAVSDC5.js → chunk-XHNOCBUU.js} +4 -2
  32. package/chunk-XNO3T6RB.js +18504 -0
  33. package/chunk-Z6S2JBE4.js +2471 -0
  34. package/{chunk-M3HN7RBV.js → chunk-ZCVO2HLZ.js} +1 -1
  35. package/{contentThunks-BHML6O7K.js → contentThunks-6K4RZXKH.js} +5 -5
  36. package/{createAgentAutomationAction-K5YJO4IA.js → createAgentAutomationAction-6XYIZ3GS.js} +5 -5
  37. package/{createDialogAction-SFMZLPS4.js → createDialogAction-TJWDXAKL.js} +6 -6
  38. package/{createPageAction-UD7BSFQS.js → createPageAction-EZ2LPB6K.js} +5 -5
  39. package/{dialogCommands-2ABSL4ND.js → dialogCommands-ULXMRIAM.js} +5 -5
  40. package/{dialogSlice-DEC5GV6X.js → dialogSlice-5DRM6AQQ.js} +4 -4
  41. package/{docCreateCommands-2QZCW4HZ.js → docCreateCommands-PPHO6KUM.js} +5 -5
  42. package/{docDeleteCommands-WKZKQAKM.js → docDeleteCommands-U2GVGQPR.js} +5 -5
  43. package/{docReadCommands-WMKJCR4Q.js → docReadCommands-CYY3DJXY.js} +5 -5
  44. package/{docStore-IBPCRTTX.js → docStore-OJXM46BB.js} +1 -1
  45. package/{docUpdateCommands-KPLM63NK.js → docUpdateCommands-B5UVFLJU.js} +5 -5
  46. package/{handleSendMessageAction-C7CZNGMB.js → handleSendMessageAction-EWY3J2AV.js} +4 -4
  47. package/index.js +41 -41
  48. package/{machineCommands-6BG3AHT5.js → machineCommands-B76BYAJF.js} +14 -14
  49. package/{machineWsRunDispatch-G2KJ6NQF.js → machineWsRunDispatch-LN6274EL.js} +14 -14
  50. package/package.json +1 -1
  51. package/{readlineWorkspace-5LZ3EDIQ.js → readlineWorkspace-UFHEJIDS.js} +77 -18
  52. package/{runAgentClientLoop-CICP3O2T.js → runAgentClientLoop-MAER6Y5K.js} +11 -11
  53. package/{spaceCommands-NQOIERT6.js → spaceCommands-2YT7C56D.js} +5 -5
  54. package/{streamAgentChatTurn-QUD4FY5I.js → streamAgentChatTurn-AKUDQL5W.js} +14 -14
  55. package/{tools-MAP6O2YZ.js → tools-NM36O7ZG.js} +8 -8
  56. package/{tuiSummaryLlmCaller-VL5RDGLT.js → tuiSummaryLlmCaller-ZGATEM35.js} +2 -2
  57. package/{updateDialogTitleAction-L6CCRVUK.js → updateDialogTitleAction-RHH353JB.js} +5 -5
  58. package/chunk-CLZYOOI3.js +0 -4463
  59. package/chunk-IF6UQNAK.js +0 -5062
@@ -0,0 +1,2471 @@
1
+ import {
2
+ getCurrentSpaceId,
3
+ getCurrentSpaceIdRaw,
4
+ updateCurrentSpaceIfMatch
5
+ } from "./chunk-ZJ7UHBJS.js";
6
+ import {
7
+ deleteDialog,
8
+ i18nBaseConfig,
9
+ initReactI18next,
10
+ instance,
11
+ toast
12
+ } from "./chunk-XNO3T6RB.js";
13
+ import {
14
+ require_date_fns
15
+ } from "./chunk-M76ECQRD.js";
16
+ import {
17
+ require_react
18
+ } from "./chunk-YDH3FDFQ.js";
19
+ import {
20
+ isSystemAdmin
21
+ } from "./chunk-OPNHMILE.js";
22
+ import {
23
+ asRecordOrEmpty
24
+ } from "./chunk-KX6YBIHG.js";
25
+ import {
26
+ UNCATEGORIZED_ID,
27
+ addContentAction,
28
+ checkSpaceMembership,
29
+ localSpaceAuthorityPatchStamp
30
+ } from "./chunk-IM5EETJX.js";
31
+ import {
32
+ createSpaceKey,
33
+ normalizeSpaceId
34
+ } from "./chunk-UAD2WT54.js";
35
+ import {
36
+ patch,
37
+ read,
38
+ readAndWait,
39
+ remove,
40
+ resolveFileCategory,
41
+ uploadFileAction,
42
+ upsertSSREntity,
43
+ write
44
+ } from "./chunk-4K6DB3GJ.js";
45
+ import {
46
+ SEPARATOR,
47
+ createKey,
48
+ fileKey,
49
+ isAgentKey,
50
+ isPageKey,
51
+ metaKey,
52
+ rowKey,
53
+ splitKey,
54
+ ulid
55
+ } from "./chunk-NHRQCXIQ.js";
56
+ import {
57
+ asOptionalFiniteNumber
58
+ } from "./chunk-WWC7I6TA.js";
59
+ import {
60
+ asTrimmedNonEmptyStringArray
61
+ } from "./chunk-I42VC5KR.js";
62
+ import {
63
+ extractUserId
64
+ } from "./chunk-BJIRLHJR.js";
65
+ import {
66
+ DEVICE_LOCAL_OWNER_ID,
67
+ createAsyncThunk,
68
+ getRuntimeServerContext,
69
+ isDeviceLocalSpaceBody,
70
+ resolveReplicationServers,
71
+ scheduleDeleteReplication,
72
+ scheduleWriteReplication
73
+ } from "./chunk-3RAG2NAD.js";
74
+ import {
75
+ createClientLogger
76
+ } from "./chunk-QOKAKDPE.js";
77
+ import {
78
+ selectIdentityUserId
79
+ } from "./chunk-SEJ5OS6F.js";
80
+ import {
81
+ buildTombstoneRecord
82
+ } from "./chunk-GBRG75BQ.js";
83
+ import {
84
+ asTrimmedString
85
+ } from "./chunk-3EUW3WEO.js";
86
+ import {
87
+ asOptionalPositiveFiniteNumber
88
+ } from "./chunk-U6VC4MU4.js";
89
+ import {
90
+ isRecord
91
+ } from "./chunk-KUG52IAP.js";
92
+ import {
93
+ asOptionalTrimmedString
94
+ } from "./chunk-G3SUCT4W.js";
95
+ import {
96
+ __toESM
97
+ } from "./chunk-4VNS5WPM.js";
98
+
99
+ // packages/render/table/tableStore.ts
100
+ var import_react = __toESM(require_react(), 1);
101
+ var import_date_fns2 = __toESM(require_date_fns(), 1);
102
+ import { ulid as ulid3 } from "ulid";
103
+
104
+ // packages/render/table/fetchAndCacheTableRows.ts
105
+ var getRowTimestamp = (row) => {
106
+ if (!row || typeof row !== "object") return 0;
107
+ return asOptionalPositiveFiniteNumber(Date.parse(row.updatedAt ?? "")) ?? asOptionalPositiveFiniteNumber(Date.parse(row.createdAt ?? "")) ?? 0;
108
+ };
109
+ var shouldReplaceMergedRow = (nextRow, currentRow) => {
110
+ const nextTs = getRowTimestamp(nextRow);
111
+ const currentTs = getRowTimestamp(currentRow);
112
+ if (nextTs !== currentTs) return nextTs > currentTs;
113
+ return Boolean(nextRow?.deletedAt) && !currentRow?.deletedAt;
114
+ };
115
+ var mergeTableRows = (...rowLists) => {
116
+ const merged = /* @__PURE__ */ new Map();
117
+ for (const rowList of rowLists) {
118
+ for (const row of rowList) {
119
+ const dbKey = row?.dbKey;
120
+ if (!dbKey) continue;
121
+ const existing = merged.get(dbKey);
122
+ if (!existing || shouldReplaceMergedRow(row, existing)) {
123
+ merged.set(dbKey, row);
124
+ }
125
+ }
126
+ }
127
+ return Array.from(merged.values());
128
+ };
129
+ var TABLE_SYNC_ENVELOPE = "table-sync-v1";
130
+ var getLatestTableMeta = (snapshots) => {
131
+ let latestMeta = null;
132
+ for (const snapshot of snapshots) {
133
+ const tableMeta = snapshot.tableMeta;
134
+ if (!tableMeta || typeof tableMeta !== "object") continue;
135
+ if (!latestMeta || shouldReplaceMergedRow(tableMeta, latestMeta)) {
136
+ latestMeta = tableMeta;
137
+ }
138
+ }
139
+ return latestMeta;
140
+ };
141
+ var loadLocalTableRows = async (db, tenantId, tableId) => {
142
+ if (!db || typeof db.iterator !== "function") {
143
+ return [];
144
+ }
145
+ const rows = [];
146
+ const { gte, lte } = rowKey.range(tenantId, tableId);
147
+ try {
148
+ for await (const [, value] of db.iterator({ gte, lte })) {
149
+ if (value?.type === "table_row" /* TABLE_ROW */) {
150
+ rows.push(value);
151
+ }
152
+ }
153
+ } catch {
154
+ return [];
155
+ }
156
+ return rows;
157
+ };
158
+ var fetchTableRowsFromServer = async (server, tenantId, tableId, headers) => {
159
+ const res = await fetch(`${server}/rpc/listTableRows`, {
160
+ method: "POST",
161
+ headers,
162
+ body: JSON.stringify({
163
+ tenantId,
164
+ tableId,
165
+ includeDeleted: true,
166
+ envelope: TABLE_SYNC_ENVELOPE
167
+ })
168
+ });
169
+ if (!res.ok) {
170
+ let msg = `\u52A0\u8F7D\u8868 ${tableId} \u884C\u5931\u8D25\uFF08${res.status}\uFF09`;
171
+ try {
172
+ const err2 = await res.json();
173
+ if (err2 && typeof err2.message === "string") {
174
+ msg = err2.message;
175
+ }
176
+ } catch {
177
+ }
178
+ throw new Error(msg);
179
+ }
180
+ const data = await res.json();
181
+ if (Array.isArray(data)) {
182
+ return {
183
+ rows: data,
184
+ deletedRows: [],
185
+ tableMeta: null,
186
+ complete: false
187
+ };
188
+ }
189
+ if (!data || typeof data !== "object" || !Array.isArray(data.rows)) {
190
+ throw new Error("\u670D\u52A1\u5668\u8FD4\u56DE\u683C\u5F0F\u9519\u8BEF\uFF1A\u9884\u671F\u4E3A\u6570\u7EC4");
191
+ }
192
+ return {
193
+ rows: data.rows,
194
+ deletedRows: Array.isArray(data.deletedRows) ? data.deletedRows : [],
195
+ tableMeta: data.tableMeta ?? null,
196
+ complete: data.complete === true
197
+ };
198
+ };
199
+ var cacheMergedTableRows = async (db, mergedRows) => {
200
+ if (!db) return;
201
+ await Promise.all(
202
+ mergedRows.map(async (mergedRow) => {
203
+ if (!mergedRow?.dbKey) return;
204
+ try {
205
+ const localRow = await db.get(mergedRow.dbKey).catch(() => null);
206
+ if (!localRow) {
207
+ await db.put(mergedRow.dbKey, mergedRow);
208
+ return;
209
+ }
210
+ const serverTs = new Date(
211
+ mergedRow.updatedAt ?? mergedRow.createdAt ?? 0
212
+ ).getTime();
213
+ const localTs = new Date(
214
+ localRow.updatedAt ?? localRow.createdAt ?? 0
215
+ ).getTime();
216
+ const shouldOverwrite = serverTs > localTs || serverTs === localTs && Boolean(mergedRow.deletedAt) && !Boolean(localRow.deletedAt);
217
+ if (shouldOverwrite) {
218
+ await db.put(mergedRow.dbKey, mergedRow);
219
+ }
220
+ } catch {
221
+ }
222
+ })
223
+ );
224
+ };
225
+ var clearStaleLocalRows = async (db, localRows, authoritativeRows) => {
226
+ if (!db || typeof db.del !== "function") return;
227
+ const authoritativeKeys = new Set(
228
+ authoritativeRows.map((row) => row?.dbKey).filter((dbKey) => typeof dbKey === "string" && dbKey.length > 0)
229
+ );
230
+ await Promise.all(
231
+ localRows.map(async (row) => {
232
+ const dbKey = row?.dbKey;
233
+ if (typeof dbKey !== "string" || authoritativeKeys.has(dbKey)) return;
234
+ try {
235
+ await db.del(dbKey);
236
+ } catch {
237
+ }
238
+ })
239
+ );
240
+ };
241
+ var keepRemoteRowForPartialMerge = (row, localRowsByKey) => {
242
+ const dbKey = row?.dbKey;
243
+ if (typeof dbKey !== "string" || !dbKey) return false;
244
+ const localRow = localRowsByKey.get(dbKey);
245
+ if (!localRow) return true;
246
+ const remoteDeleted = Boolean(row?.deletedAt);
247
+ const localDeleted = Boolean(localRow?.deletedAt);
248
+ return remoteDeleted === localDeleted;
249
+ };
250
+ var fetchAndCacheTableRows = async ({
251
+ db,
252
+ tenantId,
253
+ tableId,
254
+ token,
255
+ remoteServers = []
256
+ }) => {
257
+ const headers = {
258
+ "Content-Type": "application/json"
259
+ };
260
+ if (token) {
261
+ headers.Authorization = `Bearer ${token}`;
262
+ }
263
+ const localRows = await loadLocalTableRows(db, tenantId, tableId);
264
+ const remoteResults = await Promise.allSettled(
265
+ remoteServers.map(
266
+ (server) => fetchTableRowsFromServer(server, tenantId, tableId, headers)
267
+ )
268
+ );
269
+ const fulfilledRemoteSnapshots = remoteResults.filter(
270
+ (result) => result.status === "fulfilled"
271
+ ).map((result) => result.value);
272
+ if (fulfilledRemoteSnapshots.length === 0 && localRows.length === 0) {
273
+ const firstFailure = remoteResults.find(
274
+ (result) => result.status === "rejected"
275
+ );
276
+ throw new Error(firstFailure?.reason?.message || "\u52A0\u8F7D\u8868\u884C\u5931\u8D25");
277
+ }
278
+ const allRemoteSnapshotsComplete = remoteServers.length > 0 && remoteResults.length === remoteServers.length && fulfilledRemoteSnapshots.length === remoteServers.length && fulfilledRemoteSnapshots.every((snapshot) => snapshot.complete);
279
+ const localRowsByKey = new Map(
280
+ localRows.filter((row) => typeof row?.dbKey === "string" && row.dbKey.length > 0).map((row) => [row.dbKey, row])
281
+ );
282
+ const remoteRowLists = fulfilledRemoteSnapshots.map((snapshot) => {
283
+ const snapshotRows = [...snapshot.rows, ...snapshot.deletedRows];
284
+ return allRemoteSnapshotsComplete ? snapshotRows : snapshotRows.filter((row) => keepRemoteRowForPartialMerge(row, localRowsByKey));
285
+ });
286
+ const authoritativeRemoteRows = remoteRowLists.flat();
287
+ const tableDeleted = allRemoteSnapshotsComplete && Boolean(getLatestTableMeta(fulfilledRemoteSnapshots)?.deletedAt);
288
+ if (allRemoteSnapshotsComplete) {
289
+ await clearStaleLocalRows(db, localRows, authoritativeRemoteRows);
290
+ }
291
+ const localRowsForMerge = allRemoteSnapshotsComplete ? localRows.filter(
292
+ (row) => authoritativeRemoteRows.some((remoteRow) => remoteRow?.dbKey === row?.dbKey)
293
+ ) : localRows;
294
+ const mergedRows = mergeTableRows(localRowsForMerge, ...remoteRowLists);
295
+ await cacheMergedTableRows(db, mergedRows);
296
+ return tableDeleted ? [] : mergedRows.filter((row) => !row?.deletedAt);
297
+ };
298
+
299
+ // packages/render/table/tableColumnCore.ts
300
+ var ok = (value) => ({ ok: true, value });
301
+ var err = (error) => ({ ok: false, error });
302
+ var hasOwn = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key);
303
+ var buildMeta = (meta, columns, updatedAt) => ({
304
+ meta: { ...meta, columns, updatedAt },
305
+ metaChanges: { columns, updatedAt },
306
+ noop: false
307
+ });
308
+ var reorderList = (list, from, to) => {
309
+ const next = [...list];
310
+ const [moved] = next.splice(from, 1);
311
+ next.splice(to, 0, moved);
312
+ return next;
313
+ };
314
+ function addColumnToMeta(meta, input, deps) {
315
+ const { columnName } = input;
316
+ if (!columnName.trim()) {
317
+ return err("\u5B57\u6BB5\u540D\u4E0D\u80FD\u4E3A\u7A7A");
318
+ }
319
+ if (meta.columns.some((c) => c.name === columnName)) {
320
+ return err(`\u5B57\u6BB5 ${columnName} \u5DF2\u5B58\u5728`);
321
+ }
322
+ const newColumn = {
323
+ id: deps.id,
324
+ name: columnName,
325
+ label: columnName
326
+ };
327
+ return ok(buildMeta(meta, [...meta.columns, newColumn], deps.nowIso));
328
+ }
329
+ function deleteColumnFromMeta(meta, rows, input, deps) {
330
+ const { columnName } = input;
331
+ const { nowIso } = deps;
332
+ if (!meta.columns.some((c) => c.name === columnName)) {
333
+ return err(`\u5B57\u6BB5 ${columnName} \u4E0D\u5B58\u5728`);
334
+ }
335
+ const newColumns = meta.columns.filter((c) => c.name !== columnName);
336
+ const rowPatches = rows.filter((row) => hasOwn(row, columnName)).map((row) => ({
337
+ dbKey: row.dbKey,
338
+ changes: { [columnName]: null, updatedAt: nowIso }
339
+ }));
340
+ const newRows = rows.map((row) => {
341
+ if (!hasOwn(row, columnName)) {
342
+ return row;
343
+ }
344
+ const { [columnName]: _removed, ...rest } = row;
345
+ return { ...rest, updatedAt: nowIso };
346
+ });
347
+ return ok({
348
+ ...buildMeta(meta, newColumns, nowIso),
349
+ rows: newRows,
350
+ rowPatches
351
+ });
352
+ }
353
+ function reorderColumnInMeta(meta, input, deps) {
354
+ const { fromIndex, toIndex } = input;
355
+ const columnCount = meta.columns.length;
356
+ if (fromIndex < 0 || fromIndex >= columnCount || toIndex < 0 || toIndex >= columnCount) {
357
+ return err("\u5217\u7D22\u5F15\u8D85\u51FA\u8303\u56F4");
358
+ }
359
+ if (fromIndex === toIndex) {
360
+ return ok({
361
+ meta,
362
+ metaChanges: { columns: meta.columns, updatedAt: meta.updatedAt },
363
+ noop: true
364
+ });
365
+ }
366
+ return ok(
367
+ buildMeta(meta, reorderList(meta.columns, fromIndex, toIndex), deps.nowIso)
368
+ );
369
+ }
370
+ function renameColumnInMeta(meta, rows, input, deps) {
371
+ const { oldName } = input;
372
+ const { nowIso } = deps;
373
+ const newName = input.newName.trim();
374
+ if (!newName) {
375
+ return err("\u65B0\u7684\u5B57\u6BB5\u540D\u4E0D\u80FD\u4E3A\u7A7A");
376
+ }
377
+ if (!meta.columns.some((c) => c.name === oldName)) {
378
+ return err(`\u5B57\u6BB5 ${oldName} \u4E0D\u5B58\u5728`);
379
+ }
380
+ if (meta.columns.some((c) => c.name === newName)) {
381
+ return err(`\u5B57\u6BB5 ${newName} \u5DF2\u5B58\u5728`);
382
+ }
383
+ const newColumns = meta.columns.map(
384
+ (c) => c.name === oldName ? { ...c, name: newName } : c
385
+ );
386
+ const rowPatches = rows.filter((row) => hasOwn(row, oldName)).map((row) => ({
387
+ dbKey: row.dbKey,
388
+ changes: {
389
+ [newName]: row[oldName],
390
+ [oldName]: null,
391
+ updatedAt: nowIso
392
+ }
393
+ }));
394
+ const newRows = rows.map((row) => {
395
+ if (!hasOwn(row, oldName)) {
396
+ return row;
397
+ }
398
+ const { [oldName]: oldValue, ...rest } = row;
399
+ return { ...rest, [newName]: oldValue, updatedAt: nowIso };
400
+ });
401
+ return ok({
402
+ ...buildMeta(meta, newColumns, nowIso),
403
+ rows: newRows,
404
+ rowPatches
405
+ });
406
+ }
407
+ function renameColumnLabelInMeta(meta, input, deps) {
408
+ const { columnId } = input;
409
+ const label = input.label.trim();
410
+ if (!label) {
411
+ return err("\u5B57\u6BB5\u663E\u793A\u540D\u4E0D\u80FD\u4E3A\u7A7A");
412
+ }
413
+ if (!meta.columns.some((c) => c.id === columnId)) {
414
+ return err("\u8981\u91CD\u547D\u540D\u7684\u5B57\u6BB5\u4E0D\u5B58\u5728");
415
+ }
416
+ const newColumns = meta.columns.map(
417
+ (c) => c.id === columnId ? { ...c, label } : c
418
+ );
419
+ return ok(buildMeta(meta, newColumns, deps.nowIso));
420
+ }
421
+ function updateColumnWidthInMeta(meta, input, deps) {
422
+ const { columnId, width } = input;
423
+ if (!meta.columns.some((c) => c.id === columnId)) {
424
+ return err("\u8981\u8C03\u6574\u5BBD\u5EA6\u7684\u5B57\u6BB5\u4E0D\u5B58\u5728");
425
+ }
426
+ const normalizedWidth = typeof width === "number" && width > 0 ? Math.round(width) : void 0;
427
+ const newColumns = meta.columns.map(
428
+ (c) => c.id === columnId ? { ...c, width: normalizedWidth } : c
429
+ );
430
+ return ok(buildMeta(meta, newColumns, deps.nowIso));
431
+ }
432
+ function addColumnOptionInMeta(meta, input, deps) {
433
+ const { columnId } = input;
434
+ const option = input.option.trim();
435
+ if (!option) {
436
+ return err("\u9009\u9879\u540D\u4E0D\u80FD\u4E3A\u7A7A");
437
+ }
438
+ const column = meta.columns.find((c) => c.id === columnId);
439
+ if (!column) {
440
+ return err("\u8981\u65B0\u589E\u9009\u9879\u7684\u5B57\u6BB5\u4E0D\u5B58\u5728");
441
+ }
442
+ if ((column.options ?? []).some((o) => o.trim() === option)) {
443
+ return ok({
444
+ meta,
445
+ metaChanges: { columns: meta.columns, updatedAt: meta.updatedAt },
446
+ noop: true
447
+ });
448
+ }
449
+ const newColumns = meta.columns.map(
450
+ (c) => c.id === columnId ? { ...c, options: [...c.options ?? [], option] } : c
451
+ );
452
+ return ok(buildMeta(meta, newColumns, deps.nowIso));
453
+ }
454
+
455
+ // packages/render/table/createTableAction.ts
456
+ var import_date_fns = __toESM(require_date_fns(), 1);
457
+ import { ulid as ulid2 } from "ulid";
458
+
459
+ // packages/app/i18n/client.ts
460
+ instance.use(initReactI18next).init({
461
+ ...i18nBaseConfig,
462
+ lng: "zh-CN" /* ZH_CN */,
463
+ fallbackLng: "zh-CN" /* ZH_CN */,
464
+ compatibilityJSON: "v3"
465
+ });
466
+ var client_default = instance;
467
+
468
+ // packages/render/table/createTableAction.ts
469
+ var DEFAULT_COLUMNS = [
470
+ {
471
+ name: "title",
472
+ label: "\u6807\u9898",
473
+ type: "text",
474
+ description: "\u8FD9\u4E00\u884C\u8BB0\u5F55\u7684\u4E3B\u9898\u6216\u540D\u79F0\u3002",
475
+ isPrimary: true,
476
+ required: true
477
+ },
478
+ {
479
+ name: "note",
480
+ label: "\u5907\u6CE8",
481
+ type: "text",
482
+ description: "\u5BF9\u8BE5\u6761\u76EE\u7684\u8865\u5145\u8BF4\u660E\u3002",
483
+ required: false
484
+ }
485
+ ];
486
+ var normalizeColumns = (inputColumns) => {
487
+ const base = Array.isArray(inputColumns) ? inputColumns : [];
488
+ const normalized = base.map((c) => {
489
+ if (!c || typeof c.name !== "string") return null;
490
+ const name = c.name.trim();
491
+ if (!name) return null;
492
+ const col = {
493
+ id: asOptionalTrimmedString(c.id) ?? ulid2(),
494
+ name
495
+ };
496
+ const label = asOptionalTrimmedString(c.label);
497
+ if (label) col.label = label;
498
+ if (typeof c.type === "string") {
499
+ col.type = c.type;
500
+ }
501
+ const description = asOptionalTrimmedString(c.description);
502
+ if (description) col.description = description;
503
+ if (typeof c.isPrimary === "boolean") {
504
+ col.isPrimary = c.isPrimary;
505
+ }
506
+ if (typeof c.required === "boolean") {
507
+ col.required = c.required;
508
+ }
509
+ if (Array.isArray(c.options)) {
510
+ const opts = asTrimmedNonEmptyStringArray(c.options);
511
+ if (opts.length) {
512
+ col.options = opts;
513
+ }
514
+ }
515
+ return col;
516
+ }).filter(Boolean);
517
+ if (normalized.length > 0) {
518
+ if (!normalized.some((c) => c.isPrimary)) {
519
+ normalized[0].isPrimary = true;
520
+ }
521
+ return normalized;
522
+ }
523
+ return DEFAULT_COLUMNS.map((c) => ({
524
+ ...c,
525
+ id: ulid2()
526
+ }));
527
+ };
528
+ var normalizeStringArray = (value) => {
529
+ if (!Array.isArray(value)) return void 0;
530
+ const items = [...new Set(asTrimmedNonEmptyStringArray(value))];
531
+ return items.length ? items : void 0;
532
+ };
533
+ var normalizePublicIntake = (input) => {
534
+ if (!isRecord(input)) return void 0;
535
+ const allowedFields = normalizeStringArray(input.allowedFields) ?? [];
536
+ if (input.enabled !== true) {
537
+ return { enabled: false, allowedFields };
538
+ }
539
+ if (allowedFields.length === 0) {
540
+ throw new Error("publicIntake.allowedFields \u81F3\u5C11\u9700\u8981\u4E00\u4E2A\u5B57\u6BB5\u3002");
541
+ }
542
+ const slug = asOptionalTrimmedString(input.slug);
543
+ const honeypotField = asOptionalTrimmedString(input.honeypotField);
544
+ return {
545
+ enabled: true,
546
+ ...slug ? { slug } : {},
547
+ ...normalizeStringArray(input.appIds) ? { appIds: normalizeStringArray(input.appIds) } : {},
548
+ allowedFields,
549
+ ...normalizeStringArray(input.requiredFields) ? { requiredFields: normalizeStringArray(input.requiredFields) } : {},
550
+ ...honeypotField ? { honeypotField } : {}
551
+ };
552
+ };
553
+ var createTableAction = async ({
554
+ spaceId: customSpaceId,
555
+ title: customTitle,
556
+ purpose: customPurpose,
557
+ description: customDescription,
558
+ tags: customTags,
559
+ publicIntake,
560
+ categoryId,
561
+ columns,
562
+ withDefaultRows = true
563
+ } = {}, { dispatch, getState }) => {
564
+ const state3 = getState();
565
+ const userId = selectIdentityUserId(state3);
566
+ if (!userId) throw new Error("User ID not found.");
567
+ const spaceId = customSpaceId ?? getCurrentSpaceId();
568
+ const tableId = ulid2();
569
+ const now = /* @__PURE__ */ new Date();
570
+ const nowIso = (0, import_date_fns.formatISO)(now);
571
+ const dbKey = metaKey(userId, tableId);
572
+ const defaultTitle = client_default.t("space:newTable", {
573
+ defaultValue: "\u65B0\u5EFA\u8868\u683C"
574
+ });
575
+ const title = asOptionalTrimmedString(customTitle) ?? defaultTitle;
576
+ const purpose = asOptionalTrimmedString(customPurpose);
577
+ const description = asOptionalTrimmedString(customDescription);
578
+ const tags = Array.isArray(customTags) && customTags.length ? asTrimmedNonEmptyStringArray(customTags) : void 0;
579
+ const finalPublicIntake = normalizePublicIntake(publicIntake);
580
+ const finalColumns = normalizeColumns(columns);
581
+ const tableMeta = {
582
+ dbKey,
583
+ tenantId: userId,
584
+ tableId,
585
+ spaceId: spaceId ?? null,
586
+ displayName: title,
587
+ purpose,
588
+ description,
589
+ tags,
590
+ schemaVersion: 1,
591
+ columns: finalColumns,
592
+ views: [],
593
+ // 后续可以在 UI 中新增视图
594
+ triggers: [],
595
+ // 后续可以在 UI/配置中新增触发器
596
+ aiConfig: void 0,
597
+ ...finalPublicIntake ? { publicIntake: finalPublicIntake } : {},
598
+ createdAt: nowIso,
599
+ updatedAt: nowIso,
600
+ type: "table" /* TABLE */
601
+ };
602
+ await dispatch(
603
+ write({
604
+ data: tableMeta,
605
+ customKey: dbKey
606
+ })
607
+ ).unwrap();
608
+ if (withDefaultRows) {
609
+ const defaultRows = [
610
+ {
611
+ title: "\u793A\u4F8B\u4E00",
612
+ note: "\u4F60\u53EF\u4EE5\u5728\u8FD9\u91CC\u8BB0\u5F55\u4EFB\u4F55\u5185\u5BB9\uFF0C\u4F8B\u5982\u4EFB\u52A1\u3001\u60F3\u6CD5\u6216\u914D\u7F6E\u9879\u3002"
613
+ },
614
+ {
615
+ title: "\u793A\u4F8B\u4E8C",
616
+ note: "\u53CC\u51FB\u5355\u5143\u683C\u5F00\u59CB\u7F16\u8F91\uFF0C\u53F3\u4E0A\u89D2\u53EF\u4EE5\u6DFB\u52A0\u5B57\u6BB5\u548C\u884C\u3002"
617
+ }
618
+ ];
619
+ await Promise.all(
620
+ defaultRows.map(async (values) => {
621
+ const { dbKey: rowKeyStr, rowId } = rowKey.create(userId, tableId);
622
+ const row = {
623
+ dbKey: rowKeyStr,
624
+ tenantId: userId,
625
+ tableId,
626
+ rowId,
627
+ createdAt: nowIso,
628
+ updatedAt: nowIso,
629
+ type: "table_row" /* TABLE_ROW */,
630
+ ...values
631
+ };
632
+ await dispatch(
633
+ write({
634
+ data: row,
635
+ customKey: rowKeyStr
636
+ })
637
+ ).unwrap();
638
+ })
639
+ );
640
+ }
641
+ if (spaceId) {
642
+ await dispatch(
643
+ addContentToSpace({
644
+ spaceId,
645
+ contentKey: dbKey,
646
+ type: "table" /* TABLE */,
647
+ title,
648
+ categoryId
649
+ })
650
+ ).unwrap();
651
+ }
652
+ if (typeof window !== "undefined") {
653
+ window.dispatchEvent(new Event("nolo-user-data-updated"));
654
+ }
655
+ return dbKey;
656
+ };
657
+
658
+ // packages/render/table/deleteTableAction.ts
659
+ var parseMetaKey = (dbKey) => {
660
+ const parts = dbKey.split(SEPARATOR);
661
+ if (parts[0] !== "meta" || parts.length < 3) {
662
+ throw new Error(`\u975E\u6CD5\u8868 key\uFF1A${dbKey}`);
663
+ }
664
+ const tenantId = parts[1];
665
+ const tableId = parts.slice(2).join(SEPARATOR);
666
+ return { tenantId, tableId };
667
+ };
668
+ var collectEntriesByPrefix = async (db, prefix) => {
669
+ const entries = [];
670
+ for await (const [key, value] of db.iterator({
671
+ gte: prefix,
672
+ lte: prefix + "\uFFFF"
673
+ })) {
674
+ entries.push([key, value]);
675
+ }
676
+ return entries;
677
+ };
678
+ var belongsToTable = (value, tenantId, tableId) => Boolean(
679
+ value && typeof value === "object" && value.tenantId === tenantId && value.tableId === tableId
680
+ );
681
+ var indexValueReferencesRows = (value, rowDbKeys, rowIds) => {
682
+ if (typeof value === "string") {
683
+ return rowDbKeys.has(value) || rowIds.has(value);
684
+ }
685
+ if (!value || typeof value !== "object") return false;
686
+ const candidate = value;
687
+ return typeof candidate.dbKey === "string" && rowDbKeys.has(candidate.dbKey) || typeof candidate.rowDbKey === "string" && rowDbKeys.has(candidate.rowDbKey) || typeof candidate.rowId === "string" && rowIds.has(candidate.rowId);
688
+ };
689
+ var deleteTableAction = async ({ dbKey }, {
690
+ dispatch,
691
+ getState,
692
+ extra
693
+ }) => {
694
+ const { db } = extra;
695
+ const state3 = getState();
696
+ const { currentServer, syncServers } = getRuntimeServerContext(state3);
697
+ const { tenantId, tableId } = parseMetaKey(dbKey);
698
+ const nowIso = (/* @__PURE__ */ new Date()).toISOString();
699
+ const rowPrefix = createKey("row", tenantId, tableId, "");
700
+ const rowEntries = (await collectEntriesByPrefix(db, rowPrefix)).filter(
701
+ ([, value]) => belongsToTable(value, tenantId, tableId)
702
+ );
703
+ const rowDbKeys = new Set(rowEntries.map(([key]) => key));
704
+ const rowIds = new Set(
705
+ rowEntries.map(([, value]) => value.rowId).filter((rowId) => typeof rowId === "string")
706
+ );
707
+ const idxPrefix = createKey("idx", tenantId, tableId, "");
708
+ const idxEntries = await collectEntriesByPrefix(db, idxPrefix);
709
+ const idxKeys = idxEntries.filter(
710
+ ([, value]) => belongsToTable(value, tenantId, tableId) || indexValueReferencesRows(value, rowDbKeys, rowIds)
711
+ ).map(([key]) => key);
712
+ const viewPrefix = createKey("view", tenantId, tableId, "");
713
+ const viewEntries = await collectEntriesByPrefix(db, viewPrefix);
714
+ const viewKeys = viewEntries.filter(([, value]) => belongsToTable(value, tenantId, tableId)).map(([key]) => key);
715
+ const metaRecord = typeof db.get === "function" ? await db.get(dbKey).catch(() => null) : null;
716
+ const keysToDelete = Array.from(
717
+ /* @__PURE__ */ new Set([
718
+ ...idxKeys,
719
+ ...viewKeys
720
+ ])
721
+ );
722
+ const putOps = [
723
+ ...metaRecord && typeof metaRecord === "object" ? [
724
+ {
725
+ type: "put",
726
+ key: dbKey,
727
+ value: buildTombstoneRecord(metaRecord, nowIso)
728
+ }
729
+ ] : [],
730
+ ...rowEntries.map(([key, value]) => ({
731
+ type: "put",
732
+ key,
733
+ value: buildTombstoneRecord(value, nowIso)
734
+ }))
735
+ ];
736
+ if (keysToDelete.length > 0 || putOps.length > 0) {
737
+ const ops = [
738
+ ...putOps,
739
+ ...keysToDelete.map((key) => ({
740
+ type: "del",
741
+ key
742
+ }))
743
+ ];
744
+ await db.batch(ops);
745
+ }
746
+ scheduleDeleteReplication({
747
+ currentServer,
748
+ syncServers,
749
+ dbKey,
750
+ deleteOptions: { type: "table" },
751
+ state: state3
752
+ });
753
+ return dbKey;
754
+ };
755
+
756
+ // packages/render/table/tableStore.ts
757
+ async function safeDispatch(dispatch, action) {
758
+ if (!dispatch) return void 0;
759
+ const res = await dispatch(action);
760
+ if (res && typeof res.unwrap === "function") {
761
+ return await res.unwrap();
762
+ }
763
+ return res?.payload ?? res;
764
+ }
765
+ var createInitialState = () => ({
766
+ currentTable: null,
767
+ isLoading: false,
768
+ isInitialized: false,
769
+ error: null,
770
+ rows: [],
771
+ focusContext: null
772
+ });
773
+ var listeners = /* @__PURE__ */ new Set();
774
+ var version = 0;
775
+ var state = createInitialState();
776
+ var notify = () => {
777
+ for (const listener of listeners) {
778
+ try {
779
+ listener();
780
+ } catch {
781
+ }
782
+ }
783
+ };
784
+ var bump = () => {
785
+ version += 1;
786
+ notify();
787
+ };
788
+ var setState = (updater) => {
789
+ state = typeof updater === "function" ? updater(state) : updater;
790
+ bump();
791
+ };
792
+ function getTableState() {
793
+ return state;
794
+ }
795
+ function createTableCommand(name, fn) {
796
+ const command = (args) => {
797
+ return async (dispatch, getState, extra) => {
798
+ try {
799
+ const payload = await fn(args, { dispatch, getState, extra });
800
+ return {
801
+ type: `${name}/fulfilled`,
802
+ payload,
803
+ meta: { arg: args },
804
+ unwrap: async () => payload
805
+ };
806
+ } catch (err2) {
807
+ const message = err2?.message || String(err2);
808
+ return {
809
+ type: `${name}/rejected`,
810
+ payload: message,
811
+ error: { message },
812
+ unwrap: async () => {
813
+ throw err2 instanceof Error ? err2 : new Error(message);
814
+ }
815
+ };
816
+ }
817
+ };
818
+ };
819
+ command.fulfilled = {
820
+ type: `${name}/fulfilled`,
821
+ match: (action) => action?.type === `${name}/fulfilled`
822
+ };
823
+ command.rejected = {
824
+ type: `${name}/rejected`,
825
+ match: (action) => action?.type === `${name}/rejected`
826
+ };
827
+ command.pending = {
828
+ type: `${name}/pending`,
829
+ match: (action) => action?.type === `${name}/pending`
830
+ };
831
+ command.run = (args, context = {}) => fn(args, context);
832
+ return command;
833
+ }
834
+ var initTable = createTableCommand(
835
+ "table/initTable",
836
+ async (args, { dispatch } = {}) => {
837
+ const { tenantId, tableId } = args;
838
+ const dbKey = metaKey(tenantId, tableId);
839
+ setState((s) => ({
840
+ ...s,
841
+ isLoading: true,
842
+ error: null,
843
+ isInitialized: false,
844
+ currentTable: null,
845
+ rows: []
846
+ }));
847
+ try {
848
+ if (!dispatch) {
849
+ throw new Error("dispatch is required to initialize table");
850
+ }
851
+ const readAction = await dispatch(readAndWait(dbKey));
852
+ const isMatch = typeof readAndWait?.fulfilled?.match === "function" && readAndWait.fulfilled.match(readAction);
853
+ const meta = isMatch && readAction.payload ? readAction.payload : readAction?.payload || readAction;
854
+ if (meta && typeof meta === "object" && ("columns" in meta || "displayName" in meta || "tableId" in meta)) {
855
+ setState((s) => ({
856
+ ...s,
857
+ isLoading: false,
858
+ isInitialized: true,
859
+ currentTable: meta,
860
+ error: null
861
+ }));
862
+ return meta;
863
+ }
864
+ const msg = readAction.payload?.message || `\u65E0\u6CD5\u52A0\u8F7D\u8868 ${tableId}`;
865
+ setState((s) => ({
866
+ ...s,
867
+ isLoading: false,
868
+ isInitialized: true,
869
+ currentTable: null,
870
+ error: msg,
871
+ rows: []
872
+ }));
873
+ throw new Error(msg);
874
+ } catch (e) {
875
+ const msg = e?.message || `\u521D\u59CB\u5316\u8868 ${tableId} \u65F6\u51FA\u9519`;
876
+ setState((s) => ({
877
+ ...s,
878
+ isLoading: false,
879
+ isInitialized: true,
880
+ currentTable: null,
881
+ error: msg,
882
+ rows: []
883
+ }));
884
+ throw e;
885
+ }
886
+ }
887
+ );
888
+ var loadTableRows = createTableCommand(
889
+ "table/loadTableRows",
890
+ async (args, { getState, extra } = {}) => {
891
+ const { tenantId, tableId } = args;
892
+ const db = extra?.db;
893
+ setState((s) => {
894
+ if (s.currentTable && s.currentTable.tenantId === tenantId && s.currentTable.tableId === tableId) {
895
+ return { ...s, error: null };
896
+ }
897
+ return s;
898
+ });
899
+ try {
900
+ const stateObj = getState ? getState() : {};
901
+ const { currentToken: token, remoteServers } = getRuntimeServerContext(stateObj);
902
+ const rows = await fetchAndCacheTableRows({
903
+ db,
904
+ tenantId,
905
+ tableId,
906
+ token,
907
+ remoteServers
908
+ });
909
+ setState((s) => {
910
+ if (s.currentTable && s.currentTable.tenantId === tenantId && s.currentTable.tableId === tableId) {
911
+ return { ...s, rows };
912
+ }
913
+ return s;
914
+ });
915
+ return rows;
916
+ } catch (e) {
917
+ const msg = e?.message || "\u52A0\u8F7D\u8868\u884C\u5931\u8D25";
918
+ setState((s) => {
919
+ if (s.currentTable && s.currentTable.tenantId === tenantId && s.currentTable.tableId === tableId) {
920
+ return { ...s, error: msg, rows: [] };
921
+ }
922
+ return s;
923
+ });
924
+ throw e;
925
+ }
926
+ }
927
+ );
928
+ var addRow = createTableCommand(
929
+ "table/addRow",
930
+ async (args, { dispatch } = {}) => {
931
+ const { tenantId, tableId, values } = args;
932
+ setState((s) => {
933
+ if (s.currentTable && s.currentTable.tenantId === tenantId && s.currentTable.tableId === tableId) {
934
+ return { ...s, error: null };
935
+ }
936
+ return s;
937
+ });
938
+ try {
939
+ const { dbKey, rowId } = rowKey.create(tenantId, tableId);
940
+ const nowIso = (0, import_date_fns2.formatISO)(/* @__PURE__ */ new Date());
941
+ const row = {
942
+ dbKey,
943
+ tenantId,
944
+ tableId,
945
+ rowId,
946
+ createdAt: nowIso,
947
+ updatedAt: nowIso,
948
+ type: "table_row" /* TABLE_ROW */,
949
+ ...values
950
+ };
951
+ if (dispatch) {
952
+ await safeDispatch(
953
+ dispatch,
954
+ write({
955
+ data: row,
956
+ customKey: dbKey
957
+ })
958
+ );
959
+ }
960
+ setState((s) => {
961
+ const meta = s.currentTable;
962
+ if (meta && row?.tenantId === meta.tenantId && row?.tableId === meta.tableId) {
963
+ return { ...s, rows: [...s.rows, row] };
964
+ }
965
+ return s;
966
+ });
967
+ return row;
968
+ } catch (e) {
969
+ const msg = e?.message || "\u65B0\u589E\u8868\u884C\u5931\u8D25";
970
+ setState((s) => {
971
+ if (s.currentTable && s.currentTable.tenantId === tenantId && s.currentTable.tableId === tableId) {
972
+ return { ...s, error: msg };
973
+ }
974
+ return s;
975
+ });
976
+ throw e;
977
+ }
978
+ }
979
+ );
980
+ var deleteRow = createTableCommand(
981
+ "table/deleteRow",
982
+ async (dbKey, { dispatch, getState, extra } = {}) => {
983
+ try {
984
+ let row = state.rows.find((item) => item?.dbKey === dbKey);
985
+ if (!row && extra?.db && typeof extra.db.get === "function") {
986
+ try {
987
+ row = await extra.db.get(dbKey);
988
+ } catch {
989
+ }
990
+ }
991
+ if (!row && dispatch) {
992
+ try {
993
+ const readAction = await safeDispatch(dispatch, readAndWait(dbKey));
994
+ row = readAction?.payload || readAction;
995
+ } catch {
996
+ }
997
+ }
998
+ if (!row) {
999
+ throw new Error(`\u5F53\u524D\u8868\u4E2D\u627E\u4E0D\u5230\u8981\u5220\u9664\u7684\u884C\uFF1A${dbKey}`);
1000
+ }
1001
+ const nowIso = (0, import_date_fns2.formatISO)(/* @__PURE__ */ new Date());
1002
+ const tombstoneRow = {
1003
+ ...row,
1004
+ deletedAt: nowIso,
1005
+ updatedAt: nowIso,
1006
+ type: "table_row" /* TABLE_ROW */
1007
+ };
1008
+ if (extra?.db && typeof extra.db.put === "function") {
1009
+ await extra.db.put(dbKey, tombstoneRow);
1010
+ }
1011
+ if (dispatch) {
1012
+ dispatch(upsertSSREntity(tombstoneRow));
1013
+ }
1014
+ const stateObj = getState ? getState() : {};
1015
+ const { currentServer, syncServers } = getRuntimeServerContext(stateObj);
1016
+ const servers = resolveReplicationServers(currentServer, syncServers);
1017
+ scheduleWriteReplication(
1018
+ servers,
1019
+ {
1020
+ data: tombstoneRow,
1021
+ customKey: dbKey
1022
+ },
1023
+ stateObj
1024
+ );
1025
+ setState((s) => ({
1026
+ ...s,
1027
+ rows: s.rows.filter((r) => r.dbKey !== dbKey)
1028
+ }));
1029
+ return dbKey;
1030
+ } catch (e) {
1031
+ const msg = e?.message || "\u5220\u9664\u8868\u884C\u5931\u8D25";
1032
+ setState((s) => ({ ...s, error: msg }));
1033
+ throw e;
1034
+ }
1035
+ }
1036
+ );
1037
+ var createTable = createTableCommand(
1038
+ "table/createTable",
1039
+ async (args, context = {}) => {
1040
+ return await createTableAction(args, context);
1041
+ }
1042
+ );
1043
+ var deleteTable = createTableCommand(
1044
+ "table/deleteTable",
1045
+ async (args, context = {}) => {
1046
+ setState((s) => ({ ...s, error: null }));
1047
+ try {
1048
+ const deletedKey = await deleteTableAction(args, context);
1049
+ setState((s) => {
1050
+ if (s.currentTable?.dbKey === deletedKey) {
1051
+ return {
1052
+ ...s,
1053
+ currentTable: null,
1054
+ rows: [],
1055
+ isInitialized: false
1056
+ };
1057
+ }
1058
+ return s;
1059
+ });
1060
+ return deletedKey;
1061
+ } catch (e) {
1062
+ const msg = e?.message || "\u5220\u9664\u8868\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
1063
+ setState((s) => ({ ...s, error: msg }));
1064
+ throw e;
1065
+ }
1066
+ }
1067
+ );
1068
+ var addColumn = createTableCommand(
1069
+ "table/addColumn",
1070
+ async (args, { dispatch } = {}) => {
1071
+ const { tenantId, tableId, columnName } = args;
1072
+ const meta = state.currentTable;
1073
+ if (!meta || meta.tenantId !== tenantId || meta.tableId !== tableId) {
1074
+ throw new Error("\u5F53\u524D\u6CA1\u6709\u52A0\u8F7D\u5BF9\u5E94\u7684\u8868\u5B9A\u4E49");
1075
+ }
1076
+ const result = addColumnToMeta(
1077
+ meta,
1078
+ { columnName },
1079
+ { id: ulid3(), nowIso: (0, import_date_fns2.formatISO)(/* @__PURE__ */ new Date()) }
1080
+ );
1081
+ if (!result.ok) {
1082
+ throw new Error(result.error);
1083
+ }
1084
+ setState((s) => ({ ...s, error: null }));
1085
+ try {
1086
+ if (dispatch) {
1087
+ await safeDispatch(
1088
+ dispatch,
1089
+ patch({
1090
+ dbKey: meta.dbKey,
1091
+ changes: result.value.metaChanges
1092
+ })
1093
+ );
1094
+ }
1095
+ setState((s) => ({
1096
+ ...s,
1097
+ currentTable: result.value.meta,
1098
+ isInitialized: true
1099
+ }));
1100
+ return result.value.meta;
1101
+ } catch (e) {
1102
+ const msg = e?.message || "\u6DFB\u52A0\u5B57\u6BB5\u5931\u8D25";
1103
+ setState((s) => ({ ...s, error: msg }));
1104
+ throw e;
1105
+ }
1106
+ }
1107
+ );
1108
+ var deleteColumn = createTableCommand(
1109
+ "table/deleteColumn",
1110
+ async (args, { dispatch } = {}) => {
1111
+ const { tenantId, tableId, columnName } = args;
1112
+ const meta = state.currentTable;
1113
+ if (!meta || meta.tenantId !== tenantId || meta.tableId !== tableId) {
1114
+ throw new Error("\u5F53\u524D\u6CA1\u6709\u52A0\u8F7D\u5BF9\u5E94\u7684\u8868\u5B9A\u4E49");
1115
+ }
1116
+ const result = deleteColumnFromMeta(
1117
+ meta,
1118
+ state.rows,
1119
+ { columnName },
1120
+ { nowIso: (0, import_date_fns2.formatISO)(/* @__PURE__ */ new Date()) }
1121
+ );
1122
+ if (!result.ok) {
1123
+ throw new Error(result.error);
1124
+ }
1125
+ const { meta: nextMeta, metaChanges, rows: newRows, rowPatches } = result.value;
1126
+ setState((s) => ({ ...s, error: null }));
1127
+ try {
1128
+ if (dispatch) {
1129
+ await Promise.all(
1130
+ rowPatches.map((p) => safeDispatch(dispatch, patch(p)))
1131
+ );
1132
+ await safeDispatch(
1133
+ dispatch,
1134
+ patch({ dbKey: meta.dbKey, changes: metaChanges })
1135
+ );
1136
+ }
1137
+ setState((s) => ({
1138
+ ...s,
1139
+ currentTable: nextMeta,
1140
+ rows: newRows,
1141
+ isInitialized: true
1142
+ }));
1143
+ return { meta: nextMeta, rows: newRows };
1144
+ } catch (e) {
1145
+ const msg = e?.message || "\u5220\u9664\u5B57\u6BB5\u5931\u8D25";
1146
+ setState((s) => ({ ...s, error: msg }));
1147
+ throw e;
1148
+ }
1149
+ }
1150
+ );
1151
+ var reorderColumn = createTableCommand(
1152
+ "table/reorderColumn",
1153
+ async (args, { dispatch } = {}) => {
1154
+ const { tenantId, tableId, fromIndex, toIndex } = args;
1155
+ const meta = state.currentTable;
1156
+ if (!meta || meta.tenantId !== tenantId || meta.tableId !== tableId) {
1157
+ throw new Error("\u5F53\u524D\u6CA1\u6709\u52A0\u8F7D\u5BF9\u5E94\u7684\u8868\u5B9A\u4E49");
1158
+ }
1159
+ const result = reorderColumnInMeta(
1160
+ meta,
1161
+ { fromIndex, toIndex },
1162
+ { nowIso: (0, import_date_fns2.formatISO)(/* @__PURE__ */ new Date()) }
1163
+ );
1164
+ if (!result.ok) {
1165
+ throw new Error(result.error);
1166
+ }
1167
+ if (result.value.noop) {
1168
+ return meta;
1169
+ }
1170
+ const { meta: nextMeta, metaChanges } = result.value;
1171
+ setState((s) => ({ ...s, error: null }));
1172
+ try {
1173
+ if (dispatch) {
1174
+ await safeDispatch(
1175
+ dispatch,
1176
+ patch({ dbKey: meta.dbKey, changes: metaChanges })
1177
+ );
1178
+ }
1179
+ setState((s) => ({
1180
+ ...s,
1181
+ currentTable: nextMeta,
1182
+ isInitialized: true
1183
+ }));
1184
+ return nextMeta;
1185
+ } catch (e) {
1186
+ const msg = e?.message || "\u8C03\u6574\u5217\u987A\u5E8F\u5931\u8D25";
1187
+ setState((s) => ({ ...s, error: msg }));
1188
+ throw e;
1189
+ }
1190
+ }
1191
+ );
1192
+ var renameColumn = createTableCommand(
1193
+ "table/renameColumn",
1194
+ async (args, { dispatch } = {}) => {
1195
+ const { tenantId, tableId, oldName, newName } = args;
1196
+ const meta = state.currentTable;
1197
+ if (!meta || meta.tenantId !== tenantId || meta.tableId !== tableId) {
1198
+ throw new Error("\u5F53\u524D\u6CA1\u6709\u52A0\u8F7D\u5BF9\u5E94\u7684\u8868\u5B9A\u4E49");
1199
+ }
1200
+ const result = renameColumnInMeta(
1201
+ meta,
1202
+ state.rows,
1203
+ { oldName, newName },
1204
+ { nowIso: (0, import_date_fns2.formatISO)(/* @__PURE__ */ new Date()) }
1205
+ );
1206
+ if (!result.ok) {
1207
+ throw new Error(result.error);
1208
+ }
1209
+ const { meta: nextMeta, metaChanges, rows: newRows, rowPatches } = result.value;
1210
+ setState((s) => ({ ...s, error: null }));
1211
+ try {
1212
+ if (dispatch) {
1213
+ await Promise.all(
1214
+ rowPatches.map((p) => safeDispatch(dispatch, patch(p)))
1215
+ );
1216
+ await safeDispatch(
1217
+ dispatch,
1218
+ patch({ dbKey: meta.dbKey, changes: metaChanges })
1219
+ );
1220
+ }
1221
+ setState((s) => ({
1222
+ ...s,
1223
+ currentTable: nextMeta,
1224
+ rows: newRows,
1225
+ isInitialized: true
1226
+ }));
1227
+ return { meta: nextMeta, rows: newRows };
1228
+ } catch (e) {
1229
+ const msg = e?.message || "\u91CD\u547D\u540D\u5B57\u6BB5\u5931\u8D25";
1230
+ setState((s) => ({ ...s, error: msg }));
1231
+ throw e;
1232
+ }
1233
+ }
1234
+ );
1235
+ var renameColumnLabel = createTableCommand(
1236
+ "table/renameColumnLabel",
1237
+ async (args, { dispatch } = {}) => {
1238
+ const { tenantId, tableId, columnId, newLabel } = args;
1239
+ const meta = state.currentTable;
1240
+ if (!meta || meta.tenantId !== tenantId || meta.tableId !== tableId) {
1241
+ throw new Error("\u5F53\u524D\u6CA1\u6709\u52A0\u8F7D\u5BF9\u5E94\u7684\u8868\u5B9A\u4E49");
1242
+ }
1243
+ const result = renameColumnLabelInMeta(
1244
+ meta,
1245
+ { columnId, label: newLabel },
1246
+ { nowIso: (0, import_date_fns2.formatISO)(/* @__PURE__ */ new Date()) }
1247
+ );
1248
+ if (!result.ok) {
1249
+ throw new Error(result.error);
1250
+ }
1251
+ const { meta: nextMeta, metaChanges } = result.value;
1252
+ setState((s) => ({ ...s, error: null }));
1253
+ try {
1254
+ if (dispatch) {
1255
+ await safeDispatch(
1256
+ dispatch,
1257
+ patch({ dbKey: meta.dbKey, changes: metaChanges })
1258
+ );
1259
+ }
1260
+ setState((s) => ({
1261
+ ...s,
1262
+ currentTable: nextMeta,
1263
+ isInitialized: true
1264
+ }));
1265
+ return nextMeta;
1266
+ } catch (e) {
1267
+ const msg = e?.message || "\u91CD\u547D\u540D\u5B57\u6BB5\u663E\u793A\u540D\u5931\u8D25";
1268
+ setState((s) => ({ ...s, error: msg }));
1269
+ throw e;
1270
+ }
1271
+ }
1272
+ );
1273
+ var updateColumnWidth = createTableCommand(
1274
+ "table/updateColumnWidth",
1275
+ async (args, { dispatch } = {}) => {
1276
+ const { tenantId, tableId, columnId, width } = args;
1277
+ const meta = state.currentTable;
1278
+ if (!meta || meta.tenantId !== tenantId || meta.tableId !== tableId) {
1279
+ throw new Error("\u5F53\u524D\u6CA1\u6709\u52A0\u8F7D\u5BF9\u5E94\u7684\u8868\u5B9A\u4E49");
1280
+ }
1281
+ const result = updateColumnWidthInMeta(
1282
+ meta,
1283
+ { columnId, width },
1284
+ { nowIso: (0, import_date_fns2.formatISO)(/* @__PURE__ */ new Date()) }
1285
+ );
1286
+ if (!result.ok) {
1287
+ throw new Error(result.error);
1288
+ }
1289
+ const { meta: nextMeta, metaChanges } = result.value;
1290
+ setState((s) => ({ ...s, error: null }));
1291
+ try {
1292
+ if (dispatch) {
1293
+ await safeDispatch(
1294
+ dispatch,
1295
+ patch({ dbKey: meta.dbKey, changes: metaChanges })
1296
+ );
1297
+ }
1298
+ setState((s) => ({
1299
+ ...s,
1300
+ currentTable: nextMeta,
1301
+ isInitialized: true
1302
+ }));
1303
+ return nextMeta;
1304
+ } catch (e) {
1305
+ const msg = e?.message || "\u66F4\u65B0\u5B57\u6BB5\u5BBD\u5EA6\u5931\u8D25";
1306
+ setState((s) => ({ ...s, error: msg }));
1307
+ throw e;
1308
+ }
1309
+ }
1310
+ );
1311
+ var addColumnOption = createTableCommand(
1312
+ "table/addColumnOption",
1313
+ async (args, { dispatch } = {}) => {
1314
+ const { tenantId, tableId, columnId, option } = args;
1315
+ const meta = state.currentTable;
1316
+ if (!meta || meta.tenantId !== tenantId || meta.tableId !== tableId) {
1317
+ throw new Error("\u5F53\u524D\u6CA1\u6709\u52A0\u8F7D\u5BF9\u5E94\u7684\u8868\u5B9A\u4E49");
1318
+ }
1319
+ const result = addColumnOptionInMeta(
1320
+ meta,
1321
+ { columnId, option },
1322
+ { nowIso: (0, import_date_fns2.formatISO)(/* @__PURE__ */ new Date()) }
1323
+ );
1324
+ if (!result.ok) {
1325
+ throw new Error(result.error);
1326
+ }
1327
+ if (result.value.noop) {
1328
+ return meta;
1329
+ }
1330
+ const { meta: nextMeta, metaChanges } = result.value;
1331
+ setState((s) => ({ ...s, error: null }));
1332
+ try {
1333
+ if (dispatch) {
1334
+ await safeDispatch(
1335
+ dispatch,
1336
+ patch({ dbKey: meta.dbKey, changes: metaChanges })
1337
+ );
1338
+ }
1339
+ setState((s) => ({
1340
+ ...s,
1341
+ currentTable: nextMeta,
1342
+ isInitialized: true
1343
+ }));
1344
+ return nextMeta;
1345
+ } catch (e) {
1346
+ const msg = e?.message || "\u65B0\u589E\u9009\u9879\u5931\u8D25";
1347
+ setState((s) => ({ ...s, error: msg }));
1348
+ throw e;
1349
+ }
1350
+ }
1351
+ );
1352
+ var renameTable = createTableCommand(
1353
+ "table/renameTable",
1354
+ async (args, { dispatch } = {}) => {
1355
+ const { tenantId, tableId, newName } = args;
1356
+ const trimmedName = newName.trim();
1357
+ if (!trimmedName) {
1358
+ throw new Error("\u8868\u540D\u4E0D\u80FD\u4E3A\u7A7A");
1359
+ }
1360
+ const meta = state.currentTable;
1361
+ if (!meta || meta.tenantId !== tenantId || meta.tableId !== tableId) {
1362
+ throw new Error("\u5F53\u524D\u6CA1\u6709\u52A0\u8F7D\u5BF9\u5E94\u7684\u8868\u5B9A\u4E49");
1363
+ }
1364
+ const nowIso = (0, import_date_fns2.formatISO)(/* @__PURE__ */ new Date());
1365
+ setState((s) => ({ ...s, error: null }));
1366
+ try {
1367
+ if (dispatch) {
1368
+ await safeDispatch(
1369
+ dispatch,
1370
+ patch({
1371
+ dbKey: meta.dbKey,
1372
+ changes: {
1373
+ displayName: trimmedName,
1374
+ updatedAt: nowIso
1375
+ }
1376
+ })
1377
+ );
1378
+ }
1379
+ const nextMeta = {
1380
+ ...meta,
1381
+ displayName: trimmedName,
1382
+ updatedAt: nowIso
1383
+ };
1384
+ setState((s) => ({
1385
+ ...s,
1386
+ currentTable: nextMeta,
1387
+ isInitialized: true
1388
+ }));
1389
+ return nextMeta;
1390
+ } catch (e) {
1391
+ const msg = e?.message || "\u91CD\u547D\u540D\u8868\u5931\u8D25";
1392
+ setState((s) => ({ ...s, error: msg }));
1393
+ throw e;
1394
+ }
1395
+ }
1396
+ );
1397
+ var updateTableIcon = createTableCommand(
1398
+ "table/updateTableIcon",
1399
+ async (args, { dispatch } = {}) => {
1400
+ const { tenantId, tableId, icon } = args;
1401
+ const meta = state.currentTable;
1402
+ if (!meta || meta.tenantId !== tenantId || meta.tableId !== tableId) {
1403
+ throw new Error("\u5F53\u524D\u6CA1\u6709\u52A0\u8F7D\u5BF9\u5E94\u7684\u8868\u5B9A\u4E49");
1404
+ }
1405
+ const nowIso = (0, import_date_fns2.formatISO)(/* @__PURE__ */ new Date());
1406
+ setState((s) => ({ ...s, error: null }));
1407
+ try {
1408
+ if (dispatch) {
1409
+ await safeDispatch(
1410
+ dispatch,
1411
+ patch({
1412
+ dbKey: meta.dbKey,
1413
+ changes: {
1414
+ icon: icon ?? null,
1415
+ updatedAt: nowIso
1416
+ }
1417
+ })
1418
+ );
1419
+ }
1420
+ const nextMeta = {
1421
+ ...meta,
1422
+ icon: icon ?? null,
1423
+ updatedAt: nowIso
1424
+ };
1425
+ setState((s) => ({
1426
+ ...s,
1427
+ currentTable: nextMeta
1428
+ }));
1429
+ return nextMeta;
1430
+ } catch (e) {
1431
+ const msg = e?.message || "\u66F4\u65B0\u8868\u683C\u56FE\u6807\u5931\u8D25";
1432
+ setState((s) => ({ ...s, error: msg }));
1433
+ throw e;
1434
+ }
1435
+ }
1436
+ );
1437
+ var updateCell = createTableCommand(
1438
+ "table/updateCell",
1439
+ async (args, { dispatch } = {}) => {
1440
+ const { dbKey, columnName, value } = args;
1441
+ setState((s) => ({ ...s, error: null }));
1442
+ try {
1443
+ const nowIso = (0, import_date_fns2.formatISO)(/* @__PURE__ */ new Date());
1444
+ if (dispatch) {
1445
+ await safeDispatch(
1446
+ dispatch,
1447
+ patch({
1448
+ dbKey,
1449
+ changes: {
1450
+ [columnName]: value,
1451
+ updatedAt: nowIso
1452
+ }
1453
+ })
1454
+ );
1455
+ }
1456
+ setState((s) => ({
1457
+ ...s,
1458
+ rows: s.rows.map((r) => {
1459
+ if (r.dbKey === dbKey) {
1460
+ return {
1461
+ ...r,
1462
+ [columnName]: value,
1463
+ updatedAt: nowIso
1464
+ };
1465
+ }
1466
+ return r;
1467
+ })
1468
+ }));
1469
+ return { dbKey, columnName, value, updatedAt: nowIso };
1470
+ } catch (e) {
1471
+ const msg = e?.message || "\u66F4\u65B0\u5355\u5143\u683C\u5931\u8D25";
1472
+ setState((s) => ({ ...s, error: msg }));
1473
+ throw e;
1474
+ }
1475
+ }
1476
+ );
1477
+
1478
+ // packages/create/space/content/deleteContentFromSpaceAction.ts
1479
+ var nextSpaceUpdatedAt = (value) => {
1480
+ const previousTimestamp = typeof value === "number" ? value : typeof value === "string" ? Date.parse(value) || 0 : 0;
1481
+ const nextTimestamp = Math.max(Date.now(), previousTimestamp + 1);
1482
+ return typeof value === "string" ? new Date(nextTimestamp).toISOString() : nextTimestamp;
1483
+ };
1484
+ var findContentReference = (spaceData, requestedContentKey) => {
1485
+ const contents = spaceData.contents ?? {};
1486
+ const directMatch = contents[requestedContentKey];
1487
+ if (directMatch) {
1488
+ return { entryKey: requestedContentKey, contentInfo: directMatch };
1489
+ }
1490
+ for (const [entryKey, item] of Object.entries(contents)) {
1491
+ if (!item) continue;
1492
+ if (item.contentKey === requestedContentKey) {
1493
+ return { entryKey, contentInfo: item };
1494
+ }
1495
+ }
1496
+ return null;
1497
+ };
1498
+ var ENTITY_DELETE_STRATEGIES = {
1499
+ dialog: async (key, { dispatch }) => {
1500
+ await dispatch(deleteDialog(key)).unwrap();
1501
+ },
1502
+ page: async (key, { dispatch, userId, sourceServerOrigin }) => {
1503
+ const isOwnerByKey = extractUserId(key) === userId;
1504
+ if (isOwnerByKey || isSystemAdmin(userId)) {
1505
+ await dispatch(remove({ dbKey: key, preferredServerOrigin: sourceServerOrigin }));
1506
+ }
1507
+ },
1508
+ table: async (key, { dispatch }) => {
1509
+ await dispatch(deleteTable({ dbKey: key })).unwrap();
1510
+ },
1511
+ file: async (key, { thunkAPI }) => {
1512
+ const { deleteFileAction } = await import("./deleteFile-LWSR674W.js");
1513
+ await deleteFileAction(key, thunkAPI);
1514
+ },
1515
+ image: async (key, { thunkAPI }) => {
1516
+ const { deleteFileAction } = await import("./deleteFile-LWSR674W.js");
1517
+ await deleteFileAction(key, thunkAPI);
1518
+ },
1519
+ agent: async (key, { dispatch, userId, sourceServerOrigin }) => {
1520
+ const parts = splitKey(key);
1521
+ const isPublic = parts[1] === "pub";
1522
+ const isOwnerByKey = parts[1] === userId;
1523
+ if (!isPublic) {
1524
+ if (isOwnerByKey || isSystemAdmin(userId)) {
1525
+ await dispatch(remove({ dbKey: key, preferredServerOrigin: sourceServerOrigin }));
1526
+ }
1527
+ } else {
1528
+ const agentData = await dispatch(read({
1529
+ dbKey: key,
1530
+ preferredServerOrigin: sourceServerOrigin
1531
+ })).unwrap();
1532
+ if (agentData) {
1533
+ const isCreator = agentData.userId === userId;
1534
+ const isAdmin = isSystemAdmin(userId);
1535
+ if (isCreator || isAdmin) {
1536
+ await dispatch(remove({ dbKey: key, preferredServerOrigin: sourceServerOrigin }));
1537
+ }
1538
+ }
1539
+ }
1540
+ }
1541
+ };
1542
+ var deleteContentFromSpaceAction = async (input, thunkAPI) => {
1543
+ const { contentKey, sourceServerOrigin } = input;
1544
+ const spaceId = normalizeSpaceId(input.spaceId);
1545
+ const { dispatch, getState } = thunkAPI;
1546
+ const accountUserId = selectIdentityUserId(getState());
1547
+ const spaceKey = createSpaceKey.space(spaceId);
1548
+ const spaceData = await dispatch(read({
1549
+ dbKey: spaceKey,
1550
+ preferredServerOrigin: sourceServerOrigin
1551
+ })).unwrap();
1552
+ if (!spaceData) throw new Error("\u7A7A\u95F4\u4E0D\u5B58\u5728");
1553
+ checkSpaceMembership(spaceData, accountUserId);
1554
+ const contentReference = findContentReference(spaceData, contentKey);
1555
+ if (!contentReference) {
1556
+ return { contentKey, spaceId, updatedSpaceData: spaceData };
1557
+ }
1558
+ const { entryKey, contentInfo } = contentReference;
1559
+ const entityKey = String(contentInfo.contentKey || contentKey || entryKey);
1560
+ const contentDeletes = {
1561
+ [entryKey]: null
1562
+ };
1563
+ if (entityKey !== entryKey) {
1564
+ contentDeletes[entityKey] = null;
1565
+ }
1566
+ const updatedSpaceData = await dispatch(
1567
+ patch({
1568
+ dbKey: spaceKey,
1569
+ preferredServerOrigin: sourceServerOrigin,
1570
+ changes: {
1571
+ contents: contentDeletes,
1572
+ updatedAt: nextSpaceUpdatedAt(spaceData.updatedAt),
1573
+ ...localSpaceAuthorityPatchStamp(spaceData)
1574
+ }
1575
+ })
1576
+ ).unwrap();
1577
+ const userId = isDeviceLocalSpaceBody(spaceData) ? DEVICE_LOCAL_OWNER_ID : String(accountUserId ?? "");
1578
+ let entityRemoveError = null;
1579
+ const contentType = String(contentInfo.type || "").toLowerCase();
1580
+ try {
1581
+ const strategy = ENTITY_DELETE_STRATEGIES[contentType];
1582
+ if (strategy) {
1583
+ await strategy(entityKey, { dispatch, userId, thunkAPI, sourceServerOrigin });
1584
+ } else if (isPageKey(entityKey)) {
1585
+ await ENTITY_DELETE_STRATEGIES.page(entityKey, {
1586
+ dispatch,
1587
+ userId,
1588
+ thunkAPI,
1589
+ sourceServerOrigin
1590
+ });
1591
+ } else if (isAgentKey(entityKey)) {
1592
+ await ENTITY_DELETE_STRATEGIES.agent(entityKey, {
1593
+ dispatch,
1594
+ userId,
1595
+ thunkAPI,
1596
+ sourceServerOrigin
1597
+ });
1598
+ }
1599
+ } catch (err2) {
1600
+ console.error(`[deleteContent] Failed to delete entity ${entityKey}:`, err2);
1601
+ entityRemoveError = err2.message || "Unknown error";
1602
+ }
1603
+ return {
1604
+ contentKey,
1605
+ spaceId,
1606
+ updatedSpaceData,
1607
+ entityRemoveError
1608
+ };
1609
+ };
1610
+
1611
+ // packages/create/space/content/moveContentAction.ts
1612
+ var logger = createClientLogger("move-content");
1613
+ var moveContentAction = async (input, thunkAPI) => {
1614
+ const {
1615
+ contentKey,
1616
+ sourceSpaceId,
1617
+ targetSpaceId,
1618
+ targetCategoryId: rawTargetCategoryId
1619
+ } = input;
1620
+ const { dispatch, getState } = thunkAPI;
1621
+ const state3 = getState();
1622
+ const userId = selectIdentityUserId(state3);
1623
+ const now = Date.now();
1624
+ logger.info({ ...input, userId }, "Initiating moveContentAction");
1625
+ if (sourceSpaceId === targetSpaceId) {
1626
+ logger.error("Source and target space IDs are the same.");
1627
+ throw new Error(
1628
+ "\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"
1629
+ );
1630
+ }
1631
+ if (!contentKey || typeof contentKey !== "string" || contentKey.trim() === "") {
1632
+ logger.error("Invalid contentKey provided.");
1633
+ throw new Error("\u65E0\u6548\u7684\u5185\u5BB9 Key\u3002");
1634
+ }
1635
+ let sourceSpaceData = null;
1636
+ let targetSpaceData = null;
1637
+ let contentDataFromSource = null;
1638
+ let finalSourceData = null;
1639
+ let finalTargetData = null;
1640
+ let overallError = void 0;
1641
+ try {
1642
+ const sourceSpaceKey = createSpaceKey.space(sourceSpaceId);
1643
+ const targetSpaceKey = createSpaceKey.space(targetSpaceId);
1644
+ logger.info(
1645
+ { sourceSpaceKey, targetSpaceKey },
1646
+ "Reading source and target space data."
1647
+ );
1648
+ const [sourceResult, targetResult] = await Promise.allSettled([
1649
+ dispatch(read({
1650
+ dbKey: sourceSpaceKey
1651
+ })).unwrap(),
1652
+ dispatch(read({
1653
+ dbKey: targetSpaceKey
1654
+ })).unwrap()
1655
+ ]);
1656
+ if (sourceResult.status === "rejected" || !sourceResult.value) {
1657
+ const reason = sourceResult.status === "rejected" ? sourceResult.reason : "Data is null";
1658
+ throw new Error(
1659
+ `\u65E0\u6CD5\u52A0\u8F7D\u6E90\u7A7A\u95F4 (${sourceSpaceId}): ${reason?.message || reason}`
1660
+ );
1661
+ }
1662
+ sourceSpaceData = sourceResult.value;
1663
+ if (targetResult.status === "rejected" || !targetResult.value) {
1664
+ const reason = targetResult.status === "rejected" ? targetResult.reason : "Data is null";
1665
+ throw new Error(
1666
+ `\u65E0\u6CD5\u52A0\u8F7D\u76EE\u6807\u7A7A\u95F4 (${targetSpaceId}): ${reason?.message || reason}`
1667
+ );
1668
+ }
1669
+ targetSpaceData = targetResult.value;
1670
+ logger.info("Checking permissions for source and target spaces.");
1671
+ checkSpaceMembership(sourceSpaceData, userId);
1672
+ checkSpaceMembership(targetSpaceData, userId);
1673
+ if (!sourceSpaceData.contents || !sourceSpaceData.contents[contentKey]) {
1674
+ logger.error(
1675
+ { contentKey, sourceSpaceId },
1676
+ "Content key not found in source space contents."
1677
+ );
1678
+ throw new Error(
1679
+ `\u5185\u5BB9 (${contentKey}) \u4E0D\u5728\u6E90\u7A7A\u95F4 (${sourceSpaceId}) \u4E2D\u3002`
1680
+ );
1681
+ }
1682
+ contentDataFromSource = sourceSpaceData.contents[contentKey];
1683
+ if (targetSpaceData.contents && targetSpaceData.contents[contentKey]) {
1684
+ logger.warn(
1685
+ { contentKey, targetSpaceId },
1686
+ "Content key already exists in target space. Overwriting."
1687
+ );
1688
+ }
1689
+ let categoryIdForTargetStorage;
1690
+ if (rawTargetCategoryId && rawTargetCategoryId !== "" && rawTargetCategoryId !== UNCATEGORIZED_ID) {
1691
+ if (targetSpaceData.categories?.[rawTargetCategoryId]) {
1692
+ categoryIdForTargetStorage = rawTargetCategoryId;
1693
+ } else {
1694
+ logger.warn(
1695
+ `Target category ${rawTargetCategoryId} not found in target space ${targetSpaceId}. Content will be uncategorized.`
1696
+ );
1697
+ categoryIdForTargetStorage = void 0;
1698
+ }
1699
+ } else {
1700
+ categoryIdForTargetStorage = void 0;
1701
+ }
1702
+ const contentReferenceForTarget = {
1703
+ ...contentDataFromSource,
1704
+ updatedAt: now
1705
+ };
1706
+ delete contentReferenceForTarget.categoryId;
1707
+ if (categoryIdForTargetStorage !== void 0) {
1708
+ contentReferenceForTarget.categoryId = categoryIdForTargetStorage;
1709
+ }
1710
+ const sourcePatchChanges = {
1711
+ contents: {
1712
+ [contentKey]: null
1713
+ // 从源移除引用 (null value in patch typically means delete key)
1714
+ },
1715
+ updatedAt: now,
1716
+ ...localSpaceAuthorityPatchStamp(sourceSpaceData)
1717
+ };
1718
+ const targetPatchChanges = {
1719
+ contents: {
1720
+ [contentKey]: contentReferenceForTarget
1721
+ // 向目标添加(或覆盖)引用
1722
+ },
1723
+ updatedAt: now,
1724
+ ...localSpaceAuthorityPatchStamp(targetSpaceData)
1725
+ };
1726
+ logger.info("Patching source and target space data.");
1727
+ await Promise.all([
1728
+ dispatch(
1729
+ patch({ dbKey: sourceSpaceKey, changes: sourcePatchChanges })
1730
+ ).unwrap(),
1731
+ dispatch(
1732
+ patch({ dbKey: targetSpaceKey, changes: targetPatchChanges })
1733
+ ).unwrap()
1734
+ ]);
1735
+ logger.info("Successfully patched both source and target spaces.");
1736
+ } catch (error) {
1737
+ logger.error(
1738
+ { error: error.message, stack: error.stack },
1739
+ "Error during move content action execution."
1740
+ );
1741
+ overallError = error.message || "\u79FB\u52A8\u5185\u5BB9\u65F6\u53D1\u751F\u672A\u77E5\u9519\u8BEF";
1742
+ } finally {
1743
+ logger.info("Attempting to re-read final space data.");
1744
+ const sourceSpaceKey = createSpaceKey.space(sourceSpaceId);
1745
+ const targetSpaceKey = createSpaceKey.space(targetSpaceId);
1746
+ const [finalSourceResult, finalTargetResult] = await Promise.allSettled([
1747
+ dispatch(read({
1748
+ dbKey: sourceSpaceKey
1749
+ })).unwrap(),
1750
+ dispatch(read({
1751
+ dbKey: targetSpaceKey
1752
+ })).unwrap()
1753
+ ]);
1754
+ if (finalSourceResult.status === "fulfilled") {
1755
+ finalSourceData = finalSourceResult.value;
1756
+ } else {
1757
+ logger.error(
1758
+ { sourceSpaceId, reason: finalSourceResult.reason },
1759
+ "Failed to re-read final source space data."
1760
+ );
1761
+ }
1762
+ if (finalTargetResult.status === "fulfilled") {
1763
+ finalTargetData = finalTargetResult.value;
1764
+ } else {
1765
+ logger.error(
1766
+ { targetSpaceId, reason: finalTargetResult.reason },
1767
+ "Failed to re-read final target space data."
1768
+ );
1769
+ }
1770
+ logger.info(
1771
+ {
1772
+ hasError: !!overallError,
1773
+ sourceReadSuccess: !!finalSourceData,
1774
+ targetReadSuccess: !!finalTargetData
1775
+ },
1776
+ "Move content action finished."
1777
+ );
1778
+ const result = {
1779
+ sourceSpaceId,
1780
+ updatedSourceSpaceData: finalSourceData,
1781
+ targetSpaceId,
1782
+ updatedTargetSpaceData: finalTargetData,
1783
+ error: overallError
1784
+ // 如果过程中有错误,则传递错误信息
1785
+ };
1786
+ return result;
1787
+ }
1788
+ };
1789
+
1790
+ // packages/create/space/content/spaceContentPatch.ts
1791
+ var notifyUserDataUpdated = () => {
1792
+ if (typeof window !== "undefined" && typeof window.dispatchEvent === "function" && typeof window.Event === "function") {
1793
+ window.dispatchEvent(new window.Event("nolo-user-data-updated"));
1794
+ }
1795
+ };
1796
+ var loadSpaceContentOrThrow = async (dispatch, spaceId, contentKey, sourceServerOrigin) => {
1797
+ if (!contentKey || typeof contentKey !== "string" || contentKey.trim() === "") {
1798
+ throw new Error("Invalid contentKey provided.");
1799
+ }
1800
+ const spaceKey = createSpaceKey.space(spaceId);
1801
+ let spaceData = null;
1802
+ try {
1803
+ spaceData = await dispatch(
1804
+ read({ dbKey: spaceKey, preferredServerOrigin: sourceServerOrigin })
1805
+ ).unwrap();
1806
+ } catch (readError) {
1807
+ throw new Error(`\u65E0\u6CD5\u52A0\u8F7D\u7A7A\u95F4\u6570\u636E: ${spaceId}`);
1808
+ }
1809
+ if (!spaceData) {
1810
+ throw new Error("Space not found");
1811
+ }
1812
+ const content = spaceData.contents?.[contentKey];
1813
+ if (!content) {
1814
+ throw new Error("Content not found in space");
1815
+ }
1816
+ return { spaceKey, spaceData, content };
1817
+ };
1818
+ var patchIndividualContentRecord = async (dispatch, contentKey, changes, sourceServerOrigin, failMessagePrefix) => {
1819
+ let hasIndividualRecord = false;
1820
+ try {
1821
+ const existing = await dispatch(
1822
+ read({ dbKey: contentKey, preferredServerOrigin: sourceServerOrigin })
1823
+ ).unwrap();
1824
+ hasIndividualRecord = Boolean(existing);
1825
+ } catch {
1826
+ hasIndividualRecord = false;
1827
+ }
1828
+ if (hasIndividualRecord) {
1829
+ try {
1830
+ await dispatch(
1831
+ patch({
1832
+ dbKey: contentKey,
1833
+ changes,
1834
+ preferredServerOrigin: sourceServerOrigin
1835
+ })
1836
+ ).unwrap();
1837
+ notifyUserDataUpdated();
1838
+ } catch (contentPatchError) {
1839
+ throw new Error(
1840
+ `${failMessagePrefix}: ${contentPatchError?.message || "\u672A\u77E5\u9519\u8BEF"}`
1841
+ );
1842
+ }
1843
+ }
1844
+ };
1845
+
1846
+ // packages/create/space/content/updateContentTitleAction.ts
1847
+ var buildContentRecordTitleChanges = (content, title, updatedAt) => {
1848
+ const changes = { title, updatedAt };
1849
+ if (content.type === "app") {
1850
+ changes.name = title;
1851
+ }
1852
+ return changes;
1853
+ };
1854
+ var updateContentTitleAction = async (input, thunkAPI) => {
1855
+ const { spaceId, contentKey, title, skillSummary, sourceServerOrigin } = input;
1856
+ const { dispatch } = thunkAPI;
1857
+ if (title === void 0 || title === null || typeof title !== "string") {
1858
+ throw new Error("Invalid title provided.");
1859
+ }
1860
+ if (title.trim() === "") {
1861
+ throw new Error("Title cannot be empty.");
1862
+ }
1863
+ const { spaceKey, spaceData, content } = await loadSpaceContentOrThrow(
1864
+ dispatch,
1865
+ spaceId,
1866
+ contentKey,
1867
+ sourceServerOrigin
1868
+ );
1869
+ const trimmedTitle = title.trim();
1870
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1871
+ const changes = {
1872
+ contents: {
1873
+ [contentKey]: {
1874
+ ...spaceData.contents[contentKey],
1875
+ title: trimmedTitle,
1876
+ updatedAt: now,
1877
+ ...skillSummary !== void 0 ? { skillSummary } : {}
1878
+ }
1879
+ },
1880
+ updatedAt: now
1881
+ };
1882
+ let updatedSpaceData;
1883
+ try {
1884
+ updatedSpaceData = await dispatch(
1885
+ patch({
1886
+ dbKey: spaceKey,
1887
+ changes,
1888
+ preferredServerOrigin: sourceServerOrigin
1889
+ })
1890
+ ).unwrap();
1891
+ } catch (patchError) {
1892
+ throw new Error(`\u66F4\u65B0\u5185\u5BB9\u6807\u9898\u5931\u8D25: ${patchError.message || "\u672A\u77E5\u9519\u8BEF"}`);
1893
+ }
1894
+ await patchIndividualContentRecord(
1895
+ dispatch,
1896
+ contentKey,
1897
+ buildContentRecordTitleChanges(content, trimmedTitle, now),
1898
+ sourceServerOrigin,
1899
+ "\u6807\u9898\u5DF2\u5199\u5165\u7A7A\u95F4\uFF0C\u4F46\u540C\u6B65\u72EC\u7ACB\u8BB0\u5F55\u5931\u8D25"
1900
+ );
1901
+ if (contentKey.startsWith("meta-")) {
1902
+ const parts = contentKey.split(SEPARATOR);
1903
+ if (parts.length >= 3) {
1904
+ const tableId = parts.slice(2).join(SEPARATOR);
1905
+ const tenantId = parts[1];
1906
+ try {
1907
+ await dispatch(
1908
+ renameTable({
1909
+ tenantId,
1910
+ tableId,
1911
+ newName: trimmedTitle
1912
+ })
1913
+ ).unwrap();
1914
+ } catch (tableError) {
1915
+ console.error("Failed to sync title to TableMeta:", tableError);
1916
+ }
1917
+ }
1918
+ }
1919
+ return { spaceId, updatedSpaceData };
1920
+ };
1921
+
1922
+ // packages/create/space/content/updateContentPinnedAction.ts
1923
+ var updateContentPinnedAction = async (input, thunkAPI) => {
1924
+ const { spaceId, contentKey, pinned, sourceServerOrigin } = input;
1925
+ const { dispatch } = thunkAPI;
1926
+ if (typeof pinned !== "boolean") {
1927
+ throw new Error("Invalid pinned value provided.");
1928
+ }
1929
+ if (!spaceId) {
1930
+ if (!contentKey || typeof contentKey !== "string" || contentKey.trim() === "") {
1931
+ throw new Error("Invalid contentKey provided.");
1932
+ }
1933
+ await patchIndividualContentRecord(
1934
+ dispatch,
1935
+ contentKey,
1936
+ { pinned },
1937
+ sourceServerOrigin,
1938
+ "\u66F4\u65B0\u7F6E\u9876\u72B6\u6001\u5931\u8D25"
1939
+ );
1940
+ return { spaceId: null, updatedSpaceData: null };
1941
+ }
1942
+ const { spaceKey, spaceData } = await loadSpaceContentOrThrow(
1943
+ dispatch,
1944
+ spaceId,
1945
+ contentKey,
1946
+ sourceServerOrigin
1947
+ );
1948
+ const changes = {
1949
+ contents: {
1950
+ [contentKey]: { ...spaceData.contents[contentKey], pinned }
1951
+ },
1952
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1953
+ };
1954
+ let updatedSpaceData;
1955
+ try {
1956
+ updatedSpaceData = await dispatch(
1957
+ patch({ dbKey: spaceKey, changes, preferredServerOrigin: sourceServerOrigin })
1958
+ ).unwrap();
1959
+ } catch (patchError) {
1960
+ throw new Error(`\u66F4\u65B0\u5185\u5BB9\u7F6E\u9876\u72B6\u6001\u5931\u8D25: ${patchError.message || "\u672A\u77E5\u9519\u8BEF"}`);
1961
+ }
1962
+ await patchIndividualContentRecord(
1963
+ dispatch,
1964
+ contentKey,
1965
+ { pinned },
1966
+ sourceServerOrigin,
1967
+ "\u7F6E\u9876\u72B6\u6001\u5DF2\u5199\u5165\u7A7A\u95F4\uFF0C\u4F46\u540C\u6B65\u72EC\u7ACB\u8BB0\u5F55\u5931\u8D25"
1968
+ );
1969
+ return { spaceId, updatedSpaceData };
1970
+ };
1971
+
1972
+ // packages/create/space/content/updateContentCategoryAction.ts
1973
+ var updateContentCategoryAction = async (input, thunkAPI) => {
1974
+ const { spaceId, contentKey, categoryId: targetContainerId } = input;
1975
+ const { dispatch, getState } = thunkAPI;
1976
+ const state3 = getState();
1977
+ const userId = selectIdentityUserId(state3);
1978
+ if (!userId) {
1979
+ throw new Error("User is not logged in.");
1980
+ }
1981
+ if (!contentKey || typeof contentKey !== "string" || contentKey.trim() === "") {
1982
+ throw new Error("Invalid contentKey provided.");
1983
+ }
1984
+ if (typeof targetContainerId !== "string") {
1985
+ throw new Error("Invalid target container ID provided (must be a string).");
1986
+ }
1987
+ const spaceKey = createSpaceKey.space(spaceId);
1988
+ let spaceData = null;
1989
+ try {
1990
+ spaceData = await dispatch(read({
1991
+ dbKey: spaceKey
1992
+ })).unwrap();
1993
+ } catch (readError) {
1994
+ console.error(
1995
+ `[updateContentCategoryAction] Failed to read space data for key ${spaceKey}:`,
1996
+ readError
1997
+ );
1998
+ throw new Error(
1999
+ `\u65E0\u6CD5\u52A0\u8F7D\u7A7A\u95F4\u6570\u636E: ${spaceId}, \u539F\u56E0: ${readError.message || "\u672A\u77E5\u9519\u8BEF"}`
2000
+ );
2001
+ }
2002
+ if (!spaceData) {
2003
+ throw new Error(`\u7A7A\u95F4\u4E0D\u5B58\u5728: ${spaceId}`);
2004
+ }
2005
+ try {
2006
+ checkSpaceMembership(spaceData, userId);
2007
+ } catch (permissionError) {
2008
+ throw new Error(`\u6743\u9650\u4E0D\u8DB3\uFF0C\u65E0\u6CD5\u4FEE\u6539\u5185\u5BB9\u5206\u7C7B: ${permissionError.message}`);
2009
+ }
2010
+ const currentContent = spaceData.contents?.[contentKey];
2011
+ if (!currentContent) {
2012
+ console.warn(
2013
+ `[updateContentCategoryAction] Content ${contentKey} not found in space ${spaceId}.`
2014
+ );
2015
+ throw new Error("Content not found");
2016
+ }
2017
+ if (targetContainerId !== UNCATEGORIZED_ID) {
2018
+ if (!spaceData.categories[targetContainerId]) {
2019
+ console.warn(
2020
+ `[updateContentCategoryAction] Target category ${targetContainerId} not found or invalid in space ${spaceId}. Cannot move content.`
2021
+ );
2022
+ throw new Error("Target category not found or is invalid");
2023
+ }
2024
+ }
2025
+ const now = Date.now();
2026
+ const categoryIdValueForPatch = targetContainerId === UNCATEGORIZED_ID ? null : targetContainerId;
2027
+ const currentCategoryId = currentContent.categoryId;
2028
+ let needsUpdate = true;
2029
+ if (categoryIdValueForPatch === null && currentCategoryId === void 0) {
2030
+ needsUpdate = false;
2031
+ } else if (categoryIdValueForPatch === currentCategoryId) {
2032
+ needsUpdate = false;
2033
+ }
2034
+ let changes = null;
2035
+ if (needsUpdate) {
2036
+ changes = {
2037
+ contents: {
2038
+ // 使用动态键更新指定的 contentKey
2039
+ [contentKey]: {
2040
+ // --- 修改: 使用计算出的 categoryIdValueForPatch ---
2041
+ categoryId: categoryIdValueForPatch,
2042
+ // null 或 目标分类 ID
2043
+ updatedAt: now
2044
+ // 更新内容的 updatedAt
2045
+ }
2046
+ },
2047
+ updatedAt: now
2048
+ // 更新顶层的 updatedAt
2049
+ };
2050
+ } else {
2051
+ console.log(
2052
+ `[updateContentCategoryAction] No category change needed for ${contentKey}. Skipping patch.`
2053
+ );
2054
+ return { spaceId, updatedSpaceData: spaceData };
2055
+ }
2056
+ let updatedSpaceData;
2057
+ try {
2058
+ updatedSpaceData = await dispatch(
2059
+ patch({ dbKey: spaceKey, changes })
2060
+ // 使用非空断言,因为已检查
2061
+ ).unwrap();
2062
+ } catch (patchError) {
2063
+ console.error(
2064
+ `[updateContentCategoryAction] Failed to patch space data for key ${spaceKey}:`,
2065
+ patchError
2066
+ );
2067
+ throw new Error(`\u66F4\u65B0\u5185\u5BB9\u5206\u7C7B\u5931\u8D25: ${patchError.message || "\u672A\u77E5\u9519\u8BEF"}`);
2068
+ }
2069
+ return { spaceId, updatedSpaceData };
2070
+ };
2071
+
2072
+ // packages/create/space/content/deleteMultipleContentAction.ts
2073
+ var logger2 = createClientLogger("delete-multiple-content");
2074
+ var deleteMultipleContentAction = async (input, thunkAPI) => {
2075
+ const { contentKeys, spaceId } = input;
2076
+ if (!contentKeys || contentKeys.length === 0) {
2077
+ logger2.warn("deleteMultipleContentAction called with no contentKeys.");
2078
+ return { spaceId, updatedSpaceData: null };
2079
+ }
2080
+ const { dispatch, getState } = thunkAPI;
2081
+ const state3 = getState();
2082
+ const userId = selectIdentityUserId(state3);
2083
+ logger2.info(
2084
+ { count: contentKeys.length, spaceId, userId },
2085
+ "Initiating deleteMultipleContentAction"
2086
+ );
2087
+ const spaceKey = createSpaceKey.space(spaceId);
2088
+ const spaceData = await dispatch(
2089
+ read({
2090
+ dbKey: spaceKey
2091
+ })
2092
+ ).unwrap();
2093
+ if (!spaceData) {
2094
+ logger2.error({ spaceKey }, "Space data not found for batch delete");
2095
+ throw new Error("\u7A7A\u95F4\u4E0D\u5B58\u5728");
2096
+ }
2097
+ if (!userId || !spaceData.members.includes(userId)) {
2098
+ logger2.warn({ userId, spaceId }, "Unauthorized attempt for batch delete");
2099
+ throw new Error("\u65E0\u6743\u4FEE\u6539\u6B64\u7A7A\u95F4");
2100
+ }
2101
+ const changes = {
2102
+ contents: contentKeys.reduce(
2103
+ (acc, key) => {
2104
+ acc[key] = null;
2105
+ return acc;
2106
+ },
2107
+ {}
2108
+ )
2109
+ };
2110
+ try {
2111
+ await dispatch(patch({ dbKey: spaceKey, changes })).unwrap();
2112
+ logger2.info(
2113
+ { spaceKey, count: contentKeys.length },
2114
+ "Successfully batched patch to remove content references"
2115
+ );
2116
+ } catch (patchError) {
2117
+ logger2.error(
2118
+ { error: patchError, spaceKey },
2119
+ "Failed to batch patch space data. Aborting."
2120
+ );
2121
+ throw new Error(`\u66F4\u65B0\u7A7A\u95F4\u5F15\u7528\u5931\u8D25: ${patchError.message}`);
2122
+ }
2123
+ const removePromises = contentKeys.map(
2124
+ (key) => dispatch(remove(key)).unwrap()
2125
+ );
2126
+ const results = await Promise.allSettled(removePromises);
2127
+ results.forEach((result, index) => {
2128
+ if (result.status === "fulfilled") {
2129
+ logger2.info({ contentKey: contentKeys[index] }, "Entity removed");
2130
+ } else {
2131
+ logger2.error(
2132
+ { contentKey: contentKeys[index], error: result.reason },
2133
+ "Failed to remove an entity"
2134
+ );
2135
+ }
2136
+ });
2137
+ const finalSpaceData = await dispatch(
2138
+ read({
2139
+ dbKey: spaceKey
2140
+ })
2141
+ ).unwrap();
2142
+ logger2.info({ spaceId }, "Finished batch delete and refetched space data.");
2143
+ return {
2144
+ spaceId,
2145
+ updatedSpaceData: finalSpaceData
2146
+ };
2147
+ };
2148
+
2149
+ // packages/create/space/content/uploadAndAddFileToSpaceAction.ts
2150
+ var uploadAndAddFileToSpaceAction = async (payload, thunkAPI) => {
2151
+ const { spaceId, file, categoryId } = payload;
2152
+ const { dispatch, getState } = thunkAPI;
2153
+ const state3 = getState();
2154
+ const userId = selectIdentityUserId(state3);
2155
+ if (!userId) {
2156
+ console.warn("[uploadAndAddFileToSpace] Warning: No userId found in state. Uploading as anonymous/unknown might cause issues.");
2157
+ }
2158
+ try {
2159
+ const id = ulid();
2160
+ const dbKey = fileKey.single(userId || "unknown", id);
2161
+ const contentType = "file" /* FILE */;
2162
+ const fileCategory = resolveFileCategory({
2163
+ mimeType: file.type,
2164
+ fileName: file.name
2165
+ });
2166
+ const fileMetadata = await uploadFileAction(
2167
+ { file, customKey: dbKey, userId },
2168
+ thunkAPI
2169
+ );
2170
+ if (!fileMetadata) {
2171
+ throw new Error("Upload failed, no metadata returned");
2172
+ }
2173
+ const contentKey = fileMetadata.dbKey || dbKey;
2174
+ const title = file.name;
2175
+ const result = await addContentAction({
2176
+ spaceId,
2177
+ contentKey,
2178
+ title,
2179
+ type: contentType,
2180
+ fileCategory,
2181
+ mimeType: file.type || void 0,
2182
+ fileSize: asOptionalFiniteNumber(file.size),
2183
+ originalName: file.name,
2184
+ categoryId
2185
+ }, thunkAPI);
2186
+ await dispatch(
2187
+ patch({
2188
+ dbKey: contentKey,
2189
+ changes: {
2190
+ title,
2191
+ spaceId,
2192
+ fileCategory,
2193
+ mimeType: file.type || void 0,
2194
+ fileSize: asOptionalFiniteNumber(file.size),
2195
+ originalName: file.name
2196
+ }
2197
+ })
2198
+ ).unwrap();
2199
+ if (typeof window !== "undefined") {
2200
+ window.dispatchEvent(new Event("nolo-user-data-updated"));
2201
+ }
2202
+ return { ...result, contentKey, fileId: fileMetadata.id };
2203
+ } catch (error) {
2204
+ console.error("Upload and add file error:", error);
2205
+ throw error;
2206
+ }
2207
+ };
2208
+
2209
+ // packages/create/space/spaceCollapsedState.ts
2210
+ var SPACE_COLLAPSE_STORAGE_PREFIX = "space-collapsed-categories:";
2211
+ var normalizeCollapsedCategories = (value) => {
2212
+ const entries = Object.entries(asRecordOrEmpty(value)).filter(
2213
+ ([key, collapsed]) => typeof key === "string" && typeof collapsed === "boolean"
2214
+ );
2215
+ return Object.fromEntries(entries);
2216
+ };
2217
+ var storageKeyForSpace = (spaceId) => `${SPACE_COLLAPSE_STORAGE_PREFIX}${spaceId}`;
2218
+ var readStoredCollapsedCategories = (spaceId, storage) => {
2219
+ if (!spaceId || !storage) return {};
2220
+ try {
2221
+ const raw = storage.getItem(storageKeyForSpace(spaceId));
2222
+ if (!raw) return { [UNCATEGORIZED_ID]: false };
2223
+ return normalizeCollapsedCategories(JSON.parse(raw));
2224
+ } catch (error) {
2225
+ console.warn("[Space] \u8BFB\u53D6\u5206\u7C7B\u6298\u53E0\u72B6\u6001\u5931\u8D25:", error);
2226
+ return {};
2227
+ }
2228
+ };
2229
+ var writeStoredCollapsedCategories = (spaceId, collapsedCategories, storage) => {
2230
+ if (!spaceId || !storage) return;
2231
+ try {
2232
+ storage.setItem(
2233
+ storageKeyForSpace(spaceId),
2234
+ JSON.stringify(normalizeCollapsedCategories(collapsedCategories))
2235
+ );
2236
+ } catch (error) {
2237
+ console.warn("[Space] \u4FDD\u5B58\u5206\u7C7B\u6298\u53E0\u72B6\u6001\u5931\u8D25:", error);
2238
+ }
2239
+ };
2240
+
2241
+ // packages/create/space/spaceUiStore.ts
2242
+ var import_react2 = __toESM(require_react(), 1);
2243
+ var DEFAULT_COLLAPSED_CATEGORIES = {
2244
+ [UNCATEGORIZED_ID]: false
2245
+ };
2246
+ var FAVORITES_COLLAPSED_STORAGE_KEY = "nolo-sidebar-favorites-collapsed";
2247
+ var readStoredFavoritesCollapsed = () => {
2248
+ try {
2249
+ if (typeof window === "undefined") return false;
2250
+ return window.localStorage.getItem(FAVORITES_COLLAPSED_STORAGE_KEY) === "1";
2251
+ } catch {
2252
+ return false;
2253
+ }
2254
+ };
2255
+ var createInitialState2 = () => ({
2256
+ favoritesCollapsed: readStoredFavoritesCollapsed(),
2257
+ collapsedCategories: {},
2258
+ collapsedCategoriesSpaceId: null
2259
+ });
2260
+ var state2 = createInitialState2();
2261
+ var listeners2 = /* @__PURE__ */ new Set();
2262
+ var version2 = 0;
2263
+ var notify2 = () => {
2264
+ version2 += 1;
2265
+ for (const listener of listeners2) {
2266
+ try {
2267
+ listener();
2268
+ } catch {
2269
+ }
2270
+ }
2271
+ };
2272
+ function getCollapsedCategories() {
2273
+ return state2.collapsedCategories;
2274
+ }
2275
+ function setCollapsedCategories(categories, spaceId) {
2276
+ state2 = {
2277
+ ...state2,
2278
+ collapsedCategories: categories,
2279
+ collapsedCategoriesSpaceId: spaceId
2280
+ };
2281
+ notify2();
2282
+ }
2283
+ function toggleCategoryCollapse(categoryId) {
2284
+ const current = state2.collapsedCategories[categoryId] ?? (DEFAULT_COLLAPSED_CATEGORIES[categoryId] ?? true);
2285
+ state2 = {
2286
+ ...state2,
2287
+ collapsedCategories: {
2288
+ ...state2.collapsedCategories,
2289
+ [categoryId]: !current
2290
+ }
2291
+ };
2292
+ notify2();
2293
+ }
2294
+ function expandCategoryInCollapsed(categoryId, spaceId) {
2295
+ if (!categoryId || categoryId === UNCATEGORIZED_ID) return;
2296
+ state2 = {
2297
+ ...state2,
2298
+ collapsedCategories: {
2299
+ ...state2.collapsedCategories,
2300
+ [categoryId]: false
2301
+ }
2302
+ };
2303
+ if (typeof window !== "undefined") {
2304
+ writeStoredCollapsedCategories(
2305
+ spaceId,
2306
+ state2.collapsedCategories,
2307
+ window.localStorage
2308
+ );
2309
+ }
2310
+ notify2();
2311
+ }
2312
+
2313
+ // packages/create/space/content/contentThunks.ts
2314
+ var syncCurrentSpaceIfNormalizedMatch = (spaceId, updatedSpaceData) => {
2315
+ const normalizedSpaceId = normalizeSpaceId(spaceId);
2316
+ const rawSpaceId = getCurrentSpaceIdRaw();
2317
+ const normalizedCurrentSpaceId = rawSpaceId ? normalizeSpaceId(rawSpaceId) : null;
2318
+ if (normalizedCurrentSpaceId === normalizedSpaceId && updatedSpaceData) {
2319
+ updateCurrentSpaceIfMatch(spaceId, updatedSpaceData);
2320
+ }
2321
+ };
2322
+ var addContentToSpace = createAsyncThunk(
2323
+ "space/addContentToSpace",
2324
+ async (input, thunkAPI) => {
2325
+ const result = await addContentAction(input, thunkAPI);
2326
+ const rawCategoryId = asTrimmedString(input.categoryId);
2327
+ const expandCategoryId = rawCategoryId && rawCategoryId !== UNCATEGORIZED_ID ? rawCategoryId : null;
2328
+ if (expandCategoryId) {
2329
+ const collapsedCategories = {
2330
+ ...getCollapsedCategories(),
2331
+ [expandCategoryId]: false
2332
+ };
2333
+ if (typeof window !== "undefined") {
2334
+ writeStoredCollapsedCategories(
2335
+ result.spaceId,
2336
+ collapsedCategories,
2337
+ window.localStorage
2338
+ );
2339
+ }
2340
+ expandCategoryInCollapsed(expandCategoryId, result.spaceId);
2341
+ syncCurrentSpaceIfNormalizedMatch(
2342
+ result.spaceId,
2343
+ result.updatedSpaceData
2344
+ );
2345
+ return { ...result, expandCategoryId, collapsedCategories };
2346
+ }
2347
+ syncCurrentSpaceIfNormalizedMatch(result.spaceId, result.updatedSpaceData);
2348
+ return { ...result, expandCategoryId: null };
2349
+ }
2350
+ );
2351
+ var moveContentToSpace = createAsyncThunk(
2352
+ "space/moveContentToSpace",
2353
+ async (arg, thunkAPI) => {
2354
+ const payload = await moveContentAction(arg, thunkAPI);
2355
+ const {
2356
+ sourceSpaceId,
2357
+ updatedSourceSpaceData,
2358
+ targetSpaceId,
2359
+ updatedTargetSpaceData
2360
+ } = payload;
2361
+ if (getCurrentSpaceIdRaw() === sourceSpaceId && updatedSourceSpaceData) {
2362
+ updateCurrentSpaceIfMatch(sourceSpaceId, updatedSourceSpaceData);
2363
+ }
2364
+ if (getCurrentSpaceIdRaw() === targetSpaceId && updatedTargetSpaceData) {
2365
+ updateCurrentSpaceIfMatch(targetSpaceId, updatedTargetSpaceData);
2366
+ }
2367
+ return payload;
2368
+ }
2369
+ );
2370
+ var deleteContentFromSpace = createAsyncThunk(
2371
+ "space/deleteContentFromSpace",
2372
+ async (arg, thunkAPI) => {
2373
+ const payload = await deleteContentFromSpaceAction(arg, thunkAPI);
2374
+ syncCurrentSpaceIfNormalizedMatch(
2375
+ payload.spaceId,
2376
+ payload.updatedSpaceData
2377
+ );
2378
+ return payload;
2379
+ }
2380
+ );
2381
+ var deleteMultipleContent = createAsyncThunk(
2382
+ "space/deleteMultipleContent",
2383
+ async (arg, thunkAPI) => {
2384
+ const payload = await deleteMultipleContentAction(arg, thunkAPI);
2385
+ syncCurrentSpaceIfNormalizedMatch(
2386
+ payload.spaceId,
2387
+ payload.updatedSpaceData
2388
+ );
2389
+ return payload;
2390
+ }
2391
+ );
2392
+ var uploadAndAddFileToSpace = createAsyncThunk(
2393
+ "space/uploadAndAddFileToSpace",
2394
+ async (arg, thunkAPI) => {
2395
+ const payload = await uploadAndAddFileToSpaceAction(arg, thunkAPI);
2396
+ if (getCurrentSpaceIdRaw() === payload.spaceId) {
2397
+ updateCurrentSpaceIfMatch(payload.spaceId, payload.updatedSpaceData);
2398
+ }
2399
+ return payload;
2400
+ }
2401
+ );
2402
+ var updateContentTitle = createAsyncThunk(
2403
+ "space/updateContentTitle",
2404
+ async (arg, thunkAPI) => {
2405
+ try {
2406
+ const payload = await updateContentTitleAction(arg, thunkAPI);
2407
+ if (getCurrentSpaceIdRaw() === payload.spaceId) {
2408
+ updateCurrentSpaceIfMatch(payload.spaceId, payload.updatedSpaceData);
2409
+ }
2410
+ return payload;
2411
+ } catch (error) {
2412
+ const message = error?.message || "\u6807\u9898\u4FDD\u5B58\u5931\u8D25";
2413
+ if (!message.includes("\u65E0\u6CD5\u52A0\u8F7D\u7A7A\u95F4\u6570\u636E")) {
2414
+ toast.error(message);
2415
+ }
2416
+ throw error;
2417
+ }
2418
+ }
2419
+ );
2420
+ var updateContentPinned = createAsyncThunk(
2421
+ "space/updateContentPinned",
2422
+ async (arg, thunkAPI) => {
2423
+ try {
2424
+ const payload = await updateContentPinnedAction(arg, thunkAPI);
2425
+ if (payload.updatedSpaceData && payload.spaceId && getCurrentSpaceIdRaw() === payload.spaceId) {
2426
+ updateCurrentSpaceIfMatch(payload.spaceId, payload.updatedSpaceData);
2427
+ }
2428
+ return payload;
2429
+ } catch (error) {
2430
+ toast.error(
2431
+ error?.message || "\u7F6E\u9876\u72B6\u6001\u66F4\u65B0\u5931\u8D25"
2432
+ );
2433
+ throw error;
2434
+ }
2435
+ }
2436
+ );
2437
+ var updateContentCategory = createAsyncThunk(
2438
+ "space/updateContentCategory",
2439
+ async (arg, thunkAPI) => {
2440
+ const payload = await updateContentCategoryAction(arg, thunkAPI);
2441
+ if (getCurrentSpaceIdRaw() === payload.spaceId) {
2442
+ updateCurrentSpaceIfMatch(payload.spaceId, payload.updatedSpaceData);
2443
+ }
2444
+ return payload;
2445
+ }
2446
+ );
2447
+
2448
+ export {
2449
+ fetchAndCacheTableRows,
2450
+ client_default,
2451
+ getTableState,
2452
+ loadTableRows,
2453
+ addRow,
2454
+ createTable,
2455
+ deleteTable,
2456
+ readStoredCollapsedCategories,
2457
+ writeStoredCollapsedCategories,
2458
+ DEFAULT_COLLAPSED_CATEGORIES,
2459
+ getCollapsedCategories,
2460
+ setCollapsedCategories,
2461
+ toggleCategoryCollapse,
2462
+ expandCategoryInCollapsed,
2463
+ addContentToSpace,
2464
+ moveContentToSpace,
2465
+ deleteContentFromSpace,
2466
+ deleteMultipleContent,
2467
+ uploadAndAddFileToSpace,
2468
+ updateContentTitle,
2469
+ updateContentPinned,
2470
+ updateContentCategory
2471
+ };