@powerhousedao/connect 1.0.16-dev.2 → 1.0.16-staging.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.
@@ -1,16 +1,10 @@
1
1
  import { jsx, jsxs, Fragment as Fragment$1 } from "react/jsx-runtime";
2
- import { t as twMerge, B as Button, m as mergeClassNameProps, E as ERROR, M as MISSING, C as CONFLICT, S as SUCCESS, h as SYNCING, I as INITIAL_SYNC, i as ConnectDropdownMenu, u as useOnClickOutside, j as useEventListener, k as useCopyToClipboard, l as Select, n as ENSAvatar, P as Provider, o as Root3, T as Trigger, p as Portal, q as Content2, v as validateInitialState, w as validateStateSchemaName, x as validateModules, y as useUnwrappedReactor, z as useConnectDid, A as useConnectCrypto, D as useTranslation, F as useModal, G as useAtomValue, H as themeAtom, J as useUser, K as useUserPermissions, L as useUiNodes, N as exportFile, O as useGetDocumentModelModule, Q as addActionContext, U as signOperation, V as useDocumentDriveServer, W as useHotkeys, X as useGetEditor, Y as isSameDocument, Z as useNavigate, _ as ErrorBoundary, $ as DriveLayout, a0 as SearchBar, a1 as useAsyncReactor, a2 as useFilteredDocumentModels, a3 as useDriveEditor, a4 as useDocumentDriveById, a5 as useParams, a6 as useDocumentDrives, a7 as toast } from "./app-DhH3gUSI.js";
2
+ import { t as twMerge, B as Button, m as mergeClassNameProps, E as ERROR, M as MISSING, C as CONFLICT, S as SUCCESS, k as SYNCING, I as INITIAL_SYNC, l as ConnectDropdownMenu, u as useOnClickOutside, n as useEventListener, o as useCopyToClipboard, p as Select, q as ENSAvatar, P as Provider, v as Root3, T as Trigger, w as Portal, x as Content2, y as validateInitialState, z as validateStateSchemaName, A as validateModules, D as useDocumentDrives, F as useUiNodesContext, G as useDriveContext, H as FILE$1, J as useUnwrappedReactor, K as useConnectDid, L as useConnectCrypto, N as useTranslation, O as useModal, Q as useAtomValue, U as themeAtom, V as useUser, W as useUserPermissions$1, X as useUiNodes, Y as exportFile, Z as useGetDocumentModelModule, _ as addActionContext$1, $ as signOperation$1, a0 as useDocumentDriveServer, a1 as useHotkeys, a2 as useGetEditor, a3 as isSameDocument, a4 as useNavigate, a5 as ErrorBoundary, a6 as DriveLayout, a7 as DriveContextProvider, a8 as SearchBar, a9 as useAsyncReactor, aa as useFilteredDocumentModels, ab as useDriveEditor, ac as useDocumentDriveById, ad as useParams, ae as useDocumentDrives$1, af as toast } from "./app-BjxLqcmz.js";
3
3
  import * as React from "react";
4
4
  import React__default, { useState, useCallback, useMemo, useEffect, Fragment, useRef, useLayoutEffect, memo as memo$1, createElement, useSyncExternalStore, Suspense } from "react";
5
- import { _ as Icon, aX as getDimensions, aY as READ, aZ as nodeOptionsMap, a_ as defaultFileOptions, a$ as DELETE, b0 as RENAME, b1 as WRITE, b2 as DUPLICATE, b3 as defaultFolderOptions, b4 as garbageCollect, b5 as sortOperations, b6 as UI_NODE, aO as DRIVE, ay as FILE, b7 as undo, b8 as redo, ac as logger, b9 as useDocumentDispatch, aP as FOLDER, ak as driveDocumentModelModule } from "./app-loader-Btk_wf_z.js";
6
- import { useDocument, useDocumentEditorProps } from "@powerhousedao/reactor-browser";
7
- import { useUiNodesContext, FILE as FILE$1 } from "@powerhousedao/reactor-browser/hooks/useUiNodesContext";
8
- import { useDriveActionsWithUiNodes } from "@powerhousedao/reactor-browser/hooks/useDriveActionsWithUiNodes";
9
- import { DriveContextProvider, useDriveContext } from "@powerhousedao/reactor-browser/hooks/useDriveContext";
10
- import "@powerhousedao/reactor-browser/uiNodes/constants";
11
- import { makeDriveDocumentStateHook } from "@powerhousedao/reactor-browser/hooks/document-state";
5
+ import { _ as Icon, aX as getDimensions, aY as READ, aZ as nodeOptionsMap, a_ as defaultFileOptions, a$ as DELETE, b0 as RENAME, b1 as WRITE, b2 as DUPLICATE, b3 as defaultFolderOptions, b4 as garbageCollect, b5 as sortOperations, b6 as UI_NODE, aP as DRIVE, az as FILE, ae as buildSignedOperation, b7 as generateId$1, aw as isFolderNode, aB as generateNodesCopy, aC as copyNode, aA as moveNode, ay as updateNode, ax as deleteNode, ar as generateAddNodeAction, as as isFileNode, av as addFolder, b8 as undo, b9 as redo, ac as logger, ba as useDocumentDispatch$1, aQ as FOLDER, al as driveDocumentModelModule } from "./app-loader-nik9-lTL.js";
12
6
  import { flushSync } from "react-dom";
13
- import "./main.C1DJvpcL.js";
7
+ import "./main.BuoJ8woF.js";
14
8
  const PaginationButton = ({ active = false, ...props }) => {
15
9
  const className = twMerge("h-8 min-w-8 border border-solid border-gray-300 bg-white px-3 py-1 text-xs text-gray-900 hover:bg-gray-100", !active && "border-0");
16
10
  return jsx(Button, { color: "light", size: "small", ...mergeClassNameProps(props, className), children: props.children });
@@ -3010,6 +3004,349 @@ const validateDocument = (document2) => {
3010
3004
  const modulesErrors = validateModules(specs.modules);
3011
3005
  return [...initialStateErrors, ...schemaStateErrors, ...modulesErrors];
3012
3006
  };
3007
+ function useUserPermissions() {
3008
+ return {
3009
+ isAllowedToCreateDocuments: true,
3010
+ isAllowedToEditDocuments: true
3011
+ };
3012
+ }
3013
+ function useDocument(reactor, documentMeta = {}) {
3014
+ const { documentId, documentType, driveId } = documentMeta;
3015
+ const [document2, setDocument] = useState();
3016
+ const onStrandUpdate = useCallback((cb) => {
3017
+ if (!reactor) {
3018
+ throw new Error("Reactor is not loaded");
3019
+ }
3020
+ return reactor.on("strandUpdate", cb);
3021
+ }, [reactor]);
3022
+ useEffect(() => {
3023
+ if (!reactor)
3024
+ return;
3025
+ if (!driveId || !documentId || !documentType)
3026
+ return;
3027
+ reactor.getDocument(driveId, documentId).then(setDocument).catch(console.error);
3028
+ }, [driveId, documentId, documentType, reactor]);
3029
+ useEffect(() => {
3030
+ if (!reactor)
3031
+ return;
3032
+ if (!driveId || !documentId || !documentType)
3033
+ return;
3034
+ const removeListener = onStrandUpdate((strand) => {
3035
+ if (strand.driveId === driveId && strand.documentId === documentId) {
3036
+ reactor.getDocument(driveId, documentId).then(setDocument).catch(console.error);
3037
+ }
3038
+ });
3039
+ return removeListener;
3040
+ }, [onStrandUpdate, driveId, documentId, documentType]);
3041
+ return document2;
3042
+ }
3043
+ async function signOperation(operation, sign, documentId, document2, reducer, user) {
3044
+ if (!user)
3045
+ return operation;
3046
+ if (!operation.context)
3047
+ return operation;
3048
+ if (!operation.context.signer)
3049
+ return operation;
3050
+ if (!reducer) {
3051
+ console.error(`Document model '${document2.documentType}' does not have a reducer`);
3052
+ return operation;
3053
+ }
3054
+ const context = {
3055
+ documentId,
3056
+ signer: operation.context.signer
3057
+ };
3058
+ const signedOperation = await buildSignedOperation(operation, reducer, document2, context, sign);
3059
+ return signedOperation;
3060
+ }
3061
+ function addActionContext(action, connectDid, user) {
3062
+ if (!user)
3063
+ return action;
3064
+ const signer = {
3065
+ app: {
3066
+ name: "Connect",
3067
+ key: connectDid || ""
3068
+ },
3069
+ user: {
3070
+ address: user.address,
3071
+ networkId: user.networkId,
3072
+ chainId: user.chainId
3073
+ },
3074
+ signatures: []
3075
+ };
3076
+ return {
3077
+ context: { signer },
3078
+ ...action
3079
+ };
3080
+ }
3081
+ function debounceOperations(callback, timeout = 50) {
3082
+ let timer;
3083
+ const operations = [];
3084
+ return (operation) => {
3085
+ if (timer) {
3086
+ clearTimeout(timer);
3087
+ }
3088
+ const index = operations.findIndex((op) => op.scope === operation.scope && op.index === operation.index);
3089
+ if (index > -1) {
3090
+ const oldOperation = operations[index];
3091
+ if (!(oldOperation.type === operation.type && JSON.stringify(operation.input) === JSON.stringify(oldOperation.input))) {
3092
+ console.warn("Two conflicting operations were dispatched:", oldOperation, operation);
3093
+ }
3094
+ operations[index] = operation;
3095
+ } else {
3096
+ operations.push(operation);
3097
+ }
3098
+ return new Promise((resolve, reject) => {
3099
+ timer = setTimeout(() => {
3100
+ callback(operations).then(resolve).catch(reject);
3101
+ }, timeout);
3102
+ });
3103
+ };
3104
+ }
3105
+ function useAddDebouncedOperations(reactor, props) {
3106
+ const { driveId, documentId } = props;
3107
+ const [documentDrives] = useDocumentDrives(reactor);
3108
+ const documentDrivesRef = useRef(documentDrives);
3109
+ const { isAllowedToEditDocuments } = useUserPermissions() || {
3110
+ isAllowedToEditDocuments: false
3111
+ };
3112
+ useEffect(() => {
3113
+ documentDrivesRef.current = documentDrives;
3114
+ }, [documentDrives]);
3115
+ const addOperations = useCallback(async (driveId2, id, operations) => {
3116
+ if (!isAllowedToEditDocuments) {
3117
+ throw new Error("User is not allowed to edit documents");
3118
+ }
3119
+ if (!reactor) {
3120
+ throw new Error("Reactor is not loaded");
3121
+ }
3122
+ const drive = documentDrivesRef.current.find((drive2) => drive2.state.global.id === driveId2);
3123
+ if (!drive) {
3124
+ throw new Error(`Drive with id ${driveId2} not found`);
3125
+ }
3126
+ const newDocument = await reactor.queueOperations(driveId2, id, operations);
3127
+ return newDocument.document;
3128
+ }, [isAllowedToEditDocuments, reactor]);
3129
+ const addDebouncedOperations = useMemo(() => {
3130
+ return debounceOperations((operations) => addOperations(driveId, documentId, operations));
3131
+ }, [addOperations, driveId, documentId]);
3132
+ return addDebouncedOperations;
3133
+ }
3134
+ function useDocumentDispatch(documentReducer, initialState, onError = console.error) {
3135
+ const [state, setState] = useState(initialState);
3136
+ const [error, setError] = useState();
3137
+ const onErrorHandler = (error2) => {
3138
+ setError(error2);
3139
+ onError(error2);
3140
+ };
3141
+ useEffect(() => {
3142
+ setState(initialState);
3143
+ }, [initialState]);
3144
+ const dispatch = (action, callback, onErrorCallback) => {
3145
+ setError(void 0);
3146
+ setState((_state) => {
3147
+ if (!documentReducer || !_state)
3148
+ return _state;
3149
+ try {
3150
+ const newState = documentReducer(_state, action);
3151
+ const scope = action.scope ?? "global";
3152
+ const operations = newState.operations[scope];
3153
+ const operation = operations[operations.length - 1];
3154
+ if (operation.error) {
3155
+ const error2 = new Error(operation.error);
3156
+ onErrorHandler(error2);
3157
+ onErrorCallback == null ? void 0 : onErrorCallback(error2);
3158
+ }
3159
+ callback == null ? void 0 : callback(operation, {
3160
+ prevState: { ..._state },
3161
+ newState: { ...newState }
3162
+ });
3163
+ return newState;
3164
+ } catch (error2) {
3165
+ onErrorHandler(error2);
3166
+ onErrorCallback == null ? void 0 : onErrorCallback(error2);
3167
+ return _state;
3168
+ }
3169
+ });
3170
+ };
3171
+ return [state, dispatch, error];
3172
+ }
3173
+ function useDocumentEditorProps(reactor, props) {
3174
+ const { nodeId, driveId, documentModelModule, document: initialDocument, user, connectDid, sign } = props;
3175
+ const addDebouncedOprations = useAddDebouncedOperations(reactor, {
3176
+ driveId,
3177
+ documentId: nodeId
3178
+ });
3179
+ const [document2, _dispatch, error] = useDocumentDispatch(documentModelModule.reducer, initialDocument);
3180
+ function dispatch(action, onErrorCallback) {
3181
+ const callback = (operation, state) => {
3182
+ const { prevState } = state;
3183
+ signOperation(operation, sign, nodeId, prevState, documentModelModule.reducer, user).then((op) => {
3184
+ return addDebouncedOprations(op);
3185
+ }).catch(console.error);
3186
+ };
3187
+ _dispatch(addActionContext(action, connectDid, user), callback, onErrorCallback);
3188
+ }
3189
+ return {
3190
+ dispatch,
3191
+ document: document2,
3192
+ error
3193
+ };
3194
+ }
3195
+ const generateId = () => generateId$1().toString();
3196
+ function getNode(id, drive) {
3197
+ return drive.state.global.nodes.find((node) => node.id === id);
3198
+ }
3199
+ function createDriveActions(document2, dispatch, context) {
3200
+ const drive = document2;
3201
+ const { id: driveId } = drive.state.global;
3202
+ const { selectedNode } = context;
3203
+ const handleAddFolder = async (name, parentFolder, id = generateId()) => {
3204
+ dispatch(addFolder({
3205
+ id,
3206
+ name,
3207
+ parentFolder: parentFolder ?? null
3208
+ }));
3209
+ };
3210
+ const addDocument = async (name, documentType, document3, parentFolder, id = generateId()) => {
3211
+ const action = generateAddNodeAction(drive.state.global, {
3212
+ id,
3213
+ name,
3214
+ parentFolder: parentFolder ?? null,
3215
+ documentType,
3216
+ document: document3
3217
+ }, ["global"]);
3218
+ dispatch(action);
3219
+ };
3220
+ const addFile = async (file, parentFolder = selectedNode && isFileNode(selectedNode) ? void 0 : selectedNode == null ? void 0 : selectedNode.id, name = file.name.replace(/\.zip$/gim, "")) => {
3221
+ const folder = parentFolder ? getNode(parentFolder, drive) : void 0;
3222
+ if (parentFolder && !folder) {
3223
+ throw new Error(`Parent folder with id "${parentFolder}" not found`);
3224
+ }
3225
+ if (folder && !isFolderNode(folder)) {
3226
+ throw new Error(`Parent folder with id "${parentFolder}" is not a folder`);
3227
+ }
3228
+ await context.addFile(file, driveId, name, parentFolder);
3229
+ };
3230
+ const handleDeleteNode = async (id) => {
3231
+ dispatch(deleteNode({ id }));
3232
+ };
3233
+ const renameNode = async (id, name) => {
3234
+ dispatch(updateNode({ id, name }));
3235
+ };
3236
+ const handleMoveNode = async (sourceId, targetId) => {
3237
+ dispatch(moveNode({
3238
+ srcFolder: sourceId,
3239
+ targetParentFolder: targetId
3240
+ }));
3241
+ };
3242
+ const handleCopyNode = async (sourceId, targetFolderId) => {
3243
+ const target = targetFolderId ? getNode(targetFolderId, drive) : void 0;
3244
+ if (targetFolderId && !target) {
3245
+ throw new Error(`Target node with id "${targetFolderId}" not found`);
3246
+ }
3247
+ if (target && !isFolderNode(target)) {
3248
+ throw new Error(`Target node with id "${targetFolderId}" is not a folder`);
3249
+ }
3250
+ const source = getNode(sourceId, drive);
3251
+ if (!source) {
3252
+ throw new Error(`Source node with id "${sourceId}" not found`);
3253
+ }
3254
+ const copyNodesInput = generateNodesCopy({
3255
+ srcId: sourceId,
3256
+ targetParentFolder: target == null ? void 0 : target.id,
3257
+ targetName: source.name
3258
+ }, generateId, drive.state.global.nodes);
3259
+ const copyActions = copyNodesInput.map((copyNodeInput) => copyNode(copyNodeInput));
3260
+ for (const copyAction of copyActions) {
3261
+ dispatch(copyAction);
3262
+ }
3263
+ };
3264
+ const duplicateNode = async (sourceId) => {
3265
+ const node = getNode(sourceId, drive);
3266
+ if (!node) {
3267
+ throw new Error(`Node with id "${sourceId}" not found`);
3268
+ }
3269
+ await handleCopyNode(node.id, node.parentFolder || void 0);
3270
+ };
3271
+ return {
3272
+ context,
3273
+ selectNode: context.selectNode,
3274
+ addFolder: handleAddFolder,
3275
+ addFile,
3276
+ addDocument,
3277
+ deleteNode: handleDeleteNode,
3278
+ renameNode,
3279
+ moveNode: handleMoveNode,
3280
+ copyNode: handleCopyNode,
3281
+ duplicateNode
3282
+ };
3283
+ }
3284
+ function useDriveActions(document2, dispatch, context) {
3285
+ return useMemo(() => createDriveActions(document2, dispatch, context), [document2, dispatch, context]);
3286
+ }
3287
+ function toNode(uiNode) {
3288
+ if (uiNode.kind === "DRIVE") {
3289
+ throw new Error("Cannot convert drive node to regular node");
3290
+ }
3291
+ const { id, name, parentFolder, kind } = uiNode;
3292
+ if (kind === "FOLDER") {
3293
+ return { id, name, parentFolder, kind: "folder" };
3294
+ } else {
3295
+ const fileNode = uiNode;
3296
+ return {
3297
+ id,
3298
+ name,
3299
+ parentFolder,
3300
+ kind: "file",
3301
+ documentType: fileNode.documentType,
3302
+ synchronizationUnits: fileNode.synchronizationUnits
3303
+ };
3304
+ }
3305
+ }
3306
+ function createUiNodeAdapter(driveActions) {
3307
+ return {
3308
+ ...driveActions,
3309
+ addFile: (file, parentNode) => driveActions.addFile(file, parentNode == null ? void 0 : parentNode.id),
3310
+ addFolder: (name, parentFolder = void 0) => driveActions.addFolder(name, parentFolder),
3311
+ renameNode: (name, node) => {
3312
+ const converted = toNode(node);
3313
+ return driveActions.renameNode(converted.id, name);
3314
+ },
3315
+ deleteNode: (node) => {
3316
+ const converted = toNode(node);
3317
+ return driveActions.deleteNode(converted.id);
3318
+ },
3319
+ moveNode: async (src, target) => {
3320
+ if (target.kind === FILE$1 || src.parentFolder === target.id)
3321
+ return;
3322
+ const srcNode = toNode(src);
3323
+ const targetNode = toNode(target);
3324
+ return driveActions.moveNode(srcNode.id, targetNode.id);
3325
+ },
3326
+ copyNode: (src, target) => {
3327
+ return driveActions.copyNode(src.id, target.id);
3328
+ },
3329
+ duplicateNode: (node) => {
3330
+ const converted = toNode(node);
3331
+ return driveActions.duplicateNode(converted.id);
3332
+ }
3333
+ };
3334
+ }
3335
+ function useDriveActionsWithUiNodes(document2, dispatch) {
3336
+ const { selectedNode, selectedDriveNode, setSelectedNode, getNodeById } = useUiNodesContext();
3337
+ const _driveContext = useDriveContext();
3338
+ const driveContext = useMemo(() => ({
3339
+ ..._driveContext,
3340
+ selectedNode,
3341
+ onSelectNode: (node) => {
3342
+ _driveContext.selectNode(node);
3343
+ setSelectedNode(getNodeById(node.id));
3344
+ }
3345
+ }), [selectedNode, selectedDriveNode == null ? void 0 : selectedDriveNode.driveId, setSelectedNode, getNodeById]);
3346
+ const driveActions = useDriveActions(document2, dispatch, driveContext);
3347
+ const uiNodeActions = useMemo(() => createUiNodeAdapter(driveActions), [driveActions]);
3348
+ return uiNodeActions;
3349
+ }
3013
3350
  function useDocumentEditor(props) {
3014
3351
  const { driveId, documentId, documentType, documentModelModule, user } = props;
3015
3352
  const reactor = useUnwrappedReactor();
@@ -3042,7 +3379,7 @@ function useEditorDispatch(node, documentDispatch, onAddOperation) {
3042
3379
  const callback = (operation, state) => {
3043
3380
  if (!(node == null ? void 0 : node.id)) return;
3044
3381
  const { prevState } = state;
3045
- signOperation(
3382
+ signOperation$1(
3046
3383
  operation,
3047
3384
  sign,
3048
3385
  node.id,
@@ -3058,7 +3395,7 @@ function useEditorDispatch(node, documentDispatch, onAddOperation) {
3058
3395
  }).catch(logger.error);
3059
3396
  };
3060
3397
  documentDispatch(
3061
- addActionContext(action, connectDid, user),
3398
+ addActionContext$1(action, connectDid, user),
3062
3399
  callback,
3063
3400
  onErrorCallback
3064
3401
  );
@@ -3080,7 +3417,7 @@ function useEditorProps(document2, node, documentDispatch, onAddOperation) {
3080
3417
  const { showModal } = useModal();
3081
3418
  const theme = useAtomValue(themeAtom);
3082
3419
  const user = useUser() || void 0;
3083
- const userPermissions = useUserPermissions();
3420
+ const userPermissions = useUserPermissions$1();
3084
3421
  const context = useMemo(() => ({ theme, user }), [theme, user]);
3085
3422
  const {
3086
3423
  selectedParentNode,
@@ -3267,7 +3604,7 @@ const DocumentEditor = (props) => {
3267
3604
  () => documentType ? getEditor(documentType) : void 0,
3268
3605
  [documentType, getEditor]
3269
3606
  );
3270
- const [document2, _dispatch, error] = useDocumentDispatch(
3607
+ const [document2, _dispatch, error] = useDocumentDispatch$1(
3271
3608
  documentModel == null ? void 0 : documentModel.reducer,
3272
3609
  initialDocument
3273
3610
  );
@@ -3275,7 +3612,7 @@ const DocumentEditor = (props) => {
3275
3612
  () => ({ theme, user }),
3276
3613
  [theme, user]
3277
3614
  );
3278
- const userPermissions = useUserPermissions();
3615
+ const userPermissions = useUserPermissions$1();
3279
3616
  const currentDocument = useRef({ ...fileNodeDocument, document: document2 });
3280
3617
  useEffect(() => {
3281
3618
  var _a;
@@ -3295,7 +3632,7 @@ const DocumentEditor = (props) => {
3295
3632
  const callback = (operation, state) => {
3296
3633
  if (!(fileNodeDocument == null ? void 0 : fileNodeDocument.documentId)) return;
3297
3634
  const { prevState } = state;
3298
- signOperation(
3635
+ signOperation$1(
3299
3636
  operation,
3300
3637
  sign,
3301
3638
  fileNodeDocument.documentId,
@@ -3311,7 +3648,7 @@ const DocumentEditor = (props) => {
3311
3648
  }).catch(logger.error);
3312
3649
  };
3313
3650
  _dispatch(
3314
- addActionContext(action, connectDid, user),
3651
+ addActionContext$1(action, connectDid, user),
3315
3652
  callback,
3316
3653
  onErrorCallback
3317
3654
  );
@@ -3751,7 +4088,7 @@ function BaseEditor(props) {
3751
4088
  const { showSearchBar, isAllowedToCreateDocuments, documentModels, showCreateDocumentModal } = useDriveContext();
3752
4089
  const { driveNodes, selectedNode, selectedNodePath, getNodeById, setSelectedNode } = useUiNodesContext();
3753
4090
  const driveNode = useMemo(() => driveNodes.find((n) => n.id === driveId), [driveNodes, driveId]);
3754
- const { addDocument, addFile, addFolder, renameNode, deleteNode, moveNode, copyNode, duplicateNode } = useDriveActionsWithUiNodes(document2, dispatch);
4091
+ const { addDocument, addFile, addFolder: addFolder2, renameNode, deleteNode: deleteNode2, moveNode: moveNode2, copyNode: copyNode2, duplicateNode } = useDriveActionsWithUiNodes(document2, dispatch);
3755
4092
  const onCreateDocument = useCallback(async (documentModel) => {
3756
4093
  const { name } = await showCreateDocumentModal(documentModel);
3757
4094
  const document3 = documentModel.utils.createDocument();
@@ -3760,8 +4097,8 @@ function BaseEditor(props) {
3760
4097
  const { isDropTarget, dropProps } = useDrop({
3761
4098
  uiNode: selectedNode,
3762
4099
  onAddFile: addFile,
3763
- onCopyNode: copyNode,
3764
- onMoveNode: moveNode
4100
+ onCopyNode: copyNode2,
4101
+ onMoveNode: moveNode2
3765
4102
  });
3766
4103
  const { breadcrumbs, onBreadcrumbSelected } = useBreadcrumbs({
3767
4104
  selectedNodePath,
@@ -3773,7 +4110,7 @@ function BaseEditor(props) {
3773
4110
  } else if ((selectedNode == null ? void 0 : selectedNode.kind) === FILE$1) {
3774
4111
  return jsx(Fragment$1, {});
3775
4112
  }
3776
- return jsxs(DriveLayout, { className, children: [children, jsxs(DriveLayout.Header, { children: [jsx(Breadcrumbs, { breadcrumbs, createEnabled: isAllowedToCreateDocuments, onCreate: addFolder, onBreadcrumbSelected }), showSearchBar && jsx(SearchBar, {})] }), jsx(DriveLayout.Content, { children: jsx(FolderView, { node: selectedNode || driveNode, onSelectNode: setSelectedNode, onRenameNode: renameNode, onDuplicateNode: duplicateNode, onDeleteNode: deleteNode, onAddFile: addFile, onCopyNode: copyNode, onMoveNode: moveNode, isDropTarget, isAllowedToCreateDocuments }) }), jsx(DriveLayout.Footer, { children: isAllowedToCreateDocuments && jsx(CreateDocument, { documentModels, createDocument: onCreateDocument }) })] });
4113
+ return jsxs(DriveLayout, { className, children: [children, jsxs(DriveLayout.Header, { children: [jsx(Breadcrumbs, { breadcrumbs, createEnabled: isAllowedToCreateDocuments, onCreate: addFolder2, onBreadcrumbSelected }), showSearchBar && jsx(SearchBar, {})] }), jsx(DriveLayout.Content, { children: jsx(FolderView, { node: selectedNode || driveNode, onSelectNode: setSelectedNode, onRenameNode: renameNode, onDuplicateNode: duplicateNode, onDeleteNode: deleteNode2, onAddFile: addFile, onCopyNode: copyNode2, onMoveNode: moveNode2, isDropTarget, isAllowedToCreateDocuments }) }), jsx(DriveLayout.Footer, { children: isAllowedToCreateDocuments && jsx(CreateDocument, { documentModels, createDocument: onCreateDocument }) })] });
3777
4114
  }
3778
4115
  function Editor(props) {
3779
4116
  return jsx(DriveContextProvider, { value: props.context, children: jsx(BaseEditor, { ...props }) });
@@ -3781,6 +4118,80 @@ function Editor(props) {
3781
4118
  const GenericDriveExplorer = {
3782
4119
  Component: Editor
3783
4120
  };
4121
+ function useDocumentsState(args) {
4122
+ const { reactor, driveId, documentIds, options } = args;
4123
+ const [statesByDocumentId, setStatesByDocumentId] = useState({});
4124
+ const isInitialized = useRef(false);
4125
+ const isSubscribed = useRef(false);
4126
+ useEffect(() => {
4127
+ async function initialize() {
4128
+ if (isInitialized.current)
4129
+ return;
4130
+ if (!reactor || !driveId)
4131
+ return;
4132
+ isInitialized.current = true;
4133
+ const ids = documentIds ?? await reactor.getDocuments(driveId);
4134
+ const statesByDocumentId2 = {};
4135
+ for (const id of ids) {
4136
+ const document2 = await reactor.getDocument(driveId, id, options);
4137
+ statesByDocumentId2[id] = {
4138
+ ...document2.state,
4139
+ documentType: document2.documentType,
4140
+ revision: document2.revision,
4141
+ created: document2.created,
4142
+ lastModified: document2.lastModified
4143
+ };
4144
+ }
4145
+ setStatesByDocumentId(statesByDocumentId2);
4146
+ }
4147
+ void initialize();
4148
+ }, [reactor, driveId, options]);
4149
+ useEffect(() => {
4150
+ if (!reactor || !driveId)
4151
+ return;
4152
+ if (isSubscribed.current)
4153
+ return;
4154
+ isSubscribed.current = true;
4155
+ const unsubscribe = reactor.on("strandUpdate", async (update) => {
4156
+ if (update.driveId !== driveId || documentIds && !documentIds.includes(update.documentId))
4157
+ return;
4158
+ const updatedDocument = await reactor.getDocument(driveId, update.documentId, options);
4159
+ setStatesByDocumentId((prev) => {
4160
+ const newStatesByDocumentId = { ...prev };
4161
+ newStatesByDocumentId[update.documentId] = {
4162
+ ...updatedDocument.state,
4163
+ documentType: updatedDocument.documentType,
4164
+ revision: updatedDocument.revision,
4165
+ created: updatedDocument.created,
4166
+ lastModified: updatedDocument.lastModified
4167
+ };
4168
+ return newStatesByDocumentId;
4169
+ });
4170
+ });
4171
+ return unsubscribe;
4172
+ }, [reactor, driveId, options]);
4173
+ return useMemo(() => statesByDocumentId, [statesByDocumentId]);
4174
+ }
4175
+ function makeDriveDocumentStateHook(reactor) {
4176
+ const useDriveDocumentState = useCallback((args) => {
4177
+ const { driveId, documentId } = args;
4178
+ return useDocumentState({
4179
+ reactor,
4180
+ driveId,
4181
+ documentId
4182
+ });
4183
+ }, [reactor]);
4184
+ return useDriveDocumentState;
4185
+ }
4186
+ function useDocumentState(args) {
4187
+ const { reactor, driveId, documentId } = args;
4188
+ const state = useDocumentsState({
4189
+ reactor,
4190
+ driveId,
4191
+ documentIds: [documentId]
4192
+ });
4193
+ return useMemo(() => state[documentId], [state, documentId]);
4194
+ }
3784
4195
  function useGetDriveDocuments(props) {
3785
4196
  const { driveId } = props;
3786
4197
  const [documents, setDocuments] = useState({});
@@ -3858,7 +4269,7 @@ function DriveEditorContainer() {
3858
4269
  } = useUiNodesContext();
3859
4270
  const { addOperationToSelectedDrive } = useUiNodes();
3860
4271
  const documentDrive = useSelectedDocumentDrive();
3861
- const [document2, _dispatch, error] = useDocumentDispatch(
4272
+ const [document2, _dispatch, error] = useDocumentDispatch$1(
3862
4273
  driveDocumentModelModule.reducer,
3863
4274
  documentDrive
3864
4275
  );
@@ -3950,7 +4361,7 @@ function DriveEditorContainer() {
3950
4361
  function Content() {
3951
4362
  const navigate = useNavigate();
3952
4363
  const { driveId } = useParams();
3953
- const [documentDrives, , , status] = useDocumentDrives();
4364
+ const [documentDrives, , , status] = useDocumentDrives$1();
3954
4365
  const uiNodes = useUiNodes();
3955
4366
  const { fileNodeDocument, selectedDriveNode, selectedNode, addFile } = uiNodes;
3956
4367
  useEffect(() => {
@@ -1,8 +1,8 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/app-loader-Btk_wf_z.js","assets/main.C1DJvpcL.js","assets/app-loader-DiF8OhX3.css"])))=>i.map(i=>d[i]);
2
- import { _ as __vitePreload } from "./main.C1DJvpcL.js";
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/app-loader-nik9-lTL.js","assets/main.BuoJ8woF.js","assets/app-loader-DiF8OhX3.css"])))=>i.map(i=>d[i]);
2
+ import { _ as __vitePreload } from "./main.BuoJ8woF.js";
3
3
  import { createRoot } from "react-dom/client";
4
4
  async function renderApp(element) {
5
- const AppLoader = await __vitePreload(() => import("./app-loader-Btk_wf_z.js").then((n) => n.c9), true ? __vite__mapDeps([0,1,2]) : void 0);
5
+ const AppLoader = await __vitePreload(() => import("./app-loader-nik9-lTL.js").then((n) => n.ca), true ? __vite__mapDeps([0,1,2]) : void 0);
6
6
  createRoot(element).render(AppLoader.default);
7
7
  }
8
8
  const AppElement = document.getElementById("app");