@fileverse-dev/dsheet 4.1.1-edit-mode-16 → 4.1.2
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.
- package/README.md +7 -9
- package/dist/{constants-B3rfAvvz.js → constants-CRFfbkoQ.js} +22 -79
- package/dist/constants.d.ts +2 -2
- package/dist/constants.js +3 -3
- package/dist/editor/components/editor-workbook.d.ts +1 -5
- package/dist/editor/components/permission-chip.d.ts +1 -5
- package/dist/editor/contexts/editor-context.d.ts +2 -11
- package/dist/editor/dsheet-editor.d.ts +2 -3
- package/dist/editor/hooks/use-collab-awareness.d.ts +6 -3
- package/dist/editor/hooks/use-editor-data.d.ts +2 -2
- package/dist/editor/hooks/use-editor-sync.d.ts +2 -6
- package/dist/editor/types/comments.d.ts +11 -0
- package/dist/editor/types.d.ts +4 -30
- package/dist/editor/utils/apply-comment-markers.d.ts +3 -11
- package/dist/editor/utils/comment-anchors-ydoc.d.ts +32 -0
- package/dist/editor/utils/remap-comment-anchors.d.ts +26 -0
- package/dist/{executeStringFunction-CxsiamWG.js → executeStringFunction-BhS7NspU.js} +1152 -1107
- package/dist/formula.js +1 -1
- package/dist/{index-DQvYqAJz.js → index-CufCBExa.js} +23501 -23656
- package/dist/index.d.ts +3 -4
- package/dist/index.es.js +52 -55
- package/dist/persistence-utils-DsM_MOB1.js +89 -0
- package/dist/persistence-utils.d.ts +0 -6
- package/dist/persistence.js +1 -1
- package/dist/sheet-engine/core/index.d.ts +1 -1
- package/dist/sheet-engine/core/settings.d.ts +40 -0
- package/dist/sheet-engine/core/utils/comment-anchor-move.d.ts +17 -0
- package/dist/sheet-engine/react/components/Toolbar/index.d.ts +0 -1
- package/dist/sheet-engine/react/components/Workbook/index.d.ts +0 -1
- package/dist/style.css +1 -1
- package/dist/sync-local/SyncManager.d.ts +9 -54
- package/dist/sync-local/index.d.ts +1 -1
- package/dist/sync-local/socketClient.d.ts +8 -75
- package/dist/sync-local/types/index.d.ts +15 -111
- package/dist/sync-local/useSyncManager.d.ts +0 -4
- package/dist/sync-local/utils/objectToFile.d.ts +1 -0
- package/dist/{use-xlsx-import-impl-DjiPGIoS.js → use-xlsx-import-impl-BrpzMELW.js} +148 -148
- package/dist/{xlsx-defined-names-Dr4_psg0.js → xlsx-defined-names-DR03Ea-E.js} +2 -2
- package/dist/{xlsx-export-impl-D2YNoxJm.js → xlsx-export-impl-wJaTTBGt.js} +192 -188
- package/dist/{xlsx-hyperlink-inline-BkLFFNwP.js → xlsx-hyperlink-inline-53h_A_BI.js} +2 -2
- package/package.json +1 -1
- package/dist/editor/components/editor-workbook-controls.d.ts +0 -11
- package/dist/editor/components/permission-chip-model.d.ts +0 -34
- package/dist/editor/components/permission-chip.test.d.ts +0 -1
- package/dist/editor/hooks/collaboration-lifecycle.d.ts +0 -35
- package/dist/editor/hooks/collaboration-lifecycle.test.d.ts +0 -1
- package/dist/editor/utils/detach-workbook-data.d.ts +0 -8
- package/dist/editor/utils/detach-workbook-data.test.d.ts +0 -1
- package/dist/editor/utils/editor-handle.d.ts +0 -11
- package/dist/editor/utils/editor-handle.test.d.ts +0 -1
- package/dist/persistence-utils-BXFajzvq.js +0 -98
- package/dist/persistence-utils.test.d.ts +0 -1
- package/dist/sync-local/crypto/room-key.d.ts +0 -2
- package/dist/sync-local/crypto/room-key.test.d.ts +0 -1
- package/dist/sync-local/floor.d.ts +0 -8
- package/dist/sync-local/floor.test.d.ts +0 -1
- package/dist/sync-local/presence.d.ts +0 -13
- package/dist/sync-local/presence.test.d.ts +0 -1
- package/dist/sync-local/session-tools.d.ts +0 -31
- package/dist/sync-local/session-tools.test.d.ts +0 -1
- /package/dist/editor/{components/editor-workbook-controls.test.d.ts → utils/remap-comment-anchors.test.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,21 +1,19 @@
|
|
|
1
|
-
# Fileverse
|
|
1
|
+
# Fileverse dSheets
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@fileverse-dev/dsheet)
|
|
4
4
|
[](https://www.typescriptlang.org/)
|
|
5
5
|
|
|
6
|
-
[dsheets.new](http://dsheets.new/) is your
|
|
6
|
+
[dsheets.new](http://dsheets.new/) is your end-to-end encrypted alternative to Google Sheets & Excel. Use it to read, manipulate, and even write financial data, in real-time. Built on the same middleware as ddocs.new, the app is privacy-focused, sovereign, and gives you full control over your data.
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## 𓆣 Features include:
|
|
9
9
|
- End-to-end encryption
|
|
10
10
|
- Local & peer-to-peer storage
|
|
11
|
-
- Query live data from APIs & smart contracts
|
|
12
|
-
-
|
|
11
|
+
- Query live data from APIs & even smart contracts
|
|
12
|
+
- Enable dark mode and other color themes
|
|
13
13
|
- Use a familiar spreadsheets interface & functions (VLOOKUP, INDEX, MATCH…)
|
|
14
|
-
- Granular access permissions (
|
|
14
|
+
- Granular access permissions (e.g., give view, comment, edit, suggest access to specific email addresses)
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-

|
|
16
|
+
<img width="1532" height="974" alt="dsheetsnew" src="https://github.com/user-attachments/assets/8bd67463-e999-41f4-b414-9d017fbf9466" />
|
|
19
17
|
|
|
20
18
|
|
|
21
19
|
## Installation
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { E as
|
|
2
|
-
const
|
|
1
|
+
import { E as a, S as n } from "./crypto-constants-ZTlAYRUf.js";
|
|
2
|
+
const E = a, d = n, f = [
|
|
3
3
|
{
|
|
4
4
|
id: "0",
|
|
5
5
|
name: "Sheet1",
|
|
@@ -7,7 +7,7 @@ const h = l, S = u, _ = [
|
|
|
7
7
|
config: {},
|
|
8
8
|
order: 0
|
|
9
9
|
}
|
|
10
|
-
],
|
|
10
|
+
], m = [
|
|
11
11
|
"undo",
|
|
12
12
|
"redo",
|
|
13
13
|
"format-painter",
|
|
@@ -45,7 +45,7 @@ const h = l, S = u, _ = [
|
|
|
45
45
|
"quick-formula",
|
|
46
46
|
"dataVerification",
|
|
47
47
|
"search"
|
|
48
|
-
],
|
|
48
|
+
], u = [
|
|
49
49
|
"cut",
|
|
50
50
|
"copy",
|
|
51
51
|
"paste",
|
|
@@ -82,7 +82,7 @@ const h = l, S = u, _ = [
|
|
|
82
82
|
"freeze-row",
|
|
83
83
|
"|",
|
|
84
84
|
"clear-format"
|
|
85
|
-
],
|
|
85
|
+
], S = [
|
|
86
86
|
"cut",
|
|
87
87
|
"copy",
|
|
88
88
|
"paste",
|
|
@@ -119,14 +119,14 @@ const h = l, S = u, _ = [
|
|
|
119
119
|
"freeze-column",
|
|
120
120
|
"|",
|
|
121
121
|
"clear-format"
|
|
122
|
-
],
|
|
122
|
+
], _ = {
|
|
123
123
|
height: null,
|
|
124
124
|
isShow: !1,
|
|
125
125
|
left: null,
|
|
126
126
|
top: null,
|
|
127
127
|
value: "",
|
|
128
128
|
width: null
|
|
129
|
-
},
|
|
129
|
+
}, l = "#5298FF", r = [
|
|
130
130
|
"#30bced",
|
|
131
131
|
"#6eeb83",
|
|
132
132
|
"#fa69d1",
|
|
@@ -136,81 +136,24 @@ const h = l, S = u, _ = [
|
|
|
136
136
|
"#0ad7f2",
|
|
137
137
|
"#1bff39"
|
|
138
138
|
];
|
|
139
|
-
function
|
|
140
|
-
|
|
141
|
-
return o.forEach((r) => {
|
|
142
|
-
const i = r == null ? void 0 : r.socketId, e = r == null ? void 0 : r.user;
|
|
143
|
-
typeof i == "string" && e && t.set(i, {
|
|
144
|
-
name: e.name ?? "",
|
|
145
|
-
color: e.color ?? a,
|
|
146
|
-
isEns: e.isEns ?? ""
|
|
147
|
-
});
|
|
148
|
-
}), t;
|
|
139
|
+
function c(e) {
|
|
140
|
+
return r[e % r.length];
|
|
149
141
|
}
|
|
150
|
-
function
|
|
151
|
-
const r = o.map((e) => {
|
|
152
|
-
const n = t.get(e);
|
|
153
|
-
return n ? {
|
|
154
|
-
clientId: e,
|
|
155
|
-
name: n.name,
|
|
156
|
-
color: n.color,
|
|
157
|
-
isEns: n.isEns,
|
|
158
|
-
isPlaceholder: !1
|
|
159
|
-
} : {
|
|
160
|
-
clientId: e,
|
|
161
|
-
name: "",
|
|
162
|
-
color: a,
|
|
163
|
-
isEns: "",
|
|
164
|
-
isPlaceholder: !0
|
|
165
|
-
};
|
|
166
|
-
});
|
|
167
|
-
r.sort((e, n) => !!e.isPlaceholder != !!n.isPlaceholder ? e.isPlaceholder ? 1 : -1 : String(e.clientId).localeCompare(String(n.clientId)));
|
|
168
|
-
const i = /* @__PURE__ */ new Set();
|
|
169
|
-
return r.filter((e) => e.isPlaceholder || !e.name ? !0 : i.has(e.name) ? !1 : (i.add(e.name), !0));
|
|
170
|
-
}
|
|
171
|
-
function R(o, t) {
|
|
172
|
-
const r = new Set(
|
|
173
|
-
o.filter(({ isPlaceholder: e, name: n }) => !e && n).map(({ name: e }) => e)
|
|
174
|
-
);
|
|
175
|
-
t.forEach((e, n) => {
|
|
176
|
-
r.has(n) || t.delete(n);
|
|
177
|
-
});
|
|
178
|
-
const i = /* @__PURE__ */ new Set();
|
|
179
|
-
return o.forEach((e) => {
|
|
180
|
-
if (e.isPlaceholder || !e.name) return;
|
|
181
|
-
let n = t.get(e.name);
|
|
182
|
-
(!n || i.has(n)) && (n = s.find((c) => !i.has(c)) ?? n ?? s[t.size % s.length], t.set(e.name, n)), i.add(n), e.color = n;
|
|
183
|
-
}), o;
|
|
184
|
-
}
|
|
185
|
-
function O(o, t) {
|
|
186
|
-
return o.slice().sort().map((r) => {
|
|
187
|
-
const i = t.get(r);
|
|
188
|
-
return i ? `${r}:${i.name}:${i.isEns}` : `${r}:?`;
|
|
189
|
-
}).join("|");
|
|
190
|
-
}
|
|
191
|
-
const d = "#5298FF";
|
|
192
|
-
function f(o) {
|
|
193
|
-
return s[o % s.length];
|
|
194
|
-
}
|
|
195
|
-
function E() {
|
|
142
|
+
function i() {
|
|
196
143
|
return "#" + Math.floor(Math.random() * 16777215).toString(16).padStart(6, "0");
|
|
197
144
|
}
|
|
198
|
-
function
|
|
199
|
-
return
|
|
145
|
+
function h(e, o, t) {
|
|
146
|
+
return e ? l : o ?? (t != null ? c(t) : i());
|
|
200
147
|
}
|
|
201
148
|
export {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
S,
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
d as e,
|
|
213
|
-
O as i,
|
|
214
|
-
L as m,
|
|
215
|
-
P as p
|
|
149
|
+
_ as C,
|
|
150
|
+
f as D,
|
|
151
|
+
E,
|
|
152
|
+
S as H,
|
|
153
|
+
d as S,
|
|
154
|
+
m as T,
|
|
155
|
+
r as a,
|
|
156
|
+
u as b,
|
|
157
|
+
l as c,
|
|
158
|
+
h as p
|
|
216
159
|
};
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { ERROR_MESSAGES_FLAG, SERVICES_API_KEY, } from './editor/constants/shared-constants';
|
|
2
|
-
export { COLLAB_PRESENCE_COLORS } from './sync-local/presence';
|
|
3
2
|
export declare const ENS_PRESENCE_COLOR = "#5298FF";
|
|
4
|
-
|
|
3
|
+
export declare const COLLAB_PRESENCE_COLORS: readonly ["#30bced", "#6eeb83", "#fa69d1", "#ecd444", "#ee6352", "#db3041", "#0ad7f2", "#1bff39"];
|
|
4
|
+
/** ENS brand color, else `color`, else palette by `clientId`, else random. */
|
|
5
5
|
export declare function presenceColor(isEns: boolean | undefined, color?: string, clientId?: number): string;
|
package/dist/constants.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as R, c as _, E as C, S as a, p as s } from "./constants-CRFfbkoQ.js";
|
|
2
2
|
export {
|
|
3
3
|
R as COLLAB_PRESENCE_COLORS,
|
|
4
4
|
_ as ENS_PRESENCE_COLOR,
|
|
5
5
|
C as ERROR_MESSAGES_FLAG,
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
a as SERVICES_API_KEY,
|
|
7
|
+
s as presenceColor
|
|
8
8
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
import { SidebarPortalRegistryHandle, SidebarPortalRenderer } from '../../sheet-engine/react';
|
|
3
3
|
import { ThemeKey } from '../../sheet-engine/core/theme';
|
|
4
|
-
import { OnboardingHandlerType
|
|
4
|
+
import { OnboardingHandlerType } from '../types';
|
|
5
5
|
import { CommentsConfig } from '../types/comments';
|
|
6
6
|
|
|
7
7
|
type OnboardingHandler = OnboardingHandlerType;
|
|
@@ -24,10 +24,6 @@ interface EditorWorkbookProps {
|
|
|
24
24
|
sidebarActivePanel?: string | null;
|
|
25
25
|
sidebarPortalRegistry?: SidebarPortalRegistryHandle | null;
|
|
26
26
|
sidebarPortalRenderers?: Record<string, SidebarPortalRenderer>;
|
|
27
|
-
permissionMode?: DSheetPermissionMode | null;
|
|
28
|
-
onEnterEdit?: () => void;
|
|
29
|
-
onSignInToComment?: () => void;
|
|
30
|
-
onViewerModeChange?: (mode: 'comment' | 'view') => void;
|
|
31
27
|
theme?: ThemeKey;
|
|
32
28
|
}
|
|
33
29
|
export declare const EditorWorkbook: React.NamedExoticComponent<EditorWorkbookProps>;
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
-
import { DSheetPermissionMode } from '../types';
|
|
3
2
|
|
|
4
3
|
interface PermissionChipProps {
|
|
5
|
-
|
|
6
|
-
onEnterEdit?: () => void;
|
|
7
|
-
onSignInToComment?: () => void;
|
|
8
|
-
onViewerModeChange?: (mode: 'comment' | 'view') => void;
|
|
4
|
+
allowComments: boolean;
|
|
9
5
|
}
|
|
10
6
|
export declare const PermissionChip: React.FC<PermissionChipProps>;
|
|
11
7
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
import { LiveQueryData, Sheet, WorkbookInstance } from '../../sheet-engine/react';
|
|
3
3
|
import { IndexeddbPersistence } from 'y-indexeddb';
|
|
4
|
-
import { SheetUpdateData, DataBlockEvent
|
|
4
|
+
import { SheetUpdateData, DataBlockEvent } from '../types';
|
|
5
5
|
import { CommentsConfig } from '../types/comments';
|
|
6
6
|
import { ApiKeyStorage } from '../utils/api-key-storage';
|
|
7
7
|
import { OpenApiKeyModalFn } from '../utils/data-block-error-handler';
|
|
@@ -32,7 +32,6 @@ export interface EditorContextType {
|
|
|
32
32
|
}>>;
|
|
33
33
|
refreshIndexedDB: () => Promise<void>;
|
|
34
34
|
sheetEditorRef: React.MutableRefObject<WorkbookInstance | null>;
|
|
35
|
-
setSheetEditorRef: React.RefCallback<WorkbookInstance>;
|
|
36
35
|
ydocRef: React.MutableRefObject<Y.Doc | null>;
|
|
37
36
|
persistenceRef: React.MutableRefObject<IndexeddbPersistence | null>;
|
|
38
37
|
sheetData: Sheet[];
|
|
@@ -46,7 +45,6 @@ export interface EditorContextType {
|
|
|
46
45
|
setForceSheetRender: React.Dispatch<React.SetStateAction<number>>;
|
|
47
46
|
syncStatus: 'initializing' | 'syncing' | 'synced' | 'error';
|
|
48
47
|
collabEnabled?: boolean;
|
|
49
|
-
isLiveCollabSession: boolean;
|
|
50
48
|
collabIsOwner?: boolean;
|
|
51
49
|
collabState?: CollabState;
|
|
52
50
|
isCollabReady?: boolean;
|
|
@@ -81,8 +79,7 @@ interface EditorProviderProps {
|
|
|
81
79
|
onContentUpdate?: () => void;
|
|
82
80
|
onChange?: (data: SheetUpdateData, encodedUpdate?: string) => void;
|
|
83
81
|
collaboration?: CollaborationProps;
|
|
84
|
-
externalEditorRef?: React.
|
|
85
|
-
legacyEditorRef?: React.Ref<DSheetEditorHandle>;
|
|
82
|
+
externalEditorRef?: React.MutableRefObject<WorkbookInstance | null>;
|
|
86
83
|
commentsConfig?: CommentsConfig;
|
|
87
84
|
editorStateRef?: React.MutableRefObject<{
|
|
88
85
|
refreshIndexedDB: () => Promise<void>;
|
|
@@ -90,10 +87,6 @@ interface EditorProviderProps {
|
|
|
90
87
|
mergeContent: (encodedState: string) => DSheetContentSnapshot;
|
|
91
88
|
terminateSession?: () => void;
|
|
92
89
|
updateCollaboratorName?: (name: string) => void;
|
|
93
|
-
updateSessionTitle?: (args: {
|
|
94
|
-
encryptedTitle: string;
|
|
95
|
-
documentTitle: string;
|
|
96
|
-
}) => void;
|
|
97
90
|
rehydrateAfterCollabSync?: (reason?: string) => boolean;
|
|
98
91
|
} | null>;
|
|
99
92
|
enableLiveQuery?: boolean;
|
|
@@ -102,8 +95,6 @@ interface EditorProviderProps {
|
|
|
102
95
|
onDataBlockEvent?: (event: DataBlockEvent) => void;
|
|
103
96
|
smartContracts?: SmartContractConfig;
|
|
104
97
|
onContentSyncStatusChange?: (status: 'initializing' | 'syncing' | 'synced' | 'error') => void;
|
|
105
|
-
onCollaborationInitializationComplete?: (result: 'ready' | 'error') => void;
|
|
106
|
-
onIndexedDbError?: (error: Error) => void;
|
|
107
98
|
}
|
|
108
99
|
export declare const EditorProvider: React.FC<EditorProviderProps>;
|
|
109
100
|
export declare const useEditor: () => EditorContextType;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { DSheetEditorHandle, DsheetProps } from './types';
|
|
1
|
+
import { DsheetProps } from './types';
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
4
|
* SpreadsheetEditor component that provides a collaborative spreadsheet interface
|
|
@@ -8,5 +7,5 @@ import { DSheetEditorHandle, DsheetProps } from './types';
|
|
|
8
7
|
* @param props - Component properties
|
|
9
8
|
* @returns The SpreadsheetEditor component
|
|
10
9
|
*/
|
|
11
|
-
declare const SpreadsheetEditor:
|
|
10
|
+
declare const SpreadsheetEditor: ({ isReadOnly, allowSheetDownload, renderNavbar, enableIndexeddbSync, dsheetId, portalContent, onContentUpdate, onChange, username, selectedTemplate, toggleTemplateSidebar, isTemplateOpen, onboardingComplete, onboardingCompleteLocalStorageKey, onboardingHandler, commentsConfig, setFetchingURLData, setShowFetchURLModal, setInputFetchURLDataBlock, sheetEditorRef: externalSheetEditorRef, onDuneChartEmbed, onSheetCountChange, isAuthorized, getDocumentTitle, updateDocumentTitle, editorStateRef, setSelectedTemplate, isNewSheet, liveQueryRefreshRate, enableLiveQuery, collaboration, customPanels, apiKeyStorage, onDataBlockEvent, smartContracts, theme, onContentSyncStatusChange, }: DsheetProps) => JSX.Element;
|
|
12
11
|
export default SpreadsheetEditor;
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { Awareness } from 'y-protocols/awareness';
|
|
2
2
|
import { WorkbookInstance } from '../../sheet-engine/react';
|
|
3
|
+
import { CollabUser } from '../../sync-local/types';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Reads remote cursor positions from Yjs awareness and keeps Fortune sheet's
|
|
6
7
|
* native presence list in sync. Fortune renders colored cell borders + username
|
|
7
8
|
* labels automatically via context.presences[].
|
|
8
9
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
10
|
+
* Also emits the full collaborator list (including the local user) via
|
|
11
|
+
* `onCollaboratorsChange` so host apps can render navbar chips. This mirrors
|
|
12
|
+
* ddoc's editor-layer awareness handler, which maps awareness.states →
|
|
13
|
+
* `{ clientId, ...user }` and fires on every awareness update + once on mount.
|
|
11
14
|
*/
|
|
12
|
-
export declare const useCollabAwareness: (awareness: Awareness | null | undefined, sheetEditorRef: React.MutableRefObject<WorkbookInstance | null
|
|
15
|
+
export declare const useCollabAwareness: (awareness: Awareness | null | undefined, sheetEditorRef: React.MutableRefObject<WorkbookInstance | null>, onCollaboratorsChange?: (collaborators: CollabUser[]) => void) => {
|
|
13
16
|
localColor: "#30bced" | "#6eeb83" | "#fa69d1" | "#ecd444" | "#ee6352" | "#db3041" | "#0ad7f2" | "#1bff39";
|
|
14
17
|
};
|
|
@@ -8,7 +8,7 @@ import * as Y from 'yjs';
|
|
|
8
8
|
* Hook for managing sheet data
|
|
9
9
|
* Handles initialization, updates, and persistence of sheet data
|
|
10
10
|
*/
|
|
11
|
-
export declare const useEditorData: (ydocRef: React.MutableRefObject<Y.Doc | null>, dsheetId: string, sheetEditorRef: React.MutableRefObject<WorkbookInstance | null>, setForceSheetRender?: React.Dispatch<React.SetStateAction<number>>, isReadOnly?: boolean, onChange?: (data: Sheet[]) => void, syncStatus?: "initializing" | "syncing" | "synced" | "error",
|
|
11
|
+
export declare const useEditorData: (ydocRef: React.MutableRefObject<Y.Doc | null>, dsheetId: string, sheetEditorRef: React.MutableRefObject<WorkbookInstance | null>, setForceSheetRender?: React.Dispatch<React.SetStateAction<number>>, portalContent?: string, isReadOnly?: boolean, onChange?: (data: Sheet[]) => void, syncStatus?: "initializing" | "syncing" | "synced" | "error", commentData?: object, dataBlockCalcFunction?: {
|
|
12
12
|
[key: string]: {
|
|
13
13
|
[key: string]: any;
|
|
14
14
|
};
|
|
@@ -16,7 +16,7 @@ export declare const useEditorData: (ydocRef: React.MutableRefObject<Y.Doc | nul
|
|
|
16
16
|
[key: string]: {
|
|
17
17
|
[key: string]: any;
|
|
18
18
|
};
|
|
19
|
-
}>>, enableLiveQuery?: boolean, liveQueryRefreshRate?: number, apiKeyStorage?: ApiKeyStorage, openApiKeyModal?: OpenApiKeyModalFn, onDataBlockEvent?: (event: DataBlockEvent) => void, allowComments?: boolean, collabEnabled?: boolean) => {
|
|
19
|
+
}>>, enableLiveQuery?: boolean, liveQueryRefreshRate?: number, apiKeyStorage?: ApiKeyStorage, openApiKeyModal?: OpenApiKeyModalFn, onDataBlockEvent?: (event: DataBlockEvent) => void, allowComments?: boolean, hasCollabContentInitialised?: boolean, collabEnabled?: boolean) => {
|
|
20
20
|
sheetData: Sheet[];
|
|
21
21
|
setSheetData: import('react').Dispatch<import('react').SetStateAction<Sheet[]>>;
|
|
22
22
|
currentDataRef: import('react').MutableRefObject<Sheet[]>;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { IndexeddbPersistence } from 'y-indexeddb';
|
|
2
2
|
import { CollaborationProps } from '../../sync-local/types';
|
|
3
3
|
import * as Y from 'yjs';
|
|
4
|
-
export declare const useEditorSync: (dsheetId: string, enableIndexeddbSync?: boolean, isReadOnly?: boolean,
|
|
4
|
+
export declare const useEditorSync: (dsheetId: string, enableIndexeddbSync?: boolean, isReadOnly?: boolean, collaboration?: CollaborationProps, onCollabUpdate?: (fullState: string, updateChunk: string) => void) => {
|
|
5
5
|
ydocRef: import('react').MutableRefObject<Y.Doc | null>;
|
|
6
6
|
persistenceRef: import('react').MutableRefObject<IndexeddbPersistence | null>;
|
|
7
7
|
syncStatus: "error" | "syncing" | "initializing" | "synced";
|
|
8
|
-
|
|
8
|
+
isSyncedRef: import('react').MutableRefObject<boolean>;
|
|
9
9
|
refreshIndexedDB: () => Promise<void>;
|
|
10
10
|
getContentSnapshot: () => import('../../persistence-utils').DSheetContentSnapshot;
|
|
11
11
|
mergeContent: (encodedState: string) => import('../../persistence-utils').DSheetContentSnapshot;
|
|
@@ -13,10 +13,6 @@ export declare const useEditorSync: (dsheetId: string, enableIndexeddbSync?: boo
|
|
|
13
13
|
isCollabReady: boolean;
|
|
14
14
|
isCollabSyncing: boolean;
|
|
15
15
|
terminateSession: () => void;
|
|
16
|
-
updateTitle: (args: {
|
|
17
|
-
encryptedTitle: string;
|
|
18
|
-
documentTitle: string;
|
|
19
|
-
}) => void;
|
|
20
16
|
awareness: import('y-protocols/awareness.js').Awareness | null;
|
|
21
17
|
hasCollabContentInitialised: boolean;
|
|
22
18
|
};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
+
import { CommentAnchorMove } from '../../sheet-engine/core/settings';
|
|
2
3
|
|
|
4
|
+
export type { CommentAnchorMove };
|
|
3
5
|
export interface CommentThread {
|
|
4
6
|
id: string;
|
|
5
7
|
key: string;
|
|
@@ -12,6 +14,8 @@ export interface CommentThread {
|
|
|
12
14
|
replies: CommentReply[];
|
|
13
15
|
isResolved?: boolean;
|
|
14
16
|
isDeleted?: boolean;
|
|
17
|
+
/** IPFS/indexer hash — stable across local `comment-*` ids and on-chain uuids. */
|
|
18
|
+
contentHash?: string;
|
|
15
19
|
}
|
|
16
20
|
export interface CommentReply {
|
|
17
21
|
id: string;
|
|
@@ -41,6 +45,11 @@ export interface CommentsConfig {
|
|
|
41
45
|
commentsData: Record<string, CommentThread>;
|
|
42
46
|
onSendComment: (key: string, textareaId: string) => void;
|
|
43
47
|
onCommentAction: (action: CommentActionParams) => void;
|
|
48
|
+
/**
|
|
49
|
+
* Called after row/column drag-drop or a cell-range move so the host can
|
|
50
|
+
* remap comment keys. Use `remapCommentAnchors` from the package.
|
|
51
|
+
*/
|
|
52
|
+
onCellPositionsChanged?: (move: CommentAnchorMove) => void;
|
|
44
53
|
userName?: string;
|
|
45
54
|
ownerAddress?: string;
|
|
46
55
|
currentUserAddress?: string;
|
|
@@ -118,6 +127,8 @@ export interface CommentCellUIProps {
|
|
|
118
127
|
dragHandler: (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
|
|
119
128
|
isHover?: boolean;
|
|
120
129
|
disabled?: boolean;
|
|
130
|
+
isAuthenticated?: boolean;
|
|
131
|
+
unauthenticatedFallback?: React.ReactNode;
|
|
121
132
|
}
|
|
122
133
|
export interface CommentsContentProps {
|
|
123
134
|
sheetEditorRef: React.RefObject<SheetEditorRef>;
|
package/dist/editor/types.d.ts
CHANGED
|
@@ -10,8 +10,7 @@ import { DSheetContentSnapshot } from '../persistence';
|
|
|
10
10
|
|
|
11
11
|
import * as Y from 'yjs';
|
|
12
12
|
export type { ThemeKey } from '../sheet-engine/core/theme';
|
|
13
|
-
export type
|
|
14
|
-
export type { CommentThread, CommentReply, CommentActionParams, CommentsConfig, } from './types/comments';
|
|
13
|
+
export type { CommentThread, CommentReply, CommentActionParams, CommentsConfig, CommentAnchorMove, } from './types/comments';
|
|
15
14
|
export { CommentAction } from './types/comments';
|
|
16
15
|
export interface SheetUpdateData {
|
|
17
16
|
data: Sheet[];
|
|
@@ -23,15 +22,6 @@ export interface EditorValues {
|
|
|
23
22
|
openPanel: (panelId: string) => void;
|
|
24
23
|
closePanel: () => void;
|
|
25
24
|
}
|
|
26
|
-
export type DSheetEditorHandle = WorkbookInstance & {
|
|
27
|
-
refreshIndexedDB: () => Promise<void>;
|
|
28
|
-
terminateSession: () => void;
|
|
29
|
-
updateCollaboratorName: (name: string) => void;
|
|
30
|
-
updateSessionTitle: (args: {
|
|
31
|
-
encryptedTitle: string;
|
|
32
|
-
documentTitle: string;
|
|
33
|
-
}) => void;
|
|
34
|
-
};
|
|
35
25
|
export interface PanelConfig {
|
|
36
26
|
id: string;
|
|
37
27
|
header: {
|
|
@@ -77,23 +67,9 @@ export interface DsheetProps {
|
|
|
77
67
|
onContentUpdate?: () => void;
|
|
78
68
|
onChange?: (updateData: SheetUpdateData, encodedUpdate?: string) => void;
|
|
79
69
|
collaboration?: CollaborationProps;
|
|
80
|
-
/** Called when local IndexedDB persistence fails. The editor and durable
|
|
81
|
-
* collaboration continue using the in-memory Y.Doc, matching dDoc. */
|
|
82
|
-
onIndexedDbError?: (error: Error) => void;
|
|
83
70
|
username?: string;
|
|
84
71
|
portalContent?: string;
|
|
85
72
|
isReadOnly?: boolean;
|
|
86
|
-
/** Permission status displayed above the toolbar. When omitted, read-only
|
|
87
|
-
* sheets retain the existing View/View-and-comment behavior. */
|
|
88
|
-
permissionMode?: DSheetPermissionMode;
|
|
89
|
-
/** Called when a read-only consumer asks to elevate to edit mode. The host
|
|
90
|
-
* owns access proof, loading, errors, and the resulting mode transition. */
|
|
91
|
-
onEnterEdit?: () => void;
|
|
92
|
-
/** Called when an invited commenter needs to authenticate before the host can
|
|
93
|
-
* recover comment capability. */
|
|
94
|
-
onSignInToComment?: () => void;
|
|
95
|
-
/** Lets the host toggle a recovered commenter between comment and view mode. */
|
|
96
|
-
onViewerModeChange?: (mode: 'comment' | 'view') => void;
|
|
97
73
|
allowSheetDownload?: boolean;
|
|
98
74
|
isTemplateOpen?: boolean;
|
|
99
75
|
selectedTemplate?: string;
|
|
@@ -104,8 +80,9 @@ export interface DsheetProps {
|
|
|
104
80
|
setForceSheetRender?: React.Dispatch<React.SetStateAction<number>>;
|
|
105
81
|
commentsConfig?: CommentsConfig;
|
|
106
82
|
toggleTemplateSidebar?: () => void;
|
|
107
|
-
|
|
108
|
-
|
|
83
|
+
sheetEditorRef?: RefObject<WorkbookInstance & {
|
|
84
|
+
refreshIndexedDB: () => Promise<void>;
|
|
85
|
+
}>;
|
|
109
86
|
/** Override where datablock API keys are stored (default: localStorage). */
|
|
110
87
|
apiKeyStorage?: ApiKeyStorage;
|
|
111
88
|
/** Optional lifecycle events for analytics / side-effects. */
|
|
@@ -116,9 +93,6 @@ export interface DsheetProps {
|
|
|
116
93
|
* collab start/resume on 'synced' — starting before local content is fully
|
|
117
94
|
* synced is what let the RTC layer bind to a stale doc in the past. */
|
|
118
95
|
onContentSyncStatusChange?: (status: 'initializing' | 'syncing' | 'synced' | 'error') => void;
|
|
119
|
-
/** Fires once the first collaboration sync has been reconciled with the
|
|
120
|
-
* workbook, or when that reconciliation fails. */
|
|
121
|
-
onCollaborationInitializationComplete?: (result: 'ready' | 'error') => void;
|
|
122
96
|
editorStateRef?: React.MutableRefObject<{
|
|
123
97
|
refreshIndexedDB: () => Promise<void>;
|
|
124
98
|
getContentSnapshot: () => DSheetContentSnapshot;
|
|
@@ -4,17 +4,9 @@ type CommentData = object | null | undefined;
|
|
|
4
4
|
* the consumer-provided `commentData`.
|
|
5
5
|
*
|
|
6
6
|
* `ps` is a per-client, permission-gated *view overlay* — it is NOT persisted in
|
|
7
|
-
* ydoc
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* gated on the local `allowComments` permission, it must never be written back
|
|
11
|
-
* to shared ydoc state — doing so would let one viewer wipe markers for all.
|
|
12
|
-
*
|
|
13
|
-
* Handles both shapes:
|
|
14
|
-
* - Dense `sheet.data` (the live active sheet in `luckysheetfile`).
|
|
15
|
-
* - Sparse `sheet.celldata` (plain snapshots from `ySheetArrayToPlain`, and
|
|
16
|
-
* inactive sheets). `initSheetData()` converts celldata → data on activation,
|
|
17
|
-
* so `ps` set on celldata carries through.
|
|
7
|
+
* ydoc (`shouldPersistCelldataCell` ignores marker-only cells). Empty cells are
|
|
8
|
+
* `null`, so a tiny `{ ps }` object is created in the live view only so the
|
|
9
|
+
* triangle can render. Row/column drag still owns real cell data.
|
|
18
10
|
*
|
|
19
11
|
* Mutates in place and returns the same array.
|
|
20
12
|
*/
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import * as Y from 'yjs';
|
|
2
|
+
/** Sibling share key on the same Y.Doc as the sheet array. */
|
|
3
|
+
export declare function getCommentAnchorsMapKey(dsheetId: string): string;
|
|
4
|
+
export declare function getCommentAnchorsYMap(ydoc: Y.Doc, dsheetId: string): Y.Map<string>;
|
|
5
|
+
export declare function readCommentAnchorsFromYdoc(ydoc: Y.Doc | null | undefined, dsheetId: string): Record<string, string>;
|
|
6
|
+
type CommentAnchorRecord = {
|
|
7
|
+
id?: string;
|
|
8
|
+
key?: string;
|
|
9
|
+
contentHash?: string;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Re-key comments by identity first (id, then contentHash), then the comment's
|
|
13
|
+
* own current cell-key. Stale cell-key aliases that now belong to another
|
|
14
|
+
* thread must not steal or duplicate it.
|
|
15
|
+
*/
|
|
16
|
+
export declare function applyCommentAnchorMap<T extends CommentAnchorRecord>(commentsData: Record<string, T> | null | undefined, anchors: Record<string, string>): Record<string, T>;
|
|
17
|
+
export declare function applyYdocCommentAnchors<T extends CommentAnchorRecord>(commentsData: Record<string, T> | object | null | undefined, ydoc: Y.Doc | null | undefined, dsheetId: string): Record<string, T>;
|
|
18
|
+
/**
|
|
19
|
+
* Persist current commentId/contentHash → cell-key into ydoc so viewers/publish
|
|
20
|
+
* see the remapped positions. No-ops when the map already matches.
|
|
21
|
+
*/
|
|
22
|
+
export declare function writeCommentAnchorsToYdoc({ ydoc, dsheetId, commentsData, handleContentPortal, skipUnmapped, keyMoves, }: {
|
|
23
|
+
ydoc: Y.Doc | null | undefined;
|
|
24
|
+
dsheetId: string;
|
|
25
|
+
commentsData: Record<string, CommentAnchorRecord> | null | undefined;
|
|
26
|
+
handleContentPortal?: () => void;
|
|
27
|
+
/** When the map already has entries, skip comments that are not in it yet. */
|
|
28
|
+
skipUnmapped?: boolean;
|
|
29
|
+
/** old cell-key → new cell-key so indexer keys still resolve after remap. */
|
|
30
|
+
keyMoves?: Record<string, string>;
|
|
31
|
+
}): void;
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { CommentAnchorMove } from '../../sheet-engine/core/settings';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* old cell-key → new cell-key, matched by comment id. Used when writing
|
|
5
|
+
* ydoc aliases so indexer keys still resolve after a remap.
|
|
6
|
+
*/
|
|
7
|
+
export declare function commentKeyMovesById<T extends {
|
|
8
|
+
id?: string;
|
|
9
|
+
key?: string;
|
|
10
|
+
}>(before: Record<string, T>, after: Record<string, T>): Record<string, string>;
|
|
11
|
+
/**
|
|
12
|
+
* Remap in-memory comment keys after a row/column drag, cell-range move,
|
|
13
|
+
* or insert/delete of rows/columns.
|
|
14
|
+
*
|
|
15
|
+
* - Row/column drag: apply the full permutation `indexMap` (no collisions).
|
|
16
|
+
* - Cells: comments in the source rectangle follow the offset; comments that
|
|
17
|
+
* only lived in the destination are detached to `WITHOUT_CELL_<id>` so they
|
|
18
|
+
* remain in the sidebar instead of colliding with the incoming thread.
|
|
19
|
+
* - Insert: comments at/after the insertion point shift by `count`.
|
|
20
|
+
* - Delete: comments on removed rows/cols are detached; later ones shift up/left.
|
|
21
|
+
*/
|
|
22
|
+
export declare function remapCommentAnchors<T extends {
|
|
23
|
+
key?: string;
|
|
24
|
+
id?: string;
|
|
25
|
+
}>(commentsData: Record<string, T>, move: CommentAnchorMove): Record<string, T>;
|
|
26
|
+
export type { CommentAnchorMove };
|