@powerhousedao/reactor-browser 1.10.2 → 1.11.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 (108) hide show
  1. package/dist/package.json +47 -0
  2. package/dist/src/context/index.d.ts +1 -1
  3. package/dist/src/context/index.d.ts.map +1 -1
  4. package/dist/src/context/index.js +1 -0
  5. package/dist/src/context/read-mode.d.ts +3 -3
  6. package/dist/src/context/read-mode.d.ts.map +1 -1
  7. package/dist/src/context/read-mode.js +198 -0
  8. package/dist/src/crypto/browser.d.ts +1 -1
  9. package/dist/src/crypto/browser.d.ts.map +1 -1
  10. package/dist/src/crypto/browser.js +49 -0
  11. package/dist/src/crypto/index.js +121 -0
  12. package/dist/src/document-model.d.ts +3 -3
  13. package/dist/src/document-model.d.ts.map +1 -1
  14. package/dist/src/document-model.js +5 -0
  15. package/dist/src/hooks/index.d.ts +9 -5
  16. package/dist/src/hooks/index.d.ts.map +1 -1
  17. package/dist/src/hooks/index.js +9 -0
  18. package/dist/src/hooks/useAddDebouncedOperations.d.ts +3 -3
  19. package/dist/src/hooks/useAddDebouncedOperations.d.ts.map +1 -1
  20. package/dist/src/hooks/useAddDebouncedOperations.js +55 -0
  21. package/dist/src/hooks/useConnectCrypto.d.ts +1 -1
  22. package/dist/src/hooks/useConnectCrypto.d.ts.map +1 -1
  23. package/dist/src/hooks/useConnectCrypto.js +40 -0
  24. package/dist/src/hooks/useDocument.d.ts +3 -3
  25. package/dist/src/hooks/useDocument.d.ts.map +1 -1
  26. package/dist/src/hooks/useDocument.js +37 -0
  27. package/dist/src/hooks/useDocumentDispatch.d.ts +6 -10
  28. package/dist/src/hooks/useDocumentDispatch.d.ts.map +1 -1
  29. package/dist/src/hooks/useDocumentDispatch.js +41 -0
  30. package/dist/src/hooks/useDocumentDrives.d.ts +4 -3
  31. package/dist/src/hooks/useDocumentDrives.d.ts.map +1 -1
  32. package/dist/src/hooks/useDocumentDrives.js +84 -0
  33. package/dist/src/hooks/useDocumentEditor.d.ts +13 -13
  34. package/dist/src/hooks/useDocumentEditor.d.ts.map +1 -1
  35. package/dist/src/hooks/useDocumentEditor.js +30 -0
  36. package/dist/src/hooks/useDriveActions.d.ts +82 -0
  37. package/dist/src/hooks/useDriveActions.d.ts.map +1 -0
  38. package/dist/src/hooks/useDriveActions.js +125 -0
  39. package/dist/src/hooks/useDriveActionsWithUiNodes.d.ts +17 -0
  40. package/dist/src/hooks/useDriveActionsWithUiNodes.d.ts.map +1 -0
  41. package/dist/src/hooks/useDriveActionsWithUiNodes.js +71 -0
  42. package/dist/src/hooks/useDriveContext.d.ts +66 -0
  43. package/dist/src/hooks/useDriveContext.d.ts.map +1 -0
  44. package/dist/src/hooks/useDriveContext.js +25 -0
  45. package/dist/src/hooks/useUiNodesContext.d.ts +25 -0
  46. package/dist/src/hooks/useUiNodesContext.d.ts.map +1 -0
  47. package/dist/src/hooks/useUiNodesContext.js +167 -0
  48. package/dist/src/hooks/useUserPermissions.js +6 -0
  49. package/dist/src/index.d.ts +5 -5
  50. package/dist/src/index.d.ts.map +1 -1
  51. package/dist/src/index.js +4 -0
  52. package/dist/src/reactor.d.ts +3 -3
  53. package/dist/src/reactor.d.ts.map +1 -1
  54. package/dist/src/reactor.js +54 -0
  55. package/dist/src/renown/constants.js +39 -0
  56. package/dist/src/renown/types.d.ts +3 -3
  57. package/dist/src/renown/types.d.ts.map +1 -1
  58. package/dist/src/renown/types.js +1 -0
  59. package/dist/src/storage/index.d.ts +1 -1
  60. package/dist/src/storage/index.d.ts.map +1 -1
  61. package/dist/src/storage/index.js +1 -0
  62. package/dist/src/storage/types.js +1 -0
  63. package/dist/src/uiNodes/constants.d.ts +17 -0
  64. package/dist/src/uiNodes/constants.d.ts.map +1 -0
  65. package/dist/src/uiNodes/constants.js +23 -0
  66. package/dist/src/uiNodes/types.d.ts +61 -0
  67. package/dist/src/uiNodes/types.d.ts.map +1 -0
  68. package/dist/src/uiNodes/types.js +1 -0
  69. package/dist/src/utils/index.d.ts +3 -3
  70. package/dist/src/utils/index.d.ts.map +1 -1
  71. package/dist/src/utils/index.js +8 -0
  72. package/dist/src/utils/signature.d.ts +3 -3
  73. package/dist/src/utils/signature.d.ts.map +1 -1
  74. package/dist/src/utils/signature.js +39 -0
  75. package/dist/tsconfig.tsbuildinfo +1 -0
  76. package/package.json +15 -22
  77. package/dist/_virtual/__vite-browser-external.js +0 -5
  78. package/dist/_virtual/__vite-browser-external.js.map +0 -1
  79. package/dist/context/read-mode.js +0 -159
  80. package/dist/context/read-mode.js.map +0 -1
  81. package/dist/crypto/browser.js +0 -50
  82. package/dist/crypto/browser.js.map +0 -1
  83. package/dist/crypto/index.js +0 -109
  84. package/dist/crypto/index.js.map +0 -1
  85. package/dist/document-model.js +0 -11
  86. package/dist/document-model.js.map +0 -1
  87. package/dist/hooks/useAddDebouncedOperations.js +0 -54
  88. package/dist/hooks/useAddDebouncedOperations.js.map +0 -1
  89. package/dist/hooks/useConnectCrypto.js +0 -34
  90. package/dist/hooks/useConnectCrypto.js.map +0 -1
  91. package/dist/hooks/useDocument.js +0 -20
  92. package/dist/hooks/useDocument.js.map +0 -1
  93. package/dist/hooks/useDocumentDispatch.js +0 -30
  94. package/dist/hooks/useDocumentDispatch.js.map +0 -1
  95. package/dist/hooks/useDocumentDrives.js +0 -86
  96. package/dist/hooks/useDocumentDrives.js.map +0 -1
  97. package/dist/hooks/useDocumentEditor.js +0 -46
  98. package/dist/hooks/useDocumentEditor.js.map +0 -1
  99. package/dist/hooks/useUserPermissions.js +0 -10
  100. package/dist/hooks/useUserPermissions.js.map +0 -1
  101. package/dist/index.js +0 -26
  102. package/dist/index.js.map +0 -1
  103. package/dist/reactor.js +0 -59
  104. package/dist/reactor.js.map +0 -1
  105. package/dist/utils/index.js +0 -16
  106. package/dist/utils/index.js.map +0 -1
  107. package/dist/utils/signature.js +0 -35
  108. package/dist/utils/signature.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"useDocument.d.ts","sourceRoot":"","sources":["../../../src/hooks/useDocument.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAgB,MAAM,uBAAuB,CAAC;AAE3E,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,wBAAgB,WAAW,CACzB,OAAO,EAAE,oBAAoB,GAAG,SAAS,EACzC,YAAY,GAAE,YAAiB,wBA2ChC"}
1
+ {"version":3,"file":"useDocument.d.ts","sourceRoot":"","sources":["../../../src/hooks/useDocument.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAgB,MAAM,gBAAgB,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAG5C,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,wBAAgB,WAAW,CACzB,OAAO,EAAE,oBAAoB,GAAG,SAAS,EACzC,YAAY,GAAE,YAAiB,0BA2ChC"}
@@ -0,0 +1,37 @@
1
+ import { useCallback, useEffect, useState } from "react";
2
+ export function useDocument(reactor, documentMeta = {}) {
3
+ const { documentId, documentType, driveId } = documentMeta;
4
+ const [document, setDocument] = useState();
5
+ const onStrandUpdate = useCallback((cb) => {
6
+ if (!reactor) {
7
+ throw new Error("Reactor is not loaded");
8
+ }
9
+ return reactor.on("strandUpdate", cb);
10
+ }, [reactor]);
11
+ useEffect(() => {
12
+ if (!reactor)
13
+ return;
14
+ if (!driveId || !documentId || !documentType)
15
+ return;
16
+ reactor
17
+ .getDocument(driveId, documentId)
18
+ .then(setDocument)
19
+ .catch(console.error);
20
+ }, [driveId, documentId, documentType, reactor]);
21
+ useEffect(() => {
22
+ if (!reactor)
23
+ return;
24
+ if (!driveId || !documentId || !documentType)
25
+ return;
26
+ const removeListener = onStrandUpdate((strand) => {
27
+ if (strand.driveId === driveId && strand.documentId === documentId) {
28
+ reactor
29
+ .getDocument(driveId, documentId)
30
+ .then(setDocument)
31
+ .catch(console.error);
32
+ }
33
+ });
34
+ return removeListener;
35
+ }, [onStrandUpdate, driveId, documentId, documentType]);
36
+ return document;
37
+ }
@@ -1,14 +1,10 @@
1
- import { Action, ActionErrorCallback, BaseAction, Document, Operation, Reducer } from 'document-model/document';
2
- export type DocumentDispatchCallback<State, A extends Action, LocalState> = (operation: Operation, state: {
3
- prevState: Document<State, A, LocalState>;
4
- newState: Document<State, A, LocalState>;
1
+ import type { ActionErrorCallback, ActionFromDocument, OperationFromDocument, PHDocument, Reducer } from "document-model";
2
+ export type DocumentDispatchCallback<TDocument extends PHDocument> = (operation: OperationFromDocument<TDocument>, state: {
3
+ prevState: TDocument;
4
+ newState: TDocument;
5
5
  }) => void;
6
- export type DocumentDispatch<State, A extends Action, LocalState> = (action: A | BaseAction, callback?: DocumentDispatchCallback<State, A, LocalState>, onErrorCallback?: ActionErrorCallback) => void;
6
+ export type DocumentDispatch<TDocument extends PHDocument> = (action: ActionFromDocument<TDocument>, callback?: DocumentDispatchCallback<TDocument>, onErrorCallback?: ActionErrorCallback) => void;
7
7
  type OnErrorHandler = (error: unknown) => void;
8
- export declare function useDocumentDispatch<State, A extends Action, LocalState>(documentReducer: Reducer<State, A, LocalState> | undefined, initialState: Document<State, A, LocalState> | undefined, onError?: OnErrorHandler): readonly [
9
- Document<State, A, LocalState> | undefined,
10
- DocumentDispatch<State, A, LocalState>,
11
- unknown
12
- ];
8
+ export declare function useDocumentDispatch<TDocument extends PHDocument>(documentReducer: Reducer<TDocument> | undefined, initialState: TDocument | undefined, onError?: OnErrorHandler): readonly [TDocument | undefined, DocumentDispatch<TDocument>, unknown];
13
9
  export {};
14
10
  //# sourceMappingURL=useDocumentDispatch.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useDocumentDispatch.d.ts","sourceRoot":"","sources":["../../../src/hooks/useDocumentDispatch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EACN,mBAAmB,EACnB,UAAU,EACV,QAAQ,EACR,SAAS,EACT,OAAO,EACR,MAAM,yBAAyB,CAAC;AAGjC,MAAM,MAAM,wBAAwB,CAAC,KAAK,EAAE,CAAC,SAAS,MAAM,EAAE,UAAU,IAAI,CAC1E,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE;IACL,SAAS,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC;IAC1C,QAAQ,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC;CAC1C,KACE,IAAI,CAAC;AAEV,MAAM,MAAM,gBAAgB,CAAC,KAAK,EAAE,CAAC,SAAS,MAAM,EAAE,UAAU,IAAI,CAClE,MAAM,EAAE,CAAC,GAAG,UAAU,EACtB,QAAQ,CAAC,EAAE,wBAAwB,CAAC,KAAK,EAAE,CAAC,EAAE,UAAU,CAAC,EACzD,eAAe,CAAC,EAAE,mBAAmB,KAClC,IAAI,CAAC;AAEV,KAAK,cAAc,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;AAE/C,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,CAAC,SAAS,MAAM,EAAE,UAAU,EACrE,eAAe,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,UAAU,CAAC,GAAG,SAAS,EAC1D,YAAY,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,UAAU,CAAC,GAAG,SAAS,EACxD,OAAO,GAAE,cAA8B,GACtC,SAAS;IACV,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,UAAU,CAAC,GAAG,SAAS;IAC1C,gBAAgB,CAAC,KAAK,EAAE,CAAC,EAAE,UAAU,CAAC;IACtC,OAAO;CACR,CAkDA"}
1
+ {"version":3,"file":"useDocumentDispatch.d.ts","sourceRoot":"","sources":["../../../src/hooks/useDocumentDispatch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EACrB,UAAU,EACV,OAAO,EACR,MAAM,gBAAgB,CAAC;AAGxB,MAAM,MAAM,wBAAwB,CAAC,SAAS,SAAS,UAAU,IAAI,CACnE,SAAS,EAAE,qBAAqB,CAAC,SAAS,CAAC,EAC3C,KAAK,EAAE;IACL,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,SAAS,CAAC;CACrB,KACE,IAAI,CAAC;AAEV,MAAM,MAAM,gBAAgB,CAAC,SAAS,SAAS,UAAU,IAAI,CAC3D,MAAM,EAAE,kBAAkB,CAAC,SAAS,CAAC,EACrC,QAAQ,CAAC,EAAE,wBAAwB,CAAC,SAAS,CAAC,EAC9C,eAAe,CAAC,EAAE,mBAAmB,KAClC,IAAI,CAAC;AAEV,KAAK,cAAc,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;AAE/C,wBAAgB,mBAAmB,CAAC,SAAS,SAAS,UAAU,EAC9D,eAAe,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,EAC/C,YAAY,EAAE,SAAS,GAAG,SAAS,EACnC,OAAO,GAAE,cAA8B,GACtC,SAAS,CAAC,SAAS,GAAG,SAAS,EAAE,gBAAgB,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,CAkDxE"}
@@ -0,0 +1,41 @@
1
+ import { useEffect, useState } from "react";
2
+ export function useDocumentDispatch(documentReducer, initialState, onError = console.error) {
3
+ const [state, setState] = useState(initialState);
4
+ const [error, setError] = useState();
5
+ const onErrorHandler = (error) => {
6
+ setError(error);
7
+ onError(error);
8
+ };
9
+ useEffect(() => {
10
+ setState(initialState);
11
+ }, [initialState]);
12
+ const dispatch = (action, callback, onErrorCallback) => {
13
+ setError(undefined);
14
+ setState((_state) => {
15
+ if (!documentReducer || !_state)
16
+ return _state;
17
+ try {
18
+ const newState = documentReducer(_state, action);
19
+ const scope = action.scope ?? "global";
20
+ const operations = newState.operations[scope];
21
+ const operation = operations[operations.length - 1];
22
+ if (operation.error) {
23
+ const error = new Error(operation.error);
24
+ onErrorHandler(error);
25
+ onErrorCallback?.(error);
26
+ }
27
+ callback?.(operation, {
28
+ prevState: { ..._state },
29
+ newState: { ...newState },
30
+ });
31
+ return newState;
32
+ }
33
+ catch (error) {
34
+ onErrorHandler(error);
35
+ onErrorCallback?.(error);
36
+ return _state;
37
+ }
38
+ });
39
+ };
40
+ return [state, dispatch, error];
41
+ }
@@ -1,8 +1,9 @@
1
- import { IDocumentDriveServer } from 'document-drive/server';
2
- import { DocumentDriveDocument, Trigger } from 'document-model-libs/document-drive';
1
+ import type { IDocumentDriveServer } from "document-drive";
2
+ import { DocumentDriveDocument } from "document-drive";
3
+ import { Trigger } from "document-drive";
3
4
  export declare function drivesToHash(drives: DocumentDriveDocument[]): string;
4
5
  export type IDrivesState = "INITIAL" | "LOADING" | "LOADED" | "ERROR";
5
- export declare const documentDrivesInitializedMapAtomFamily: import('jotai/vanilla/utils/atomFamily').AtomFamily<unknown, import('jotai').PrimitiveAtom<IDrivesState> & {
6
+ export declare const documentDrivesInitializedMapAtomFamily: import("jotai/vanilla/utils/atomFamily").AtomFamily<unknown, import("jotai").PrimitiveAtom<IDrivesState> & {
6
7
  init: IDrivesState;
7
8
  }>;
8
9
  export type ClientErrorHandler = {
@@ -1 +1 @@
1
- {"version":3,"file":"useDocumentDrives.d.ts","sourceRoot":"","sources":["../../../src/hooks/useDocumentDrives.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAG3E,OAAO,EAAE,OAAO,EAAE,MAAM,oCAAoC,CAAC;AAQ7D,wBAAgB,YAAY,CAAC,MAAM,EAAE,qBAAqB,EAAE,GAAG,MAAM,CAEpE;AAuBD,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AACtE,eAAO,MAAM,sCAAsC;;EAElD,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,mBAAmB,EAAE,CACnB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,KACjB,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE,oBAAoB,gFAwCvC,kBAAkB,6CA2C1C"}
1
+ {"version":3,"file":"useDocumentDrives.d.ts","sourceRoot":"","sources":["../../../src/hooks/useDocumentDrives.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAGvD,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAQzC,wBAAgB,YAAY,CAAC,MAAM,EAAE,qBAAqB,EAAE,GAAG,MAAM,CAEpE;AAuBD,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AACtE,eAAO,MAAM,sCAAsC;;EAElD,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,mBAAmB,EAAE,CACnB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,KACjB,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE,oBAAoB,gFAwCvC,kBAAkB,6CA2C1C"}
@@ -0,0 +1,84 @@
1
+ import { useMemo, useCallback } from "react";
2
+ import { atom, useAtom } from "jotai";
3
+ import { atomFamily } from "jotai/utils";
4
+ import { documentToHash } from "../utils/index.js";
5
+ const documentDrivesAtom = atom(new Map());
6
+ export function drivesToHash(drives) {
7
+ return drives.map(documentToHash).join("&");
8
+ }
9
+ const readWriteDocumentDrivesAtom = (server) => () => atom((get) => (server ? (get(documentDrivesAtom).get(server) ?? []) : []), (_get, set, newDrives) => {
10
+ set(documentDrivesAtom, (map) => {
11
+ if (!server) {
12
+ return new Map();
13
+ }
14
+ const currentDrives = map.get(server) ?? [];
15
+ if (currentDrives.length !== newDrives.length ||
16
+ drivesToHash(currentDrives) !== drivesToHash(newDrives)) {
17
+ return new Map(map).set(server, newDrives);
18
+ }
19
+ else {
20
+ return map;
21
+ }
22
+ });
23
+ });
24
+ export const documentDrivesInitializedMapAtomFamily = atomFamily(() => atom("INITIAL"));
25
+ export function useDocumentDrives(reactor) {
26
+ const [documentDrives, setDocumentDrives] = useAtom(useMemo(readWriteDocumentDrivesAtom(reactor), [reactor]));
27
+ const refreshDocumentDrives = useCallback(async () => {
28
+ if (!reactor) {
29
+ return;
30
+ }
31
+ const documentDrives = [];
32
+ try {
33
+ const driveIds = await reactor.getDrives();
34
+ for (const id of driveIds) {
35
+ try {
36
+ const drive = await reactor.getDrive(id);
37
+ documentDrives.push(drive);
38
+ }
39
+ catch (error) {
40
+ console.error(error);
41
+ }
42
+ }
43
+ }
44
+ catch (error) {
45
+ console.error(error);
46
+ }
47
+ finally {
48
+ setDocumentDrives(documentDrives);
49
+ }
50
+ }, [reactor]);
51
+ const [status, setStatus] = useAtom(documentDrivesInitializedMapAtomFamily(reactor));
52
+ if (status === "INITIAL") {
53
+ setStatus("LOADING");
54
+ refreshDocumentDrives()
55
+ .then(() => setStatus("LOADED"))
56
+ .catch(() => setStatus("ERROR"));
57
+ }
58
+ const serverSubscribeUpdates = useCallback((clientErrorhandler) => {
59
+ if (!reactor) {
60
+ return;
61
+ }
62
+ const unsub1 = reactor.on("syncStatus", async (_event, _status, error) => {
63
+ if (error) {
64
+ console.error(error);
65
+ }
66
+ await refreshDocumentDrives();
67
+ });
68
+ const unsub2 = reactor.on("strandUpdate", () => refreshDocumentDrives());
69
+ const unsubOnSyncError = reactor.on("clientStrandsError", clientErrorhandler.strandsErrorHandler);
70
+ const unsub3 = reactor.on("defaultRemoteDrive", () => refreshDocumentDrives());
71
+ return () => {
72
+ unsub1();
73
+ unsub2();
74
+ unsubOnSyncError();
75
+ unsub3();
76
+ };
77
+ }, [reactor, refreshDocumentDrives]);
78
+ return useMemo(() => [
79
+ documentDrives,
80
+ refreshDocumentDrives,
81
+ serverSubscribeUpdates,
82
+ status,
83
+ ], [documentDrives, status]);
84
+ }
@@ -1,23 +1,23 @@
1
- import { Action, Document, Operation, BaseAction, DocumentModel, ActionErrorCallback } from 'document-model/document';
2
- import { IDocumentDriveServer } from 'document-drive';
3
- import { User } from '../renown/types';
4
- export type DocumentDispatchCallback<State, A extends Action, LocalState> = (operation: Operation, state: {
5
- prevState: Document<State, A, LocalState>;
6
- newState: Document<State, A, LocalState>;
1
+ import { IDocumentDriveServer } from "document-drive";
2
+ import { ActionErrorCallback, ActionFromDocument, DocumentModelModule, OperationFromDocument, PHDocument } from "document-model";
3
+ import { User } from "../renown/types.js";
4
+ export type DocumentDispatchCallback<TDocument extends PHDocument> = (operation: OperationFromDocument<TDocument>, state: {
5
+ prevState: TDocument;
6
+ newState: TDocument;
7
7
  }) => void;
8
- export type UseDocumentEditorProps<T = unknown, A extends Action = Action, LocalState = unknown> = {
8
+ export type UseDocumentEditorProps<TDocument extends PHDocument> = {
9
9
  driveId: string;
10
10
  nodeId: string;
11
- document: Document<T, A, LocalState> | undefined;
12
- documentModel: DocumentModel<unknown, Action>;
11
+ document: TDocument | undefined;
12
+ documentModelModule: DocumentModelModule<TDocument>;
13
13
  user?: User;
14
14
  onExport?: () => void;
15
15
  onOpenSwitchboardLink?: () => Promise<void>;
16
- onChange?: (document: Document<T, A, LocalState>) => void;
16
+ onChange?: (document: TDocument) => void;
17
17
  };
18
- export declare function useDocumentEditor(reactor: IDocumentDriveServer | undefined, props: UseDocumentEditorProps): {
19
- dispatch: (action: BaseAction | Action, onErrorCallback?: ActionErrorCallback) => void;
20
- document: Document<unknown, Action, unknown> | undefined;
18
+ export declare function useDocumentEditor<TDocument extends PHDocument>(reactor: IDocumentDriveServer | undefined, props: UseDocumentEditorProps<TDocument>): {
19
+ dispatch: (action: ActionFromDocument<TDocument>, onErrorCallback?: ActionErrorCallback) => void;
20
+ document: TDocument | undefined;
21
21
  error: unknown;
22
22
  };
23
23
  //# sourceMappingURL=useDocumentEditor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useDocumentEditor.d.ts","sourceRoot":"","sources":["../../../src/hooks/useDocumentEditor.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,QAAQ,EACR,SAAS,EACT,UAAU,EACV,aAAa,EACb,mBAAmB,EACpB,MAAM,yBAAyB,CAAC;AAKjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAEvC,MAAM,MAAM,wBAAwB,CAAC,KAAK,EAAE,CAAC,SAAS,MAAM,EAAE,UAAU,IAAI,CAC1E,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE;IACL,SAAS,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC;IAC1C,QAAQ,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC;CAC1C,KACE,IAAI,CAAC;AAEV,MAAM,MAAM,sBAAsB,CAChC,CAAC,GAAG,OAAO,EACX,CAAC,SAAS,MAAM,GAAG,MAAM,EACzB,UAAU,GAAG,OAAO,IAClB;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,GAAG,SAAS,CAAC;IACjD,aAAa,EAAE,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC9C,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,qBAAqB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,KAAK,IAAI,CAAC;CAC3D,CAAC;AAEF,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,oBAAoB,GAAG,SAAS,EACzC,KAAK,EAAE,sBAAsB;uBAwBnB,UAAU,GAAG,MAAM,oBACT,mBAAmB;;;EAkCxC"}
1
+ {"version":3,"file":"useDocumentEditor.d.ts","sourceRoot":"","sources":["../../../src/hooks/useDocumentEditor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,UAAU,EACX,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAM1C,MAAM,MAAM,wBAAwB,CAAC,SAAS,SAAS,UAAU,IAAI,CACnE,SAAS,EAAE,qBAAqB,CAAC,SAAS,CAAC,EAC3C,KAAK,EAAE;IACL,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,SAAS,CAAC;CACrB,KACE,IAAI,CAAC;AAEV,MAAM,MAAM,sBAAsB,CAAC,SAAS,SAAS,UAAU,IAAI;IACjE,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,SAAS,GAAG,SAAS,CAAC;IAChC,mBAAmB,EAAE,mBAAmB,CAAC,SAAS,CAAC,CAAC;IACpD,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,qBAAqB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,KAAK,IAAI,CAAC;CAC1C,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,SAAS,SAAS,UAAU,EAC5D,OAAO,EAAE,oBAAoB,GAAG,SAAS,EACzC,KAAK,EAAE,sBAAsB,CAAC,SAAS,CAAC;uBAwB9B,kBAAkB,CAAC,SAAS,CAAC,oBACnB,mBAAmB;;;EAkCxC"}
@@ -0,0 +1,30 @@
1
+ import { addActionContext, signOperation } from "../utils/signature.js";
2
+ import { useAddDebouncedOperations } from "./useAddDebouncedOperations.js";
3
+ import { useConnectCrypto, useConnectDid } from "./useConnectCrypto.js";
4
+ import { useDocumentDispatch } from "./useDocumentDispatch.js";
5
+ export function useDocumentEditor(reactor, props) {
6
+ const { nodeId, driveId, documentModelModule, document: initialDocument, user, } = props;
7
+ const connectDid = useConnectDid();
8
+ const { sign } = useConnectCrypto();
9
+ const addDebouncedOprations = useAddDebouncedOperations(reactor, {
10
+ driveId,
11
+ documentId: nodeId,
12
+ });
13
+ const [document, _dispatch, error] = useDocumentDispatch(documentModelModule.reducer, initialDocument);
14
+ function dispatch(action, onErrorCallback) {
15
+ const callback = (operation, state) => {
16
+ const { prevState } = state;
17
+ signOperation(operation, sign, nodeId, prevState, documentModelModule.reducer, user)
18
+ .then((op) => {
19
+ return addDebouncedOprations(op);
20
+ })
21
+ .catch(console.error);
22
+ };
23
+ _dispatch(addActionContext(action, connectDid, user), callback, onErrorCallback);
24
+ }
25
+ return {
26
+ dispatch,
27
+ document,
28
+ error,
29
+ };
30
+ }
@@ -0,0 +1,82 @@
1
+ import { DocumentDriveAction, DocumentDriveDocument } from "document-drive";
2
+ import { EditorDispatch, PHDocument } from "document-model";
3
+ import { UiNode } from "../uiNodes/types.js";
4
+ import { IDriveContext } from "./useDriveContext.js";
5
+ /**
6
+ * Actions for managing a document drive
7
+ */
8
+ export interface IDriveActions {
9
+ /** The drive context provided by the host application */
10
+ context: IDriveContext;
11
+ /** Selects a node in the drive */
12
+ selectNode: (node: UiNode | null) => void;
13
+ /**
14
+ * Creates a new folder in the drive
15
+ * @param name - Name of the folder
16
+ * @param parentFolder - Optional ID of parent folder
17
+ * @param id - Optional custom ID for the folder
18
+ */
19
+ addFolder: (name: string, parentFolder?: string | null, id?: string) => Promise<void>;
20
+ /**
21
+ * Adds a file to the drive
22
+ * @param file - File to be added
23
+ * @param parentFolder - Optional ID of parent folder (defaults to selected folder)
24
+ * @param name - Optional custom name for the file
25
+ */
26
+ addFile: (file: File, parentFolder?: string, name?: string) => Promise<void>;
27
+ /**
28
+ * Creates a new document in the drive
29
+ * @param name - Name of the document
30
+ * @param documentType - Type of document to create
31
+ * @param document - Optional document content
32
+ * @param parentFolder - Optional ID of parent folder
33
+ * @param id - Optional custom ID for the document
34
+ */
35
+ addDocument: (name: string, documentType: string, document?: PHDocument, parentFolder?: string, id?: string) => Promise<void>;
36
+ /**
37
+ * Deletes a node from the drive
38
+ * @param id - ID of the node to delete
39
+ */
40
+ deleteNode: (id: string) => Promise<void>;
41
+ /**
42
+ * Renames a node in the drive
43
+ * @param id - ID of the node to rename
44
+ * @param name - New name for the node
45
+ */
46
+ renameNode: (id: string, name: string) => Promise<void>;
47
+ /**
48
+ * Moves a node to a new parent folder
49
+ * @param sourceId - ID of the node to move
50
+ * @param targetId - ID of the target parent folder
51
+ */
52
+ moveNode: (sourceId: string, targetId: string) => Promise<void>;
53
+ /**
54
+ * Copies a node to a new location
55
+ * @param sourceId - ID of the node to copy
56
+ * @param targetFolderId - Optional ID of the target folder
57
+ */
58
+ copyNode: (sourceId: string, targetFolderId: string | undefined) => Promise<void>;
59
+ /**
60
+ * Creates a copy of a node in the same folder
61
+ * @param sourceId - ID of the node to duplicate
62
+ */
63
+ duplicateNode: (sourceId: string) => Promise<void>;
64
+ }
65
+ /**
66
+ * Hook that provides actions for managing a document drive
67
+ *
68
+ * @param document - The document drive document
69
+ * @param dispatch - Function to dispatch drive actions
70
+ * @param context - The drive context containing UI-related functions
71
+ * @returns Object containing drive management actions
72
+ *
73
+ * @example
74
+ * const {
75
+ * addFolder,
76
+ * addFile,
77
+ * deleteNode,
78
+ * moveNode
79
+ * } = useDriveActions(document, dispatch, driveContext);
80
+ */
81
+ export declare function useDriveActions(document: DocumentDriveDocument, dispatch: EditorDispatch<DocumentDriveAction>, context: IDriveContext): IDriveActions;
82
+ //# sourceMappingURL=useDriveActions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDriveActions.d.ts","sourceRoot":"","sources":["../../../src/hooks/useDriveActions.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EAUtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,cAAc,EACd,UAAU,EAEX,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAcrD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,yDAAyD;IACzD,OAAO,EAAE,aAAa,CAAC;IAEvB,kCAAkC;IAClC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAE1C;;;;;OAKG;IACH,SAAS,EAAE,CACT,IAAI,EAAE,MAAM,EACZ,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,EAC5B,EAAE,CAAC,EAAE,MAAM,KACR,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnB;;;;;OAKG;IACH,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7E;;;;;;;OAOG;IACH,WAAW,EAAE,CACX,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,UAAU,EACrB,YAAY,CAAC,EAAE,MAAM,EACrB,EAAE,CAAC,EAAE,MAAM,KACR,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnB;;;OAGG;IACH,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1C;;;;OAIG;IACH,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAExD;;;;OAIG;IACH,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhE;;;;OAIG;IACH,QAAQ,EAAE,CACR,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,GAAG,SAAS,KAC/B,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnB;;;OAGG;IACH,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACpD;AAyJD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,qBAAqB,EAC/B,QAAQ,EAAE,cAAc,CAAC,mBAAmB,CAAC,EAC7C,OAAO,EAAE,aAAa,GACrB,aAAa,CAKf"}
@@ -0,0 +1,125 @@
1
+ import { addFolder, copyNode, deleteNode, generateAddNodeAction, generateNodesCopy, isFileNode, isFolderNode, moveNode, updateNode, } from "document-drive";
2
+ import { generateId as _generateId, } from "document-model";
3
+ import { useMemo } from "react";
4
+ const generateId = () => _generateId().toString();
5
+ /**
6
+ * Retrieves a node from the drive by its ID
7
+ * @param id - The ID of the node to find
8
+ * @param drive - The document drive to search in
9
+ * @returns The found node or undefined
10
+ */
11
+ function getNode(id, drive) {
12
+ return drive.state.global.nodes.find((node) => node.id === id);
13
+ }
14
+ /**
15
+ * Creates an object containing actions for managing a document drive
16
+ * @param document - The document drive document
17
+ * @param dispatch - Function to dispatch drive actions
18
+ * @param context - The drive context provided by the host application
19
+ */
20
+ function createDriveActions(document, dispatch, context) {
21
+ const drive = document;
22
+ const { id: driveId } = drive.state.global;
23
+ const { selectedNode } = context;
24
+ const handleAddFolder = async (name, parentFolder, id = generateId()) => {
25
+ dispatch(addFolder({
26
+ id,
27
+ name,
28
+ parentFolder: parentFolder ?? null,
29
+ }));
30
+ };
31
+ const addDocument = async (name, documentType, document, parentFolder, id = generateId()) => {
32
+ const action = generateAddNodeAction(drive.state.global, {
33
+ id,
34
+ name,
35
+ parentFolder: parentFolder ?? null,
36
+ documentType,
37
+ document,
38
+ }, ["global"]);
39
+ dispatch(action);
40
+ };
41
+ const addFile = async (file, parentFolder = selectedNode && isFileNode(selectedNode)
42
+ ? undefined
43
+ : selectedNode?.id, name = file.name.replace(/\.zip$/gim, "")) => {
44
+ const folder = parentFolder ? getNode(parentFolder, drive) : undefined;
45
+ if (parentFolder && !folder) {
46
+ throw new Error(`Parent folder with id "${parentFolder}" not found`);
47
+ }
48
+ if (folder && !isFolderNode(folder)) {
49
+ throw new Error(`Parent folder with id "${parentFolder}" is not a folder`);
50
+ }
51
+ await context.addFile(file, driveId, name, parentFolder);
52
+ };
53
+ const handleDeleteNode = async (id) => {
54
+ dispatch(deleteNode({ id }));
55
+ };
56
+ const renameNode = async (id, name) => {
57
+ dispatch(updateNode({ id, name }));
58
+ };
59
+ const handleMoveNode = async (sourceId, targetId) => {
60
+ dispatch(moveNode({
61
+ srcFolder: sourceId,
62
+ targetParentFolder: targetId,
63
+ }));
64
+ };
65
+ const handleCopyNode = async (sourceId, targetFolderId) => {
66
+ const target = targetFolderId ? getNode(targetFolderId, drive) : undefined;
67
+ if (targetFolderId && !target) {
68
+ throw new Error(`Target node with id "${targetFolderId}" not found`);
69
+ }
70
+ if (target && !isFolderNode(target)) {
71
+ throw new Error(`Target node with id "${targetFolderId}" is not a folder`);
72
+ }
73
+ const source = getNode(sourceId, drive);
74
+ if (!source) {
75
+ throw new Error(`Source node with id "${sourceId}" not found`);
76
+ }
77
+ const copyNodesInput = generateNodesCopy({
78
+ srcId: sourceId,
79
+ targetParentFolder: target?.id,
80
+ targetName: source.name,
81
+ }, generateId, drive.state.global.nodes);
82
+ const copyActions = copyNodesInput.map((copyNodeInput) => copyNode(copyNodeInput));
83
+ for (const copyAction of copyActions) {
84
+ dispatch(copyAction); // TODO support batching dispatch
85
+ }
86
+ };
87
+ const duplicateNode = async (sourceId) => {
88
+ const node = getNode(sourceId, drive);
89
+ if (!node) {
90
+ throw new Error(`Node with id "${sourceId}" not found`);
91
+ }
92
+ await handleCopyNode(node.id, node.parentFolder || undefined);
93
+ };
94
+ return {
95
+ context,
96
+ selectNode: context.selectNode,
97
+ addFolder: handleAddFolder,
98
+ addFile,
99
+ addDocument,
100
+ deleteNode: handleDeleteNode,
101
+ renameNode,
102
+ moveNode: handleMoveNode,
103
+ copyNode: handleCopyNode,
104
+ duplicateNode,
105
+ };
106
+ }
107
+ /**
108
+ * Hook that provides actions for managing a document drive
109
+ *
110
+ * @param document - The document drive document
111
+ * @param dispatch - Function to dispatch drive actions
112
+ * @param context - The drive context containing UI-related functions
113
+ * @returns Object containing drive management actions
114
+ *
115
+ * @example
116
+ * const {
117
+ * addFolder,
118
+ * addFile,
119
+ * deleteNode,
120
+ * moveNode
121
+ * } = useDriveActions(document, dispatch, driveContext);
122
+ */
123
+ export function useDriveActions(document, dispatch, context) {
124
+ return useMemo(() => createDriveActions(document, dispatch, context), [document, dispatch, context]);
125
+ }
@@ -0,0 +1,17 @@
1
+ import { DocumentDriveAction, DocumentDriveDocument } from "document-drive";
2
+ import { EditorDispatch } from "document-model";
3
+ import type { UiNode } from "../uiNodes/types.js";
4
+ import { IDriveContext } from "./useDriveContext.js";
5
+ export declare function useDriveActionsWithUiNodes(document: DocumentDriveDocument, dispatch: EditorDispatch<DocumentDriveAction>): {
6
+ addFile: (file: File, parentNode: UiNode | null) => Promise<void>;
7
+ addFolder: (name: string, parentFolder?: string | undefined) => Promise<void>;
8
+ renameNode: (name: string, node: UiNode) => Promise<void>;
9
+ deleteNode: (node: UiNode) => Promise<void>;
10
+ moveNode: (src: UiNode, target: UiNode) => Promise<void>;
11
+ copyNode: (src: UiNode, target: UiNode) => Promise<void>;
12
+ duplicateNode: (node: UiNode) => Promise<void>;
13
+ context: IDriveContext;
14
+ selectNode: (node: UiNode | null) => void;
15
+ addDocument: (name: string, documentType: string, document?: import("document-model").PHDocument, parentFolder?: string, id?: string) => Promise<void>;
16
+ };
17
+ //# sourceMappingURL=useDriveActionsWithUiNodes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDriveActionsWithUiNodes.d.ts","sourceRoot":"","sources":["../../../src/hooks/useDriveActionsWithUiNodes.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EAItB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGhD,OAAO,KAAK,EAAc,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAE,aAAa,EAAmB,MAAM,sBAAsB,CAAC;AAiEtE,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,qBAAqB,EAC/B,QAAQ,EAAE,cAAc,CAAC,mBAAmB,CAAC;oBApC3B,IAAI,cAAc,MAAM,GAAG,IAAI;sBAG7B,MAAM,iBAA8B,MAAM,GAAG,SAAS;uBAGrD,MAAM,QAAQ,MAAM;uBAKpB,MAAM;oBAKH,MAAM,UAAU,MAAM;oBAO5B,MAAM,UAAU,MAAM;0BAIhB,MAAM;;;8DAPwB,CAAC,mDAGzC,CAAC,YAAgB,CAAC;EAuCjC"}
@@ -0,0 +1,71 @@
1
+ import { useMemo } from "react";
2
+ import { FILE } from "../uiNodes/constants.js";
3
+ import { useDriveActions } from "./useDriveActions.js";
4
+ import { useDriveContext } from "./useDriveContext.js";
5
+ import { useUiNodesContext } from "./useUiNodesContext.js";
6
+ function toNode(uiNode) {
7
+ if (uiNode.kind === "DRIVE") {
8
+ throw new Error("Cannot convert drive node to regular node");
9
+ }
10
+ const { id, name, parentFolder, kind } = uiNode;
11
+ if (kind === "FOLDER") {
12
+ return { id, name, parentFolder, kind: "folder" };
13
+ }
14
+ else {
15
+ // Remove after ts reset is fixed
16
+ const fileNode = uiNode;
17
+ return {
18
+ id,
19
+ name,
20
+ parentFolder,
21
+ kind: "file",
22
+ documentType: fileNode.documentType,
23
+ synchronizationUnits: fileNode.synchronizationUnits,
24
+ };
25
+ }
26
+ }
27
+ // Adapter to convert between UiNodes and drive actions
28
+ function createUiNodeAdapter(driveActions) {
29
+ return {
30
+ ...driveActions,
31
+ addFile: (file, parentNode) => driveActions.addFile(file, parentNode?.id),
32
+ addFolder: (name, parentFolder = undefined) => driveActions.addFolder(name, parentFolder),
33
+ renameNode: (name, node) => {
34
+ const converted = toNode(node);
35
+ return driveActions.renameNode(converted.id, name);
36
+ },
37
+ deleteNode: (node) => {
38
+ const converted = toNode(node);
39
+ return driveActions.deleteNode(converted.id);
40
+ },
41
+ moveNode: async (src, target) => {
42
+ if (target.kind === FILE || src.parentFolder === target.id)
43
+ return;
44
+ const srcNode = toNode(src);
45
+ const targetNode = toNode(target);
46
+ return driveActions.moveNode(srcNode.id, targetNode.id);
47
+ },
48
+ copyNode: (src, target) => {
49
+ return driveActions.copyNode(src.id, target.id);
50
+ },
51
+ duplicateNode: (node) => {
52
+ const converted = toNode(node);
53
+ return driveActions.duplicateNode(converted.id);
54
+ },
55
+ };
56
+ }
57
+ export function useDriveActionsWithUiNodes(document, dispatch) {
58
+ const { selectedNode, selectedDriveNode, setSelectedNode, getNodeById } = useUiNodesContext();
59
+ const _driveContext = useDriveContext();
60
+ const driveContext = useMemo(() => ({
61
+ ..._driveContext,
62
+ selectedNode: selectedNode,
63
+ onSelectNode: (node) => {
64
+ _driveContext.selectNode(node);
65
+ setSelectedNode(getNodeById(node.id));
66
+ },
67
+ }), [selectedNode, selectedDriveNode?.driveId, setSelectedNode, getNodeById]);
68
+ const driveActions = useDriveActions(document, dispatch, driveContext);
69
+ const uiNodeActions = useMemo(() => createUiNodeAdapter(driveActions), [driveActions]);
70
+ return uiNodeActions;
71
+ }