Skip to content

Commit 30f754e

Browse files
authored
(chore) @otjs/utils: Generic Event Emitter Implementation
Generic abstract class to be extended by each even-driven modules without reimplementing same functionalities. Remove 3rd party dependency from child packages. Fixes: #122 Signed-off-by: Progyan Bhattacharya <[email protected]>
1 parent 33d3a6f commit 30f754e

28 files changed

+369
-301
lines changed

packages/ace/package.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,6 @@
4848
"@types/ace": "0.0.48",
4949
"@types/lodash": "4.14.191"
5050
},
51-
"dependencies": {
52-
"mitt": "3.0.1"
53-
},
5451
"peerDependencies": {
5552
"@otjs/plaintext": "^0.2.0",
5653
"@otjs/plaintext-editor": "^0.2.0",

packages/ace/src/ace-adapter.ts

Lines changed: 32 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,15 @@ import {
3535
ITextOperation,
3636
PlainTextOperation,
3737
} from "@otjs/plaintext";
38-
import { IDisposable, IDisposableCollection } from "@otjs/types";
38+
import { IDisposable, IDisposableCollection, IEventHandler } from "@otjs/types";
3939
import {
4040
addStyleRule,
4141
assert,
4242
Disposable,
4343
DisposableCollection,
4444
EndOfLineSequence,
45+
EventEmitter,
4546
} from "@otjs/utils";
46-
import mitt, { Emitter, Handler } from "mitt";
4747
import { TAceAdapterConstructionOptions } from "./api";
4848
import { createCursorWidget, disposeCursorWidgets } from "./cursor-widget.impl";
4949

@@ -57,7 +57,10 @@ const Range: typeof AceAjax.Range = ace.require("ace/range").Range;
5757
* Create Editor Adapter for Plain Text Editor using Ace as Editor.
5858
* @param constructorOptions - A Configuration Object consisting Ace Editor Instance.
5959
*/
60-
export class AceAdapter implements IEditorAdapter {
60+
export class AceAdapter
61+
extends EventEmitter<EditorAdapterEvent, TEditorAdapterEventArgs>
62+
implements IEditorAdapter
63+
{
6164
protected _ace: AceAjax.Editor;
6265
protected readonly _toDispose: IDisposableCollection =
6366
new DisposableCollection();
@@ -68,19 +71,19 @@ export class AceAdapter implements IEditorAdapter {
6871
protected _bindEvents: boolean;
6972
protected _initiated: boolean = false;
7073
protected _ignoreChanges: boolean = false;
71-
protected _undoCallback: Handler<void> | null = null;
72-
protected _redoCallback: Handler<void> | null = null;
73-
protected _originalUndo: Handler<void> | null = null;
74-
protected _originalRedo: Handler<void> | null = null;
74+
protected _undoCallback: IEventHandler<void> | null = null;
75+
protected _redoCallback: IEventHandler<void> | null = null;
76+
protected _originalUndo: IEventHandler<void> | null = null;
77+
protected _originalRedo: IEventHandler<void> | null = null;
7578
protected _lastDocLines: string[] = [];
7679
protected _lastCursorRange: AceAjax.Range | null = null;
77-
protected _emitter: Emitter<TEditorAdapterEventArgs> = mitt();
7880

7981
constructor({
8082
editor,
8183
announcementDuration = 1000,
8284
bindEvents = false,
8385
}: TAceAdapterConstructionOptions) {
86+
super();
8487
this._ace = editor;
8588
this._announcementDuration = announcementDuration;
8689
this._aceSession = this._ace.getSession();
@@ -99,7 +102,7 @@ export class AceAdapter implements IEditorAdapter {
99102
set events(bindEvents: boolean) {
100103
assert(
101104
typeof bindEvents === "boolean",
102-
"events property takes only boolean value"
105+
"events property takes only boolean value",
103106
);
104107

105108
if (this._bindEvents === bindEvents) {
@@ -145,39 +148,17 @@ export class AceAdapter implements IEditorAdapter {
145148
this._bindEvents = false;
146149
}
147150

148-
on<Key extends keyof TEditorAdapterEventArgs>(
149-
event: Key,
150-
listener: Handler<TEditorAdapterEventArgs[Key]>
151-
): void {
152-
return this._emitter?.on(event, listener);
153-
}
154-
155-
off<Key extends keyof TEditorAdapterEventArgs>(
156-
event: Key,
157-
listener?: Handler<TEditorAdapterEventArgs[Key]>
158-
): void {
159-
return this._emitter?.off(event, listener);
160-
}
161-
162-
/** Trigger an event with optional payload */
163-
protected _trigger<Key extends keyof TEditorAdapterEventArgs>(
164-
event: Key,
165-
payload: TEditorAdapterEventArgs[Key]
166-
): void {
167-
return this._emitter!.emit(event, payload);
168-
}
169-
170-
registerUndo(undoCallback: Handler<void>): void {
151+
registerUndo(undoCallback: IEventHandler<void>): void {
171152
this._originalUndo = this._ace.undo;
172153
this._ace.undo = this._undoCallback = undoCallback;
173154
}
174155

175-
registerRedo(redoCallback: Handler<void>): void {
156+
registerRedo(redoCallback: IEventHandler<void>): void {
176157
this._originalRedo = this._ace.redo;
177158
this._ace.redo = this._redoCallback = redoCallback;
178159
}
179160

180-
deregisterUndo(undoCallback?: Handler<void>): void {
161+
deregisterUndo(undoCallback?: IEventHandler<void>): void {
181162
if (undoCallback != null && this._undoCallback !== undoCallback) {
182163
return;
183164
}
@@ -190,7 +171,7 @@ export class AceAdapter implements IEditorAdapter {
190171
this._originalUndo = null;
191172
}
192173

193-
deregisterRedo(redoCallback?: Handler<void>): void {
174+
deregisterRedo(redoCallback?: IEventHandler<void>): void {
194175
if (redoCallback != null && this._redoCallback !== redoCallback) {
195176
return;
196177
}
@@ -208,10 +189,10 @@ export class AceAdapter implements IEditorAdapter {
208189

209190
try {
210191
start = this._aceDocument.positionToIndex(
211-
this._aceSession.selection.getRange().start
192+
this._aceSession.selection.getRange().start,
212193
);
213194
end = this._aceDocument.positionToIndex(
214-
this._aceSession.selection.getRange().end
195+
this._aceSession.selection.getRange().end,
215196
);
216197
} catch (err) /* istanbul ignore next */ {
217198
console.log("Failed to get cursor position from Ace editor: ", err);
@@ -224,7 +205,7 @@ export class AceAdapter implements IEditorAdapter {
224205
console.log(
225206
"Couldn't figure out the cursor range:",
226207
err2,
227-
"-- setting it to 0:0."
208+
"-- setting it to 0:0.",
228209
);
229210

230211
return null;
@@ -247,7 +228,7 @@ export class AceAdapter implements IEditorAdapter {
247228

248229
/** Create Selection in the Editor */
249230
this._aceSession.selection.setSelectionRange(
250-
new Range(start.row, start.column, end.row, end.column)
231+
new Range(start.row, start.column, end.row, end.column),
251232
);
252233
}
253234

@@ -259,12 +240,12 @@ export class AceAdapter implements IEditorAdapter {
259240
}: TEditorAdapterCursorParams): IDisposable {
260241
assert(
261242
typeof cursor === "object" && typeof cursor.toJSON === "function",
262-
"Cursor must be an implementation of ICursor"
243+
"Cursor must be an implementation of ICursor",
263244
);
264245

265246
assert(
266247
typeof clientId === "string" && typeof cursorColor === "string",
267-
"Client Id and User Color must be strings."
248+
"Client Id and User Color must be strings.",
268249
);
269250

270251
/** Remove non-alphanumeric characters to create valid classname */
@@ -290,7 +271,7 @@ export class AceAdapter implements IEditorAdapter {
290271
let originalClipRows = cursorRange.clipRows;
291272
cursorRange.clipRows = /* istanbul ignore next */ function (
292273
firstRow: number,
293-
lastRow: number
274+
lastRow: number,
294275
): AceAjax.Range {
295276
const range = originalClipRows.call(cursorRange, firstRow, lastRow);
296277
range.isEmpty = function () {
@@ -308,21 +289,21 @@ export class AceAdapter implements IEditorAdapter {
308289
// @ts-expect-error
309290
cursorRange.start = this._aceDocument.createAnchor(
310291
cursorRange.start.row,
311-
cursorRange.start.column
292+
cursorRange.start.column,
312293
);
313294

314295
// @ts-expect-error
315296
cursorRange.end = this._aceDocument.createAnchor(
316297
cursorRange.end.row,
317-
cursorRange.end.column
298+
cursorRange.end.column,
318299
);
319300

320301
// @ts-expect-error
321302
cursorRange.id = this._aceSession.addMarker(
322303
cursorRange,
323304
decorationClassName,
324305
"text",
325-
false
306+
false,
326307
);
327308

328309
/** Add Cursor Widget to the editor */
@@ -449,7 +430,7 @@ export class AceAdapter implements IEditorAdapter {
449430
* @param changes - Set of Changes from Ace Editor Change Event.
450431
*/
451432
protected _operationFromACEChange(
452-
change: AceAjax.EditorChangeEvent
433+
change: AceAjax.EditorChangeEvent,
453434
): [operation: IPlainTextOperation, inverse: IPlainTextOperation] {
454435
const { action, lines, start: startPosition } = change;
455436

@@ -485,7 +466,7 @@ export class AceAdapter implements IEditorAdapter {
485466
* @param ops - List of Individual Text Operations.
486467
*/
487468
protected _applyOperationToACE(
488-
ops: IterableIterator<[index: number, operation: ITextOperation]>
469+
ops: IterableIterator<[index: number, operation: ITextOperation]>,
489470
) {
490471
let index = 0;
491472
let opValue: IteratorResult<[index: number, operation: ITextOperation]>;
@@ -503,7 +484,7 @@ export class AceAdapter implements IEditorAdapter {
503484
/** Insert Operation */
504485
this._aceDocument.insert(
505486
this._aceDocument.indexToPosition(index, 0),
506-
op.textContent()
487+
op.textContent(),
507488
);
508489
index += op.textContent()!.length;
509490
break;
@@ -513,7 +494,7 @@ export class AceAdapter implements IEditorAdapter {
513494
const start = this._aceDocument.indexToPosition(index, 0);
514495
const end = this._aceDocument.indexToPosition(
515496
index + op.characterCount(),
516-
0
497+
0,
517498
);
518499
const range = Range.fromPoints(start, end);
519500
this._aceDocument.remove(range);
@@ -525,4 +506,5 @@ export class AceAdapter implements IEditorAdapter {
525506
}
526507
}
527508

528-
export { IDisposable, IDisposableCollection } from "@otjs/types";
509+
export type { EventEmitter };
510+
export { IDisposable, IDisposableCollection, IEventEmitter } from "@otjs/types";

packages/ace/src/cursor-widget.impl.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@
2222
* See LICENSE file in the root directory for more details.
2323
*/
2424

25+
import { debounce, DebouncedFunc } from "lodash";
2526
import { IDisposable } from "@otjs/types";
2627
import {
2728
createTooltipNode,
2829
createWidgetNode,
2930
Disposable,
3031
DisposableCollection,
3132
} from "@otjs/utils";
32-
import { debounce, DebouncedFunc } from "lodash";
3333
import {
3434
ICursorWidget,
3535
TCursorWidgetConstructionOptions,
@@ -91,7 +91,7 @@ class CursorWidget implements ICursorWidget {
9191
this._widget = new TooltipMarker(
9292
this._editor.session,
9393
this._position!,
94-
this._widgetNode
94+
this._widgetNode,
9595
);
9696
this._hideTooltip = debounce(this._hideTooltip, this._duration);
9797
this._editor.session.addDynamicMarker(this._widget, true);
@@ -201,7 +201,7 @@ const widgets: Map<string, ICursorWidget> = new Map();
201201
* @param options - Construction Options for the Cursor Widget.
202202
*/
203203
export function createCursorWidget(
204-
options: TCursorWidgetConstructionOptions
204+
options: TCursorWidgetConstructionOptions,
205205
): void {
206206
const { clientId, range, userName } = options;
207207

packages/firebase-ace/src/firebase-ace.impl.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import {
3030
IEditorClient,
3131
TEditorClientEventArgs,
3232
} from "@otjs/plaintext-editor";
33-
import { Handler } from "mitt";
33+
import { IEventHandler } from "@otjs/types";
3434
import {
3535
IFireAceEditor,
3636
TFireAceEditorConstructionOptions,
@@ -168,14 +168,14 @@ export class FireAceEditor implements IFireAceEditor {
168168

169169
on<Key extends keyof TEditorClientEventArgs>(
170170
event: Key,
171-
listener: Handler<TEditorClientEventArgs[Key]>
171+
listener: IEventHandler<TEditorClientEventArgs[Key]>,
172172
): void {
173173
this._editorClient.on(event, listener);
174174
}
175175

176176
off<Key extends keyof TEditorClientEventArgs>(
177177
event: Key,
178-
listener?: Handler<TEditorClientEventArgs[Key]>
178+
listener?: IEventHandler<TEditorClientEventArgs[Key]>,
179179
): void {
180180
this._editorClient.off(event, listener);
181181
}

packages/firebase-ace/src/firebase-ace.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import {
2929
TEditorClientEventArgs,
3030
} from "@otjs/plaintext-editor";
3131
import { IDisposable, IEventEmitter } from "@otjs/types";
32-
import { Handler } from "mitt";
3332

3433
/**
3534
* @public

packages/firebase-monaco/src/firebase-monaco.impl.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import {
3030
IEditorClient,
3131
TEditorClientEventArgs,
3232
} from "@otjs/plaintext-editor";
33-
import { Handler } from "mitt";
33+
import { IEventHandler } from "@otjs/types";
3434
import {
3535
IFireMonacoEditor,
3636
TFireMonacoEditorConstructionOptions,
@@ -168,14 +168,14 @@ export class FireMonacoEditor implements IFireMonacoEditor {
168168

169169
on<Key extends keyof TEditorClientEventArgs>(
170170
event: Key,
171-
listener: Handler<TEditorClientEventArgs[Key]>
171+
listener: IEventHandler<TEditorClientEventArgs[Key]>,
172172
): void {
173173
this._editorClient.on(event, listener);
174174
}
175175

176176
off<Key extends keyof TEditorClientEventArgs>(
177177
event: Key,
178-
listener?: Handler<TEditorClientEventArgs[Key]>
178+
listener?: IEventHandler<TEditorClientEventArgs[Key]>,
179179
): void {
180180
this._editorClient.off(event, listener);
181181
}

packages/firebase-plaintext/package.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,6 @@
4949
"@otjs/utils": "workspace:*",
5050
"firebase": "9.15.0"
5151
},
52-
"dependencies": {
53-
"mitt": "3.0.1"
54-
},
5552
"peerDependencies": {
5653
"@otjs/plaintext": "^0.2.0",
5754
"@otjs/plaintext-editor": "^0.2.0",

0 commit comments

Comments
 (0)