-
-
Notifications
You must be signed in to change notification settings - Fork 132
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
480 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
export { createEmitter, isEventEmitter } from './createEmitter.mjs'; | ||
export * from './operators/index.mjs'; | ||
export { pipe } from './pipe.mjs'; | ||
export type { EventEmitter } from './types.mjs'; | ||
export type { EmitterEvent, EventEmitter, EventListener, EventOperator } from './types.mjs'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
export type MachineId = string; | ||
export type Timestamp = number; | ||
|
||
export type Events = 'replace' | 'activate'; | ||
|
||
/** | ||
* A log entry. | ||
* - ts - The timestamp of the event. | ||
* - range - The timestamp of the end of the event range. (this is used to group events). | ||
* - event - The event that occurred. | ||
* - count - The number of times the event occurred. (this is used to group events). | ||
* - args - Additional arguments for the event. | ||
*/ | ||
export type LogEntryBase = [ts: Timestamp, range: Timestamp | 0, event: string, count: number, ...args: unknown[]]; | ||
|
||
/** Replace a word with a suggestion. */ | ||
export type LogEntryReplace = [ts: Timestamp, range: Timestamp | 0, 'replace', count: number, word: string, suggestion: string]; | ||
|
||
/** Indicates that the extension was activated. */ | ||
export type LogEntryActivate = [ts: Timestamp, range: Timestamp | 0, 'activate', count: number]; | ||
|
||
export type LogEntry = LogEntryReplace | LogEntryActivate; | ||
|
||
export interface EventLog { | ||
/** | ||
* The log of events that have occurred. | ||
*/ | ||
log: LogEntryBase[]; | ||
|
||
/** | ||
* The synchronization timestamp of each machine. | ||
* The timestamp is the timestamp of the last event added to the log for a given machine id. | ||
*/ | ||
sync: Record<MachineId, Timestamp>; | ||
} | ||
|
||
export function isLogEntryReplace(entry: LogEntryBase): entry is LogEntryReplace { | ||
return entry[2] === 'replace'; | ||
} | ||
|
||
export function isLogEntryActivate(entry: LogEntryBase): entry is LogEntryActivate { | ||
return entry[2] === 'activate'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
import type { Disposable } from 'vscode'; | ||
import { env, Uri } from 'vscode'; | ||
|
||
import { logErrors } from '../util/errors.js'; | ||
import type { LogEntry, LogEntryBase } from './EventLog.mjs'; | ||
import { MementoFile } from './mementoFile.mjs'; | ||
|
||
export interface EventLogger { | ||
readonly eventLog: readonly LogEntryBase[]; | ||
log(event: LogEntry): void; | ||
logActivate(): void; | ||
logReplace(word: string, suggestion: string): void; | ||
flush(): Promise<void>; | ||
} | ||
|
||
export function createReplaceEvent(word: string, suggestion: string): LogEntry { | ||
return [Date.now(), 0, 'replace', 1, word, suggestion]; | ||
} | ||
|
||
export function createActivateEvent(): LogEntry { | ||
return [Date.now(), 0, 'activate', 1]; | ||
} | ||
|
||
interface LocalEventLogData { | ||
machineId: string; | ||
ts: number; | ||
log: LogEntry[]; | ||
} | ||
|
||
class EventLoggerImpl implements EventLogger, Disposable { | ||
#data: MementoFile<LocalEventLogData> | undefined; | ||
#pData: Promise<MementoFile<LocalEventLogData>>; | ||
#pending: LogEntry[] = []; | ||
#pFlush: Promise<void> | undefined = undefined; | ||
#timeout: NodeJS.Timeout | undefined = undefined; | ||
|
||
constructor(readonly uriStorageDir: Uri) { | ||
this.#pData = MementoFile.createMemento<LocalEventLogData>(Uri.joinPath(uriStorageDir, 'eventLog.json')); | ||
this.#pData.then((data) => (this.#data = data)); | ||
} | ||
|
||
log(event: LogEntry): void { | ||
this.#pending.push(event); | ||
this.queueFlush(); | ||
} | ||
|
||
logActivate(): void { | ||
this.log(createActivateEvent()); | ||
} | ||
|
||
logReplace(word: string, suggestion: string): void { | ||
this.log(createReplaceEvent(word, suggestion)); | ||
} | ||
|
||
get eventLog(): readonly LogEntryBase[] { | ||
if (!this.#data) return []; | ||
return this.#data.get('log', []); | ||
} | ||
|
||
queueFlush(): void { | ||
if (this.#timeout) return; | ||
this.#timeout = setTimeout(() => { | ||
this.#timeout = undefined; | ||
logErrors(this.flush(), 'EventLogger.flush'); | ||
}, 10); | ||
} | ||
|
||
flush(): Promise<void> { | ||
const doFlush = async () => { | ||
if (!this.#pending.length) return; | ||
const memo = this.#data ?? (await this.#pData); | ||
const machineId = memo.get('machineId', env.machineId); | ||
const ts = Date.now(); | ||
const log = [...memo.get('log', []), ...this.#pending]; | ||
this.#pending = []; | ||
await memo.update({ machineId, ts, log }); | ||
}; | ||
const pFlush = this.#pFlush ? this.#pFlush.then(doFlush) : doFlush(); | ||
this.#pFlush = pFlush; | ||
pFlush.finally(() => { | ||
if (this.#pFlush === pFlush) this.#pFlush = undefined; | ||
}); | ||
return pFlush; | ||
} | ||
|
||
dispose(): void { | ||
if (this.#data) { | ||
this.#data.dispose(); | ||
} else { | ||
this.#pData.then((data) => data.dispose()); | ||
} | ||
} | ||
} | ||
|
||
export function createEventLogger(uriStorageDir: Uri): EventLogger { | ||
return new EventLoggerImpl(uriStorageDir); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import type { EventLog, Timestamp } from './EventLog.mjs'; | ||
import type { Memento } from './memento.mjs'; | ||
|
||
export interface GlobalStateData { | ||
eventLog: EventLog; | ||
} | ||
|
||
export interface GlobalStateControl extends Memento<GlobalStateData> { | ||
/** | ||
* List of fields that are synced across machines. | ||
*/ | ||
readonly syncFields: string[]; | ||
|
||
/** | ||
* This field is used to store the signature of last time the global state was updated on this machine. | ||
* It is used to detect changes to the global state. | ||
*/ | ||
readonly signature: string; | ||
|
||
/** | ||
* The timestamp of the last time the global state was updated on this machine. | ||
*/ | ||
readonly ts: Timestamp; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export type { ContextTypes } from './context.mjs'; | ||
export { setContext, updateDocumentRelatedContext } from './context.mjs'; | ||
export type { EventLogger } from './EventLogger.mjs'; | ||
export { createActivateEvent, createEventLogger, createReplaceEvent } from './EventLogger.mjs'; |
Oops, something went wrong.