Skip to content

Commit 0754863

Browse files
Fix type errors in devtools package (#938)
* Add EventsForDocReplay to handle document replay events * Resolve other type errors in devtools package * Update devtools-publish workflow trigger condition * Rename ReplayDocEventType to DocEventScope --------- Co-authored-by: Youngteac Hong <susukang98@gmail.com>
1 parent a217445 commit 0754863

File tree

11 files changed

+152
-109
lines changed

11 files changed

+152
-109
lines changed

.github/workflows/devtools-publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ on:
55
branches:
66
- 'main'
77
paths:
8-
- packages/devtools/**
8+
- packages/devtools/package.json
99
jobs:
1010
build-and-deploy:
1111
runs-on: ubuntu-latest

packages/devtools/src/devtools/components/Detail.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,13 @@ function TreeGraph({ tree }: { tree: Devtools.TreeNodeInfo }) {
110110
[],
111111
);
112112

113-
return flattenTreeWithDepth(tree).map((node) => (
114-
<TreeNode key={node.id} node={node} />
115-
));
113+
return (
114+
<>
115+
{flattenTreeWithDepth(tree).map((node) => (
116+
<TreeNode key={node.id} node={node} />
117+
))}
118+
</>
119+
);
116120
}
117121

118122
export function TreeDetail({

packages/devtools/src/devtools/components/Tree.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import useResizeObserver from 'use-resize-observer';
2222

2323
import { useSelectedNode } from '../contexts/SelectedNode';
2424
import { useSelectedPresence } from '../contexts/SelectedPresence';
25-
import type { Devtools } from 'yorkie-js-sdk';
25+
import type { Devtools, Json } from 'yorkie-js-sdk';
2626

2727
import {
2828
ArrayIcon,
@@ -47,7 +47,7 @@ export type UserNode = Devtools.Client & {
4747
export type PresenceJsonNode = {
4848
id: string;
4949
key: string;
50-
value: Devtools.Json;
50+
value: Json;
5151
isLastChild: boolean;
5252
type: 'JSON';
5353
};

packages/devtools/src/devtools/contexts/YorkieSource.tsx

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,14 @@ import {
2424
useState,
2525
} from 'react';
2626

27-
import {
28-
DocEventType,
29-
type SDKToPanelMessage,
30-
type TransactionEvent,
31-
} from 'yorkie-js-sdk';
27+
import { DocEventType, Devtools, type SDKToPanelMessage } from 'yorkie-js-sdk';
3228
import { connectPort, sendToSDK } from '../../port';
3329
import { Code, YorkieError } from '@yorkie-js-sdk/src/util/error';
3430

3531
const DocKeyContext = createContext<string>(null);
3632
const YorkieDocContext = createContext(null);
37-
const TransactionEventsContext = createContext<{
38-
events: Array<TransactionEvent>;
33+
const DocEventsForReplayContext = createContext<{
34+
events: Array<Devtools.DocEventsForReplay>;
3935
hidePresenceEvents: boolean;
4036
setHidePresenceEvents: Dispatch<SetStateAction<boolean>>;
4137
}>(null);
@@ -47,17 +43,16 @@ type Props = {
4743
export function YorkieSourceProvider({ children }: Props) {
4844
const [currentDocKey, setCurrentDocKey] = useState<string>('');
4945
const [doc, setDoc] = useState(null);
50-
const [transactionEvents, setTransactionEvents] = useState<
51-
Array<TransactionEvent>
46+
const [docEventsForReplay, setDocEventsForReplay] = useState<
47+
Array<Devtools.DocEventsForReplay>
5248
>([]);
5349

5450
// filter out presence events
55-
const [hideTransactionPresenceEvents, setHideTransactionPresenceEvents] =
56-
useState(false);
51+
const [hidePresenceEvents, setHidePresenceEvents] = useState(false);
5752

5853
const resetDocument = () => {
5954
setCurrentDocKey('');
60-
setTransactionEvents([]);
55+
setDocEventsForReplay([]);
6156
setDoc(null);
6257
};
6358

@@ -77,11 +72,11 @@ export function YorkieSourceProvider({ children }: Props) {
7772
case 'doc::sync::full':
7873
// TODO(chacha912): Notify the user that they need to use the latest version of Yorkie-JS-SDK.
7974
if (message.events === undefined) break;
80-
setTransactionEvents(message.events);
75+
setDocEventsForReplay(message.events);
8176
break;
8277
case 'doc::sync::partial':
8378
if (message.event === undefined) break;
84-
setTransactionEvents((events) => [...events, message.event]);
79+
setDocEventsForReplay((events) => [...events, message.event]);
8580
break;
8681
}
8782
}, []);
@@ -108,17 +103,17 @@ export function YorkieSourceProvider({ children }: Props) {
108103

109104
return (
110105
<DocKeyContext.Provider value={currentDocKey}>
111-
<TransactionEventsContext.Provider
106+
<DocEventsForReplayContext.Provider
112107
value={{
113-
events: transactionEvents,
114-
hidePresenceEvents: hideTransactionPresenceEvents,
115-
setHidePresenceEvents: setHideTransactionPresenceEvents,
108+
events: docEventsForReplay,
109+
hidePresenceEvents,
110+
setHidePresenceEvents,
116111
}}
117112
>
118113
<YorkieDocContext.Provider value={[doc, setDoc]}>
119114
{children}
120115
</YorkieDocContext.Provider>
121-
</TransactionEventsContext.Provider>
116+
</DocEventsForReplayContext.Provider>
122117
</DocKeyContext.Provider>
123118
);
124119
}
@@ -145,51 +140,54 @@ export function useYorkieDoc() {
145140
return value;
146141
}
147142

148-
export enum TransactionEventType {
149-
Document = 'document',
143+
/**
144+
* `DocEventScope` represents the scope of the document event.
145+
*/
146+
export enum DocEventScope {
147+
Root = 'root',
150148
Presence = 'presence',
149+
Document = 'document',
151150
}
152151

153-
export const getTransactionEventType = (
154-
event: TransactionEvent,
155-
): TransactionEventType => {
156-
for (const docEvent of event) {
152+
export const getDocEventsScope = (
153+
events: Devtools.DocEventsForReplay,
154+
): DocEventScope => {
155+
for (const e of events) {
157156
if (
158-
docEvent.type === DocEventType.StatusChanged ||
159-
docEvent.type === DocEventType.Snapshot ||
160-
docEvent.type === DocEventType.LocalChange ||
161-
docEvent.type === DocEventType.RemoteChange
157+
e.type === DocEventType.Snapshot ||
158+
e.type === DocEventType.LocalChange ||
159+
e.type === DocEventType.RemoteChange
162160
) {
163-
return TransactionEventType.Document;
161+
return DocEventScope.Root;
162+
} else if (e.type === DocEventType.StatusChanged) {
163+
return DocEventScope.Document;
164164
}
165165
}
166166

167-
return TransactionEventType.Presence;
167+
return DocEventScope.Presence;
168168
};
169169

170-
export function useTransactionEvents() {
170+
export function useDocEventsForReplay() {
171171
const { events, hidePresenceEvents, setHidePresenceEvents } = useContext(
172-
TransactionEventsContext,
172+
DocEventsForReplayContext,
173173
);
174174

175175
if (events === undefined) {
176176
throw new YorkieError(
177177
Code.ErrContextNotProvided,
178-
'useTransactionEvents should be used within YorkieSourceProvider',
178+
'useDocEventsForReplay should be used within YorkieSourceProvider',
179179
);
180180
}
181181

182182
// create an enhanced events with metadata
183183
const enhancedEvents = useMemo(() => {
184184
return events.map((event) => {
185-
const transactionEventType = getTransactionEventType(event);
185+
const scope = getDocEventsScope(event);
186186

187187
return {
188188
event,
189-
transactionEventType,
190-
isFiltered:
191-
hidePresenceEvents &&
192-
transactionEventType === TransactionEventType.Presence,
189+
scope,
190+
isFiltered: hidePresenceEvents && scope === DocEventScope.Presence,
193191
};
194192
});
195193
}, [hidePresenceEvents, events]);

packages/devtools/src/devtools/panel/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import { SelectedPresenceProvider } from '../contexts/SelectedPresence';
2323
import {
2424
YorkieSourceProvider,
2525
useCurrentDocKey,
26-
useTransactionEvents,
26+
useDocEventsForReplay,
2727
useYorkieDoc,
2828
} from '../contexts/YorkieSource';
2929
import { Document } from '../tabs/Document';
@@ -34,7 +34,7 @@ import { Separator } from '../components/ResizableSeparator';
3434
const Panel = () => {
3535
const currentDocKey = useCurrentDocKey();
3636
const { originalEvents, presenceFilteredEvents, hidePresenceEvents } =
37-
useTransactionEvents();
37+
useDocEventsForReplay();
3838
const [, setDoc] = useYorkieDoc();
3939
const [selectedEventIndexInfo, setSelectedEventIndexInfo] = useState({
4040
index: null,
@@ -91,7 +91,7 @@ const Panel = () => {
9191
filteredEventIndex++;
9292
}
9393

94-
doc.applyTransactionEvent(originalEvents[eventIndex].event);
94+
doc.applyDocEventsForReplay(originalEvents[eventIndex].event);
9595
eventIndex++;
9696
}
9797

packages/devtools/src/devtools/tabs/History.tsx

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,15 @@
1515
*/
1616

1717
import { useEffect, useState, useRef } from 'react';
18-
import { DocEventType, Change, type TransactionEvent } from 'yorkie-js-sdk';
18+
import { DocEventType, Change, Devtools } from 'yorkie-js-sdk';
1919
import Slider from 'rc-slider';
2020
import { JSONView } from '../components/JsonView';
2121
import { CursorIcon, DocumentIcon } from '../icons';
22-
import {
23-
TransactionEventType,
24-
useTransactionEvents,
25-
} from '../contexts/YorkieSource';
22+
import { DocEventScope, useDocEventsForReplay } from '../contexts/YorkieSource';
2623

2724
const SLIDER_MARK_WIDTH = 24;
2825

29-
const getEventInfo = (event: TransactionEvent) => {
26+
const getEventInfo = (event: Devtools.DocEventsForReplay) => {
3027
const info = [];
3128
for (const docEvent of event) {
3229
if (
@@ -75,7 +72,7 @@ export function History({
7572
presenceFilteredEvents,
7673
hidePresenceEvents,
7774
setHidePresenceEvents,
78-
} = useTransactionEvents();
75+
} = useDocEventsForReplay();
7976

8077
const events = hidePresenceEvents ? presenceFilteredEvents : originalEvents;
8178

@@ -109,13 +106,10 @@ export function History({
109106
const marks = {};
110107
for (const [index, event] of events.entries()) {
111108
const source = event.event[0].source;
112-
const transactionEventType = event.transactionEventType;
113109

114110
marks[index] = (
115-
<span
116-
className={`mark-history mark-${source} mark-${transactionEventType}`}
117-
>
118-
{transactionEventType === TransactionEventType.Presence ? (
111+
<span className={`mark-history mark-${source} mark-${event.scope}`}>
112+
{event.scope === DocEventScope.Presence ? (
119113
<CursorIcon />
120114
) : (
121115
<DocumentIcon />

packages/sdk/src/devtools/index.ts

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,33 +14,29 @@
1414
* limitations under the License.
1515
*/
1616

17-
import {
18-
Document,
19-
Indexable,
20-
TransactionEvent,
21-
} from '@yorkie-js-sdk/src/yorkie';
22-
import { DocEventType } from '@yorkie-js-sdk/src/document/document';
17+
import { Document, Indexable } from '@yorkie-js-sdk/src/yorkie';
2318
import { logger } from '@yorkie-js-sdk/src/util/logger';
2419
import type * as DevTools from './protocol';
2520
import { EventSourceDevPanel, EventSourceSDK } from './protocol';
21+
import { DocEventsForReplay, isDocEventsForReplay } from './types';
2622

2723
type DevtoolsStatus = 'connected' | 'disconnected' | 'synced';
2824
let devtoolsStatus: DevtoolsStatus = 'disconnected';
2925
const unsubsByDocKey = new Map<string, Array<() => void>>();
3026

3127
/**
32-
* `transactionEventsByDocKey` stores all events in the document for replaying
28+
* `docEventsForReplayByDocKey` stores all events in the document for replaying
3329
* (time-traveling feature) in Devtools. Later, external storage such as
3430
* IndexedDB will be used.
3531
*/
36-
const transactionEventsByDocKey = new Map<string, Array<TransactionEvent>>();
32+
const docEventsForReplayByDocKey = new Map<string, Array<DocEventsForReplay>>();
3733
declare global {
3834
interface Window {
39-
transactionEventsByDocKey: Map<string, Array<TransactionEvent>>;
35+
docEventsForReplayByDocKey: Map<string, Array<DocEventsForReplay>>;
4036
}
4137
}
4238
if (typeof window !== 'undefined') {
43-
window.transactionEventsByDocKey = transactionEventsByDocKey;
39+
window.docEventsForReplayByDocKey = docEventsForReplayByDocKey;
4440
}
4541

4642
/**
@@ -79,25 +75,13 @@ export function setupDevtools<T, P extends Indexable>(
7975
return;
8076
}
8177

82-
transactionEventsByDocKey.set(doc.getKey(), []);
78+
docEventsForReplayByDocKey.set(doc.getKey(), []);
8379
const unsub = doc.subscribe('all', (event) => {
84-
if (
85-
event.some(
86-
(docEvent) =>
87-
docEvent.type !== DocEventType.StatusChanged &&
88-
docEvent.type !== DocEventType.Snapshot &&
89-
docEvent.type !== DocEventType.LocalChange &&
90-
docEvent.type !== DocEventType.RemoteChange &&
91-
docEvent.type !== DocEventType.Initialized &&
92-
docEvent.type !== DocEventType.Watched &&
93-
docEvent.type !== DocEventType.Unwatched &&
94-
docEvent.type !== DocEventType.PresenceChanged,
95-
)
96-
) {
80+
if (!isDocEventsForReplay(event)) {
9781
return;
9882
}
9983

100-
transactionEventsByDocKey.get(doc.getKey())!.push(event);
84+
docEventsForReplayByDocKey.get(doc.getKey())!.push(event);
10185
if (devtoolsStatus === 'synced') {
10286
sendToPanel({
10387
msg: 'doc::sync::partial',
@@ -148,7 +132,7 @@ export function setupDevtools<T, P extends Indexable>(
148132
sendToPanel({
149133
msg: 'doc::sync::full',
150134
docKey: doc.getKey(),
151-
events: transactionEventsByDocKey.get(doc.getKey())!,
135+
events: docEventsForReplayByDocKey.get(doc.getKey())!,
152136
});
153137
logger.info(`[YD] Devtools subscribed. Doc: ${doc.getKey()}`);
154138
break;

packages/sdk/src/devtools/protocol.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
import type { TransactionEvent } from '@yorkie-js-sdk/src/document/document';
17+
import { DocEventsForReplay } from './types';
1818

1919
/**
2020
* `EventSourceDevPanel` is the name of the source representing messages
@@ -76,15 +76,15 @@ export type SDKToPanelMessage =
7676
| {
7777
msg: 'doc::sync::full';
7878
docKey: string;
79-
events: Array<TransactionEvent>;
79+
events: Array<DocEventsForReplay>;
8080
}
8181
/**
8282
* Sent whenever the document is changed.
8383
*/
8484
| {
8585
msg: 'doc::sync::partial';
8686
docKey: string;
87-
event: TransactionEvent;
87+
event: DocEventsForReplay;
8888
};
8989

9090
export type FullPanelToSDKMessage = PanelToSDKMessage & {

0 commit comments

Comments
 (0)