@synclineapi/editor 2.0.0 → 3.0.1
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 +296 -7
- package/dist/syncline-editor.es.js +1837 -1010
- package/dist/syncline-editor.es.js.map +1 -1
- package/dist/syncline-editor.umd.js +107 -25
- package/dist/syncline-editor.umd.js.map +1 -1
- package/dist/types/index.d.ts +413 -0
- package/package.json +2 -1
package/dist/types/index.d.ts
CHANGED
|
@@ -1,3 +1,69 @@
|
|
|
1
|
+
export declare class AwarenessManager {
|
|
2
|
+
private _local;
|
|
3
|
+
private _peers;
|
|
4
|
+
private _transport;
|
|
5
|
+
private _unsub;
|
|
6
|
+
private _heartbeat;
|
|
7
|
+
private _gcTimer;
|
|
8
|
+
private _onChange;
|
|
9
|
+
constructor(transport: CRDTTransport, name: string);
|
|
10
|
+
/** Called by the binding when the local cursor moves */
|
|
11
|
+
updateCursor(row: number, col: number): void;
|
|
12
|
+
updateSelection(from: {
|
|
13
|
+
row: number;
|
|
14
|
+
col: number;
|
|
15
|
+
}, to: {
|
|
16
|
+
row: number;
|
|
17
|
+
col: number;
|
|
18
|
+
}): void;
|
|
19
|
+
clearSelection(): void;
|
|
20
|
+
get localState(): AwarenessState;
|
|
21
|
+
get peers(): Map<string, AwarenessState>;
|
|
22
|
+
onChange(cb: (peers: Map<string, AwarenessState>) => void): void;
|
|
23
|
+
/** Expose broadcast for external use (e.g. initial announcement) */
|
|
24
|
+
broadcast(): void;
|
|
25
|
+
private _broadcast;
|
|
26
|
+
destroy(): void;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export declare interface AwarenessState {
|
|
30
|
+
readonly siteId: string;
|
|
31
|
+
readonly name: string;
|
|
32
|
+
readonly color: string;
|
|
33
|
+
cursor: {
|
|
34
|
+
row: number;
|
|
35
|
+
col: number;
|
|
36
|
+
} | null;
|
|
37
|
+
selection: {
|
|
38
|
+
from: {
|
|
39
|
+
row: number;
|
|
40
|
+
col: number;
|
|
41
|
+
};
|
|
42
|
+
to: {
|
|
43
|
+
row: number;
|
|
44
|
+
col: number;
|
|
45
|
+
};
|
|
46
|
+
} | null;
|
|
47
|
+
readonly updatedAt: number;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export declare interface BindingOptions {
|
|
51
|
+
/** Display name shown to remote peers (default: 'Peer') */
|
|
52
|
+
name?: string;
|
|
53
|
+
/** Called whenever the set of remote peers changes */
|
|
54
|
+
onPeersChange?: (peers: Map<string, AwarenessState>) => void;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export declare class BroadcastChannelTransport implements CRDTTransport {
|
|
58
|
+
readonly siteId: string;
|
|
59
|
+
private readonly _channel;
|
|
60
|
+
private readonly _cbs;
|
|
61
|
+
constructor(channelName: string, siteId: string);
|
|
62
|
+
send(msg: ChannelMessage): void;
|
|
63
|
+
onMessage(cb: (msg: ChannelMessage) => void): () => void;
|
|
64
|
+
close(): void;
|
|
65
|
+
}
|
|
66
|
+
|
|
1
67
|
export declare const BUILT_IN_THEMES: ThemeDefinition[];
|
|
2
68
|
|
|
3
69
|
/**
|
|
@@ -15,6 +81,56 @@ export declare interface CacheMetrics {
|
|
|
15
81
|
size: number;
|
|
16
82
|
}
|
|
17
83
|
|
|
84
|
+
export declare type ChannelMessage = {
|
|
85
|
+
type: 'ops';
|
|
86
|
+
fromSite: string;
|
|
87
|
+
ops: CRDTOp[];
|
|
88
|
+
sv: Record<string, number>;
|
|
89
|
+
} | {
|
|
90
|
+
type: 'awareness';
|
|
91
|
+
state: AwarenessState;
|
|
92
|
+
} | {
|
|
93
|
+
type: 'sync-request';
|
|
94
|
+
fromSite: string;
|
|
95
|
+
sv: Record<string, number>;
|
|
96
|
+
} | {
|
|
97
|
+
type: 'sync-reply';
|
|
98
|
+
fromSite: string;
|
|
99
|
+
ops: CRDTOp[];
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/** Unique identifier for a character node in the CRDT sequence */
|
|
103
|
+
export declare interface CharId {
|
|
104
|
+
readonly site: string;
|
|
105
|
+
readonly clock: number;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export declare function charIdEq(a: CharId, b: CharId): boolean;
|
|
109
|
+
|
|
110
|
+
export declare function charIdToStr(id: CharId): string;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Collaboration configuration passed to `EditorConfig.collab`.
|
|
114
|
+
* When set, the editor automatically creates a CRDT binding and renders
|
|
115
|
+
* remote peer cursors, selections, and presence indicators.
|
|
116
|
+
*/
|
|
117
|
+
export declare interface CollabConfig {
|
|
118
|
+
/** The transport layer to use (LocalTransport, BroadcastChannelTransport, or WebSocketTransport). */
|
|
119
|
+
transport: CRDTTransport;
|
|
120
|
+
/** Display name shown to remote peers. Default: `'Peer'`. */
|
|
121
|
+
name?: string;
|
|
122
|
+
/**
|
|
123
|
+
* Called whenever the set of connected peers changes.
|
|
124
|
+
* The map is keyed by siteId and contains each peer's latest awareness state.
|
|
125
|
+
*/
|
|
126
|
+
onPeersChange?: (peers: Map<string, AwarenessState>) => void;
|
|
127
|
+
/**
|
|
128
|
+
* Called when the WebSocket connection status changes.
|
|
129
|
+
* Only relevant when using `WebSocketTransport`.
|
|
130
|
+
*/
|
|
131
|
+
onStatus?: (status: 'connecting' | 'connected' | 'disconnected' | 'syncing') => void;
|
|
132
|
+
}
|
|
133
|
+
|
|
18
134
|
/**
|
|
19
135
|
* Context passed to a `provideCompletions` callback.
|
|
20
136
|
* Describes the current cursor position and document state at the moment
|
|
@@ -104,6 +220,74 @@ export declare interface CompletionItem {
|
|
|
104
220
|
*/
|
|
105
221
|
export declare type CompletionKind = 'kw' | 'fn' | 'typ' | 'cls' | 'var' | 'snip' | 'emmet';
|
|
106
222
|
|
|
223
|
+
export declare class CRDTBinding {
|
|
224
|
+
readonly doc: RGADocument;
|
|
225
|
+
readonly awareness: AwarenessManager;
|
|
226
|
+
private readonly _editor;
|
|
227
|
+
private readonly _transport;
|
|
228
|
+
private readonly _unsub;
|
|
229
|
+
private _lastText;
|
|
230
|
+
private _suppress;
|
|
231
|
+
constructor(editor: EditorLike, doc: RGADocument, transport: CRDTTransport, opts?: BindingOptions);
|
|
232
|
+
private _onEditorChange;
|
|
233
|
+
private _onMessage;
|
|
234
|
+
private _applyRemoteOps;
|
|
235
|
+
destroy(): void;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/** A node in the CRDT linked sequence */
|
|
239
|
+
export declare interface CRDTChar {
|
|
240
|
+
readonly id: CharId;
|
|
241
|
+
readonly after: CharId;
|
|
242
|
+
readonly char: string;
|
|
243
|
+
deleted: boolean;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export declare type CRDTOp = InsertOp | DeleteOp;
|
|
247
|
+
|
|
248
|
+
export declare interface CRDTTransport {
|
|
249
|
+
readonly siteId: string;
|
|
250
|
+
send(msg: ChannelMessage): void;
|
|
251
|
+
onMessage(cb: (msg: ChannelMessage) => void): () => void;
|
|
252
|
+
close(): void;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Convenience factory: create a fully wired collaborative editor session.
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* ```ts
|
|
260
|
+
* const session = createCollabSession(editor, { room: 'my-doc', name: 'Alice' });
|
|
261
|
+
* // Later:
|
|
262
|
+
* session.destroy();
|
|
263
|
+
* ```
|
|
264
|
+
*/
|
|
265
|
+
export declare function createCollabSession(editor: {
|
|
266
|
+
getValue(): string;
|
|
267
|
+
setValue(v: string): void;
|
|
268
|
+
updateConfig(c: Record<string, unknown>): void;
|
|
269
|
+
}, options?: {
|
|
270
|
+
/** Room / channel name shared by all collaborating peers */
|
|
271
|
+
room?: string;
|
|
272
|
+
/** Stable unique ID for this peer. Defaults to crypto.randomUUID(). */
|
|
273
|
+
siteId?: string;
|
|
274
|
+
/** Display name shown to remote peers */
|
|
275
|
+
name?: string;
|
|
276
|
+
/**
|
|
277
|
+
* Transport type:
|
|
278
|
+
* - 'local' (default) — in-process event bus, for same-page demos
|
|
279
|
+
* - 'broadcastchannel' — cross-tab on same origin
|
|
280
|
+
* - A CRDTTransport constructor (e.g. WebSocketTransport)
|
|
281
|
+
*/
|
|
282
|
+
transport?: 'local' | 'broadcastchannel' | (new (room: string, siteId: string) => CRDTTransport);
|
|
283
|
+
/** Called whenever the set of remote peers changes */
|
|
284
|
+
onPeersChange?: (peers: Map<string, AwarenessState>) => void;
|
|
285
|
+
}): {
|
|
286
|
+
binding: CRDTBinding;
|
|
287
|
+
doc: RGADocument;
|
|
288
|
+
destroy(): void;
|
|
289
|
+
};
|
|
290
|
+
|
|
107
291
|
/** Convenience type alias for the `createEditor` function signature. */
|
|
108
292
|
export declare type CreateEditor = typeof createEditor;
|
|
109
293
|
|
|
@@ -153,6 +337,29 @@ export declare interface CursorPosition {
|
|
|
153
337
|
col: number;
|
|
154
338
|
}
|
|
155
339
|
|
|
340
|
+
export declare interface DeleteOp {
|
|
341
|
+
readonly type: 'delete';
|
|
342
|
+
readonly id: CharId;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
export declare interface DiffEdit {
|
|
346
|
+
readonly type: 'insert' | 'delete';
|
|
347
|
+
readonly offset: number;
|
|
348
|
+
readonly chars: string;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Compute a minimal edit script from `oldText` to `newText`.
|
|
353
|
+
*
|
|
354
|
+
* Strategy: trim common prefix and suffix, then the middle is
|
|
355
|
+
* either a pure delete, a pure insert, or a replace (delete at
|
|
356
|
+
* position P + insert at position P). Offsets are in old-text
|
|
357
|
+
* coordinates for deletes and new-text coordinates for inserts.
|
|
358
|
+
*
|
|
359
|
+
* This is O(n) and correct for all practical editor operations.
|
|
360
|
+
*/
|
|
361
|
+
export declare function diffText(a: string, b: string): DiffEdit[];
|
|
362
|
+
|
|
156
363
|
/**
|
|
157
364
|
* Public API surface returned by `SynclineEditor.create()`.
|
|
158
365
|
* All methods are safe to call at any time after construction.
|
|
@@ -689,6 +896,54 @@ export declare interface EditorConfig {
|
|
|
689
896
|
* ```
|
|
690
897
|
*/
|
|
691
898
|
provideHover?: (context: HoverContext) => HoverDoc | null | undefined;
|
|
899
|
+
/**
|
|
900
|
+
* Ghost text shown inside the editor when the document is completely empty.
|
|
901
|
+
* Only rendered when this string is non-empty.
|
|
902
|
+
* @default ''
|
|
903
|
+
*/
|
|
904
|
+
placeholder?: string;
|
|
905
|
+
/**
|
|
906
|
+
* Enable the Go to Line bar (Ctrl+G / Cmd+G).
|
|
907
|
+
* When `false` the shortcut does nothing and the bar is never shown.
|
|
908
|
+
* @default false
|
|
909
|
+
*/
|
|
910
|
+
goToLine?: boolean;
|
|
911
|
+
/**
|
|
912
|
+
* Enable real-time collaborative editing via CRDT.
|
|
913
|
+
*
|
|
914
|
+
* When set, the editor automatically:
|
|
915
|
+
* - Creates an RGA CRDT document and binds it to this editor instance.
|
|
916
|
+
* - Broadcasts local edits and cursor/selection state to remote peers.
|
|
917
|
+
* - Renders remote peer cursors (coloured beams + name labels) and
|
|
918
|
+
* remote selections (semi-transparent coloured highlights) live.
|
|
919
|
+
* - Reconciles state on reconnect — works offline and re-syncs automatically.
|
|
920
|
+
*
|
|
921
|
+
* To enable collaboration just pass a transport:
|
|
922
|
+
* ```ts
|
|
923
|
+
* import { WebSocketTransport } from '@synclineapi/editor';
|
|
924
|
+
*
|
|
925
|
+
* const editor = SynclineEditor.create(container, {
|
|
926
|
+
* collab: {
|
|
927
|
+
* transport: new WebSocketTransport('wss://relay.example.com', 'my-room', crypto.randomUUID()),
|
|
928
|
+
* name: 'Alice',
|
|
929
|
+
* onPeersChange: (peers) => console.log('peers:', [...peers.values()].map(p => p.name)),
|
|
930
|
+
* },
|
|
931
|
+
* });
|
|
932
|
+
* ```
|
|
933
|
+
*
|
|
934
|
+
* To change or remove collab at runtime call `updateConfig({ collab: ... })`.
|
|
935
|
+
* Pass `undefined` to tear down the existing binding.
|
|
936
|
+
*
|
|
937
|
+
* @default undefined
|
|
938
|
+
*/
|
|
939
|
+
collab?: CollabConfig;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
/** Minimal interface required from the editor */
|
|
943
|
+
declare interface EditorLike {
|
|
944
|
+
getValue(): string;
|
|
945
|
+
setValue(v: string): void;
|
|
946
|
+
updateConfig(c: Record<string, unknown>): void;
|
|
692
947
|
}
|
|
693
948
|
|
|
694
949
|
/**
|
|
@@ -759,12 +1014,30 @@ declare interface HoverDoc {
|
|
|
759
1014
|
language?: string | string[];
|
|
760
1015
|
}
|
|
761
1016
|
|
|
1017
|
+
export declare interface InsertOp {
|
|
1018
|
+
readonly type: 'insert';
|
|
1019
|
+
readonly id: CharId;
|
|
1020
|
+
readonly after: CharId;
|
|
1021
|
+
readonly char: string;
|
|
1022
|
+
}
|
|
1023
|
+
|
|
762
1024
|
/**
|
|
763
1025
|
* Supported language identifiers for syntax highlighting and autocomplete.
|
|
764
1026
|
* Pass as the `language` option in `EditorConfig`.
|
|
765
1027
|
*/
|
|
766
1028
|
export declare type Language = 'typescript' | 'javascript' | 'css' | 'json' | 'markdown' | 'text';
|
|
767
1029
|
|
|
1030
|
+
export declare class LocalTransport implements CRDTTransport {
|
|
1031
|
+
readonly siteId: string;
|
|
1032
|
+
private readonly _room;
|
|
1033
|
+
private readonly _cbs;
|
|
1034
|
+
constructor(room: string, siteId: string);
|
|
1035
|
+
private readonly _receive;
|
|
1036
|
+
send(msg: ChannelMessage): void;
|
|
1037
|
+
onMessage(cb: (msg: ChannelMessage) => void): () => void;
|
|
1038
|
+
close(): void;
|
|
1039
|
+
}
|
|
1040
|
+
|
|
768
1041
|
/**
|
|
769
1042
|
* Colour palette used when painting the minimap canvas.
|
|
770
1043
|
* Each value is a CSS colour string resolved from the active theme.
|
|
@@ -796,6 +1069,72 @@ export declare interface MinimapColors {
|
|
|
796
1069
|
[key: string]: string;
|
|
797
1070
|
}
|
|
798
1071
|
|
|
1072
|
+
export declare class RGADocument {
|
|
1073
|
+
/** All nodes, keyed by their canonical string ID */
|
|
1074
|
+
private readonly _chars;
|
|
1075
|
+
/** The full ordered sequence of IDs (visible + tombstones) */
|
|
1076
|
+
private _seq;
|
|
1077
|
+
/** Reverse index: idStr → index in _seq (invalidated on splice, rebuilt lazily) */
|
|
1078
|
+
private _idxDirty;
|
|
1079
|
+
private _idxMap;
|
|
1080
|
+
readonly siteId: string;
|
|
1081
|
+
private _clock;
|
|
1082
|
+
readonly stateVector: StateVector;
|
|
1083
|
+
/** Full operation log — used to answer sync-requests from peers */
|
|
1084
|
+
private readonly _opLog;
|
|
1085
|
+
constructor(siteId: string);
|
|
1086
|
+
get clock(): number;
|
|
1087
|
+
/** Return the visible document text */
|
|
1088
|
+
getText(): string;
|
|
1089
|
+
/** Number of visible characters */
|
|
1090
|
+
get length(): number;
|
|
1091
|
+
/**
|
|
1092
|
+
* Insert `text` at visible offset `offset`.
|
|
1093
|
+
* Returns the generated ops (apply them locally AND send to peers).
|
|
1094
|
+
*/
|
|
1095
|
+
localInsert(offset: number, text: string): InsertOp[];
|
|
1096
|
+
/**
|
|
1097
|
+
* Delete `length` visible characters starting at `offset`.
|
|
1098
|
+
* Returns the generated ops.
|
|
1099
|
+
*/
|
|
1100
|
+
localDelete(offset: number, length: number): DeleteOp[];
|
|
1101
|
+
/**
|
|
1102
|
+
* Apply an op from a remote peer.
|
|
1103
|
+
* Returns true if the op was new (applied), false if already seen.
|
|
1104
|
+
*/
|
|
1105
|
+
apply(op: CRDTOp): boolean;
|
|
1106
|
+
/** Return all ops not yet seen by `sv` */
|
|
1107
|
+
getOpsSince(sv: StateVector): CRDTOp[];
|
|
1108
|
+
getStateVector(): StateVector;
|
|
1109
|
+
serialize(): {
|
|
1110
|
+
siteId: string;
|
|
1111
|
+
clock: number;
|
|
1112
|
+
ops: CRDTOp[];
|
|
1113
|
+
};
|
|
1114
|
+
static deserialize(data: {
|
|
1115
|
+
siteId: string;
|
|
1116
|
+
clock: number;
|
|
1117
|
+
ops: CRDTOp[];
|
|
1118
|
+
}): RGADocument;
|
|
1119
|
+
private _genId;
|
|
1120
|
+
private _updateSV;
|
|
1121
|
+
private _applyInsert;
|
|
1122
|
+
private _applyDelete;
|
|
1123
|
+
/**
|
|
1124
|
+
* YATA comparison: returns >0 if `a` has priority (goes first / to the left).
|
|
1125
|
+
* Higher clock wins; equal clock → lower siteId wins.
|
|
1126
|
+
*/
|
|
1127
|
+
private _cmp;
|
|
1128
|
+
private _rebuildIdx;
|
|
1129
|
+
/** Return the ID of the n-th visible character (0-indexed). Returns ROOT_ID for n<0. */
|
|
1130
|
+
private _visibleIdAt;
|
|
1131
|
+
/** Return IDs of `len` visible characters starting at `offset` */
|
|
1132
|
+
private _visibleIdsInRange;
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
/** Sentinel root node — logical start-of-document anchor */
|
|
1136
|
+
export declare const ROOT_ID: CharId;
|
|
1137
|
+
|
|
799
1138
|
/**
|
|
800
1139
|
* A selection range defined by an anchor (where selection started)
|
|
801
1140
|
* and a focus (where the caret currently sits). Either end can be
|
|
@@ -813,6 +1152,15 @@ declare interface Selection_2 {
|
|
|
813
1152
|
}
|
|
814
1153
|
export { Selection_2 as Selection }
|
|
815
1154
|
|
|
1155
|
+
export declare function siteColor(siteId: string): string;
|
|
1156
|
+
|
|
1157
|
+
/** Maps siteId → highest clock value seen from that site */
|
|
1158
|
+
export declare type StateVector = Map<string, number>;
|
|
1159
|
+
|
|
1160
|
+
export declare function svFromRecord(r: Record<string, number>): StateVector;
|
|
1161
|
+
|
|
1162
|
+
export declare function svToRecord(sv: StateVector): Record<string, number>;
|
|
1163
|
+
|
|
816
1164
|
export declare class SynclineEditor implements EditorAPI {
|
|
817
1165
|
private readonly _host;
|
|
818
1166
|
private readonly _shadow;
|
|
@@ -835,6 +1183,10 @@ export declare class SynclineEditor implements EditorAPI {
|
|
|
835
1183
|
private readonly _hoverTip;
|
|
836
1184
|
private readonly _themeOverlay;
|
|
837
1185
|
private readonly _themePanel;
|
|
1186
|
+
private readonly _placeholderEl;
|
|
1187
|
+
private readonly _goToLineBar;
|
|
1188
|
+
private readonly _goToLineInput;
|
|
1189
|
+
private readonly _goToLineHint;
|
|
838
1190
|
private _config;
|
|
839
1191
|
private _tab;
|
|
840
1192
|
private _wm;
|
|
@@ -867,6 +1219,10 @@ export declare class SynclineEditor implements EditorAPI {
|
|
|
867
1219
|
private _dynamicStyleEl;
|
|
868
1220
|
private _emmetExpanded;
|
|
869
1221
|
private _snippetExpanded;
|
|
1222
|
+
/** Active snippet tab-stop session. Cleared on click, Escape, or structural edit. */
|
|
1223
|
+
private _snippetSession;
|
|
1224
|
+
private _collabBinding;
|
|
1225
|
+
private _remotePeers;
|
|
870
1226
|
/** Pending debounce timer ID for autocomplete re-computation. */
|
|
871
1227
|
private _acDebounceTimer;
|
|
872
1228
|
/** Pending requestAnimationFrame ID for coalesced renders. */
|
|
@@ -893,8 +1249,15 @@ export declare class SynclineEditor implements EditorAPI {
|
|
|
893
1249
|
undo(): void;
|
|
894
1250
|
redo(): void;
|
|
895
1251
|
executeCommand(command: string): void;
|
|
1252
|
+
private _initCollab;
|
|
1253
|
+
private _destroyCollab;
|
|
1254
|
+
/** Notify remote peers of the current local cursor / selection position. */
|
|
1255
|
+
private _broadcastCursorToCollab;
|
|
896
1256
|
destroy(): void;
|
|
897
1257
|
private _buildFindBar;
|
|
1258
|
+
private _buildGoToLineBar;
|
|
1259
|
+
private _openGoToLine;
|
|
1260
|
+
private _closeGoToLine;
|
|
898
1261
|
private _buildStatusBar;
|
|
899
1262
|
private _applyDynamicStyles;
|
|
900
1263
|
/**
|
|
@@ -974,6 +1337,7 @@ export declare class SynclineEditor implements EditorAPI {
|
|
|
974
1337
|
private _isWordChar;
|
|
975
1338
|
private _wordSkipRight;
|
|
976
1339
|
private _wordSkipLeft;
|
|
1340
|
+
private _duplicateLines;
|
|
977
1341
|
private _moveLines;
|
|
978
1342
|
private _scheduleHover;
|
|
979
1343
|
private _doHover;
|
|
@@ -1180,4 +1544,53 @@ export declare interface TokenColors {
|
|
|
1180
1544
|
decorator?: string;
|
|
1181
1545
|
}
|
|
1182
1546
|
|
|
1547
|
+
export declare class WebSocketTransport implements CRDTTransport {
|
|
1548
|
+
readonly siteId: string;
|
|
1549
|
+
private _ws;
|
|
1550
|
+
private readonly _baseUrl;
|
|
1551
|
+
private readonly _cbs;
|
|
1552
|
+
private _reconnectTimer;
|
|
1553
|
+
private _pingTimer;
|
|
1554
|
+
private _closed;
|
|
1555
|
+
private _attempt;
|
|
1556
|
+
private _queue;
|
|
1557
|
+
private readonly _opts;
|
|
1558
|
+
/**
|
|
1559
|
+
* @param serverUrl Base WebSocket URL **without** trailing slash.
|
|
1560
|
+
* Room and siteId are appended automatically.
|
|
1561
|
+
* Example: `"ws://localhost:8080"` → connects to
|
|
1562
|
+
* `ws://localhost:8080/<room>?site=<siteId>`
|
|
1563
|
+
* @param room Document / collaboration room identifier.
|
|
1564
|
+
* @param siteId This peer's unique ID (UUID).
|
|
1565
|
+
* @param opts Optional behaviour hooks and tuning knobs.
|
|
1566
|
+
*/
|
|
1567
|
+
constructor(serverUrl: string, room: string, siteId: string, opts?: WebSocketTransportOptions);
|
|
1568
|
+
private _connect;
|
|
1569
|
+
/** Exponential back-off: 250 ms × 2^attempt, capped at maxBackoffMs. */
|
|
1570
|
+
private _scheduleReconnect;
|
|
1571
|
+
private _startPing;
|
|
1572
|
+
private _stopPing;
|
|
1573
|
+
send(msg: ChannelMessage): void;
|
|
1574
|
+
private _rawSend;
|
|
1575
|
+
onMessage(cb: (msg: ChannelMessage) => void): () => void;
|
|
1576
|
+
close(): void;
|
|
1577
|
+
/** Current WebSocket ready-state as a human-readable string. */
|
|
1578
|
+
get connectionState(): 'connecting' | 'open' | 'closing' | 'closed';
|
|
1579
|
+
/** Number of messages currently buffered waiting for reconnection. */
|
|
1580
|
+
get queuedMessageCount(): number;
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
declare interface WebSocketTransportOptions {
|
|
1584
|
+
/** Called each time the connection is established (including re-connects). */
|
|
1585
|
+
onConnect?: () => void;
|
|
1586
|
+
/** Called when the connection drops. `willReconnect` is false on explicit close(). */
|
|
1587
|
+
onDisconnect?: (willReconnect: boolean) => void;
|
|
1588
|
+
/** Called on unrecoverable or unexpected errors. */
|
|
1589
|
+
onError?: (err: Event) => void;
|
|
1590
|
+
/** Ping interval in ms. Default 25 000. Set to 0 to disable. */
|
|
1591
|
+
pingIntervalMs?: number;
|
|
1592
|
+
/** Maximum reconnection delay in ms. Default 30 000. */
|
|
1593
|
+
maxBackoffMs?: number;
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1183
1596
|
export { }
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "
|
|
6
|
+
"version": "3.0.1",
|
|
7
7
|
"description": "A zero-dependency, pixel-perfect, fully customisable browser-based code editor",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"main": "./dist/syncline-editor.umd.js",
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
],
|
|
23
23
|
"scripts": {
|
|
24
24
|
"dev": "vite --config vite.config.ts",
|
|
25
|
+
"dev:app": "vite --config vite.config.app.ts",
|
|
25
26
|
"build": "tsc --noEmit && vite build --config vite.lib.config.ts",
|
|
26
27
|
"build:app": "vite build --config vite.config.app.ts",
|
|
27
28
|
"preview": "vite preview --config vite.config.ts",
|