@ai-matrx/media 0.8.0 → 0.9.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 (185) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/files/engine/api/assets.d.ts +223 -0
  3. package/dist/files/engine/api/assets.js +124 -0
  4. package/dist/files/engine/api/assets.js.map +1 -0
  5. package/dist/files/engine/api/direct.d.ts +43 -0
  6. package/dist/files/engine/api/direct.js +73 -0
  7. package/dist/files/engine/api/direct.js.map +1 -0
  8. package/dist/files/engine/api/fileOrganization.d.ts +34 -0
  9. package/dist/files/engine/api/fileOrganization.js +38 -0
  10. package/dist/files/engine/api/fileOrganization.js.map +1 -0
  11. package/dist/files/engine/api/files.d.ts +249 -0
  12. package/dist/files/engine/api/files.js +231 -0
  13. package/dist/files/engine/api/files.js.map +1 -0
  14. package/dist/files/engine/api/folders.d.ts +63 -0
  15. package/dist/files/engine/api/folders.js +56 -0
  16. package/dist/files/engine/api/folders.js.map +1 -0
  17. package/dist/files/engine/api/office.d.ts +27 -0
  18. package/dist/files/engine/api/office.js +19 -0
  19. package/dist/files/engine/api/office.js.map +1 -0
  20. package/dist/files/engine/api/permissions.d.ts +37 -0
  21. package/dist/files/engine/api/permissions.js +109 -0
  22. package/dist/files/engine/api/permissions.js.map +1 -0
  23. package/dist/files/engine/api/versions.d.ts +26 -0
  24. package/dist/files/engine/api/versions.js +37 -0
  25. package/dist/files/engine/api/versions.js.map +1 -0
  26. package/dist/files/engine/cache/idb-store.d.ts +95 -0
  27. package/dist/files/engine/cache/idb-store.js +172 -0
  28. package/dist/files/engine/cache/idb-store.js.map +1 -0
  29. package/dist/files/engine/cache/policy.d.ts +14 -0
  30. package/dist/files/engine/cache/policy.js +40 -0
  31. package/dist/files/engine/cache/policy.js.map +1 -0
  32. package/dist/files/engine/cache/register-service-worker.d.ts +57 -0
  33. package/dist/files/engine/cache/register-service-worker.js +80 -0
  34. package/dist/files/engine/cache/register-service-worker.js.map +1 -0
  35. package/dist/files/engine/db-types.d.ts +48865 -0
  36. package/dist/files/engine/db-types.js +1 -0
  37. package/dist/files/engine/db-types.js.map +1 -0
  38. package/dist/files/engine/filesDb.d.ts +1913 -0
  39. package/dist/files/engine/filesDb.js +28 -0
  40. package/dist/files/engine/filesDb.js.map +1 -0
  41. package/dist/files/engine/handler/handler.d.ts +82 -0
  42. package/dist/files/engine/handler/handler.js +124 -0
  43. package/dist/files/engine/handler/handler.js.map +1 -0
  44. package/dist/files/engine/handler/hooks/useFile.d.ts +17 -0
  45. package/dist/files/engine/handler/hooks/useFile.js +75 -0
  46. package/dist/files/engine/handler/hooks/useFile.js.map +1 -0
  47. package/dist/files/engine/handler/hooks/useFileUpload.d.ts +76 -0
  48. package/dist/files/engine/handler/hooks/useFileUpload.js +67 -0
  49. package/dist/files/engine/handler/hooks/useFileUpload.js.map +1 -0
  50. package/dist/files/engine/handler/input/normalize.d.ts +14 -0
  51. package/dist/files/engine/handler/input/normalize.js +365 -0
  52. package/dist/files/engine/handler/input/normalize.js.map +1 -0
  53. package/dist/files/engine/handler/intelligence/access.d.ts +35 -0
  54. package/dist/files/engine/handler/intelligence/access.js +85 -0
  55. package/dist/files/engine/handler/intelligence/access.js.map +1 -0
  56. package/dist/files/engine/handler/intelligence/magic-bytes.d.ts +21 -0
  57. package/dist/files/engine/handler/intelligence/magic-bytes.js +67 -0
  58. package/dist/files/engine/handler/intelligence/magic-bytes.js.map +1 -0
  59. package/dist/files/engine/handler/output/target.d.ts +19 -0
  60. package/dist/files/engine/handler/output/target.js +222 -0
  61. package/dist/files/engine/handler/output/target.js.map +1 -0
  62. package/dist/files/engine/handler/resolver.d.ts +34 -0
  63. package/dist/files/engine/handler/resolver.js +133 -0
  64. package/dist/files/engine/handler/resolver.js.map +1 -0
  65. package/dist/files/engine/handler/types.d.ts +367 -0
  66. package/dist/files/engine/handler/types.js +1 -0
  67. package/dist/files/engine/handler/types.js.map +1 -0
  68. package/dist/files/engine/handler/upload.d.ts +32 -0
  69. package/dist/files/engine/handler/upload.js +295 -0
  70. package/dist/files/engine/handler/upload.js.map +1 -0
  71. package/dist/files/engine/handler/utils/classify.d.ts +14 -0
  72. package/dist/files/engine/handler/utils/classify.js +27 -0
  73. package/dist/files/engine/handler/utils/classify.js.map +1 -0
  74. package/dist/files/engine/handler/utils/prefer-locator.d.ts +32 -0
  75. package/dist/files/engine/handler/utils/prefer-locator.js +34 -0
  76. package/dist/files/engine/handler/utils/prefer-locator.js.map +1 -0
  77. package/dist/files/engine/handler/utils/python-base.d.ts +129 -0
  78. package/dist/files/engine/handler/utils/python-base.js +60 -0
  79. package/dist/files/engine/handler/utils/python-base.js.map +1 -0
  80. package/dist/files/engine/hooks/blob-cache.d.ts +130 -0
  81. package/dist/files/engine/hooks/blob-cache.js +162 -0
  82. package/dist/files/engine/hooks/blob-cache.js.map +1 -0
  83. package/dist/files/engine/hooks/office-extraction-cache.d.ts +28 -0
  84. package/dist/files/engine/hooks/office-extraction-cache.js +67 -0
  85. package/dist/files/engine/hooks/office-extraction-cache.js.map +1 -0
  86. package/dist/files/engine/host/configure.d.ts +166 -0
  87. package/dist/files/engine/host/configure.js +30 -0
  88. package/dist/files/engine/host/configure.js.map +1 -0
  89. package/dist/files/engine/host/org.d.ts +8 -0
  90. package/dist/files/engine/host/org.js +16 -0
  91. package/dist/files/engine/host/org.js.map +1 -0
  92. package/dist/files/engine/host/python-client.d.ts +60 -0
  93. package/dist/files/engine/host/python-client.js +46 -0
  94. package/dist/files/engine/host/python-client.js.map +1 -0
  95. package/dist/files/engine/host/share-links.d.ts +20 -0
  96. package/dist/files/engine/host/share-links.js +32 -0
  97. package/dist/files/engine/host/share-links.js.map +1 -0
  98. package/dist/files/engine/host/store.d.ts +24 -0
  99. package/dist/files/engine/host/store.js +23 -0
  100. package/dist/files/engine/host/store.js.map +1 -0
  101. package/dist/files/engine/host/supabase.d.ts +3808 -0
  102. package/dist/files/engine/host/supabase.js +33 -0
  103. package/dist/files/engine/host/supabase.js.map +1 -0
  104. package/dist/files/engine/host/toast.d.ts +14 -0
  105. package/dist/files/engine/host/toast.js +20 -0
  106. package/dist/files/engine/host/toast.js.map +1 -0
  107. package/dist/files/engine/host/typed-client.d.ts +136 -0
  108. package/dist/files/engine/host/typed-client.js +66 -0
  109. package/dist/files/engine/host/typed-client.js.map +1 -0
  110. package/dist/files/engine/index.d.ts +22 -0
  111. package/dist/files/engine/index.js +49 -0
  112. package/dist/files/engine/index.js.map +1 -0
  113. package/dist/files/engine/media/our-file-sources.d.ts +39 -0
  114. package/dist/files/engine/media/our-file-sources.js +83 -0
  115. package/dist/files/engine/media/our-file-sources.js.map +1 -0
  116. package/dist/files/engine/media/signed-url.d.ts +1 -0
  117. package/dist/files/engine/media/signed-url.js +6 -0
  118. package/dist/files/engine/media/signed-url.js.map +1 -0
  119. package/dist/files/engine/redux/converters.d.ts +73 -0
  120. package/dist/files/engine/redux/converters.js +286 -0
  121. package/dist/files/engine/redux/converters.js.map +1 -0
  122. package/dist/files/engine/redux/file-hydration.d.ts +15 -0
  123. package/dist/files/engine/redux/file-hydration.js +46 -0
  124. package/dist/files/engine/redux/file-hydration.js.map +1 -0
  125. package/dist/files/engine/redux/file-tree-auth-boundary.d.ts +5 -0
  126. package/dist/files/engine/redux/file-tree-auth-boundary.js +28 -0
  127. package/dist/files/engine/redux/file-tree-auth-boundary.js.map +1 -0
  128. package/dist/files/engine/redux/file-tree-timeout.d.ts +32 -0
  129. package/dist/files/engine/redux/file-tree-timeout.js +73 -0
  130. package/dist/files/engine/redux/file-tree-timeout.js.map +1 -0
  131. package/dist/files/engine/redux/mutation-toast-middleware.d.ts +27 -0
  132. package/dist/files/engine/redux/mutation-toast-middleware.js +103 -0
  133. package/dist/files/engine/redux/mutation-toast-middleware.js.map +1 -0
  134. package/dist/files/engine/redux/realtime-middleware.d.ts +61 -0
  135. package/dist/files/engine/redux/realtime-middleware.js +431 -0
  136. package/dist/files/engine/redux/realtime-middleware.js.map +1 -0
  137. package/dist/files/engine/redux/request-ledger.d.ts +68 -0
  138. package/dist/files/engine/redux/request-ledger.js +66 -0
  139. package/dist/files/engine/redux/request-ledger.js.map +1 -0
  140. package/dist/files/engine/redux/selectors.d.ts +3254 -0
  141. package/dist/files/engine/redux/selectors.js +428 -0
  142. package/dist/files/engine/redux/selectors.js.map +1 -0
  143. package/dist/files/engine/redux/slice.d.ts +157 -0
  144. package/dist/files/engine/redux/slice.js +836 -0
  145. package/dist/files/engine/redux/slice.js.map +1 -0
  146. package/dist/files/engine/redux/thunks.d.ts +449 -0
  147. package/dist/files/engine/redux/thunks.js +1684 -0
  148. package/dist/files/engine/redux/thunks.js.map +1 -0
  149. package/dist/files/engine/redux/tree-utils.d.ts +90 -0
  150. package/dist/files/engine/redux/tree-utils.js +200 -0
  151. package/dist/files/engine/redux/tree-utils.js.map +1 -0
  152. package/dist/files/engine/support/claimsUser.d.ts +77 -0
  153. package/dist/files/engine/support/claimsUser.js +48 -0
  154. package/dist/files/engine/support/claimsUser.js.map +1 -0
  155. package/dist/files/engine/support/datetime.d.ts +6 -0
  156. package/dist/files/engine/support/datetime.js +15 -0
  157. package/dist/files/engine/support/datetime.js.map +1 -0
  158. package/dist/files/engine/support/document-visibility.d.ts +14 -0
  159. package/dist/files/engine/support/document-visibility.js +28 -0
  160. package/dist/files/engine/support/document-visibility.js.map +1 -0
  161. package/dist/files/engine/support/logger.d.ts +28 -0
  162. package/dist/files/engine/support/logger.js +36 -0
  163. package/dist/files/engine/support/logger.js.map +1 -0
  164. package/dist/files/engine/types.d.ts +1081 -0
  165. package/dist/files/engine/types.js +30 -0
  166. package/dist/files/engine/types.js.map +1 -0
  167. package/dist/files/engine/upload/cloudUpload.d.ts +182 -0
  168. package/dist/files/engine/upload/cloudUpload.js +418 -0
  169. package/dist/files/engine/upload/cloudUpload.js.map +1 -0
  170. package/dist/files/engine/upload/tusUpload.d.ts +100 -0
  171. package/dist/files/engine/upload/tusUpload.js +258 -0
  172. package/dist/files/engine/upload/tusUpload.js.map +1 -0
  173. package/dist/files/engine/upload/uploadDedupGuard.d.ts +58 -0
  174. package/dist/files/engine/upload/uploadDedupGuard.js +41 -0
  175. package/dist/files/engine/upload/uploadDedupGuard.js.map +1 -0
  176. package/dist/files/engine/upload/uploadGuardOpeners.d.ts +70 -0
  177. package/dist/files/engine/upload/uploadGuardOpeners.js +54 -0
  178. package/dist/files/engine/upload/uploadGuardOpeners.js.map +1 -0
  179. package/dist/files/engine/utils/file-types.d.ts +243 -0
  180. package/dist/files/engine/utils/file-types.js +1722 -0
  181. package/dist/files/engine/utils/file-types.js.map +1 -0
  182. package/dist/files/engine/utils/user-visible.d.ts +133 -0
  183. package/dist/files/engine/utils/user-visible.js +115 -0
  184. package/dist/files/engine/utils/user-visible.js.map +1 -0
  185. package/package.json +393 -9
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/files/engine/redux/slice.ts"],"sourcesContent":["/**\n * features/files/redux/slice.ts\n *\n * Normalized cloud-files slice. Pattern: copied from\n * features/agents/redux/agent-shortcuts/slice.ts — dirty-tracking via\n * FieldFlags, optimistic + rollback via _fieldHistory, RTK reducers only\n * (async logic lives in thunks.ts).\n */\n\nimport { createSlice, type PayloadAction } from \"@reduxjs/toolkit\";\nimport {\n addField,\n assignField,\n createFieldFlags,\n hasField,\n removeField,\n} from \"@ai-matrx/agents/field-flags\";\nimport type {\n CloudFile,\n CloudFileFieldSnapshot,\n CloudFilePermission,\n CloudFileRecord,\n CloudFilesState,\n CloudFileVersion,\n CloudFolder,\n CloudFolderFieldSnapshot,\n CloudFolderRecord,\n CloudShareLink,\n AccessFilter,\n ChipFilter,\n ColumnFilters,\n ColumnId,\n DetailsLevel,\n KindFilter,\n ModifiedFilter,\n OwnerFilter,\n RagFilter,\n RagStatus,\n SelectionState,\n SizeFilter,\n SortBy,\n SortDirection,\n TreeChildren,\n TypeFilter,\n UiState,\n UploadState,\n UploadStatus,\n ViewMode,\n Visibility,\n VisibleColumns,\n} from \"../types\";\nimport { DEFAULT_VISIBLE_COLUMNS } from \"../types\";\n\n// ---------------------------------------------------------------------------\n// Record factories\n// ---------------------------------------------------------------------------\n\nfunction emptyFileRecord(id: string): CloudFileRecord {\n return {\n id,\n ownerId: \"\",\n filePath: \"\",\n fileName: \"\",\n mimeType: null,\n fileSize: null,\n checksum: null,\n visibility: \"personal\",\n currentVersion: 1,\n parentFolderId: null,\n metadata: {},\n createdAt: \"\",\n updatedAt: \"\",\n deletedAt: null,\n publicUrl: null,\n url: null,\n cdnUrl: null,\n downloadUrl: null,\n thumbnailUrl: null,\n source: { kind: \"real\" },\n\n _dirty: false,\n _dirtyFields: createFieldFlags<keyof CloudFile>(),\n _fieldHistory: {},\n _loadedFields: createFieldFlags<keyof CloudFile>(),\n _loading: false,\n _error: null,\n _pendingRequestIds: [],\n };\n}\n\nfunction emptyFolderRecord(id: string): CloudFolderRecord {\n return {\n id,\n ownerId: \"\",\n folderPath: \"\",\n folderName: \"\",\n parentId: null,\n visibility: \"personal\",\n metadata: {},\n createdAt: \"\",\n updatedAt: \"\",\n deletedAt: null,\n source: { kind: \"real\" },\n\n _dirty: false,\n _dirtyFields: createFieldFlags<keyof CloudFolder>(),\n _fieldHistory: {},\n _loadedFields: createFieldFlags<keyof CloudFolder>(),\n _loading: false,\n _error: null,\n _pendingRequestIds: [],\n };\n}\n\n// ---------------------------------------------------------------------------\n// Merge helpers — apply a fetched partial onto a record without touching\n// runtime flags, and track which fields have been loaded.\n// ---------------------------------------------------------------------------\n\nfunction mergeFileIntoRecord(\n record: CloudFileRecord,\n partial: Partial<CloudFile>,\n): void {\n (Object.keys(partial) as (keyof CloudFile)[]).forEach((key) => {\n const value = partial[key];\n if (value !== undefined) {\n assignField(record, key, value);\n addField(record._loadedFields, key);\n }\n });\n}\n\nfunction mergeFolderIntoRecord(\n record: CloudFolderRecord,\n partial: Partial<CloudFolder>,\n): void {\n (Object.keys(partial) as (keyof CloudFolder)[]).forEach((key) => {\n const value = partial[key];\n if (value !== undefined) {\n assignField(record, key, value);\n addField(record._loadedFields, key);\n }\n });\n}\n\nfunction applyFileFieldEdit<K extends keyof CloudFile>(\n record: CloudFileRecord,\n field: K,\n value: CloudFile[K],\n): void {\n if (!hasField(record._dirtyFields, field)) {\n // Only snapshot if this field is tracked in the snapshot shape.\n if (\n field === \"fileName\" ||\n field === \"filePath\" ||\n field === \"visibility\" ||\n field === \"parentFolderId\" ||\n field === \"metadata\" ||\n field === \"deletedAt\"\n ) {\n (record._fieldHistory as CloudFileFieldSnapshot)[\n field as keyof CloudFileFieldSnapshot\n ] = record[field as keyof CloudFileFieldSnapshot] as never;\n }\n }\n assignField(record, field, value);\n addField(record._dirtyFields, field);\n record._dirty = true;\n}\n\nfunction applyFolderFieldEdit<K extends keyof CloudFolder>(\n record: CloudFolderRecord,\n field: K,\n value: CloudFolder[K],\n): void {\n if (!hasField(record._dirtyFields, field)) {\n if (\n field === \"folderName\" ||\n field === \"folderPath\" ||\n field === \"parentId\" ||\n field === \"visibility\" ||\n field === \"metadata\"\n ) {\n (record._fieldHistory as CloudFolderFieldSnapshot)[\n field as keyof CloudFolderFieldSnapshot\n ] = record[field as keyof CloudFolderFieldSnapshot] as never;\n }\n }\n assignField(record, field, value);\n addField(record._dirtyFields, field);\n record._dirty = true;\n}\n\nfunction markFileClean(record: CloudFileRecord): void {\n record._dirty = false;\n record._dirtyFields = createFieldFlags<keyof CloudFile>();\n record._fieldHistory = {};\n record._error = null;\n}\n\nfunction markFolderClean(record: CloudFolderRecord): void {\n record._dirty = false;\n record._dirtyFields = createFieldFlags<keyof CloudFolder>();\n record._fieldHistory = {};\n record._error = null;\n}\n\n// ---------------------------------------------------------------------------\n// Initial state\n// ---------------------------------------------------------------------------\n\nconst initialState: CloudFilesState = {\n filesById: {},\n foldersById: {},\n versionsByFileId: {},\n permissionsByResourceId: {},\n shareLinksByResourceId: {},\n\n tree: {\n rootFolderIds: [],\n rootFileIds: [],\n childrenByFolderId: {},\n fullyLoadedFolderIds: {},\n status: \"idle\",\n error: null,\n lastReconciledAt: null,\n },\n selection: {\n selectedIds: [],\n anchorId: null,\n },\n ui: {\n viewMode: \"list\",\n // Files lists always open most-recently-updated first. Folders still\n // group above files (see `compareNodes`); within each group the newest\n // edit floats to the top.\n sortBy: \"updated_at\",\n sortDir: \"desc\",\n kindFilter: \"all\",\n detailsLevel: \"compact\",\n columnFilters: {\n name: \"\",\n type: [],\n extension: \"\",\n mime: \"\",\n path: \"\",\n owner: [],\n modified: \"any\",\n created: \"any\",\n size: \"any\",\n access: \"any\",\n rag: [],\n },\n visibleColumns: { ...DEFAULT_VISIBLE_COLUMNS },\n searchQuery: \"\",\n chipFilter: null,\n activeFileId: null,\n activeFolderId: null,\n focusedId: null,\n },\n uploads: {},\n ragStatus: {\n byFileId: {},\n isFetching: false,\n lastFetchedAt: null,\n },\n realtime: {\n status: \"detached\",\n userId: null,\n lastEventAt: null,\n error: null,\n },\n};\n\n// ---------------------------------------------------------------------------\n// Slice\n// ---------------------------------------------------------------------------\n\nconst slice = createSlice({\n name: \"cloudFiles\",\n initialState,\n reducers: {\n // ---- Files: upsert / merge ---------------------------------------------\n upsertFiles(state, action: PayloadAction<Partial<CloudFile>[]>) {\n for (const partial of action.payload) {\n if (!partial.id) continue;\n const existing =\n state.filesById[partial.id] ?? emptyFileRecord(partial.id);\n mergeFileIntoRecord(existing, partial);\n state.filesById[partial.id] = existing;\n }\n },\n\n upsertFile(state, action: PayloadAction<Partial<CloudFile>>) {\n const partial = action.payload;\n if (!partial.id) return;\n const existing =\n state.filesById[partial.id] ?? emptyFileRecord(partial.id);\n mergeFileIntoRecord(existing, partial);\n state.filesById[partial.id] = existing;\n },\n\n // ---- Files: field edits (optimistic) -----------------------------------\n setFileField(\n state,\n action: PayloadAction<{\n id: string;\n field: keyof CloudFile;\n value: CloudFile[keyof CloudFile];\n }>,\n ) {\n const { id, field, value } = action.payload;\n const record = state.filesById[id];\n if (!record) return;\n applyFileFieldEdit(record, field, value);\n },\n\n resetFileField(\n state,\n action: PayloadAction<{ id: string; field: keyof CloudFile }>,\n ) {\n const { id, field } = action.payload;\n const record = state.filesById[id];\n if (!record) return;\n const snapKey = field as keyof CloudFileFieldSnapshot;\n const snapshotValue = record._fieldHistory[snapKey];\n if (snapKey in record._fieldHistory && snapshotValue !== undefined) {\n assignField(record, snapKey, snapshotValue);\n delete record._fieldHistory[snapKey];\n removeField(record._dirtyFields, field);\n }\n if (Object.keys(record._dirtyFields).length === 0) {\n record._dirty = false;\n }\n },\n\n markFileSaved(state, action: PayloadAction<{ id: string }>) {\n const record = state.filesById[action.payload.id];\n if (!record) return;\n markFileClean(record);\n },\n\n rollbackFileOptimisticUpdate(\n state,\n action: PayloadAction<{\n id: string;\n snapshot: CloudFileFieldSnapshot;\n }>,\n ) {\n const { id, snapshot } = action.payload;\n const record = state.filesById[id];\n if (!record) return;\n Object.assign(record, snapshot);\n record._dirty = false;\n record._dirtyFields = createFieldFlags<keyof CloudFile>();\n record._fieldHistory = {};\n },\n\n // ---- Files: remove / pending requests ----------------------------------\n removeFile(state, action: PayloadAction<{ id: string }>) {\n const { id } = action.payload;\n delete state.filesById[id];\n delete state.versionsByFileId[id];\n // Unlink from tree if present.\n for (const parentId of Object.keys(state.tree.childrenByFolderId)) {\n const bucket = state.tree.childrenByFolderId[parentId];\n const idx = bucket.fileIds.indexOf(id);\n if (idx >= 0) bucket.fileIds.splice(idx, 1);\n }\n const rootIdx = state.tree.rootFileIds.indexOf(id);\n if (rootIdx >= 0) state.tree.rootFileIds.splice(rootIdx, 1);\n },\n\n addFilePendingRequest(\n state,\n action: PayloadAction<{ id: string; requestId: string }>,\n ) {\n const { id, requestId } = action.payload;\n const record = state.filesById[id];\n if (!record) return;\n if (!record._pendingRequestIds.includes(requestId)) {\n record._pendingRequestIds.push(requestId);\n }\n },\n\n removeFilePendingRequest(\n state,\n action: PayloadAction<{ id: string; requestId: string }>,\n ) {\n const { id, requestId } = action.payload;\n const record = state.filesById[id];\n if (!record) return;\n const idx = record._pendingRequestIds.indexOf(requestId);\n if (idx >= 0) record._pendingRequestIds.splice(idx, 1);\n },\n\n setFileLoading(\n state,\n action: PayloadAction<{ id: string; loading: boolean }>,\n ) {\n const record = state.filesById[action.payload.id];\n if (!record) return;\n record._loading = action.payload.loading;\n },\n\n setFileError(\n state,\n action: PayloadAction<{ id: string; error: string | null }>,\n ) {\n const record = state.filesById[action.payload.id];\n if (!record) return;\n record._error = action.payload.error;\n },\n\n // ---- Folders: mirror of file reducers ----------------------------------\n upsertFolders(state, action: PayloadAction<Partial<CloudFolder>[]>) {\n for (const partial of action.payload) {\n if (!partial.id) continue;\n const existing =\n state.foldersById[partial.id] ?? emptyFolderRecord(partial.id);\n mergeFolderIntoRecord(existing, partial);\n state.foldersById[partial.id] = existing;\n }\n },\n\n upsertFolder(state, action: PayloadAction<Partial<CloudFolder>>) {\n const partial = action.payload;\n if (!partial.id) return;\n const existing =\n state.foldersById[partial.id] ?? emptyFolderRecord(partial.id);\n mergeFolderIntoRecord(existing, partial);\n state.foldersById[partial.id] = existing;\n },\n\n setFolderField(\n state,\n action: PayloadAction<{\n id: string;\n field: keyof CloudFolder;\n value: CloudFolder[keyof CloudFolder];\n }>,\n ) {\n const { id, field, value } = action.payload;\n const record = state.foldersById[id];\n if (!record) return;\n applyFolderFieldEdit(record, field, value);\n },\n\n markFolderSaved(state, action: PayloadAction<{ id: string }>) {\n const record = state.foldersById[action.payload.id];\n if (!record) return;\n markFolderClean(record);\n },\n\n rollbackFolderOptimisticUpdate(\n state,\n action: PayloadAction<{\n id: string;\n snapshot: CloudFolderFieldSnapshot;\n }>,\n ) {\n const { id, snapshot } = action.payload;\n const record = state.foldersById[id];\n if (!record) return;\n Object.assign(record, snapshot);\n record._dirty = false;\n record._dirtyFields = createFieldFlags<keyof CloudFolder>();\n record._fieldHistory = {};\n },\n\n removeFolder(state, action: PayloadAction<{ id: string }>) {\n const { id } = action.payload;\n delete state.foldersById[id];\n delete state.tree.childrenByFolderId[id];\n for (const parentId of Object.keys(state.tree.childrenByFolderId)) {\n const bucket = state.tree.childrenByFolderId[parentId];\n const idx = bucket.folderIds.indexOf(id);\n if (idx >= 0) bucket.folderIds.splice(idx, 1);\n }\n const rootIdx = state.tree.rootFolderIds.indexOf(id);\n if (rootIdx >= 0) state.tree.rootFolderIds.splice(rootIdx, 1);\n },\n\n // ---- Versions ----------------------------------------------------------\n upsertVersionsForFile(\n state,\n action: PayloadAction<{ fileId: string; versions: CloudFileVersion[] }>,\n ) {\n state.versionsByFileId[action.payload.fileId] = action.payload.versions;\n },\n\n // ---- Permissions -------------------------------------------------------\n upsertPermissionsForResource(\n state,\n action: PayloadAction<{\n resourceId: string;\n permissions: CloudFilePermission[];\n }>,\n ) {\n state.permissionsByResourceId[action.payload.resourceId] =\n action.payload.permissions;\n },\n\n removePermissionForResource(\n state,\n action: PayloadAction<{\n resourceId: string;\n granteeId: string;\n granteeType?: \"user\" | \"group\";\n }>,\n ) {\n const { resourceId, granteeId, granteeType } = action.payload;\n const list = state.permissionsByResourceId[resourceId];\n if (!list) return;\n state.permissionsByResourceId[resourceId] = list.filter(\n (p) =>\n !(\n p.granteeId === granteeId &&\n (granteeType ? p.granteeType === granteeType : true)\n ),\n );\n },\n\n // ---- Share links -------------------------------------------------------\n upsertShareLinksForResource(\n state,\n action: PayloadAction<{\n resourceId: string;\n shareLinks: CloudShareLink[];\n }>,\n ) {\n state.shareLinksByResourceId[action.payload.resourceId] =\n action.payload.shareLinks;\n },\n\n removeShareLink(state, action: PayloadAction<{ linkId: string }>) {\n const { linkId } = action.payload;\n for (const resourceId of Object.keys(state.shareLinksByResourceId)) {\n state.shareLinksByResourceId[resourceId] = state.shareLinksByResourceId[\n resourceId\n ].filter((l) => l.id !== linkId);\n }\n },\n\n // ---- Tree --------------------------------------------------------------\n setTreeStatus(\n state,\n action: PayloadAction<{\n status: \"idle\" | \"loading\" | \"loaded\" | \"error\";\n error?: string | null;\n }>,\n ) {\n state.tree.status = action.payload.status;\n state.tree.error = action.payload.error ?? null;\n },\n\n replaceTree(\n state,\n action: PayloadAction<{\n rootFolderIds: string[];\n rootFileIds: string[];\n childrenByFolderId: Record<string, TreeChildren>;\n fullyLoadedFolderIds?: Record<string, true>;\n }>,\n ) {\n // Preserve virtual roots across real-tree reloads. Without this, every\n // `loadUserFileTree` (re)load would wipe the synthetic adapter roots\n // that were mounted via `attachVirtualRoot`, and they'd disappear from\n // the sidebar even though their folder records still exist in\n // `foldersById`. Virtual roots come first so they always render at the\n // top of the tree.\n const incomingIds = new Set(action.payload.rootFolderIds);\n const virtualRoots = state.tree.rootFolderIds.filter((id) => {\n if (incomingIds.has(id)) return false;\n return state.foldersById[id]?.source.kind === \"virtual\";\n });\n state.tree.rootFolderIds = [\n ...virtualRoots,\n ...action.payload.rootFolderIds,\n ];\n state.tree.rootFileIds = action.payload.rootFileIds;\n // Same for childrenByFolderId — virtual subtrees must survive the\n // reload so already-hydrated adapter folders aren't emptied.\n const preservedChildren: Record<string, TreeChildren> = {};\n for (const [folderId, children] of Object.entries(\n state.tree.childrenByFolderId,\n )) {\n if (state.foldersById[folderId]?.source.kind === \"virtual\") {\n preservedChildren[folderId] = children;\n }\n }\n state.tree.childrenByFolderId = {\n ...preservedChildren,\n ...action.payload.childrenByFolderId,\n };\n state.tree.fullyLoadedFolderIds =\n action.payload.fullyLoadedFolderIds ?? {};\n state.tree.status = \"loaded\";\n state.tree.error = null;\n state.tree.lastReconciledAt = Date.now();\n },\n\n markFolderFullyLoaded(state, action: PayloadAction<{ folderId: string }>) {\n state.tree.fullyLoadedFolderIds[action.payload.folderId] = true;\n },\n\n /**\n * Mount a virtual adapter as a synthetic root folder. Called once per\n * registered `VirtualSourceAdapter` from `attachVirtualRoots()` (a thunk\n * fired during `/files` bootstrap). The synthetic folder has id\n * `vfs:<adapterId>:__root__` and `source.kind: \"virtual\"` so the existing\n * tree renderer and selectors treat it like any other folder.\n */\n attachVirtualRoot(\n state,\n action: PayloadAction<{\n adapterId: string;\n rootId: string;\n label: string;\n }>,\n ) {\n const { adapterId, rootId, label } = action.payload;\n // Idempotent: re-registering the same adapter is a no-op.\n if (state.foldersById[rootId]) return;\n state.foldersById[rootId] = {\n id: rootId,\n ownerId: \"\",\n folderPath: `/${label}`,\n folderName: label,\n parentId: null,\n visibility: \"personal\",\n metadata: {},\n createdAt: \"\",\n updatedAt: \"\",\n deletedAt: null,\n source: { kind: \"virtual\", adapterId, virtualId: \"__root__\" },\n\n _dirty: false,\n _dirtyFields: {},\n _fieldHistory: {},\n _loadedFields: {},\n _loading: false,\n _error: null,\n _pendingRequestIds: [],\n };\n if (!state.tree.rootFolderIds.includes(rootId)) {\n // Prepend so virtual roots always render at the top of the tree,\n // regardless of whether `attachVirtualRoot` fires before or after\n // `loadUserFileTree`'s `replaceTree`.\n state.tree.rootFolderIds.unshift(rootId);\n }\n },\n\n attachChildToFolder(\n state,\n action: PayloadAction<{\n parentFolderId: string | null;\n kind: \"file\" | \"folder\";\n id: string;\n }>,\n ) {\n const { parentFolderId, kind, id } = action.payload;\n if (!parentFolderId) {\n if (kind === \"file\") {\n if (!state.tree.rootFileIds.includes(id)) {\n state.tree.rootFileIds.push(id);\n }\n } else {\n if (!state.tree.rootFolderIds.includes(id)) {\n state.tree.rootFolderIds.push(id);\n }\n }\n return;\n }\n const bucket = (state.tree.childrenByFolderId[parentFolderId] ??= {\n folderIds: [],\n fileIds: [],\n });\n const list = kind === \"file\" ? bucket.fileIds : bucket.folderIds;\n if (!list.includes(id)) list.push(id);\n },\n\n detachChildFromFolder(\n state,\n action: PayloadAction<{\n parentFolderId: string | null;\n kind: \"file\" | \"folder\";\n id: string;\n }>,\n ) {\n const { parentFolderId, kind, id } = action.payload;\n if (!parentFolderId) {\n const list =\n kind === \"file\" ? state.tree.rootFileIds : state.tree.rootFolderIds;\n const idx = list.indexOf(id);\n if (idx >= 0) list.splice(idx, 1);\n return;\n }\n const bucket = state.tree.childrenByFolderId[parentFolderId];\n if (!bucket) return;\n const list = kind === \"file\" ? bucket.fileIds : bucket.folderIds;\n const idx = list.indexOf(id);\n if (idx >= 0) list.splice(idx, 1);\n },\n\n // ---- Selection + UI ---------------------------------------------------\n setSelection(state, action: PayloadAction<SelectionState>) {\n state.selection = action.payload;\n },\n\n clearSelection(state) {\n state.selection = { selectedIds: [], anchorId: null };\n },\n\n toggleSelection(state, action: PayloadAction<{ id: string }>) {\n const { id } = action.payload;\n const idx = state.selection.selectedIds.indexOf(id);\n if (idx >= 0) {\n state.selection.selectedIds.splice(idx, 1);\n if (state.selection.anchorId === id) state.selection.anchorId = null;\n } else {\n state.selection.selectedIds.push(id);\n state.selection.anchorId = id;\n }\n },\n\n setViewMode(state, action: PayloadAction<ViewMode>) {\n state.ui.viewMode = action.payload;\n },\n\n setSort(\n state,\n action: PayloadAction<{ sortBy: SortBy; sortDir: SortDirection }>,\n ) {\n state.ui.sortBy = action.payload.sortBy;\n state.ui.sortDir = action.payload.sortDir;\n },\n\n setKindFilter(state, action: PayloadAction<KindFilter>) {\n state.ui.kindFilter = action.payload;\n },\n\n setDetailsLevel(state, action: PayloadAction<DetailsLevel>) {\n state.ui.detailsLevel = action.payload;\n },\n\n setColumnFilter(\n state,\n action: PayloadAction<\n | { column: \"name\"; value: string }\n | { column: \"type\"; value: TypeFilter }\n | { column: \"extension\"; value: string }\n | { column: \"mime\"; value: string }\n | { column: \"path\"; value: string }\n | { column: \"owner\"; value: OwnerFilter }\n | { column: \"modified\"; value: ModifiedFilter }\n | { column: \"created\"; value: ModifiedFilter }\n | { column: \"size\"; value: SizeFilter }\n | { column: \"access\"; value: AccessFilter }\n | { column: \"rag\"; value: RagFilter }\n >,\n ) {\n const next = action.payload;\n // One switch statement instead of an if-ladder makes it impossible to\n // forget a column when adding a new one — TS exhaustiveness will warn.\n switch (next.column) {\n case \"name\":\n state.ui.columnFilters.name = next.value;\n break;\n case \"type\":\n state.ui.columnFilters.type = next.value;\n break;\n case \"extension\":\n state.ui.columnFilters.extension = next.value;\n break;\n case \"mime\":\n state.ui.columnFilters.mime = next.value;\n break;\n case \"path\":\n state.ui.columnFilters.path = next.value;\n break;\n case \"owner\":\n state.ui.columnFilters.owner = next.value;\n break;\n case \"modified\":\n state.ui.columnFilters.modified = next.value;\n break;\n case \"created\":\n state.ui.columnFilters.created = next.value;\n break;\n case \"size\":\n state.ui.columnFilters.size = next.value;\n break;\n case \"access\":\n state.ui.columnFilters.access = next.value;\n break;\n case \"rag\":\n state.ui.columnFilters.rag = next.value;\n break;\n }\n },\n\n clearColumnFilters(state) {\n state.ui.columnFilters = {\n name: \"\",\n type: [],\n extension: \"\",\n mime: \"\",\n path: \"\",\n owner: [],\n modified: \"any\",\n created: \"any\",\n size: \"any\",\n access: \"any\",\n rag: [],\n };\n },\n\n setColumnVisibility(\n state,\n action: PayloadAction<{ column: ColumnId; visible: boolean }>,\n ) {\n const { column, visible } = action.payload;\n // `name` is the only column that's never hideable — it's the row\n // anchor for selection, focus, drag handle, context menu, and the\n // Activate button. Hiding it would leave the row empty and break\n // every interaction. Silently ignore.\n if (column === \"name\") {\n state.ui.visibleColumns.name = true;\n return;\n }\n state.ui.visibleColumns[column] = visible;\n },\n\n resetColumnVisibility(state) {\n state.ui.visibleColumns = { ...DEFAULT_VISIBLE_COLUMNS };\n },\n\n setActiveFileId(state, action: PayloadAction<string | null>) {\n state.ui.activeFileId = action.payload;\n },\n\n setActiveFolderId(state, action: PayloadAction<string | null>) {\n state.ui.activeFolderId = action.payload;\n },\n\n /** Tree-wide search box value. Empty string clears the search. */\n setSearchQuery(state, action: PayloadAction<string>) {\n state.ui.searchQuery = action.payload;\n },\n\n /** Active sticky chip (Recents / Starred). Pass null to clear. */\n setChipFilter(state, action: PayloadAction<ChipFilter | null>) {\n state.ui.chipFilter = action.payload;\n },\n\n /**\n * Apply many UI fields in one transaction. Used by the URL-sync layer\n * to hydrate Redux from a `?...` query string on first paint without\n * dispatching N separate actions (which would each spawn a re-render).\n *\n * Only fields present in the payload are written. Pass `columnFilters`\n * with the FULL shape — partial column-filter merges are intentionally\n * not supported here; the URL serializer always emits the full shape.\n */\n setUiBatch(state, action: PayloadAction<Partial<UiState>>) {\n const next = action.payload;\n if (next.viewMode !== undefined) state.ui.viewMode = next.viewMode;\n if (next.sortBy !== undefined) state.ui.sortBy = next.sortBy;\n if (next.sortDir !== undefined) state.ui.sortDir = next.sortDir;\n if (next.kindFilter !== undefined) state.ui.kindFilter = next.kindFilter;\n if (next.detailsLevel !== undefined) {\n state.ui.detailsLevel = next.detailsLevel;\n }\n if (next.searchQuery !== undefined) {\n state.ui.searchQuery = next.searchQuery;\n }\n if (next.chipFilter !== undefined) state.ui.chipFilter = next.chipFilter;\n if (next.activeFileId !== undefined) {\n state.ui.activeFileId = next.activeFileId;\n }\n if (next.activeFolderId !== undefined) {\n state.ui.activeFolderId = next.activeFolderId;\n }\n if (next.columnFilters !== undefined) {\n const cf = next.columnFilters as Partial<ColumnFilters>;\n if (cf.name !== undefined) state.ui.columnFilters.name = cf.name;\n if (cf.type !== undefined) state.ui.columnFilters.type = cf.type;\n if (cf.extension !== undefined) {\n state.ui.columnFilters.extension = cf.extension;\n }\n if (cf.mime !== undefined) state.ui.columnFilters.mime = cf.mime;\n if (cf.path !== undefined) state.ui.columnFilters.path = cf.path;\n if (cf.owner !== undefined) state.ui.columnFilters.owner = cf.owner;\n if (cf.modified !== undefined) {\n state.ui.columnFilters.modified = cf.modified;\n }\n if (cf.created !== undefined) {\n state.ui.columnFilters.created = cf.created;\n }\n if (cf.size !== undefined) state.ui.columnFilters.size = cf.size;\n if (cf.access !== undefined) state.ui.columnFilters.access = cf.access;\n if (cf.rag !== undefined) state.ui.columnFilters.rag = cf.rag;\n }\n if (next.visibleColumns !== undefined) {\n state.ui.visibleColumns = {\n ...DEFAULT_VISIBLE_COLUMNS,\n ...next.visibleColumns,\n // `name` is the row anchor — never hideable. Keep this invariant\n // even when callers (or a malicious URL) try to flip it.\n name: true,\n };\n }\n },\n\n /**\n * Move \"focus\" (Google-Drive-style single-item highlight) to the given id.\n * Pass null to clear. Automatically set after folder/file creation so the\n * newly-created item is highlighted and scrolled into view.\n */\n setFocusedId(state, action: PayloadAction<string | null>) {\n state.ui.focusedId = action.payload;\n },\n\n // ---- Uploads -----------------------------------------------------------\n trackUploadStart(\n state,\n action: PayloadAction<{\n requestId: string;\n fileName: string;\n fileSize: number;\n parentFolderId: string | null;\n folderPath?: string | null;\n }>,\n ) {\n const { requestId, fileName, fileSize, parentFolderId, folderPath } =\n action.payload;\n state.uploads[requestId] = {\n requestId,\n fileName,\n fileSize,\n parentFolderId,\n folderPath: folderPath ?? null,\n status: \"uploading\",\n bytesUploaded: 0,\n startedAt: Date.now(),\n completedAt: null,\n error: null,\n retries: 0,\n fileId: null,\n };\n },\n\n updateUploadProgress(\n state,\n action: PayloadAction<{ requestId: string; bytesUploaded: number }>,\n ) {\n const entry = state.uploads[action.payload.requestId];\n if (!entry) return;\n entry.bytesUploaded = action.payload.bytesUploaded;\n },\n\n updateUploadStatus(\n state,\n action: PayloadAction<{\n requestId: string;\n status: UploadStatus;\n fileId?: string | null;\n error?: string | null;\n }>,\n ) {\n const entry = state.uploads[action.payload.requestId];\n if (!entry) return;\n entry.status = action.payload.status;\n if (action.payload.fileId !== undefined)\n entry.fileId = action.payload.fileId;\n if (action.payload.error !== undefined)\n entry.error = action.payload.error;\n if (\n action.payload.status === \"success\" ||\n action.payload.status === \"error\" ||\n action.payload.status === \"cancelled\"\n ) {\n entry.completedAt = Date.now();\n }\n },\n\n clearUpload(state, action: PayloadAction<{ requestId: string }>) {\n delete state.uploads[action.payload.requestId];\n },\n\n clearCompletedUploads(state) {\n for (const id of Object.keys(state.uploads)) {\n const entry = state.uploads[id];\n if (entry.status === \"success\" || entry.status === \"cancelled\") {\n delete state.uploads[id];\n }\n }\n },\n\n // ---- Realtime lifecycle -----------------------------------------------\n setRealtimeStatus(\n state,\n action: PayloadAction<{\n status: CloudFilesState[\"realtime\"][\"status\"];\n userId?: string | null;\n error?: string | null;\n }>,\n ) {\n state.realtime.status = action.payload.status;\n if (action.payload.userId !== undefined) {\n state.realtime.userId = action.payload.userId;\n }\n state.realtime.error = action.payload.error ?? null;\n if (action.payload.status === \"subscribed\") {\n state.realtime.lastEventAt = Date.now();\n }\n },\n\n touchRealtime(state) {\n state.realtime.lastEventAt = Date.now();\n },\n\n // ---- Knowledge status (per-file) ---------------------------------------------\n setRagStatusForFile(\n state,\n action: PayloadAction<{ fileId: string; status: RagStatus }>,\n ) {\n const { fileId, status } = action.payload;\n state.ragStatus.byFileId[fileId] = status;\n },\n\n setRagStatusBatch(\n state,\n action: PayloadAction<{ entries: Record<string, RagStatus> }>,\n ) {\n Object.assign(state.ragStatus.byFileId, action.payload.entries);\n state.ragStatus.lastFetchedAt = Date.now();\n },\n\n setRagStatusFetching(state, action: PayloadAction<boolean>) {\n state.ragStatus.isFetching = action.payload;\n },\n\n clearRagStatuses(state) {\n state.ragStatus.byFileId = {};\n state.ragStatus.lastFetchedAt = null;\n },\n\n resetCloudFilesState() {\n return initialState;\n },\n },\n});\n\n// ---------------------------------------------------------------------------\n// Exports\n// ---------------------------------------------------------------------------\n\nexport const {\n // files\n upsertFile,\n upsertFiles,\n setFileField,\n resetFileField,\n markFileSaved,\n rollbackFileOptimisticUpdate,\n removeFile,\n addFilePendingRequest,\n removeFilePendingRequest,\n setFileLoading,\n setFileError,\n // folders\n upsertFolder,\n upsertFolders,\n setFolderField,\n markFolderSaved,\n rollbackFolderOptimisticUpdate,\n removeFolder,\n // versions / permissions / shares\n upsertVersionsForFile,\n upsertPermissionsForResource,\n removePermissionForResource,\n upsertShareLinksForResource,\n removeShareLink,\n // tree\n setTreeStatus,\n replaceTree,\n markFolderFullyLoaded,\n attachVirtualRoot,\n attachChildToFolder,\n detachChildFromFolder,\n // selection + ui\n setSelection,\n clearSelection,\n toggleSelection,\n setViewMode,\n setSort,\n setKindFilter,\n setDetailsLevel,\n setColumnFilter,\n clearColumnFilters,\n setColumnVisibility,\n resetColumnVisibility,\n setActiveFileId,\n setActiveFolderId,\n setSearchQuery,\n setChipFilter,\n setUiBatch,\n setFocusedId,\n // uploads\n trackUploadStart,\n updateUploadProgress,\n updateUploadStatus,\n clearUpload,\n clearCompletedUploads,\n // rag status\n setRagStatusForFile,\n setRagStatusBatch,\n setRagStatusFetching,\n clearRagStatuses,\n // realtime\n setRealtimeStatus,\n touchRealtime,\n // working copies\n resetCloudFilesState,\n} = slice.actions;\n\nexport const cloudFilesReducer = slice.reducer;\nexport default slice.reducer;\n\n// Re-export for thunks / middleware that need to build empty records locally.\nexport { emptyFileRecord, emptyFolderRecord };\n\n// Re-export visibility helper type to the barrel.\nexport type { Visibility };\n"],"mappings":"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","names":["list","idx"]}
@@ -0,0 +1,449 @@
1
+ /**
2
+ * features/files/redux/thunks.ts
3
+ *
4
+ * Async orchestration for cloud files: reads via supabase-js (RLS), writes via
5
+ * the REST API client. Every mutation follows the pattern:
6
+ *
7
+ * 1. Snapshot current state for rollback.
8
+ * 2. Dispatch optimistic reducer immediately.
9
+ * 3. Register the requestId in the ledger (for realtime echo dedup).
10
+ * 4. Call the REST API.
11
+ * 5. On success: markSaved, release ledger entry.
12
+ * 6. On error: dispatch rollback, set error, release ledger entry, rethrow.
13
+ */
14
+ import type { ThunkDispatch, UnknownAction } from "@reduxjs/toolkit";
15
+ import type { CloudFilesState } from "../types.js";
16
+ type StateWithCloudFiles = {
17
+ cloudFiles: CloudFilesState;
18
+ };
19
+ type AppDispatch = ThunkDispatch<StateWithCloudFiles, unknown, UnknownAction>;
20
+ import { type CloudFileHydrationField } from "./file-hydration.js";
21
+ import type { BulkDeleteFilesArg, BulkMoveFilesArg, BulkMoveFoldersArg, BulkResponse, CloudShareLink, CreateShareLinkArg, RevokeShareLinkArg, DeleteFileArg, GrantPermissionArg, MoveFileArg, RenameFileArg, ResourceType, RestoreVersionArg, SaveFileNewVersionArg, SaveFileNewVersionResult, RevokePermissionArg, UpdateFileMetadataArg, UploadFilesArg, FileIdentityHint } from "../types.js";
22
+ export interface EnsureCloudFileFieldsArg {
23
+ fileId: string;
24
+ fields?: readonly CloudFileHydrationField[];
25
+ hint?: FileIdentityHint;
26
+ }
27
+ export type EnsureCloudFileFieldsOutcome = "ready" | "missing";
28
+ /**
29
+ * Ensure a durable file id has the requested canonical fields in Redux.
30
+ * Known hints merge first, so the network reads only what is actually absent.
31
+ */
32
+ export declare const ensureCloudFileFields: import("@reduxjs/toolkit").AsyncThunk<EnsureCloudFileFieldsOutcome, EnsureCloudFileFieldsArg, {
33
+ dispatch: AppDispatch;
34
+ state: StateWithCloudFiles;
35
+ extra?: unknown;
36
+ rejectValue?: unknown;
37
+ serializedErrorType?: unknown;
38
+ pendingMeta?: unknown;
39
+ fulfilledMeta?: unknown;
40
+ rejectedMeta?: unknown;
41
+ }>;
42
+ export declare const loadUserFileTree: import("@reduxjs/toolkit").AsyncThunk<void, {
43
+ userId: string;
44
+ }, {
45
+ dispatch: AppDispatch;
46
+ state: StateWithCloudFiles;
47
+ extra?: unknown;
48
+ rejectValue?: unknown;
49
+ serializedErrorType?: unknown;
50
+ pendingMeta?: unknown;
51
+ fulfilledMeta?: unknown;
52
+ rejectedMeta?: unknown;
53
+ }>;
54
+ /**
55
+ * Re-run the tree load. Fired by the realtime middleware when the subscription
56
+ * reconnects after an outage — guarantees we don't miss events.
57
+ */
58
+ export declare const reconcileTree: import("@reduxjs/toolkit").AsyncThunk<void, {
59
+ userId: string;
60
+ }, {
61
+ dispatch: AppDispatch;
62
+ state: StateWithCloudFiles;
63
+ extra?: unknown;
64
+ rejectValue?: unknown;
65
+ serializedErrorType?: unknown;
66
+ pendingMeta?: unknown;
67
+ fulfilledMeta?: unknown;
68
+ rejectedMeta?: unknown;
69
+ }>;
70
+ export declare const loadFolderContents: import("@reduxjs/toolkit").AsyncThunk<void, {
71
+ folderId: string;
72
+ }, {
73
+ dispatch: AppDispatch;
74
+ state: StateWithCloudFiles;
75
+ extra?: unknown;
76
+ rejectValue?: unknown;
77
+ serializedErrorType?: unknown;
78
+ pendingMeta?: unknown;
79
+ fulfilledMeta?: unknown;
80
+ rejectedMeta?: unknown;
81
+ }>;
82
+ export declare const loadFileVersions: import("@reduxjs/toolkit").AsyncThunk<void, {
83
+ fileId: string;
84
+ }, {
85
+ dispatch: AppDispatch;
86
+ state: StateWithCloudFiles;
87
+ extra?: unknown;
88
+ rejectValue?: unknown;
89
+ serializedErrorType?: unknown;
90
+ pendingMeta?: unknown;
91
+ fulfilledMeta?: unknown;
92
+ rejectedMeta?: unknown;
93
+ }>;
94
+ export declare const loadPermissions: import("@reduxjs/toolkit").AsyncThunk<void, {
95
+ resourceId: string;
96
+ }, {
97
+ dispatch: AppDispatch;
98
+ state: StateWithCloudFiles;
99
+ extra?: unknown;
100
+ rejectValue?: unknown;
101
+ serializedErrorType?: unknown;
102
+ pendingMeta?: unknown;
103
+ fulfilledMeta?: unknown;
104
+ rejectedMeta?: unknown;
105
+ }>;
106
+ export declare const loadShareLinks: import("@reduxjs/toolkit").AsyncThunk<void, {
107
+ resourceId: string;
108
+ resourceType?: ResourceType;
109
+ }, {
110
+ dispatch: AppDispatch;
111
+ state: StateWithCloudFiles;
112
+ extra?: unknown;
113
+ rejectValue?: unknown;
114
+ serializedErrorType?: unknown;
115
+ pendingMeta?: unknown;
116
+ fulfilledMeta?: unknown;
117
+ rejectedMeta?: unknown;
118
+ }>;
119
+ /**
120
+ * Create a folder via the Python REST contract. We hit `POST /folders` with
121
+ * the explicit `{ folder_name, parent_id }` form because callers already
122
+ * resolve the parent id from the tree. The path-style form (`folder_path`)
123
+ * is preferred for upload-time auto-create, which `uploadFiles` handles.
124
+ *
125
+ * Architecturally important: this thunk no longer touches `cld_folders` from
126
+ * the browser. Folder writes were the single biggest source of RLS recursion
127
+ * regressions; routing them through the backend (which uses SECURITY DEFINER
128
+ * helpers) makes the path uniform with file uploads.
129
+ */
130
+ export declare const createFolder: import("@reduxjs/toolkit").AsyncThunk<string, import("../types.js").CreateFolderArg, {
131
+ dispatch: AppDispatch;
132
+ state: StateWithCloudFiles;
133
+ extra?: unknown;
134
+ rejectValue?: unknown;
135
+ serializedErrorType?: unknown;
136
+ pendingMeta?: unknown;
137
+ fulfilledMeta?: unknown;
138
+ rejectedMeta?: unknown;
139
+ }>;
140
+ /**
141
+ * Update folder properties — rename, move (`parentId`), change visibility,
142
+ * patch metadata. Optimistic: applies the patch locally before the REST call
143
+ * and rolls back on failure.
144
+ */
145
+ export declare const updateFolder: import("@reduxjs/toolkit").AsyncThunk<void, import("../types.js").UpdateFolderArg, {
146
+ dispatch: AppDispatch;
147
+ state: StateWithCloudFiles;
148
+ extra?: unknown;
149
+ rejectValue?: unknown;
150
+ serializedErrorType?: unknown;
151
+ pendingMeta?: unknown;
152
+ fulfilledMeta?: unknown;
153
+ rejectedMeta?: unknown;
154
+ }>;
155
+ export declare const deleteFolder: import("@reduxjs/toolkit").AsyncThunk<void, import("../types.js").DeleteFolderArg, {
156
+ dispatch: AppDispatch;
157
+ state: StateWithCloudFiles;
158
+ extra?: unknown;
159
+ rejectValue?: unknown;
160
+ serializedErrorType?: unknown;
161
+ pendingMeta?: unknown;
162
+ fulfilledMeta?: unknown;
163
+ rejectedMeta?: unknown;
164
+ }>;
165
+ /**
166
+ * Ensure every segment of `folderPath` exists; create any that don't.
167
+ * Returns the leaf folder's id. Used for convention-based uploads like
168
+ * "save all pasted images under /Images".
169
+ */
170
+ export declare const ensureFolderPath: import("@reduxjs/toolkit").AsyncThunk<string, import("../types.js").EnsureFolderPathArg, {
171
+ dispatch: AppDispatch;
172
+ state: StateWithCloudFiles;
173
+ extra?: unknown;
174
+ rejectValue?: unknown;
175
+ serializedErrorType?: unknown;
176
+ pendingMeta?: unknown;
177
+ fulfilledMeta?: unknown;
178
+ rejectedMeta?: unknown;
179
+ }>;
180
+ /**
181
+ * Say, on the screen the person is actually looking at, that an upload failed —
182
+ * in the SERVER'S words.
183
+ *
184
+ * 🚨 THE 2026-09-19 SILENT FAILURE (`common-docs/systems/knowledge/ingestion/projects/acquisition-frontier/
185
+ * own-files/VERIFICATION.md` §15/§16). A 21-file drop on a fresh Rulebook fired
186
+ * 21 uploads and every one came back `400 matrx-files: this write carries no
187
+ * organization`. Every sentence was captured correctly — into
188
+ * `failed[].error` and into the upload slice — and then shown NOWHERE, because:
189
+ *
190
+ * - `mutation-toast-middleware` deliberately skips `uploadFiles`, on the
191
+ * reasoning that "uploads surface per-file errors inline in the
192
+ * UploadProgressList". That is true on the Files surface and FALSE
193
+ * everywhere else — the Rulebook sources panel never renders that list.
194
+ * - the capture toolbar that started the drop collapses N failures into
195
+ * "Failed to upload N files", dropping every reason.
196
+ *
197
+ * So the person saw a card that still read "Nothing attached yet" and no reason
198
+ * anywhere. An upload that failed must never be indistinguishable from an
199
+ * upload nobody started.
200
+ *
201
+ * This announces from the THUNK, which every caller shares, so no surface can
202
+ * forget. Reasons are deduped (21 identical 400s are one sentence, not 21
203
+ * toasts), and the toast carries a stable id so the surrounding UploadProgressList
204
+ * or capture toolbar cannot stack a second copy of the same news.
205
+ */
206
+ export declare function announceUploadFailures(failed: ReadonlyArray<{
207
+ name: string;
208
+ error: string;
209
+ }>): void;
210
+ export declare const uploadFiles: import("@reduxjs/toolkit").AsyncThunk<{
211
+ uploaded: string[];
212
+ failed: Array<{
213
+ name: string;
214
+ error: string;
215
+ }>;
216
+ }, UploadFilesArg, {
217
+ dispatch: AppDispatch;
218
+ state: StateWithCloudFiles;
219
+ extra?: unknown;
220
+ rejectValue?: unknown;
221
+ serializedErrorType?: unknown;
222
+ pendingMeta?: unknown;
223
+ fulfilledMeta?: unknown;
224
+ rejectedMeta?: unknown;
225
+ }>;
226
+ export declare const clearUploadEntry: import("@reduxjs/toolkit").AsyncThunk<void, {
227
+ requestId: string;
228
+ }, {
229
+ dispatch: AppDispatch;
230
+ state: StateWithCloudFiles;
231
+ extra?: unknown;
232
+ rejectValue?: unknown;
233
+ serializedErrorType?: unknown;
234
+ pendingMeta?: unknown;
235
+ fulfilledMeta?: unknown;
236
+ rejectedMeta?: unknown;
237
+ }>;
238
+ export declare const renameFile: import("@reduxjs/toolkit").AsyncThunk<void, RenameFileArg, {
239
+ dispatch: AppDispatch;
240
+ state: StateWithCloudFiles;
241
+ extra?: unknown;
242
+ rejectValue?: unknown;
243
+ serializedErrorType?: unknown;
244
+ pendingMeta?: unknown;
245
+ fulfilledMeta?: unknown;
246
+ rejectedMeta?: unknown;
247
+ }>;
248
+ export declare const moveFile: import("@reduxjs/toolkit").AsyncThunk<void, MoveFileArg, {
249
+ dispatch: AppDispatch;
250
+ state: StateWithCloudFiles;
251
+ extra?: unknown;
252
+ rejectValue?: unknown;
253
+ serializedErrorType?: unknown;
254
+ pendingMeta?: unknown;
255
+ fulfilledMeta?: unknown;
256
+ rejectedMeta?: unknown;
257
+ }>;
258
+ export declare const updateFileMetadata: import("@reduxjs/toolkit").AsyncThunk<void, UpdateFileMetadataArg, {
259
+ dispatch: AppDispatch;
260
+ state: StateWithCloudFiles;
261
+ extra?: unknown;
262
+ rejectValue?: unknown;
263
+ serializedErrorType?: unknown;
264
+ pendingMeta?: unknown;
265
+ fulfilledMeta?: unknown;
266
+ rejectedMeta?: unknown;
267
+ }>;
268
+ export declare const deleteFile: import("@reduxjs/toolkit").AsyncThunk<void, DeleteFileArg, {
269
+ dispatch: AppDispatch;
270
+ state: StateWithCloudFiles;
271
+ extra?: unknown;
272
+ rejectValue?: unknown;
273
+ serializedErrorType?: unknown;
274
+ pendingMeta?: unknown;
275
+ fulfilledMeta?: unknown;
276
+ rejectedMeta?: unknown;
277
+ }>;
278
+ export declare const loadTrash: import("@reduxjs/toolkit").AsyncThunk<void, {
279
+ userId: string;
280
+ }, {
281
+ dispatch: AppDispatch;
282
+ state: StateWithCloudFiles;
283
+ extra?: unknown;
284
+ rejectValue?: unknown;
285
+ serializedErrorType?: unknown;
286
+ pendingMeta?: unknown;
287
+ fulfilledMeta?: unknown;
288
+ rejectedMeta?: unknown;
289
+ }>;
290
+ /** Restore a trashed file: flip `deletedAt` off and reattach to its folder. */
291
+ export declare const restoreFile: import("@reduxjs/toolkit").AsyncThunk<void, {
292
+ fileId: string;
293
+ }, {
294
+ dispatch: AppDispatch;
295
+ state: StateWithCloudFiles;
296
+ extra?: unknown;
297
+ rejectValue?: unknown;
298
+ serializedErrorType?: unknown;
299
+ pendingMeta?: unknown;
300
+ fulfilledMeta?: unknown;
301
+ rejectedMeta?: unknown;
302
+ }>;
303
+ /**
304
+ * Restore a trashed folder + its subtree. The RPC un-deletes descendants in
305
+ * SQL; rather than mirroring that cascade optimistically we reconcile by
306
+ * reloading the live tree afterwards (folder restore is rare — correctness
307
+ * over cleverness).
308
+ */
309
+ export declare const restoreFolder: import("@reduxjs/toolkit").AsyncThunk<void, {
310
+ folderId: string;
311
+ }, {
312
+ dispatch: AppDispatch;
313
+ state: StateWithCloudFiles;
314
+ extra?: unknown;
315
+ rejectValue?: unknown;
316
+ serializedErrorType?: unknown;
317
+ pendingMeta?: unknown;
318
+ fulfilledMeta?: unknown;
319
+ rejectedMeta?: unknown;
320
+ }>;
321
+ export declare const restoreVersion: import("@reduxjs/toolkit").AsyncThunk<void, RestoreVersionArg, {
322
+ dispatch: AppDispatch;
323
+ state: StateWithCloudFiles;
324
+ extra?: unknown;
325
+ rejectValue?: unknown;
326
+ serializedErrorType?: unknown;
327
+ pendingMeta?: unknown;
328
+ fulfilledMeta?: unknown;
329
+ rejectedMeta?: unknown;
330
+ }>;
331
+ /**
332
+ * THE edit-save path: write new content as the next version of the SAME file.
333
+ *
334
+ * Every editor that saves a file's text goes through here — never `uploadFiles`.
335
+ * `uploadFiles` is the NEW-file path: it auto-renames a colliding name to
336
+ * "name (1).ext" (Drive semantics for a dropped duplicate), so an editor that
337
+ * re-uploaded its own file created a second file and left the original at
338
+ * version 1 while the UI said "Saved" (2026-09-30).
339
+ *
340
+ * ONE path for everyone: `POST /files/{id}/versions` writes by file ID, so the
341
+ * owner and an editor holding an edit grant on someone else's file save the
342
+ * same way (the server checks the caller's write right, keeps the file's owner
343
+ * and path, and records the caller + `changeSummary` on the version). The
344
+ * answer is still REFUSED if it is not that same row (a different `file_id` or
345
+ * `is_new: true`), so a save can never silently become a copy.
346
+ */
347
+ export declare const saveFileNewVersion: import("@reduxjs/toolkit").AsyncThunk<SaveFileNewVersionResult, SaveFileNewVersionArg, {
348
+ dispatch: AppDispatch;
349
+ state: StateWithCloudFiles;
350
+ extra?: unknown;
351
+ rejectValue?: unknown;
352
+ serializedErrorType?: unknown;
353
+ pendingMeta?: unknown;
354
+ fulfilledMeta?: unknown;
355
+ rejectedMeta?: unknown;
356
+ }>;
357
+ export declare const grantPermission: import("@reduxjs/toolkit").AsyncThunk<void, GrantPermissionArg, {
358
+ dispatch: AppDispatch;
359
+ state: StateWithCloudFiles;
360
+ extra?: unknown;
361
+ rejectValue?: unknown;
362
+ serializedErrorType?: unknown;
363
+ pendingMeta?: unknown;
364
+ fulfilledMeta?: unknown;
365
+ rejectedMeta?: unknown;
366
+ }>;
367
+ export declare const revokePermission: import("@reduxjs/toolkit").AsyncThunk<void, RevokePermissionArg, {
368
+ dispatch: AppDispatch;
369
+ state: StateWithCloudFiles;
370
+ extra?: unknown;
371
+ rejectValue?: unknown;
372
+ serializedErrorType?: unknown;
373
+ pendingMeta?: unknown;
374
+ fulfilledMeta?: unknown;
375
+ rejectedMeta?: unknown;
376
+ }>;
377
+ export declare const createShareLink: import("@reduxjs/toolkit").AsyncThunk<CloudShareLink, CreateShareLinkArg, {
378
+ dispatch: AppDispatch;
379
+ state: StateWithCloudFiles;
380
+ extra?: unknown;
381
+ rejectValue?: unknown;
382
+ serializedErrorType?: unknown;
383
+ pendingMeta?: unknown;
384
+ fulfilledMeta?: unknown;
385
+ rejectedMeta?: unknown;
386
+ }>;
387
+ export declare const revokeShareLink: import("@reduxjs/toolkit").AsyncThunk<void, RevokeShareLinkArg, {
388
+ dispatch: AppDispatch;
389
+ state: StateWithCloudFiles;
390
+ extra?: unknown;
391
+ rejectValue?: unknown;
392
+ serializedErrorType?: unknown;
393
+ pendingMeta?: unknown;
394
+ fulfilledMeta?: unknown;
395
+ rejectedMeta?: unknown;
396
+ }>;
397
+ export declare const getFileUrl: import("@reduxjs/toolkit").AsyncThunk<{
398
+ url: string;
399
+ }, {
400
+ fileId: string;
401
+ }, {
402
+ dispatch: AppDispatch;
403
+ state: StateWithCloudFiles;
404
+ extra?: unknown;
405
+ rejectValue?: unknown;
406
+ serializedErrorType?: unknown;
407
+ pendingMeta?: unknown;
408
+ fulfilledMeta?: unknown;
409
+ rejectedMeta?: unknown;
410
+ }>;
411
+ export declare const bulkDeleteFiles: import("@reduxjs/toolkit").AsyncThunk<BulkResponse, BulkDeleteFilesArg, {
412
+ dispatch: AppDispatch;
413
+ state: StateWithCloudFiles;
414
+ extra?: unknown;
415
+ rejectValue?: unknown;
416
+ serializedErrorType?: unknown;
417
+ pendingMeta?: unknown;
418
+ fulfilledMeta?: unknown;
419
+ rejectedMeta?: unknown;
420
+ }>;
421
+ /**
422
+ * Move many files to a new parent folder in one round-trip. Pass `null` to
423
+ * move to root.
424
+ */
425
+ export declare const bulkMoveFiles: import("@reduxjs/toolkit").AsyncThunk<BulkResponse, BulkMoveFilesArg, {
426
+ dispatch: AppDispatch;
427
+ state: StateWithCloudFiles;
428
+ extra?: unknown;
429
+ rejectValue?: unknown;
430
+ serializedErrorType?: unknown;
431
+ pendingMeta?: unknown;
432
+ fulfilledMeta?: unknown;
433
+ rejectedMeta?: unknown;
434
+ }>;
435
+ /**
436
+ * Move many folders to a new parent in one round-trip. Pass `null` to move
437
+ * to root. The backend cascades `folder_path` updates to descendants.
438
+ */
439
+ export declare const bulkMoveFolders: import("@reduxjs/toolkit").AsyncThunk<BulkResponse, BulkMoveFoldersArg, {
440
+ dispatch: AppDispatch;
441
+ state: StateWithCloudFiles;
442
+ extra?: unknown;
443
+ rejectValue?: unknown;
444
+ serializedErrorType?: unknown;
445
+ pendingMeta?: unknown;
446
+ fulfilledMeta?: unknown;
447
+ rejectedMeta?: unknown;
448
+ }>;
449
+ export {};