@lo-fi/common
Advanced tools
Comparing version 1.4.5 to 1.5.0
@@ -1,13 +0,41 @@ | ||
export declare class Batcher<T> { | ||
/// <reference types="node" resolution-mode="require"/> | ||
export declare class Batcher<T, UserData = any> { | ||
private flusher; | ||
private batches; | ||
private defaultMax; | ||
private defaultTimeout; | ||
constructor(flusher: (items: T[], batchKey: string) => any, { max, timeout, }?: { | ||
max?: number; | ||
timeout?: number; | ||
constructor(flusher: (items: T[], batchKey: string, userData: UserData) => any); | ||
add({ key, userData, items, max, timeout, }: { | ||
key: string; | ||
userData?: UserData; | ||
items: T[]; | ||
max?: number | null; | ||
timeout?: number | null; | ||
}): Batch<T, UserData>; | ||
flush: (key: string) => any; | ||
discard: (key: string) => void; | ||
} | ||
export declare class Batch<T, UserData = any> { | ||
items: Array<T>; | ||
max: number | null; | ||
startedAt: number; | ||
timeout: number | null; | ||
flushTimeout?: NodeJS.Timeout; | ||
userData?: any; | ||
flusher: (items: T[], batchKey: string, userData: UserData) => any; | ||
key: string; | ||
constructor({ max, startedAt, timeout, userData, flusher, key, }: { | ||
key: string; | ||
max: number | null; | ||
startedAt: number; | ||
timeout: number | null; | ||
userData?: UserData; | ||
flusher: (items: T[], batchKey: string, userData: UserData) => any; | ||
}); | ||
add(key: string, ...items: T[]): void; | ||
flush: (key: string) => Promise<void>; | ||
private scheduleFlush; | ||
update: ({ items, max, timeout, userData, }: { | ||
items: Array<T>; | ||
max?: number | null | undefined; | ||
timeout?: number | null | undefined; | ||
userData?: UserData | undefined; | ||
}) => void; | ||
flush: () => any; | ||
discard: () => void; | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Batcher = void 0; | ||
exports.Batch = exports.Batcher = void 0; | ||
class Batcher { | ||
constructor(flusher, { max, timeout, } = {}) { | ||
constructor(flusher) { | ||
this.flusher = flusher; | ||
this.batches = new Map(); | ||
this.flush = async (key) => { | ||
this.flush = (key) => { | ||
const batch = this.batches.get(key); | ||
if (!batch) | ||
return; | ||
batch.flushTimeout && clearTimeout(batch.flushTimeout); | ||
const items = batch.items; | ||
batch.items = []; | ||
await this.flusher(items, key); | ||
return batch.flush(); | ||
}; | ||
this.scheduleFlush = (key) => { | ||
return setTimeout(() => this.flush(key), this.defaultTimeout); | ||
this.discard = (key) => { | ||
const batch = this.batches.get(key); | ||
if (!batch) | ||
return; | ||
batch.discard(); | ||
this.batches.delete(key); | ||
}; | ||
this.defaultMax = max || 100; | ||
this.defaultTimeout = timeout || 1000; | ||
} | ||
add(key, ...items) { | ||
add({ key, userData, items, max, timeout, }) { | ||
let batch = this.batches.get(key); | ||
let needsSchedule = false; | ||
if (!batch) { | ||
needsSchedule = true; | ||
batch = { | ||
items, | ||
max: this.defaultMax, | ||
batch = new Batch({ | ||
max: max || null, | ||
startedAt: Date.now(), | ||
}; | ||
userData, | ||
timeout: timeout || null, | ||
flusher: this.flusher, | ||
key, | ||
}); | ||
this.batches.set(key, batch); | ||
} | ||
else { | ||
needsSchedule = batch.items.length === 0; | ||
batch.items.push(...items); | ||
} | ||
if (batch.items.length >= batch.max) { | ||
this.flush(key); | ||
} | ||
else if (needsSchedule) { | ||
batch.flushTimeout = this.scheduleFlush(key); | ||
} | ||
batch.update({ | ||
items, | ||
max, | ||
timeout, | ||
userData, | ||
}); | ||
return batch; | ||
} | ||
} | ||
exports.Batcher = Batcher; | ||
class Batch { | ||
constructor({ max, startedAt, timeout, userData, flusher, key, }) { | ||
this.items = []; | ||
this.update = ({ items, max, timeout, userData, }) => { | ||
this.items.push(...items); | ||
if (max !== undefined) | ||
this.max = max; | ||
if (timeout !== undefined) | ||
this.timeout = timeout; | ||
if (userData) | ||
this.userData = userData; | ||
// if the batch has items and a timeout but has not | ||
// scheduled yet, schedule it | ||
const needsSchedule = this.items.length !== 0 && this.timeout !== null && !this.flushTimeout; | ||
// if the batch has already reached its max, skip scheduling | ||
// and flush immediately | ||
if (this.max !== null && this.items.length >= this.max) { | ||
this.flush(); | ||
} | ||
else if (needsSchedule && this.timeout !== null) { | ||
this.flushTimeout = setTimeout(this.flush, this.timeout); | ||
} | ||
}; | ||
this.flush = () => { | ||
this.flushTimeout && clearTimeout(this.flushTimeout); | ||
this.flushTimeout = undefined; | ||
const items = this.items; | ||
this.items = []; | ||
return this.flusher(items, this.key, this.userData); | ||
}; | ||
this.discard = () => { | ||
this.flushTimeout && clearTimeout(this.flushTimeout); | ||
this.flushTimeout = undefined; | ||
this.items = []; | ||
}; | ||
this.max = max; | ||
this.startedAt = startedAt; | ||
this.timeout = timeout; | ||
this.userData = userData; | ||
this.flusher = flusher; | ||
this.key = key; | ||
} | ||
} | ||
exports.Batch = Batch; | ||
//# sourceMappingURL=batching.js.map |
@@ -27,3 +27,3 @@ "use strict"; | ||
const undo = getUndoOperation(oid, state, operation, getNow); | ||
undoOperations.push(...undo); | ||
undoOperations.unshift(...undo); | ||
(0, operation_js_1.applyPatch)(state, operation.data); | ||
@@ -30,0 +30,0 @@ } |
@@ -1,13 +0,41 @@ | ||
export declare class Batcher<T> { | ||
/// <reference types="node" resolution-mode="require"/> | ||
export declare class Batcher<T, UserData = any> { | ||
private flusher; | ||
private batches; | ||
private defaultMax; | ||
private defaultTimeout; | ||
constructor(flusher: (items: T[], batchKey: string) => any, { max, timeout, }?: { | ||
max?: number; | ||
timeout?: number; | ||
constructor(flusher: (items: T[], batchKey: string, userData: UserData) => any); | ||
add({ key, userData, items, max, timeout, }: { | ||
key: string; | ||
userData?: UserData; | ||
items: T[]; | ||
max?: number | null; | ||
timeout?: number | null; | ||
}): Batch<T, UserData>; | ||
flush: (key: string) => any; | ||
discard: (key: string) => void; | ||
} | ||
export declare class Batch<T, UserData = any> { | ||
items: Array<T>; | ||
max: number | null; | ||
startedAt: number; | ||
timeout: number | null; | ||
flushTimeout?: NodeJS.Timeout; | ||
userData?: any; | ||
flusher: (items: T[], batchKey: string, userData: UserData) => any; | ||
key: string; | ||
constructor({ max, startedAt, timeout, userData, flusher, key, }: { | ||
key: string; | ||
max: number | null; | ||
startedAt: number; | ||
timeout: number | null; | ||
userData?: UserData; | ||
flusher: (items: T[], batchKey: string, userData: UserData) => any; | ||
}); | ||
add(key: string, ...items: T[]): void; | ||
flush: (key: string) => Promise<void>; | ||
private scheduleFlush; | ||
update: ({ items, max, timeout, userData, }: { | ||
items: Array<T>; | ||
max?: number | null | undefined; | ||
timeout?: number | null | undefined; | ||
userData?: UserData | undefined; | ||
}) => void; | ||
flush: () => any; | ||
discard: () => void; | ||
} |
export class Batcher { | ||
constructor(flusher, { max, timeout, } = {}) { | ||
constructor(flusher) { | ||
this.flusher = flusher; | ||
this.batches = new Map(); | ||
this.flush = async (key) => { | ||
this.flush = (key) => { | ||
const batch = this.batches.get(key); | ||
if (!batch) | ||
return; | ||
batch.flushTimeout && clearTimeout(batch.flushTimeout); | ||
const items = batch.items; | ||
batch.items = []; | ||
await this.flusher(items, key); | ||
return batch.flush(); | ||
}; | ||
this.scheduleFlush = (key) => { | ||
return setTimeout(() => this.flush(key), this.defaultTimeout); | ||
this.discard = (key) => { | ||
const batch = this.batches.get(key); | ||
if (!batch) | ||
return; | ||
batch.discard(); | ||
this.batches.delete(key); | ||
}; | ||
this.defaultMax = max || 100; | ||
this.defaultTimeout = timeout || 1000; | ||
} | ||
add(key, ...items) { | ||
add({ key, userData, items, max, timeout, }) { | ||
let batch = this.batches.get(key); | ||
let needsSchedule = false; | ||
if (!batch) { | ||
needsSchedule = true; | ||
batch = { | ||
items, | ||
max: this.defaultMax, | ||
batch = new Batch({ | ||
max: max || null, | ||
startedAt: Date.now(), | ||
}; | ||
userData, | ||
timeout: timeout || null, | ||
flusher: this.flusher, | ||
key, | ||
}); | ||
this.batches.set(key, batch); | ||
} | ||
else { | ||
needsSchedule = batch.items.length === 0; | ||
batch.items.push(...items); | ||
} | ||
if (batch.items.length >= batch.max) { | ||
this.flush(key); | ||
} | ||
else if (needsSchedule) { | ||
batch.flushTimeout = this.scheduleFlush(key); | ||
} | ||
batch.update({ | ||
items, | ||
max, | ||
timeout, | ||
userData, | ||
}); | ||
return batch; | ||
} | ||
} | ||
export class Batch { | ||
constructor({ max, startedAt, timeout, userData, flusher, key, }) { | ||
this.items = []; | ||
this.update = ({ items, max, timeout, userData, }) => { | ||
this.items.push(...items); | ||
if (max !== undefined) | ||
this.max = max; | ||
if (timeout !== undefined) | ||
this.timeout = timeout; | ||
if (userData) | ||
this.userData = userData; | ||
// if the batch has items and a timeout but has not | ||
// scheduled yet, schedule it | ||
const needsSchedule = this.items.length !== 0 && this.timeout !== null && !this.flushTimeout; | ||
// if the batch has already reached its max, skip scheduling | ||
// and flush immediately | ||
if (this.max !== null && this.items.length >= this.max) { | ||
this.flush(); | ||
} | ||
else if (needsSchedule && this.timeout !== null) { | ||
this.flushTimeout = setTimeout(this.flush, this.timeout); | ||
} | ||
}; | ||
this.flush = () => { | ||
this.flushTimeout && clearTimeout(this.flushTimeout); | ||
this.flushTimeout = undefined; | ||
const items = this.items; | ||
this.items = []; | ||
return this.flusher(items, this.key, this.userData); | ||
}; | ||
this.discard = () => { | ||
this.flushTimeout && clearTimeout(this.flushTimeout); | ||
this.flushTimeout = undefined; | ||
this.items = []; | ||
}; | ||
this.max = max; | ||
this.startedAt = startedAt; | ||
this.timeout = timeout; | ||
this.userData = userData; | ||
this.flusher = flusher; | ||
this.key = key; | ||
} | ||
} | ||
//# sourceMappingURL=batching.js.map |
@@ -24,3 +24,3 @@ import { applyPatch } from './operation.js'; | ||
const undo = getUndoOperation(oid, state, operation, getNow); | ||
undoOperations.push(...undo); | ||
undoOperations.unshift(...undo); | ||
applyPatch(state, operation.data); | ||
@@ -27,0 +27,0 @@ } |
{ | ||
"name": "@lo-fi/common", | ||
"version": "1.4.5", | ||
"version": "1.5.0", | ||
"access": "public", | ||
@@ -5,0 +5,0 @@ "type": "module", |
@@ -1,63 +0,135 @@ | ||
interface Batch<T> { | ||
items: Array<T>; | ||
max: number; | ||
startedAt: number; | ||
flushTimeout?: NodeJS.Timeout; | ||
} | ||
export class Batcher<T, UserData = any> { | ||
private batches: Map<string, Batch<T, UserData>> = new Map(); | ||
export class Batcher<T> { | ||
private batches: Map<string, Batch<T>> = new Map(); | ||
private defaultMax; | ||
private defaultTimeout; | ||
constructor( | ||
private flusher: (items: T[], batchKey: string) => any, | ||
{ | ||
max, | ||
timeout, | ||
}: { | ||
max?: number; | ||
timeout?: number; | ||
} = {}, | ||
) { | ||
this.defaultMax = max || 100; | ||
this.defaultTimeout = timeout || 1000; | ||
} | ||
private flusher: (items: T[], batchKey: string, userData: UserData) => any, | ||
) {} | ||
add(key: string, ...items: T[]) { | ||
add({ | ||
key, | ||
userData, | ||
items, | ||
max, | ||
timeout, | ||
}: { | ||
key: string; | ||
userData?: UserData; | ||
items: T[]; | ||
max?: number | null; | ||
timeout?: number | null; | ||
}) { | ||
let batch = this.batches.get(key); | ||
let needsSchedule = false; | ||
if (!batch) { | ||
needsSchedule = true; | ||
batch = { | ||
items, | ||
max: this.defaultMax, | ||
batch = new Batch({ | ||
max: max || null, | ||
startedAt: Date.now(), | ||
}; | ||
userData, | ||
timeout: timeout || null, | ||
flusher: this.flusher, | ||
key, | ||
}); | ||
this.batches.set(key, batch); | ||
} else { | ||
needsSchedule = batch.items.length === 0; | ||
batch.items.push(...items); | ||
} | ||
batch.update({ | ||
items, | ||
max, | ||
timeout, | ||
userData, | ||
}); | ||
if (batch.items.length >= batch.max) { | ||
this.flush(key); | ||
} else if (needsSchedule) { | ||
batch.flushTimeout = this.scheduleFlush(key); | ||
} | ||
return batch; | ||
} | ||
flush = async (key: string) => { | ||
flush = (key: string) => { | ||
const batch = this.batches.get(key); | ||
if (!batch) return; | ||
batch.flushTimeout && clearTimeout(batch.flushTimeout); | ||
const items = batch.items; | ||
batch.items = []; | ||
await this.flusher(items, key); | ||
return batch.flush(); | ||
}; | ||
private scheduleFlush = (key: string) => { | ||
return setTimeout(() => this.flush(key), this.defaultTimeout); | ||
discard = (key: string) => { | ||
const batch = this.batches.get(key); | ||
if (!batch) return; | ||
batch.discard(); | ||
this.batches.delete(key); | ||
}; | ||
} | ||
export class Batch<T, UserData = any> { | ||
items: Array<T> = []; | ||
max: number | null; | ||
startedAt: number; | ||
timeout: number | null; | ||
flushTimeout?: NodeJS.Timeout; | ||
userData?: any; | ||
flusher: (items: T[], batchKey: string, userData: UserData) => any; | ||
key: string; | ||
constructor({ | ||
max, | ||
startedAt, | ||
timeout, | ||
userData, | ||
flusher, | ||
key, | ||
}: { | ||
key: string; | ||
max: number | null; | ||
startedAt: number; | ||
timeout: number | null; | ||
userData?: UserData; | ||
flusher: (items: T[], batchKey: string, userData: UserData) => any; | ||
}) { | ||
this.max = max; | ||
this.startedAt = startedAt; | ||
this.timeout = timeout; | ||
this.userData = userData; | ||
this.flusher = flusher; | ||
this.key = key; | ||
} | ||
update = ({ | ||
items, | ||
max, | ||
timeout, | ||
userData, | ||
}: { | ||
items: Array<T>; | ||
max?: number | null; | ||
timeout?: number | null; | ||
userData?: UserData; | ||
}) => { | ||
this.items.push(...items); | ||
if (max !== undefined) this.max = max; | ||
if (timeout !== undefined) this.timeout = timeout; | ||
if (userData) this.userData = userData; | ||
// if the batch has items and a timeout but has not | ||
// scheduled yet, schedule it | ||
const needsSchedule = | ||
this.items.length !== 0 && this.timeout !== null && !this.flushTimeout; | ||
// if the batch has already reached its max, skip scheduling | ||
// and flush immediately | ||
if (this.max !== null && this.items.length >= this.max) { | ||
this.flush(); | ||
} else if (needsSchedule && this.timeout !== null) { | ||
this.flushTimeout = setTimeout(this.flush, this.timeout); | ||
} | ||
}; | ||
flush = () => { | ||
this.flushTimeout && clearTimeout(this.flushTimeout); | ||
this.flushTimeout = undefined; | ||
const items = this.items; | ||
this.items = []; | ||
return this.flusher(items, this.key, this.userData); | ||
}; | ||
discard = () => { | ||
this.flushTimeout && clearTimeout(this.flushTimeout); | ||
this.flushTimeout = undefined; | ||
this.items = []; | ||
}; | ||
} |
@@ -31,3 +31,3 @@ import { ObjectIdentifier } from './oids.js'; | ||
const undo = getUndoOperation(oid, state, operation, getNow); | ||
undoOperations.push(...undo); | ||
undoOperations.unshift(...undo); | ||
applyPatch(state, operation.data); | ||
@@ -34,0 +34,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
687262
12747