mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-07 20:31:06 -05:00
Merge pull request #18342 from overleaf/em-tracking-props-none
Separate handling of "none" tracking type in operations GitOrigin-RevId: b07ee5320ac1a9c63e3b0059aade1a1564819943
This commit is contained in:
parent
f5aa0a7a93
commit
5d0190da0f
17 changed files with 139 additions and 114 deletions
|
@ -0,0 +1,28 @@
|
||||||
|
// @ts-check
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {import('../types').ClearTrackingPropsRawData} ClearTrackingPropsRawData
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ClearTrackingProps {
|
||||||
|
constructor() {
|
||||||
|
this.type = 'none'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {any} other
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
equals(other) {
|
||||||
|
return other instanceof ClearTrackingProps
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {ClearTrackingPropsRawData}
|
||||||
|
*/
|
||||||
|
toRaw() {
|
||||||
|
return { type: 'none' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = ClearTrackingProps
|
|
@ -1,10 +1,11 @@
|
||||||
// @ts-check
|
// @ts-check
|
||||||
const Range = require('../range')
|
const Range = require('../range')
|
||||||
const TrackedChange = require('./tracked_change')
|
const TrackedChange = require('./tracked_change')
|
||||||
|
const TrackingProps = require('../file_data/tracking_props')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @typedef {import("../types").TrackingDirective} TrackingDirective
|
||||||
* @typedef {import("../types").TrackedChangeRawData} TrackedChangeRawData
|
* @typedef {import("../types").TrackedChangeRawData} TrackedChangeRawData
|
||||||
* @typedef {import("../file_data/tracking_props")} TrackingProps
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class TrackedChangeList {
|
class TrackedChangeList {
|
||||||
|
@ -211,7 +212,7 @@ class TrackedChangeList {
|
||||||
/**
|
/**
|
||||||
* @param {number} cursor
|
* @param {number} cursor
|
||||||
* @param {number} length
|
* @param {number} length
|
||||||
* @param {{tracking?: TrackingProps}} opts
|
* @param {{tracking?: TrackingDirective}} opts
|
||||||
*/
|
*/
|
||||||
applyRetain(cursor, length, opts = {}) {
|
applyRetain(cursor, length, opts = {}) {
|
||||||
// If there's no tracking info, leave everything as-is
|
// If there's no tracking info, leave everything as-is
|
||||||
|
@ -263,7 +264,7 @@ class TrackedChangeList {
|
||||||
newTrackedChanges.push(trackedChange)
|
newTrackedChanges.push(trackedChange)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (opts.tracking?.type === 'delete' || opts.tracking?.type === 'insert') {
|
if (opts.tracking instanceof TrackingProps) {
|
||||||
// This is a new tracked change
|
// This is a new tracked change
|
||||||
const newTrackedChange = new TrackedChange(retainedRange, opts.tracking)
|
const newTrackedChange = new TrackedChange(retainedRange, opts.tracking)
|
||||||
newTrackedChanges.push(newTrackedChange)
|
newTrackedChanges.push(newTrackedChange)
|
||||||
|
|
|
@ -6,14 +6,14 @@
|
||||||
class TrackingProps {
|
class TrackingProps {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {'insert' | 'delete' | 'none'} type
|
* @param {'insert' | 'delete'} type
|
||||||
* @param {string} userId
|
* @param {string} userId
|
||||||
* @param {Date} ts
|
* @param {Date} ts
|
||||||
*/
|
*/
|
||||||
constructor(type, userId, ts) {
|
constructor(type, userId, ts) {
|
||||||
/**
|
/**
|
||||||
* @readonly
|
* @readonly
|
||||||
* @type {'insert' | 'delete' | 'none'}
|
* @type {'insert' | 'delete'}
|
||||||
*/
|
*/
|
||||||
this.type = type
|
this.type = type
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -5,6 +5,7 @@ const {
|
||||||
InvalidInsertionError,
|
InvalidInsertionError,
|
||||||
UnprocessableError,
|
UnprocessableError,
|
||||||
} = require('../errors')
|
} = require('../errors')
|
||||||
|
const ClearTrackingProps = require('../file_data/clear_tracking_props')
|
||||||
const TrackingProps = require('../file_data/tracking_props')
|
const TrackingProps = require('../file_data/tracking_props')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -13,6 +14,7 @@ const TrackingProps = require('../file_data/tracking_props')
|
||||||
* @typedef {import('../types').RawInsertOp} RawInsertOp
|
* @typedef {import('../types').RawInsertOp} RawInsertOp
|
||||||
* @typedef {import('../types').RawRetainOp} RawRetainOp
|
* @typedef {import('../types').RawRetainOp} RawRetainOp
|
||||||
* @typedef {import('../types').RawRemoveOp} RawRemoveOp
|
* @typedef {import('../types').RawRemoveOp} RawRemoveOp
|
||||||
|
* @typedef {import('../types').TrackingDirective} TrackingDirective
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class ScanOp {
|
class ScanOp {
|
||||||
|
@ -218,7 +220,7 @@ class InsertOp extends ScanOp {
|
||||||
class RetainOp extends ScanOp {
|
class RetainOp extends ScanOp {
|
||||||
/**
|
/**
|
||||||
* @param {number} length
|
* @param {number} length
|
||||||
* @param {TrackingProps | undefined} tracking
|
* @param {TrackingDirective | undefined} tracking
|
||||||
*/
|
*/
|
||||||
constructor(length, tracking = undefined) {
|
constructor(length, tracking = undefined) {
|
||||||
super()
|
super()
|
||||||
|
@ -227,7 +229,7 @@ class RetainOp extends ScanOp {
|
||||||
}
|
}
|
||||||
/** @type {number} */
|
/** @type {number} */
|
||||||
this.length = length
|
this.length = length
|
||||||
/** @type {TrackingProps | undefined} */
|
/** @type {TrackingDirective | undefined} */
|
||||||
this.tracking = tracking
|
this.tracking = tracking
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,7 +265,11 @@ class RetainOp extends ScanOp {
|
||||||
throw new Error('retain operation must have a number property')
|
throw new Error('retain operation must have a number property')
|
||||||
}
|
}
|
||||||
if (op.tracking) {
|
if (op.tracking) {
|
||||||
return new RetainOp(op.r, TrackingProps.fromRaw(op.tracking))
|
const tracking =
|
||||||
|
op.tracking.type === 'none'
|
||||||
|
? new ClearTrackingProps()
|
||||||
|
: TrackingProps.fromRaw(op.tracking)
|
||||||
|
return new RetainOp(op.r, tracking)
|
||||||
}
|
}
|
||||||
return new RetainOp(op.r)
|
return new RetainOp(op.r)
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,12 +26,15 @@ const {
|
||||||
TooLongError,
|
TooLongError,
|
||||||
} = require('../errors')
|
} = require('../errors')
|
||||||
const Range = require('../range')
|
const Range = require('../range')
|
||||||
|
const ClearTrackingProps = require('../file_data/clear_tracking_props')
|
||||||
const TrackingProps = require('../file_data/tracking_props')
|
const TrackingProps = require('../file_data/tracking_props')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('../file_data/string_file_data')} StringFileData
|
* @typedef {import('../file_data/string_file_data')} StringFileData
|
||||||
* @typedef {import('../types').RawTextOperation} RawTextOperation
|
* @typedef {import('../types').RawTextOperation} RawTextOperation
|
||||||
* @typedef {import('../operation/scan_op').ScanOp} ScanOp
|
* @typedef {import('../operation/scan_op').ScanOp} ScanOp
|
||||||
* @typedef {import('../file_data/tracked_change_list')} TrackedChangeList
|
* @typedef {import('../file_data/tracked_change_list')} TrackedChangeList
|
||||||
|
* @typedef {import('../types').TrackingDirective} TrackingDirective
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -91,7 +94,7 @@ class TextOperation extends EditOperation {
|
||||||
/**
|
/**
|
||||||
* Skip over a given number of characters.
|
* Skip over a given number of characters.
|
||||||
* @param {number | {r: number}} n
|
* @param {number | {r: number}} n
|
||||||
* @param {{tracking?: TrackingProps}} opts
|
* @param {{tracking?: TrackingDirective}} opts
|
||||||
* @returns {TextOperation}
|
* @returns {TextOperation}
|
||||||
*/
|
*/
|
||||||
retain(n, opts = {}) {
|
retain(n, opts = {}) {
|
||||||
|
@ -376,11 +379,7 @@ class TextOperation extends EditOperation {
|
||||||
|
|
||||||
let removeTrackingInfoIfNeeded
|
let removeTrackingInfoIfNeeded
|
||||||
if (op.tracking) {
|
if (op.tracking) {
|
||||||
removeTrackingInfoIfNeeded = new TrackingProps(
|
removeTrackingInfoIfNeeded = new ClearTrackingProps()
|
||||||
'none',
|
|
||||||
op.tracking.userId,
|
|
||||||
op.tracking.ts
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const trackedChange of previousRanges) {
|
for (const trackedChange of previousRanges) {
|
||||||
|
@ -575,10 +574,15 @@ class TextOperation extends EditOperation {
|
||||||
}
|
}
|
||||||
} else if (op1 instanceof InsertOp && op2 instanceof RetainOp) {
|
} else if (op1 instanceof InsertOp && op2 instanceof RetainOp) {
|
||||||
const opts = {
|
const opts = {
|
||||||
// Prefer the latter tracking info
|
|
||||||
tracking: op2.tracking ?? op1.tracking,
|
|
||||||
commentIds: op1.commentIds,
|
commentIds: op1.commentIds,
|
||||||
}
|
}
|
||||||
|
if (op2.tracking instanceof TrackingProps) {
|
||||||
|
// Prefer the tracking info on the second operation
|
||||||
|
opts.tracking = op2.tracking
|
||||||
|
} else if (!(op2.tracking instanceof ClearTrackingProps)) {
|
||||||
|
// The second operation does not cancel the first operation's tracking
|
||||||
|
opts.tracking = op1.tracking
|
||||||
|
}
|
||||||
if (op1.insertion.length > op2.length) {
|
if (op1.insertion.length > op2.length) {
|
||||||
operation.insert(op1.insertion.slice(0, op2.length), opts)
|
operation.insert(op1.insertion.slice(0, op2.length), opts)
|
||||||
op1 = new InsertOp(
|
op1 = new InsertOp(
|
||||||
|
@ -692,9 +696,9 @@ class TextOperation extends EditOperation {
|
||||||
// Simple case: retain/retain
|
// Simple case: retain/retain
|
||||||
|
|
||||||
// If both have tracking info, we use the one from op1
|
// If both have tracking info, we use the one from op1
|
||||||
/** @type {TrackingProps | undefined} */
|
/** @type {TrackingProps | ClearTrackingProps | undefined} */
|
||||||
let operation1primeTracking
|
let operation1primeTracking
|
||||||
/** @type {TrackingProps | undefined} */
|
/** @type {TrackingProps | ClearTrackingProps | undefined} */
|
||||||
let operation2primeTracking
|
let operation2primeTracking
|
||||||
if (op1.tracking) {
|
if (op1.tracking) {
|
||||||
operation1primeTracking = op1.tracking
|
operation1primeTracking = op1.tracking
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import Blob from './blob'
|
import Blob from './blob'
|
||||||
|
import TrackingProps from './file_data/tracking_props'
|
||||||
|
import ClearTrackingProps from './file_data/clear_tracking_props'
|
||||||
|
|
||||||
export type BlobStore = {
|
export type BlobStore = {
|
||||||
getBlob(hash: string): Promise<Blob | null>
|
getBlob(hash: string): Promise<Blob | null>
|
||||||
|
@ -32,11 +34,17 @@ export type TrackedChangeRawData = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TrackingPropsRawData = {
|
export type TrackingPropsRawData = {
|
||||||
type: 'insert' | 'delete' | 'none'
|
type: 'insert' | 'delete'
|
||||||
userId: string
|
userId: string
|
||||||
ts: string
|
ts: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ClearTrackingPropsRawData = {
|
||||||
|
type: 'none'
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TrackingDirective = TrackingProps | ClearTrackingProps
|
||||||
|
|
||||||
export type StringFileRawData = {
|
export type StringFileRawData = {
|
||||||
content: string
|
content: string
|
||||||
comments?: CommentRawData[]
|
comments?: CommentRawData[]
|
||||||
|
@ -58,7 +66,7 @@ export type RawRetainOp =
|
||||||
| {
|
| {
|
||||||
r: number
|
r: number
|
||||||
commentIds?: string[]
|
commentIds?: string[]
|
||||||
tracking?: TrackingPropsRawData
|
tracking?: TrackingPropsRawData | ClearTrackingPropsRawData
|
||||||
}
|
}
|
||||||
| number
|
| number
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const TrackingProps = require('../../lib/file_data/tracking_props')
|
const TrackingProps = require('../../lib/file_data/tracking_props')
|
||||||
|
const ClearTrackingProps = require('../../lib/file_data/clear_tracking_props')
|
||||||
const TextOperation = require('../../lib/operation/text_operation')
|
const TextOperation = require('../../lib/operation/text_operation')
|
||||||
const random = require('./random')
|
const random = require('./random')
|
||||||
|
|
||||||
|
@ -19,7 +20,7 @@ function randomTextOperation(str, commentIds) {
|
||||||
const trackedChange =
|
const trackedChange =
|
||||||
Math.random() < 0.1
|
Math.random() < 0.1
|
||||||
? new TrackingProps(
|
? new TrackingProps(
|
||||||
random.element(['insert', 'delete', 'none']),
|
random.element(['insert', 'delete']),
|
||||||
random.element(['user1', 'user2', 'user3']),
|
random.element(['user1', 'user2', 'user3']),
|
||||||
new Date(
|
new Date(
|
||||||
random.element([
|
random.element([
|
||||||
|
@ -41,6 +42,8 @@ function randomTextOperation(str, commentIds) {
|
||||||
})
|
})
|
||||||
} else if (r < 0.4) {
|
} else if (r < 0.4) {
|
||||||
operation.remove(l)
|
operation.remove(l)
|
||||||
|
} else if (r < 0.5) {
|
||||||
|
operation.retain(l, { tracking: new ClearTrackingProps() })
|
||||||
} else {
|
} else {
|
||||||
operation.retain(l, { tracking: trackedChange })
|
operation.retain(l, { tracking: trackedChange })
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ const TextOperation = ot.TextOperation
|
||||||
const StringFileData = require('../lib/file_data/string_file_data')
|
const StringFileData = require('../lib/file_data/string_file_data')
|
||||||
const { RetainOp, InsertOp, RemoveOp } = require('../lib/operation/scan_op')
|
const { RetainOp, InsertOp, RemoveOp } = require('../lib/operation/scan_op')
|
||||||
const TrackingProps = require('../lib/file_data/tracking_props')
|
const TrackingProps = require('../lib/file_data/tracking_props')
|
||||||
|
const ClearTrackingProps = require('../lib/file_data/clear_tracking_props')
|
||||||
|
|
||||||
describe('TextOperation', function () {
|
describe('TextOperation', function () {
|
||||||
const numTrials = 500
|
const numTrials = 500
|
||||||
|
@ -496,11 +497,7 @@ describe('TextOperation', function () {
|
||||||
new TextOperation()
|
new TextOperation()
|
||||||
.retain(4)
|
.retain(4)
|
||||||
.retain(4, {
|
.retain(4, {
|
||||||
tracking: TrackingProps.fromRaw({
|
tracking: new ClearTrackingProps(),
|
||||||
ts: '2024-01-01T00:00:00.000Z',
|
|
||||||
type: 'none',
|
|
||||||
userId: 'user2',
|
|
||||||
}),
|
|
||||||
})
|
})
|
||||||
.retain(3)
|
.retain(3)
|
||||||
)
|
)
|
||||||
|
@ -508,6 +505,42 @@ describe('TextOperation', function () {
|
||||||
content: 'foo bar baz',
|
content: 'foo bar baz',
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('it removes the tracking from an insert if operation 2 resolves it', function () {
|
||||||
|
expect(
|
||||||
|
compose(
|
||||||
|
new StringFileData('foo bar baz'),
|
||||||
|
new TextOperation()
|
||||||
|
.retain(4)
|
||||||
|
.insert('quux ', {
|
||||||
|
tracking: TrackingProps.fromRaw({
|
||||||
|
ts: '2023-01-01T00:00:00.000Z',
|
||||||
|
type: 'insert',
|
||||||
|
userId: 'user1',
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.retain(7),
|
||||||
|
new TextOperation()
|
||||||
|
.retain(6)
|
||||||
|
.retain(5, {
|
||||||
|
tracking: new ClearTrackingProps(),
|
||||||
|
})
|
||||||
|
.retain(5)
|
||||||
|
)
|
||||||
|
).to.deep.equal({
|
||||||
|
content: 'foo quux bar baz',
|
||||||
|
trackedChanges: [
|
||||||
|
{
|
||||||
|
range: { pos: 4, length: 2 },
|
||||||
|
tracking: {
|
||||||
|
ts: '2023-01-01T00:00:00.000Z',
|
||||||
|
type: 'insert',
|
||||||
|
userId: 'user1',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('transform', function () {
|
describe('transform', function () {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// @ts-check
|
// @ts-check
|
||||||
const TrackedChangeList = require('../lib/file_data/tracked_change_list')
|
const TrackedChangeList = require('../lib/file_data/tracked_change_list')
|
||||||
const TrackingProps = require('../lib/file_data/tracking_props')
|
const TrackingProps = require('../lib/file_data/tracking_props')
|
||||||
|
const ClearTrackingProps = require('../lib/file_data/clear_tracking_props')
|
||||||
const { expect } = require('chai')
|
const { expect } = require('chai')
|
||||||
/** @typedef {import('../lib/types').TrackedChangeRawData} TrackedChangeRawData */
|
/** @typedef {import('../lib/types').TrackedChangeRawData} TrackedChangeRawData */
|
||||||
|
|
||||||
|
@ -766,11 +767,7 @@ describe('TrackedChangeList', function () {
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
trackedChanges.applyRetain(0, 10, {
|
trackedChanges.applyRetain(0, 10, {
|
||||||
tracking: TrackingProps.fromRaw({
|
tracking: new ClearTrackingProps(),
|
||||||
type: 'none',
|
|
||||||
userId: 'user1',
|
|
||||||
ts: '2024-01-01T00:00:00.000Z',
|
|
||||||
}),
|
|
||||||
})
|
})
|
||||||
expect(trackedChanges.length).to.equal(0)
|
expect(trackedChanges.length).to.equal(0)
|
||||||
expect(trackedChanges.toRaw()).to.deep.equal([])
|
expect(trackedChanges.toRaw()).to.deep.equal([])
|
||||||
|
@ -788,11 +785,7 @@ describe('TrackedChangeList', function () {
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
trackedChanges.applyRetain(0, 10, {
|
trackedChanges.applyRetain(0, 10, {
|
||||||
tracking: TrackingProps.fromRaw({
|
tracking: new ClearTrackingProps(),
|
||||||
type: 'none',
|
|
||||||
userId: 'user2',
|
|
||||||
ts: '2024-01-01T00:00:00.000Z',
|
|
||||||
}),
|
|
||||||
})
|
})
|
||||||
expect(trackedChanges.length).to.equal(0)
|
expect(trackedChanges.length).to.equal(0)
|
||||||
expect(trackedChanges.toRaw()).to.deep.equal([])
|
expect(trackedChanges.toRaw()).to.deep.equal([])
|
||||||
|
@ -810,11 +803,7 @@ describe('TrackedChangeList', function () {
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
trackedChanges.applyRetain(0, 10, {
|
trackedChanges.applyRetain(0, 10, {
|
||||||
tracking: TrackingProps.fromRaw({
|
tracking: new ClearTrackingProps(),
|
||||||
type: 'none',
|
|
||||||
userId: 'user1',
|
|
||||||
ts: '2024-01-01T00:00:00.000Z',
|
|
||||||
}),
|
|
||||||
})
|
})
|
||||||
expect(trackedChanges.length).to.equal(0)
|
expect(trackedChanges.length).to.equal(0)
|
||||||
expect(trackedChanges.toRaw()).to.deep.equal([])
|
expect(trackedChanges.toRaw()).to.deep.equal([])
|
||||||
|
@ -832,11 +821,7 @@ describe('TrackedChangeList', function () {
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
trackedChanges.applyRetain(0, 10, {
|
trackedChanges.applyRetain(0, 10, {
|
||||||
tracking: TrackingProps.fromRaw({
|
tracking: new ClearTrackingProps(),
|
||||||
type: 'none',
|
|
||||||
userId: 'user2',
|
|
||||||
ts: '2024-01-01T00:00:00.000Z',
|
|
||||||
}),
|
|
||||||
})
|
})
|
||||||
expect(trackedChanges.length).to.equal(0)
|
expect(trackedChanges.length).to.equal(0)
|
||||||
expect(trackedChanges.toRaw()).to.deep.equal([])
|
expect(trackedChanges.toRaw()).to.deep.equal([])
|
||||||
|
|
|
@ -208,11 +208,7 @@ const RangesManager = {
|
||||||
op = {
|
op = {
|
||||||
p: change.op.p,
|
p: change.op.p,
|
||||||
r: change.op.i,
|
r: change.op.i,
|
||||||
tracking: {
|
tracking: { type: 'none' },
|
||||||
type: 'none',
|
|
||||||
userId: change.metadata.user_id,
|
|
||||||
ts: change.metadata.ts,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
if (unacceptedDeletes > 0) {
|
if (unacceptedDeletes > 0) {
|
||||||
op.hpos = op.p + unacceptedDeletes
|
op.hpos = op.p + unacceptedDeletes
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
import { TrackingPropsRawData } from 'overleaf-editor-core/lib/types'
|
import {
|
||||||
|
TrackingPropsRawData,
|
||||||
|
ClearTrackingPropsRawData,
|
||||||
|
} from 'overleaf-editor-core/lib/types'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An update coming from the editor
|
* An update coming from the editor
|
||||||
|
@ -97,7 +100,7 @@ export type HistoryInsertOp = InsertOp & {
|
||||||
|
|
||||||
export type HistoryRetainOp = RetainOp & {
|
export type HistoryRetainOp = RetainOp & {
|
||||||
hpos?: number
|
hpos?: number
|
||||||
tracking?: TrackingPropsRawData
|
tracking?: TrackingPropsRawData | ClearTrackingPropsRawData
|
||||||
}
|
}
|
||||||
|
|
||||||
export type HistoryDeleteOp = DeleteOp & {
|
export type HistoryDeleteOp = DeleteOp & {
|
||||||
|
|
|
@ -682,11 +682,7 @@ describe('RangesManager', function () {
|
||||||
{
|
{
|
||||||
r: 'lorem',
|
r: 'lorem',
|
||||||
p: 0,
|
p: 0,
|
||||||
tracking: {
|
tracking: { type: 'none' },
|
||||||
type: 'none',
|
|
||||||
userId: this.user_id,
|
|
||||||
ts: ranges.changes[0].metadata.ts,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -702,11 +698,7 @@ describe('RangesManager', function () {
|
||||||
{
|
{
|
||||||
r: 'ipsum',
|
r: 'ipsum',
|
||||||
p: 15,
|
p: 15,
|
||||||
tracking: {
|
tracking: { type: 'none' },
|
||||||
type: 'none',
|
|
||||||
userId: this.user_id,
|
|
||||||
ts: ranges.changes[1].metadata.ts,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -868,11 +860,7 @@ describe('RangesManager', function () {
|
||||||
r: 'xxx ',
|
r: 'xxx ',
|
||||||
p: 6,
|
p: 6,
|
||||||
hpos: 11,
|
hpos: 11,
|
||||||
tracking: {
|
tracking: { type: 'none' },
|
||||||
type: 'none',
|
|
||||||
userId: this.user_id,
|
|
||||||
ts: ranges.changes[1].metadata.ts,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
|
@ -309,11 +309,7 @@ class OperationsBuilder {
|
||||||
if (isInsert(op)) {
|
if (isInsert(op)) {
|
||||||
if (op.trackedDeleteRejection) {
|
if (op.trackedDeleteRejection) {
|
||||||
this.retain(op.i.length, {
|
this.retain(op.i.length, {
|
||||||
tracking: {
|
tracking: { type: 'none' },
|
||||||
type: 'none',
|
|
||||||
userId: update.meta.user_id,
|
|
||||||
ts: new Date(update.meta.ts).toISOString(),
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
const opts = {}
|
const opts = {}
|
||||||
|
|
|
@ -140,11 +140,13 @@ export type RawOrigin = {
|
||||||
kind: string
|
kind: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TrackingProps = {
|
export type TrackingProps =
|
||||||
type: 'insert' | 'delete' | 'none'
|
| { type: 'none' }
|
||||||
userId: string
|
| {
|
||||||
ts: string
|
type: 'insert' | 'delete'
|
||||||
}
|
userId: string
|
||||||
|
ts: string
|
||||||
|
}
|
||||||
|
|
||||||
export type RawScanOp =
|
export type RawScanOp =
|
||||||
| number
|
| number
|
||||||
|
|
|
@ -2142,11 +2142,7 @@ describe('ChunkTranslator', function () {
|
||||||
4, // Hell|o [planet ]world, this is a test
|
4, // Hell|o [planet ]world, this is a test
|
||||||
{
|
{
|
||||||
r: 4,
|
r: 4,
|
||||||
tracking: {
|
tracking: { type: 'none' },
|
||||||
type: 'none',
|
|
||||||
userId: this.author1.id,
|
|
||||||
ts: '2024-01-01T00:00:00.000Z',
|
|
||||||
},
|
|
||||||
}, // Hello pl|[anet ]world, this is a test
|
}, // Hello pl|[anet ]world, this is a test
|
||||||
{
|
{
|
||||||
r: 3,
|
r: 3,
|
||||||
|
@ -2375,11 +2371,7 @@ describe('ChunkTranslator', function () {
|
||||||
2, // Heo |{TEST }planet world, [this] is a test
|
2, // Heo |{TEST }planet world, [this] is a test
|
||||||
{
|
{
|
||||||
r: 5,
|
r: 5,
|
||||||
tracking: {
|
tracking: { type: 'none' },
|
||||||
type: 'none',
|
|
||||||
userId: '65f1baeb3cee7c3563fbd1d1',
|
|
||||||
ts: '2024-03-27T13:20:23.253Z',
|
|
||||||
},
|
|
||||||
}, // Heo TEST| planet world, [this] is a test
|
}, // Heo TEST| planet world, [this] is a test
|
||||||
14, // Heo TEST planet world, |[this] is a test
|
14, // Heo TEST planet world, |[this] is a test
|
||||||
-4, // Heo TEST planet world, | is a test
|
-4, // Heo TEST planet world, | is a test
|
||||||
|
@ -2557,11 +2549,7 @@ describe('ChunkTranslator', function () {
|
||||||
-2, // He|o planet world, [this] {TEST }is a test
|
-2, // He|o planet world, [this] {TEST }is a test
|
||||||
{
|
{
|
||||||
r: 39,
|
r: 39,
|
||||||
tracking: {
|
tracking: { type: 'none' },
|
||||||
type: 'none',
|
|
||||||
userId: this.author1.id,
|
|
||||||
ts: this.date.toISOString(),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
], // He|o planet world, this TEST is a test
|
], // He|o planet world, this TEST is a test
|
||||||
},
|
},
|
||||||
|
|
|
@ -106,7 +106,7 @@ describe('UpdateCompressor', function () {
|
||||||
(this.op2 = {
|
(this.op2 = {
|
||||||
p: 9,
|
p: 9,
|
||||||
r: 'baz',
|
r: 'baz',
|
||||||
tracking: { type: 'none', ts: this.ts1, userId: this.user_id },
|
tracking: { type: 'none' },
|
||||||
}),
|
}),
|
||||||
(this.op3 = { p: 6, i: 'bar' }),
|
(this.op3 = { p: 6, i: 'bar' }),
|
||||||
],
|
],
|
||||||
|
|
|
@ -625,11 +625,7 @@ describe('UpdateTranslator', function () {
|
||||||
{
|
{
|
||||||
p: 3,
|
p: 3,
|
||||||
r: 'lo',
|
r: 'lo',
|
||||||
tracking: {
|
tracking: { type: 'none' },
|
||||||
type: 'none',
|
|
||||||
ts: this.timestamp,
|
|
||||||
userId: this.user_id,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
v: this.version,
|
v: this.version,
|
||||||
|
@ -658,11 +654,7 @@ describe('UpdateTranslator', function () {
|
||||||
3,
|
3,
|
||||||
{
|
{
|
||||||
r: 2,
|
r: 2,
|
||||||
tracking: {
|
tracking: { type: 'none' },
|
||||||
type: 'none',
|
|
||||||
ts: this.timestamp,
|
|
||||||
userId: this.user_id,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
15,
|
15,
|
||||||
],
|
],
|
||||||
|
@ -1044,11 +1036,7 @@ describe('UpdateTranslator', function () {
|
||||||
3,
|
3,
|
||||||
{
|
{
|
||||||
r: 3,
|
r: 3,
|
||||||
tracking: {
|
tracking: { type: 'none' },
|
||||||
type: 'none',
|
|
||||||
userId: this.user_id,
|
|
||||||
ts: new Date(this.timestamp).toISOString(),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
14,
|
14,
|
||||||
],
|
],
|
||||||
|
@ -1123,11 +1111,7 @@ describe('UpdateTranslator', function () {
|
||||||
3,
|
3,
|
||||||
{
|
{
|
||||||
r: 17,
|
r: 17,
|
||||||
tracking: {
|
tracking: { type: 'none' },
|
||||||
type: 'none',
|
|
||||||
userId: this.user_id,
|
|
||||||
ts: new Date(this.timestamp).toISOString(),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
3,
|
3,
|
||||||
-18,
|
-18,
|
||||||
|
|
Loading…
Reference in a new issue