@fluidframework/matrix 2.0.0-dev-rc.5.0.0.271045 → 2.0.0-dev-rc.5.0.0.271717

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.
@@ -11,15 +11,14 @@ import { HandleCache } from "./handlecache.js";
11
11
  import { HandleTable, isHandleValid } from "./handletable.js";
12
12
  import { deserializeBlob } from "./serialization.js";
13
13
  export class PermutationSegment extends BaseSegment {
14
- static typeString = "PermutationSegment";
15
- _start = -2147483648 /* Handle.unallocated */;
16
14
  static fromJSONObject(spec) {
17
15
  const [length, start] = spec;
18
16
  return new PermutationSegment(length, start);
19
17
  }
20
- type = PermutationSegment.typeString;
21
18
  constructor(length, start = -2147483648 /* Handle.unallocated */) {
22
19
  super();
20
+ this._start = -2147483648 /* Handle.unallocated */;
21
+ this.type = PermutationSegment.typeString;
23
22
  this._start = start;
24
23
  this.cachedLength = length;
25
24
  }
@@ -64,13 +63,9 @@ export class PermutationSegment extends BaseSegment {
64
63
  : `<${this.cachedLength}: ${this.start}..${this.start + this.cachedLength - 1}>`;
65
64
  }
66
65
  }
66
+ PermutationSegment.typeString = "PermutationSegment";
67
67
  // eslint-disable-next-line import/no-deprecated
68
68
  export class PermutationVector extends Client {
69
- deltaCallback;
70
- handlesRecycledCallback;
71
- handleTable = new HandleTable(); // Tracks available storage handles for rows.
72
- handleCache = new HandleCache(this);
73
- undo;
74
69
  constructor(path, logger, runtime, deltaCallback, handlesRecycledCallback, getMinInFlightRefSeq) {
75
70
  super(PermutationSegment.fromJSONObject, createChildLogger({ logger, namespace: `Matrix.${path}.MergeTreeClient` }), {
76
71
  ...runtime.options,
@@ -78,6 +73,79 @@ export class PermutationVector extends Client {
78
73
  }, getMinInFlightRefSeq);
79
74
  this.deltaCallback = deltaCallback;
80
75
  this.handlesRecycledCallback = handlesRecycledCallback;
76
+ this.handleTable = new HandleTable(); // Tracks available storage handles for rows.
77
+ this.handleCache = new HandleCache(this);
78
+ this.onDelta = (opArgs, deltaArgs) => {
79
+ // Apply deltas in descending order to prevent positions from shifting.
80
+ const ranges = deltaArgs.deltaSegments
81
+ .map(({ segment }) => ({
82
+ segment: segment,
83
+ position: this.getPosition(segment),
84
+ }))
85
+ .sort((left, right) => left.position - right.position);
86
+ const isLocal = opArgs.sequencedMessage === undefined;
87
+ // Notify the undo provider, if any is attached.
88
+ if (this.undo !== undefined && isLocal) {
89
+ this.undo.record(deltaArgs);
90
+ }
91
+ switch (deltaArgs.operation) {
92
+ case MergeTreeDeltaType.INSERT:
93
+ // Pass 1: Perform any internal maintenance first to avoid reentrancy.
94
+ for (const { segment, position } of ranges) {
95
+ // HACK: We need to include the allocated handle in the segment's JSON representation
96
+ // for snapshots, but need to ignore the remote client's handle allocations when
97
+ // processing remote ops.
98
+ segment.reset();
99
+ this.handleCache.itemsChanged(position,
100
+ /* deleteCount: */ 0,
101
+ /* insertCount: */ segment.cachedLength);
102
+ }
103
+ // Pass 2: Notify the 'deltaCallback', which may involve callbacks into user code.
104
+ for (const { segment, position } of ranges) {
105
+ this.deltaCallback(position,
106
+ /* numRemoved: */ 0,
107
+ /* numInserted: */ segment.cachedLength);
108
+ }
109
+ break;
110
+ case MergeTreeDeltaType.REMOVE: {
111
+ // Pass 1: Perform any internal maintenance first to avoid reentrancy.
112
+ for (const { segment, position } of ranges) {
113
+ this.handleCache.itemsChanged(position /* deleteCount: */, segment.cachedLength,
114
+ /* insertCount: */ 0);
115
+ }
116
+ // Pass 2: Notify the 'deltaCallback', which may involve callbacks into user code.
117
+ for (const { segment, position } of ranges) {
118
+ this.deltaCallback(position,
119
+ /* numRemoved: */ segment.cachedLength,
120
+ /* numInsert: */ 0);
121
+ }
122
+ break;
123
+ }
124
+ default:
125
+ throw new Error("Unhandled MergeTreeDeltaType");
126
+ }
127
+ };
128
+ this.onMaintenance = (args) => {
129
+ if (args.operation === MergeTreeMaintenanceType.UNLINK) {
130
+ let freed = [];
131
+ for (const { segment } of args.deltaSegments) {
132
+ const asPerm = segment;
133
+ if (isHandleValid(asPerm.start)) {
134
+ // Note: Using the spread operator with `.splice()` can exhaust the stack.
135
+ freed = freed.concat(new Array(asPerm.cachedLength)
136
+ .fill(0)
137
+ .map((value, index) => index + asPerm.start));
138
+ }
139
+ }
140
+ // Notify matrix that handles are about to be freed. The matrix is responsible for clearing
141
+ // the rows/cols prior to free to ensure recycled row/cols are initially empty.
142
+ this.handlesRecycledCallback(freed);
143
+ // Now that the physical storage has been cleared, add the recycled handles back to the free pool.
144
+ for (const handle of freed) {
145
+ this.handleTable.free(handle);
146
+ }
147
+ }
148
+ };
81
149
  this.on("delta", this.onDelta);
82
150
  this.on("maintenance", this.onMaintenance);
83
151
  }
@@ -175,77 +243,6 @@ export class PermutationVector extends Client {
175
243
  this.handleTable = HandleTable.load(handleTableData);
176
244
  return super.load(runtime, new ObjectStoragePartition(storage, "segments" /* SnapshotPath.segments */), serializer);
177
245
  }
178
- onDelta = (opArgs, deltaArgs) => {
179
- // Apply deltas in descending order to prevent positions from shifting.
180
- const ranges = deltaArgs.deltaSegments
181
- .map(({ segment }) => ({
182
- segment: segment,
183
- position: this.getPosition(segment),
184
- }))
185
- .sort((left, right) => left.position - right.position);
186
- const isLocal = opArgs.sequencedMessage === undefined;
187
- // Notify the undo provider, if any is attached.
188
- if (this.undo !== undefined && isLocal) {
189
- this.undo.record(deltaArgs);
190
- }
191
- switch (deltaArgs.operation) {
192
- case MergeTreeDeltaType.INSERT:
193
- // Pass 1: Perform any internal maintenance first to avoid reentrancy.
194
- for (const { segment, position } of ranges) {
195
- // HACK: We need to include the allocated handle in the segment's JSON representation
196
- // for snapshots, but need to ignore the remote client's handle allocations when
197
- // processing remote ops.
198
- segment.reset();
199
- this.handleCache.itemsChanged(position,
200
- /* deleteCount: */ 0,
201
- /* insertCount: */ segment.cachedLength);
202
- }
203
- // Pass 2: Notify the 'deltaCallback', which may involve callbacks into user code.
204
- for (const { segment, position } of ranges) {
205
- this.deltaCallback(position,
206
- /* numRemoved: */ 0,
207
- /* numInserted: */ segment.cachedLength);
208
- }
209
- break;
210
- case MergeTreeDeltaType.REMOVE: {
211
- // Pass 1: Perform any internal maintenance first to avoid reentrancy.
212
- for (const { segment, position } of ranges) {
213
- this.handleCache.itemsChanged(position /* deleteCount: */, segment.cachedLength,
214
- /* insertCount: */ 0);
215
- }
216
- // Pass 2: Notify the 'deltaCallback', which may involve callbacks into user code.
217
- for (const { segment, position } of ranges) {
218
- this.deltaCallback(position,
219
- /* numRemoved: */ segment.cachedLength,
220
- /* numInsert: */ 0);
221
- }
222
- break;
223
- }
224
- default:
225
- throw new Error("Unhandled MergeTreeDeltaType");
226
- }
227
- };
228
- onMaintenance = (args) => {
229
- if (args.operation === MergeTreeMaintenanceType.UNLINK) {
230
- let freed = [];
231
- for (const { segment } of args.deltaSegments) {
232
- const asPerm = segment;
233
- if (isHandleValid(asPerm.start)) {
234
- // Note: Using the spread operator with `.splice()` can exhaust the stack.
235
- freed = freed.concat(new Array(asPerm.cachedLength)
236
- .fill(0)
237
- .map((value, index) => index + asPerm.start));
238
- }
239
- }
240
- // Notify matrix that handles are about to be freed. The matrix is responsible for clearing
241
- // the rows/cols prior to free to ensure recycled row/cols are initially empty.
242
- this.handlesRecycledCallback(freed);
243
- // Now that the physical storage has been cleared, add the recycled handles back to the free pool.
244
- for (const handle of freed) {
245
- this.handleTable.free(handle);
246
- }
247
- }
248
- };
249
246
  toString() {
250
247
  const s = [];
251
248
  this.walkSegments((segment) => {
@@ -1 +1 @@
1
- {"version":3,"file":"permutationvector.js","sourceRoot":"","sources":["../src/permutationvector.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IFluidHandle, ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport {\n\tIFluidDataStoreRuntime,\n\tIChannelStorageService,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tBaseSegment, // eslint-disable-next-line import/no-deprecated\n\tClient,\n\tIJSONSegment,\n\tIMergeTreeDeltaCallbackArgs,\n\tIMergeTreeDeltaOpArgs,\n\tIMergeTreeMaintenanceCallbackArgs,\n\tISegment,\n\tMergeTreeDeltaType,\n\tMergeTreeMaintenanceType,\n} from \"@fluidframework/merge-tree/internal\";\nimport { ISummaryTreeWithStats } from \"@fluidframework/runtime-definitions/internal\";\nimport { ObjectStoragePartition, SummaryTreeBuilder } from \"@fluidframework/runtime-utils/internal\";\nimport { IFluidSerializer } from \"@fluidframework/shared-object-base/internal\";\nimport { createChildLogger } from \"@fluidframework/telemetry-utils/internal\";\n\nimport { HandleCache } from \"./handlecache.js\";\nimport { Handle, HandleTable, isHandleValid } from \"./handletable.js\";\nimport { deserializeBlob } from \"./serialization.js\";\nimport { VectorUndoProvider } from \"./undoprovider.js\";\n\nconst enum SnapshotPath {\n\tsegments = \"segments\",\n\thandleTable = \"handleTable\",\n}\n\ntype PermutationSegmentSpec = [number, number];\n\nexport class PermutationSegment extends BaseSegment {\n\tpublic static readonly typeString: string = \"PermutationSegment\";\n\tprivate _start = Handle.unallocated;\n\n\tpublic static fromJSONObject(spec: any) {\n\t\tconst [length, start] = spec as PermutationSegmentSpec;\n\t\treturn new PermutationSegment(length, start);\n\t}\n\n\tpublic readonly type = PermutationSegment.typeString;\n\n\tconstructor(length: number, start = Handle.unallocated) {\n\t\tsuper();\n\t\tthis._start = start;\n\t\tthis.cachedLength = length;\n\t}\n\n\tpublic get start() {\n\t\treturn this._start;\n\t}\n\tpublic set start(value: Handle) {\n\t\tassert(\n\t\t\tthis._start === Handle.unallocated,\n\t\t\t0x024 /* \"Start of PermutationSegment already allocated!\" */,\n\t\t);\n\t\tassert(\n\t\t\tisHandleValid(value),\n\t\t\t0x025 /* \"Trying to set start of PermutationSegment to invalid handle!\" */,\n\t\t);\n\n\t\tthis._start = value;\n\t}\n\n\tpublic reset() {\n\t\tthis._start = Handle.unallocated;\n\t}\n\n\tpublic toJSONObject() {\n\t\treturn [this.cachedLength, this.start];\n\t}\n\n\tpublic clone(start = 0, end = this.cachedLength) {\n\t\tconst b = new PermutationSegment(\n\t\t\t/* length: */ end - start,\n\t\t\t/* start: */ this.start + start,\n\t\t);\n\t\tthis.cloneInto(b);\n\t\treturn b;\n\t}\n\n\tpublic canAppend(segment: ISegment) {\n\t\tconst asPerm = segment as PermutationSegment;\n\n\t\treturn this.start === Handle.unallocated\n\t\t\t? asPerm.start === Handle.unallocated\n\t\t\t: asPerm.start === this.start + this.cachedLength;\n\t}\n\n\tprotected createSplitSegmentAt(pos: number) {\n\t\tassert(\n\t\t\t0 < pos && pos < this.cachedLength,\n\t\t\t0x026 /* \"Trying to split segment at out-of-bounds position!\" */,\n\t\t);\n\n\t\tconst leafSegment = new PermutationSegment(\n\t\t\t/* length: */ this.cachedLength - pos,\n\t\t\t/* start: */ this.start === Handle.unallocated ? Handle.unallocated : this.start + pos,\n\t\t);\n\n\t\tthis.cachedLength = pos;\n\n\t\treturn leafSegment;\n\t}\n\n\tpublic toString() {\n\t\treturn this.start === Handle.unallocated\n\t\t\t? `<${this.cachedLength} empty>`\n\t\t\t: `<${this.cachedLength}: ${this.start}..${this.start + this.cachedLength - 1}>`;\n\t}\n}\n\n// eslint-disable-next-line import/no-deprecated\nexport class PermutationVector extends Client {\n\tprivate handleTable = new HandleTable<never>(); // Tracks available storage handles for rows.\n\tpublic readonly handleCache = new HandleCache(this);\n\tpublic undo: VectorUndoProvider | undefined;\n\n\tconstructor(\n\t\tpath: string,\n\t\tlogger: ITelemetryBaseLogger,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tprivate readonly deltaCallback: (\n\t\t\tposition: number,\n\t\t\tnumRemoved: number,\n\t\t\tnumInserted: number,\n\t\t) => void,\n\t\tprivate readonly handlesRecycledCallback: (handles: Handle[]) => void,\n\t\tgetMinInFlightRefSeq: () => number | undefined,\n\t) {\n\t\tsuper(\n\t\t\tPermutationSegment.fromJSONObject,\n\t\t\tcreateChildLogger({ logger, namespace: `Matrix.${path}.MergeTreeClient` }),\n\t\t\t{\n\t\t\t\t...runtime.options,\n\t\t\t\tnewMergeTreeSnapshotFormat: true, // Force new snapshot format as it's generally more efficient for matrices.\n\t\t\t},\n\t\t\tgetMinInFlightRefSeq,\n\t\t);\n\n\t\tthis.on(\"delta\", this.onDelta);\n\t\tthis.on(\"maintenance\", this.onMaintenance);\n\t}\n\n\tpublic insert(start: number, length: number) {\n\t\treturn this.insertSegmentLocal(start, new PermutationSegment(length));\n\t}\n\n\tpublic remove(start: number, length: number) {\n\t\treturn this.removeRangeLocal(start, start + length);\n\t}\n\n\tpublic getMaybeHandle(pos: number): Handle {\n\t\tassert(\n\t\t\t0 <= pos && pos < this.getLength(),\n\t\t\t0x027 /* \"Trying to get handle of out-of-bounds position!\" */,\n\t\t);\n\n\t\treturn this.handleCache.getHandle(pos);\n\t}\n\n\tpublic getAllocatedHandle(pos: number): Handle {\n\t\tlet handle = this.getMaybeHandle(pos);\n\t\tif (isHandleValid(handle)) {\n\t\t\treturn handle;\n\t\t}\n\n\t\tthis.walkSegments(\n\t\t\t(segment) => {\n\t\t\t\tconst asPerm = segment as PermutationSegment;\n\t\t\t\tasPerm.start = handle = this.handleTable.allocate();\n\t\t\t\treturn true;\n\t\t\t},\n\t\t\tpos,\n\t\t\tpos + 1,\n\t\t\t/* accum: */ undefined,\n\t\t\t/* splitRange: */ true,\n\t\t);\n\n\t\tthis.handleCache.addHandle(pos, handle);\n\n\t\treturn handle;\n\t}\n\n\tpublic adjustPosition(\n\t\tpos: number,\n\t\top: Pick<ISequencedDocumentMessage, \"referenceSequenceNumber\" | \"clientId\">,\n\t) {\n\t\tconst { segment, offset } = this.getContainingSegment(pos, {\n\t\t\treferenceSequenceNumber: op.referenceSequenceNumber,\n\t\t\tclientId: op.clientId,\n\t\t});\n\n\t\t// Note that until the MergeTree GCs, the segment is still reachable via `getContainingSegment()` with\n\t\t// a `refSeq` in the past. Prevent remote ops from accidentally allocating or using recycled handles\n\t\t// by checking for the presence of 'removedSeq'.\n\t\tif (segment === undefined || segment.removedSeq !== undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\treturn this.getPosition(segment) + offset!;\n\t}\n\n\tpublic handleToPosition(handle: Handle, localSeq = this.getCollabWindow().localSeq) {\n\t\tassert(\n\t\t\tlocalSeq <= this.getCollabWindow().localSeq,\n\t\t\t0x028 /* \"'localSeq' for op being resubmitted must be <= the 'localSeq' of the last submitted op.\" */,\n\t\t);\n\n\t\t// TODO: In theory, the MergeTree should be able to map the (position, refSeq, localSeq) from\n\t\t// the original operation to the current position for undo/redo scenarios. This is probably the\n\t\t// ideal solution, as we would no longer need to store row/col handles in the op metadata.\n\t\t//\n\t\t// Failing that, we could avoid the O(n) search below by building a temporary map in the\n\t\t// opposite direction from the handle to either it's current position or segment + offset\n\t\t// and reuse it for the duration of undo/redo. (Ideally, we would know when the undo/redo\n\t\t// ended so we could discard this map.)\n\t\t//\n\t\t// If we find that we frequently need a reverse handle -> position lookup, we could maintain\n\t\t// one using the Tiny-Calc adjust tree.\n\t\tlet containingSegment!: PermutationSegment;\n\t\tlet containingOffset: number;\n\n\t\tthis.walkAllSegments((segment) => {\n\t\t\tconst { start, cachedLength } = segment as PermutationSegment;\n\n\t\t\t// If the segment is unallocated, skip it.\n\t\t\tif (!isHandleValid(start)) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tconst end = start + cachedLength;\n\n\t\t\tif (start <= handle && handle < end) {\n\t\t\t\tcontainingSegment = segment as PermutationSegment;\n\t\t\t\tcontainingOffset = handle - start;\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t});\n\n\t\t// We are guaranteed to find the handle in the PermutationVector, even if the corresponding\n\t\t// row/col has been removed, because handles are not recycled until the containing segment\n\t\t// is unlinked from the MergeTree.\n\t\t//\n\t\t// Therefore, either a row/col removal has been ACKed, in which case there will be no pending\n\t\t// ops that reference the stale handle, or the removal is unACKed, in which case the handle\n\t\t// has not yet been recycled.\n\n\t\tassert(\n\t\t\tisHandleValid(containingSegment.start),\n\t\t\t0x029 /* \"Invalid handle at start of containing segment!\" */,\n\t\t);\n\n\t\t// Once we know the current position of the handle, we can use the MergeTree to get the segment\n\t\t// containing this position and use 'findReconnectionPosition' to adjust for the local ops that\n\t\t// have not yet been submitted.\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\treturn this.findReconnectionPosition(containingSegment, localSeq) + containingOffset!;\n\t}\n\n\t// Constructs an ISummaryTreeWithStats for the cell data.\n\tpublic summarize(\n\t\truntime: IFluidDataStoreRuntime,\n\t\thandle: IFluidHandle,\n\t\tserializer: IFluidSerializer,\n\t): ISummaryTreeWithStats {\n\t\tconst builder = new SummaryTreeBuilder();\n\t\tbuilder.addWithStats(\n\t\t\tSnapshotPath.segments,\n\t\t\tsuper.summarize(runtime, handle, serializer, /* catchUpMsgs: */ []),\n\t\t);\n\t\tbuilder.addBlob(\n\t\t\tSnapshotPath.handleTable,\n\t\t\tserializer.stringify(this.handleTable.getSummaryContent(), handle),\n\t\t);\n\t\treturn builder.getSummaryTree();\n\t}\n\n\tpublic async load(\n\t\truntime: IFluidDataStoreRuntime,\n\t\tstorage: IChannelStorageService,\n\t\tserializer: IFluidSerializer,\n\t) {\n\t\tconst handleTableData = await deserializeBlob(\n\t\t\tstorage,\n\t\t\tSnapshotPath.handleTable,\n\t\t\tserializer,\n\t\t);\n\n\t\tthis.handleTable = HandleTable.load<never>(handleTableData);\n\n\t\treturn super.load(\n\t\t\truntime,\n\t\t\tnew ObjectStoragePartition(storage, SnapshotPath.segments),\n\t\t\tserializer,\n\t\t);\n\t}\n\n\tprivate readonly onDelta = (\n\t\topArgs: IMergeTreeDeltaOpArgs,\n\t\tdeltaArgs: IMergeTreeDeltaCallbackArgs,\n\t) => {\n\t\t// Apply deltas in descending order to prevent positions from shifting.\n\t\tconst ranges = deltaArgs.deltaSegments\n\t\t\t.map(({ segment }) => ({\n\t\t\t\tsegment: segment as PermutationSegment,\n\t\t\t\tposition: this.getPosition(segment),\n\t\t\t}))\n\t\t\t.sort((left, right) => left.position - right.position);\n\n\t\tconst isLocal = opArgs.sequencedMessage === undefined;\n\n\t\t// Notify the undo provider, if any is attached.\n\t\tif (this.undo !== undefined && isLocal) {\n\t\t\tthis.undo.record(deltaArgs);\n\t\t}\n\n\t\tswitch (deltaArgs.operation) {\n\t\t\tcase MergeTreeDeltaType.INSERT:\n\t\t\t\t// Pass 1: Perform any internal maintenance first to avoid reentrancy.\n\t\t\t\tfor (const { segment, position } of ranges) {\n\t\t\t\t\t// HACK: We need to include the allocated handle in the segment's JSON representation\n\t\t\t\t\t// for snapshots, but need to ignore the remote client's handle allocations when\n\t\t\t\t\t// processing remote ops.\n\t\t\t\t\tsegment.reset();\n\n\t\t\t\t\tthis.handleCache.itemsChanged(\n\t\t\t\t\t\tposition,\n\t\t\t\t\t\t/* deleteCount: */ 0,\n\t\t\t\t\t\t/* insertCount: */ segment.cachedLength,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// Pass 2: Notify the 'deltaCallback', which may involve callbacks into user code.\n\t\t\t\tfor (const { segment, position } of ranges) {\n\t\t\t\t\tthis.deltaCallback(\n\t\t\t\t\t\tposition,\n\t\t\t\t\t\t/* numRemoved: */ 0,\n\t\t\t\t\t\t/* numInserted: */ segment.cachedLength,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase MergeTreeDeltaType.REMOVE: {\n\t\t\t\t// Pass 1: Perform any internal maintenance first to avoid reentrancy.\n\t\t\t\tfor (const { segment, position } of ranges) {\n\t\t\t\t\tthis.handleCache.itemsChanged(\n\t\t\t\t\t\tposition /* deleteCount: */,\n\t\t\t\t\t\tsegment.cachedLength,\n\t\t\t\t\t\t/* insertCount: */ 0,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// Pass 2: Notify the 'deltaCallback', which may involve callbacks into user code.\n\t\t\t\tfor (const { segment, position } of ranges) {\n\t\t\t\t\tthis.deltaCallback(\n\t\t\t\t\t\tposition,\n\t\t\t\t\t\t/* numRemoved: */ segment.cachedLength,\n\t\t\t\t\t\t/* numInsert: */ 0,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\tthrow new Error(\"Unhandled MergeTreeDeltaType\");\n\t\t}\n\t};\n\n\tprivate readonly onMaintenance = (args: IMergeTreeMaintenanceCallbackArgs) => {\n\t\tif (args.operation === MergeTreeMaintenanceType.UNLINK) {\n\t\t\tlet freed: number[] = [];\n\n\t\t\tfor (const { segment } of args.deltaSegments) {\n\t\t\t\tconst asPerm = segment as PermutationSegment;\n\t\t\t\tif (isHandleValid(asPerm.start)) {\n\t\t\t\t\t// Note: Using the spread operator with `.splice()` can exhaust the stack.\n\t\t\t\t\tfreed = freed.concat(\n\t\t\t\t\t\tnew Array(asPerm.cachedLength)\n\t\t\t\t\t\t\t.fill(0)\n\t\t\t\t\t\t\t.map((value, index) => index + asPerm.start),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Notify matrix that handles are about to be freed. The matrix is responsible for clearing\n\t\t\t// the rows/cols prior to free to ensure recycled row/cols are initially empty.\n\t\t\tthis.handlesRecycledCallback(freed);\n\n\t\t\t// Now that the physical storage has been cleared, add the recycled handles back to the free pool.\n\t\t\tfor (const handle of freed) {\n\t\t\t\tthis.handleTable.free(handle);\n\t\t\t}\n\t\t}\n\t};\n\n\tpublic toString() {\n\t\tconst s: string[] = [];\n\n\t\tthis.walkSegments((segment) => {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-base-to-string\n\t\t\ts.push(`${segment}`);\n\t\t\treturn true;\n\t\t});\n\n\t\treturn s.join(\"\");\n\t}\n}\n\nexport function reinsertSegmentIntoVector(\n\tvector: PermutationVector,\n\tpos: number,\n\tspec: IJSONSegment,\n) {\n\tconst original = PermutationSegment.fromJSONObject(spec);\n\n\t// (Re)insert the removed number of rows at the original position.\n\tconst op = vector.insertSegmentLocal(pos, original);\n\tconst inserted = vector.getContainingSegment(pos).segment as PermutationSegment;\n\n\t// we reuse the original handle here\n\t// so if cells exist, they can be found, and re-inserted\n\tif (isHandleValid(original.start)) {\n\t\tinserted.start = original.start;\n\t}\n\n\t// Invalidate the handleCache in case it was populated during the 'rowsChanged'\n\t// callback, which occurs before the handle span is populated.\n\tvector.handleCache.itemsChanged(\n\t\tpos,\n\t\t/* removedCount: */ 0,\n\t\t/* insertedCount: */ inserted.cachedLength,\n\t);\n\treturn { op, inserted };\n}\n"]}
1
+ {"version":3,"file":"permutationvector.js","sourceRoot":"","sources":["../src/permutationvector.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IFluidHandle, ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport {\n\tIFluidDataStoreRuntime,\n\tIChannelStorageService,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tBaseSegment, // eslint-disable-next-line import/no-deprecated\n\tClient,\n\tIJSONSegment,\n\tIMergeTreeDeltaCallbackArgs,\n\tIMergeTreeDeltaOpArgs,\n\tIMergeTreeMaintenanceCallbackArgs,\n\tISegment,\n\tMergeTreeDeltaType,\n\tMergeTreeMaintenanceType,\n} from \"@fluidframework/merge-tree/internal\";\nimport { ISummaryTreeWithStats } from \"@fluidframework/runtime-definitions/internal\";\nimport { ObjectStoragePartition, SummaryTreeBuilder } from \"@fluidframework/runtime-utils/internal\";\nimport { IFluidSerializer } from \"@fluidframework/shared-object-base/internal\";\nimport { createChildLogger } from \"@fluidframework/telemetry-utils/internal\";\n\nimport { HandleCache } from \"./handlecache.js\";\nimport { Handle, HandleTable, isHandleValid } from \"./handletable.js\";\nimport { deserializeBlob } from \"./serialization.js\";\nimport { VectorUndoProvider } from \"./undoprovider.js\";\n\nconst enum SnapshotPath {\n\tsegments = \"segments\",\n\thandleTable = \"handleTable\",\n}\n\ntype PermutationSegmentSpec = [number, number];\n\nexport class PermutationSegment extends BaseSegment {\n\tpublic static readonly typeString: string = \"PermutationSegment\";\n\tprivate _start = Handle.unallocated;\n\n\tpublic static fromJSONObject(spec: any) {\n\t\tconst [length, start] = spec as PermutationSegmentSpec;\n\t\treturn new PermutationSegment(length, start);\n\t}\n\n\tpublic readonly type = PermutationSegment.typeString;\n\n\tconstructor(length: number, start = Handle.unallocated) {\n\t\tsuper();\n\t\tthis._start = start;\n\t\tthis.cachedLength = length;\n\t}\n\n\tpublic get start() {\n\t\treturn this._start;\n\t}\n\tpublic set start(value: Handle) {\n\t\tassert(\n\t\t\tthis._start === Handle.unallocated,\n\t\t\t0x024 /* \"Start of PermutationSegment already allocated!\" */,\n\t\t);\n\t\tassert(\n\t\t\tisHandleValid(value),\n\t\t\t0x025 /* \"Trying to set start of PermutationSegment to invalid handle!\" */,\n\t\t);\n\n\t\tthis._start = value;\n\t}\n\n\tpublic reset() {\n\t\tthis._start = Handle.unallocated;\n\t}\n\n\tpublic toJSONObject() {\n\t\treturn [this.cachedLength, this.start];\n\t}\n\n\tpublic clone(start = 0, end = this.cachedLength) {\n\t\tconst b = new PermutationSegment(\n\t\t\t/* length: */ end - start,\n\t\t\t/* start: */ this.start + start,\n\t\t);\n\t\tthis.cloneInto(b);\n\t\treturn b;\n\t}\n\n\tpublic canAppend(segment: ISegment) {\n\t\tconst asPerm = segment as PermutationSegment;\n\n\t\treturn this.start === Handle.unallocated\n\t\t\t? asPerm.start === Handle.unallocated\n\t\t\t: asPerm.start === this.start + this.cachedLength;\n\t}\n\n\tprotected createSplitSegmentAt(pos: number) {\n\t\tassert(\n\t\t\t0 < pos && pos < this.cachedLength,\n\t\t\t0x026 /* \"Trying to split segment at out-of-bounds position!\" */,\n\t\t);\n\n\t\tconst leafSegment = new PermutationSegment(\n\t\t\t/* length: */ this.cachedLength - pos,\n\t\t\t/* start: */ this.start === Handle.unallocated ? Handle.unallocated : this.start + pos,\n\t\t);\n\n\t\tthis.cachedLength = pos;\n\n\t\treturn leafSegment;\n\t}\n\n\tpublic toString() {\n\t\treturn this.start === Handle.unallocated\n\t\t\t? `<${this.cachedLength} empty>`\n\t\t\t: `<${this.cachedLength}: ${this.start}..${this.start + this.cachedLength - 1}>`;\n\t}\n}\n\n// eslint-disable-next-line import/no-deprecated\nexport class PermutationVector extends Client {\n\tprivate handleTable = new HandleTable<never>(); // Tracks available storage handles for rows.\n\tpublic readonly handleCache = new HandleCache(this);\n\tpublic undo: VectorUndoProvider | undefined;\n\n\tconstructor(\n\t\tpath: string,\n\t\tlogger: ITelemetryBaseLogger,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tprivate readonly deltaCallback: (\n\t\t\tposition: number,\n\t\t\tnumRemoved: number,\n\t\t\tnumInserted: number,\n\t\t) => void,\n\t\tprivate readonly handlesRecycledCallback: (handles: Handle[]) => void,\n\t\tgetMinInFlightRefSeq: () => number | undefined,\n\t) {\n\t\tsuper(\n\t\t\tPermutationSegment.fromJSONObject,\n\t\t\tcreateChildLogger({ logger, namespace: `Matrix.${path}.MergeTreeClient` }),\n\t\t\t{\n\t\t\t\t...runtime.options,\n\t\t\t\tnewMergeTreeSnapshotFormat: true, // Force new snapshot format as it's generally more efficient for matrices.\n\t\t\t},\n\t\t\tgetMinInFlightRefSeq,\n\t\t);\n\n\t\tthis.on(\"delta\", this.onDelta);\n\t\tthis.on(\"maintenance\", this.onMaintenance);\n\t}\n\n\tpublic insert(start: number, length: number) {\n\t\treturn this.insertSegmentLocal(start, new PermutationSegment(length));\n\t}\n\n\tpublic remove(start: number, length: number) {\n\t\treturn this.removeRangeLocal(start, start + length);\n\t}\n\n\tpublic getMaybeHandle(pos: number): Handle {\n\t\tassert(\n\t\t\t0 <= pos && pos < this.getLength(),\n\t\t\t0x027 /* \"Trying to get handle of out-of-bounds position!\" */,\n\t\t);\n\n\t\treturn this.handleCache.getHandle(pos);\n\t}\n\n\tpublic getAllocatedHandle(pos: number): Handle {\n\t\tlet handle = this.getMaybeHandle(pos);\n\t\tif (isHandleValid(handle)) {\n\t\t\treturn handle;\n\t\t}\n\n\t\tthis.walkSegments(\n\t\t\t(segment) => {\n\t\t\t\tconst asPerm = segment as PermutationSegment;\n\t\t\t\tasPerm.start = handle = this.handleTable.allocate();\n\t\t\t\treturn true;\n\t\t\t},\n\t\t\tpos,\n\t\t\tpos + 1,\n\t\t\t/* accum: */ undefined,\n\t\t\t/* splitRange: */ true,\n\t\t);\n\n\t\tthis.handleCache.addHandle(pos, handle);\n\n\t\treturn handle;\n\t}\n\n\tpublic adjustPosition(\n\t\tpos: number,\n\t\top: Pick<ISequencedDocumentMessage, \"referenceSequenceNumber\" | \"clientId\">,\n\t) {\n\t\tconst { segment, offset } = this.getContainingSegment(pos, {\n\t\t\treferenceSequenceNumber: op.referenceSequenceNumber,\n\t\t\tclientId: op.clientId,\n\t\t});\n\n\t\t// Note that until the MergeTree GCs, the segment is still reachable via `getContainingSegment()` with\n\t\t// a `refSeq` in the past. Prevent remote ops from accidentally allocating or using recycled handles\n\t\t// by checking for the presence of 'removedSeq'.\n\t\tif (segment === undefined || segment.removedSeq !== undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\treturn this.getPosition(segment) + offset!;\n\t}\n\n\tpublic handleToPosition(handle: Handle, localSeq = this.getCollabWindow().localSeq) {\n\t\tassert(\n\t\t\tlocalSeq <= this.getCollabWindow().localSeq,\n\t\t\t0x028 /* \"'localSeq' for op being resubmitted must be <= the 'localSeq' of the last submitted op.\" */,\n\t\t);\n\n\t\t// TODO: In theory, the MergeTree should be able to map the (position, refSeq, localSeq) from\n\t\t// the original operation to the current position for undo/redo scenarios. This is probably the\n\t\t// ideal solution, as we would no longer need to store row/col handles in the op metadata.\n\t\t//\n\t\t// Failing that, we could avoid the O(n) search below by building a temporary map in the\n\t\t// opposite direction from the handle to either it's current position or segment + offset\n\t\t// and reuse it for the duration of undo/redo. (Ideally, we would know when the undo/redo\n\t\t// ended so we could discard this map.)\n\t\t//\n\t\t// If we find that we frequently need a reverse handle -> position lookup, we could maintain\n\t\t// one using the Tiny-Calc adjust tree.\n\t\tlet containingSegment!: PermutationSegment;\n\t\tlet containingOffset: number;\n\n\t\tthis.walkAllSegments((segment) => {\n\t\t\tconst { start, cachedLength } = segment as PermutationSegment;\n\n\t\t\t// If the segment is unallocated, skip it.\n\t\t\tif (!isHandleValid(start)) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tconst end = start + cachedLength;\n\n\t\t\tif (start <= handle && handle < end) {\n\t\t\t\tcontainingSegment = segment as PermutationSegment;\n\t\t\t\tcontainingOffset = handle - start;\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t});\n\n\t\t// We are guaranteed to find the handle in the PermutationVector, even if the corresponding\n\t\t// row/col has been removed, because handles are not recycled until the containing segment\n\t\t// is unlinked from the MergeTree.\n\t\t//\n\t\t// Therefore, either a row/col removal has been ACKed, in which case there will be no pending\n\t\t// ops that reference the stale handle, or the removal is unACKed, in which case the handle\n\t\t// has not yet been recycled.\n\n\t\tassert(\n\t\t\tisHandleValid(containingSegment.start),\n\t\t\t0x029 /* \"Invalid handle at start of containing segment!\" */,\n\t\t);\n\n\t\t// Once we know the current position of the handle, we can use the MergeTree to get the segment\n\t\t// containing this position and use 'findReconnectionPosition' to adjust for the local ops that\n\t\t// have not yet been submitted.\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\treturn this.findReconnectionPosition(containingSegment, localSeq) + containingOffset!;\n\t}\n\n\t// Constructs an ISummaryTreeWithStats for the cell data.\n\tpublic summarize(\n\t\truntime: IFluidDataStoreRuntime,\n\t\thandle: IFluidHandle,\n\t\tserializer: IFluidSerializer,\n\t): ISummaryTreeWithStats {\n\t\tconst builder = new SummaryTreeBuilder();\n\t\tbuilder.addWithStats(\n\t\t\tSnapshotPath.segments,\n\t\t\tsuper.summarize(runtime, handle, serializer, /* catchUpMsgs: */ []),\n\t\t);\n\t\tbuilder.addBlob(\n\t\t\tSnapshotPath.handleTable,\n\t\t\tserializer.stringify(this.handleTable.getSummaryContent(), handle),\n\t\t);\n\t\treturn builder.getSummaryTree();\n\t}\n\n\tpublic async load(\n\t\truntime: IFluidDataStoreRuntime,\n\t\tstorage: IChannelStorageService,\n\t\tserializer: IFluidSerializer,\n\t) {\n\t\tconst handleTableData = await deserializeBlob(\n\t\t\tstorage,\n\t\t\tSnapshotPath.handleTable,\n\t\t\tserializer,\n\t\t);\n\n\t\tthis.handleTable = HandleTable.load<never>(handleTableData);\n\n\t\treturn super.load(\n\t\t\truntime,\n\t\t\tnew ObjectStoragePartition(storage, SnapshotPath.segments),\n\t\t\tserializer,\n\t\t);\n\t}\n\n\tprivate readonly onDelta = (\n\t\topArgs: IMergeTreeDeltaOpArgs,\n\t\tdeltaArgs: IMergeTreeDeltaCallbackArgs,\n\t) => {\n\t\t// Apply deltas in descending order to prevent positions from shifting.\n\t\tconst ranges = deltaArgs.deltaSegments\n\t\t\t.map(({ segment }) => ({\n\t\t\t\tsegment: segment as PermutationSegment,\n\t\t\t\tposition: this.getPosition(segment),\n\t\t\t}))\n\t\t\t.sort((left, right) => left.position - right.position);\n\n\t\tconst isLocal = opArgs.sequencedMessage === undefined;\n\n\t\t// Notify the undo provider, if any is attached.\n\t\tif (this.undo !== undefined && isLocal) {\n\t\t\tthis.undo.record(deltaArgs);\n\t\t}\n\n\t\tswitch (deltaArgs.operation) {\n\t\t\tcase MergeTreeDeltaType.INSERT:\n\t\t\t\t// Pass 1: Perform any internal maintenance first to avoid reentrancy.\n\t\t\t\tfor (const { segment, position } of ranges) {\n\t\t\t\t\t// HACK: We need to include the allocated handle in the segment's JSON representation\n\t\t\t\t\t// for snapshots, but need to ignore the remote client's handle allocations when\n\t\t\t\t\t// processing remote ops.\n\t\t\t\t\tsegment.reset();\n\n\t\t\t\t\tthis.handleCache.itemsChanged(\n\t\t\t\t\t\tposition,\n\t\t\t\t\t\t/* deleteCount: */ 0,\n\t\t\t\t\t\t/* insertCount: */ segment.cachedLength,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// Pass 2: Notify the 'deltaCallback', which may involve callbacks into user code.\n\t\t\t\tfor (const { segment, position } of ranges) {\n\t\t\t\t\tthis.deltaCallback(\n\t\t\t\t\t\tposition,\n\t\t\t\t\t\t/* numRemoved: */ 0,\n\t\t\t\t\t\t/* numInserted: */ segment.cachedLength,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase MergeTreeDeltaType.REMOVE: {\n\t\t\t\t// Pass 1: Perform any internal maintenance first to avoid reentrancy.\n\t\t\t\tfor (const { segment, position } of ranges) {\n\t\t\t\t\tthis.handleCache.itemsChanged(\n\t\t\t\t\t\tposition /* deleteCount: */,\n\t\t\t\t\t\tsegment.cachedLength,\n\t\t\t\t\t\t/* insertCount: */ 0,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// Pass 2: Notify the 'deltaCallback', which may involve callbacks into user code.\n\t\t\t\tfor (const { segment, position } of ranges) {\n\t\t\t\t\tthis.deltaCallback(\n\t\t\t\t\t\tposition,\n\t\t\t\t\t\t/* numRemoved: */ segment.cachedLength,\n\t\t\t\t\t\t/* numInsert: */ 0,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\tthrow new Error(\"Unhandled MergeTreeDeltaType\");\n\t\t}\n\t};\n\n\tprivate readonly onMaintenance = (args: IMergeTreeMaintenanceCallbackArgs) => {\n\t\tif (args.operation === MergeTreeMaintenanceType.UNLINK) {\n\t\t\tlet freed: number[] = [];\n\n\t\t\tfor (const { segment } of args.deltaSegments) {\n\t\t\t\tconst asPerm = segment as PermutationSegment;\n\t\t\t\tif (isHandleValid(asPerm.start)) {\n\t\t\t\t\t// Note: Using the spread operator with `.splice()` can exhaust the stack.\n\t\t\t\t\tfreed = freed.concat(\n\t\t\t\t\t\tnew Array(asPerm.cachedLength)\n\t\t\t\t\t\t\t.fill(0)\n\t\t\t\t\t\t\t.map((value, index) => index + asPerm.start),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Notify matrix that handles are about to be freed. The matrix is responsible for clearing\n\t\t\t// the rows/cols prior to free to ensure recycled row/cols are initially empty.\n\t\t\tthis.handlesRecycledCallback(freed);\n\n\t\t\t// Now that the physical storage has been cleared, add the recycled handles back to the free pool.\n\t\t\tfor (const handle of freed) {\n\t\t\t\tthis.handleTable.free(handle);\n\t\t\t}\n\t\t}\n\t};\n\n\tpublic toString() {\n\t\tconst s: string[] = [];\n\n\t\tthis.walkSegments((segment) => {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-base-to-string\n\t\t\ts.push(`${segment}`);\n\t\t\treturn true;\n\t\t});\n\n\t\treturn s.join(\"\");\n\t}\n}\n\nexport function reinsertSegmentIntoVector(\n\tvector: PermutationVector,\n\tpos: number,\n\tspec: IJSONSegment,\n) {\n\tconst original = PermutationSegment.fromJSONObject(spec);\n\n\t// (Re)insert the removed number of rows at the original position.\n\tconst op = vector.insertSegmentLocal(pos, original);\n\tconst inserted = vector.getContainingSegment(pos).segment as PermutationSegment;\n\n\t// we reuse the original handle here\n\t// so if cells exist, they can be found, and re-inserted\n\tif (isHandleValid(original.start)) {\n\t\tinserted.start = original.start;\n\t}\n\n\t// Invalidate the handleCache in case it was populated during the 'rowsChanged'\n\t// callback, which occurs before the handle span is populated.\n\tvector.handleCache.itemsChanged(\n\t\tpos,\n\t\t/* removedCount: */ 0,\n\t\t/* insertedCount: */ inserted.cachedLength,\n\t);\n\treturn { op, inserted };\n}\n"]}
package/lib/runtime.js CHANGED
@@ -11,12 +11,6 @@ import { pkgVersion } from "./packageVersion.js";
11
11
  * @deprecated - Use `SharedMatrix.getFactory` instead.
12
12
  */
13
13
  export class SharedMatrixFactory {
14
- static Type = "https://graph.microsoft.com/types/sharedmatrix";
15
- static Attributes = {
16
- type: SharedMatrixFactory.Type,
17
- snapshotFormatVersion: "0.1",
18
- packageVersion: pkgVersion,
19
- };
20
14
  get type() {
21
15
  return SharedMatrixFactory.Type;
22
16
  }
@@ -37,6 +31,12 @@ export class SharedMatrixFactory {
37
31
  return matrix;
38
32
  }
39
33
  }
34
+ SharedMatrixFactory.Type = "https://graph.microsoft.com/types/sharedmatrix";
35
+ SharedMatrixFactory.Attributes = {
36
+ type: SharedMatrixFactory.Type,
37
+ snapshotFormatVersion: "0.1",
38
+ packageVersion: pkgVersion,
39
+ };
40
40
  /**
41
41
  * Entrypoint for {@link ISharedMatrix} creation.
42
42
  * @alpha
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AAErF,OAAO,EAAsB,YAAY,IAAI,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACpF,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD;;;;GAIG;AACH,MAAM,OAAO,mBAAmB;IACxB,MAAM,CAAC,IAAI,GAAG,gDAAgD,CAAC;IAE/D,MAAM,CAAU,UAAU,GAAuB;QACvD,IAAI,EAAE,mBAAmB,CAAC,IAAI;QAC9B,qBAAqB,EAAE,KAAK;QAC5B,cAAc,EAAE,UAAU;KAC1B,CAAC;IAEF,IAAW,IAAI;QACd,OAAO,mBAAmB,CAAC,IAAI,CAAC;IACjC,CAAC;IAED,IAAW,UAAU;QACpB,OAAO,mBAAmB,CAAC,UAAU,CAAC;IACvC,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,IAAI,CAChB,OAA+B,EAC/B,EAAU,EACV,QAA0B,EAC1B,UAA8B;QAE9B,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,OAAO,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC;QAC9D,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5B,OAAO,MAAM,CAAC;IACf,CAAC;IAEM,MAAM,CAAC,QAAgC,EAAE,EAAU;QACzD,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,QAAQ,EAAE,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACpE,MAAM,CAAC,eAAe,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC;IACf,CAAC;;AAGF;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,sBAAsB,CAAgB,mBAAmB,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tIChannel,\n\tIChannelAttributes,\n\tIChannelFactory,\n\tIFluidDataStoreRuntime,\n\tIChannelServices,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { createSharedObjectKind } from \"@fluidframework/shared-object-base/internal\";\n\nimport { type ISharedMatrix, SharedMatrix as SharedMatrixClass } from \"./matrix.js\";\nimport { pkgVersion } from \"./packageVersion.js\";\n\n/**\n * {@link @fluidframework/datastore-definitions#IChannelFactory} for {@link ISharedMatrix}.\n * @alpha\n * @deprecated - Use `SharedMatrix.getFactory` instead.\n */\nexport class SharedMatrixFactory implements IChannelFactory<ISharedMatrix> {\n\tpublic static Type = \"https://graph.microsoft.com/types/sharedmatrix\";\n\n\tpublic static readonly Attributes: IChannelAttributes = {\n\t\ttype: SharedMatrixFactory.Type,\n\t\tsnapshotFormatVersion: \"0.1\",\n\t\tpackageVersion: pkgVersion,\n\t};\n\n\tpublic get type() {\n\t\treturn SharedMatrixFactory.Type;\n\t}\n\n\tpublic get attributes() {\n\t\treturn SharedMatrixFactory.Attributes;\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.load}\n\t */\n\tpublic async load(\n\t\truntime: IFluidDataStoreRuntime,\n\t\tid: string,\n\t\tservices: IChannelServices,\n\t\tattributes: IChannelAttributes,\n\t): Promise<ISharedMatrix & IChannel> {\n\t\tconst matrix = new SharedMatrixClass(runtime, id, attributes);\n\t\tawait matrix.load(services);\n\t\treturn matrix;\n\t}\n\n\tpublic create(document: IFluidDataStoreRuntime, id: string): ISharedMatrix & IChannel {\n\t\tconst matrix = new SharedMatrixClass(document, id, this.attributes);\n\t\tmatrix.initializeLocal();\n\t\treturn matrix;\n\t}\n}\n\n/**\n * Entrypoint for {@link ISharedMatrix} creation.\n * @alpha\n */\nexport const SharedMatrix = createSharedObjectKind<ISharedMatrix>(SharedMatrixFactory);\n\n/**\n * Convenience alias for {@link ISharedMatrix}. Prefer to use {@link ISharedMatrix} when referring to\n * SharedMatrix as a type.\n * @alpha\n * @privateRemarks\n * This alias is for legacy compat from when the SharedMatrix class was exported as public.\n */\nexport type SharedMatrix<T = any> = ISharedMatrix<T>;\n"]}
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AAErF,OAAO,EAAsB,YAAY,IAAI,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACpF,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD;;;;GAIG;AACH,MAAM,OAAO,mBAAmB;IAS/B,IAAW,IAAI;QACd,OAAO,mBAAmB,CAAC,IAAI,CAAC;IACjC,CAAC;IAED,IAAW,UAAU;QACpB,OAAO,mBAAmB,CAAC,UAAU,CAAC;IACvC,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,IAAI,CAChB,OAA+B,EAC/B,EAAU,EACV,QAA0B,EAC1B,UAA8B;QAE9B,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,OAAO,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC;QAC9D,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5B,OAAO,MAAM,CAAC;IACf,CAAC;IAEM,MAAM,CAAC,QAAgC,EAAE,EAAU;QACzD,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,QAAQ,EAAE,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACpE,MAAM,CAAC,eAAe,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC;IACf,CAAC;;AAlCa,wBAAI,GAAG,gDAAgD,CAAC;AAE/C,8BAAU,GAAuB;IACvD,IAAI,EAAE,mBAAmB,CAAC,IAAI;IAC9B,qBAAqB,EAAE,KAAK;IAC5B,cAAc,EAAE,UAAU;CAC1B,CAAC;AA+BH;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,sBAAsB,CAAgB,mBAAmB,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tIChannel,\n\tIChannelAttributes,\n\tIChannelFactory,\n\tIFluidDataStoreRuntime,\n\tIChannelServices,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { createSharedObjectKind } from \"@fluidframework/shared-object-base/internal\";\n\nimport { type ISharedMatrix, SharedMatrix as SharedMatrixClass } from \"./matrix.js\";\nimport { pkgVersion } from \"./packageVersion.js\";\n\n/**\n * {@link @fluidframework/datastore-definitions#IChannelFactory} for {@link ISharedMatrix}.\n * @alpha\n * @deprecated - Use `SharedMatrix.getFactory` instead.\n */\nexport class SharedMatrixFactory implements IChannelFactory<ISharedMatrix> {\n\tpublic static Type = \"https://graph.microsoft.com/types/sharedmatrix\";\n\n\tpublic static readonly Attributes: IChannelAttributes = {\n\t\ttype: SharedMatrixFactory.Type,\n\t\tsnapshotFormatVersion: \"0.1\",\n\t\tpackageVersion: pkgVersion,\n\t};\n\n\tpublic get type() {\n\t\treturn SharedMatrixFactory.Type;\n\t}\n\n\tpublic get attributes() {\n\t\treturn SharedMatrixFactory.Attributes;\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.load}\n\t */\n\tpublic async load(\n\t\truntime: IFluidDataStoreRuntime,\n\t\tid: string,\n\t\tservices: IChannelServices,\n\t\tattributes: IChannelAttributes,\n\t): Promise<ISharedMatrix & IChannel> {\n\t\tconst matrix = new SharedMatrixClass(runtime, id, attributes);\n\t\tawait matrix.load(services);\n\t\treturn matrix;\n\t}\n\n\tpublic create(document: IFluidDataStoreRuntime, id: string): ISharedMatrix & IChannel {\n\t\tconst matrix = new SharedMatrixClass(document, id, this.attributes);\n\t\tmatrix.initializeLocal();\n\t\treturn matrix;\n\t}\n}\n\n/**\n * Entrypoint for {@link ISharedMatrix} creation.\n * @alpha\n */\nexport const SharedMatrix = createSharedObjectKind<ISharedMatrix>(SharedMatrixFactory);\n\n/**\n * Convenience alias for {@link ISharedMatrix}. Prefer to use {@link ISharedMatrix} when referring to\n * SharedMatrix as a type.\n * @alpha\n * @privateRemarks\n * This alias is for legacy compat from when the SharedMatrix class was exported as public.\n */\nexport type SharedMatrix<T = any> = ISharedMatrix<T>;\n"]}
@@ -37,12 +37,11 @@ const nullToUndefined = (array) => array.map((value) => {
37
37
  * A sparse 4 billion x 4 billion array stored as 16x16 tiles.
38
38
  */
39
39
  export class SparseArray2D {
40
- root;
41
40
  constructor(root = [undefined]) {
42
41
  this.root = root;
42
+ this.rowCount = 0xffffffff;
43
+ this.colCount = 0xffffffff;
43
44
  }
44
- rowCount = 0xffffffff;
45
- colCount = 0xffffffff;
46
45
  getCell(row, col) {
47
46
  const keyHi = r0c0ToMorton2x16(row >>> 16, col >>> 16);
48
47
  const level0 = this.root[keyHi];
@@ -1 +1 @@
1
- {"version":3,"file":"sparsearray2d.js","sourceRoot":"","sources":["../src/sparsearray2d.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable no-bitwise */\n\nimport { IMatrixReader, IMatrixWriter } from \"@tiny-calc/nano\";\n\n// Build a lookup table that maps a uint8 to the corresponding uint16 where 0s\n// are interleaved between the original bits. (e.g., 1111... -> 01010101...).\n//\n// (Lookup table ~17% faster than inlining the bit-twiddling on Node v12 x64)\n// (Array<T> ~2% faster than typed array on Node v12 x64)\nconst x8ToInterlacedX16 = new Array(256).fill(0).map((value, i) => {\n\tlet j = i;\n\tj = (j | (j << 4)) & 0x0f0f; // .... 7654 .... 3210\n\tj = (j | (j << 2)) & 0x3333; // ..76 ..54 ..32 ..10\n\tj = (j | (j << 1)) & 0x5555; // .7.6 .5.4 .3.2 .1.0\n\treturn j;\n});\n\n// Selects individual bytes from a given 32b integer. The left shift are used to\n// clear upper bits (faster than using masks on Node 10 x64).\nconst byte0 = (x32: number) => x32 >>> 24;\nconst byte1 = (x32: number) => (x32 << 8) >>> 24;\nconst byte2 = (x32: number) => (x32 << 16) >>> 24;\nconst byte3 = (x32: number) => (x32 << 24) >>> 24;\n\n// Given a uint16 returns the corresponding uint32 integer where 0s are\n// interleaved between the original bits. (e.g., 1111... -> 01010101...).\nconst interlaceBitsX16 = (x16: number) =>\n\t(x8ToInterlacedX16[byte2(x16)] << 16) | x8ToInterlacedX16[byte3(x16)];\n\nconst r0ToMorton16 = (row: number) => (interlaceBitsX16(row) << 1) >>> 0;\nconst c0ToMorton16 = (col: number) => interlaceBitsX16(col) >>> 0;\n\n// Given a 2D uint16 coordinate returns the corresponding unt32 Morton coded\n// coordinate. (See https://en.wikipedia.org/wiki/Z-order_curve)\nconst r0c0ToMorton2x16 = (row: number, col: number) =>\n\t(r0ToMorton16(row) | c0ToMorton16(col)) >>> 0;\n\ntype RecurArrayHelper<T> = RecurArray<T> | T;\ntype RecurArray<T> = RecurArrayHelper<T>[];\n\n/** Undo JSON serialization's coercion of 'undefined' to null. */\n// eslint-disable-next-line @rushstack/no-new-null -- Private use of 'null' to preserve 'undefined'\nconst nullToUndefined = <T>(array: RecurArray<T | null>): RecurArray<T | undefined> =>\n\tarray.map((value) => {\n\t\treturn value === null ? undefined : Array.isArray(value) ? nullToUndefined(value) : value;\n\t});\n\ntype UA<T> = (T | undefined)[];\n\n/**\n * A sparse 4 billion x 4 billion array stored as 16x16 tiles.\n */\nexport class SparseArray2D<T>\n\timplements IMatrixReader<T | undefined>, IMatrixWriter<T | undefined>\n{\n\tconstructor(private readonly root: UA<UA<UA<UA<UA<T>>>>> = [undefined]) {}\n\n\tpublic readonly rowCount = 0xffffffff;\n\tpublic readonly colCount = 0xffffffff;\n\n\tpublic getCell(row: number, col: number): T | undefined {\n\t\tconst keyHi = r0c0ToMorton2x16(row >>> 16, col >>> 16);\n\t\tconst level0 = this.root[keyHi];\n\t\tif (level0 !== undefined) {\n\t\t\tconst keyLo = r0c0ToMorton2x16(row, col);\n\t\t\tconst level1 = level0[byte0(keyLo)];\n\t\t\tif (level1 !== undefined) {\n\t\t\t\tconst level2 = level1[byte1(keyLo)];\n\t\t\t\tif (level2 !== undefined) {\n\t\t\t\t\tconst level3 = level2[byte2(keyLo)];\n\t\t\t\t\tif (level3 !== undefined) {\n\t\t\t\t\t\treturn level3[byte3(keyLo)];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tpublic get matrixProducer() {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\treturn undefined as any;\n\t}\n\n\tpublic setCell(row: number, col: number, value: T | undefined) {\n\t\tconst keyHi = r0c0ToMorton2x16(row >>> 16, col >>> 16);\n\t\tconst keyLo = r0c0ToMorton2x16(row, col);\n\n\t\tconst level0 = this.getLevel(this.root, keyHi);\n\t\tconst level1 = this.getLevel(level0, byte0(keyLo));\n\t\tconst level2 = this.getLevel(level1, byte1(keyLo));\n\t\tconst level3 = this.getLevel(level2, byte2(keyLo));\n\t\tlevel3[byte3(keyLo)] = value;\n\t}\n\n\t/**\n\t * Invokes the given 'callback' for each key in a 16 x 16 tile at the indicated row.\n\t *\n\t * (Note that 'rowBits' is the appropriate byte from 'r0ToMorton16' for the current\n\t * level being traversed.)\n\t */\n\tprivate forEachKeyInRow(rowBits: number, callback: (key: number) => void) {\n\t\tfor (let col = 0; col < 16; col++) {\n\t\t\t// Perf: Potentially faster to replace 'c0ToMorton16()' with a short look up table?\n\t\t\tcallback((rowBits | c0ToMorton16(col)) >>> 0);\n\t\t}\n\t}\n\n\t/**\n\t * Invokes the given 'callback' for each key in a 16 x 16 tile at the indicated col.\n\t *\n\t * (Note that 'colBits' is the appropriate byte from 'c0ToMorton16' for the current\n\t * level being traversed.)\n\t */\n\tprivate forEachKeyInCol(col: number, callback: (key: number) => void) {\n\t\tfor (let row = 0; row < 16; row++) {\n\t\t\t// Perf: Potentially faster to replace 'r0ToMorton16()' with a short look up table?\n\t\t\tcallback((r0ToMorton16(row) | col) >>> 0);\n\t\t}\n\t}\n\n\t/**\n\t * Invokes the give 'callback' with the next 'level' array for each populated region\n\t * of the given row in the 'currentLevel'.\n\t *\n\t * (Note that 'rowBits' is the appropriate byte from 'r0ToMorton16' for the current\n\t * level being traversed.)\n\t */\n\tprivate forEachInRow<V extends UA<any>, U extends UA<V>>(\n\t\tcurrentLevel: U,\n\t\trowBits: number,\n\t\tcallback: (level: V) => void,\n\t) {\n\t\tthis.forEachKeyInRow(rowBits, (key) => {\n\t\t\tconst nextLevel = currentLevel[key];\n\t\t\tif (nextLevel !== undefined) {\n\t\t\t\tcallback(nextLevel);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Invokes the give 'callback' with the next 'level' array for each populated region\n\t * of the given col in the 'currentLevel'.\n\t *\n\t * (Note that 'colBits' is the appropriate byte from 'c0ToMorton16' for the current\n\t * level being traversed.)\n\t */\n\tprivate forEachInCol<V extends UA<any>, U extends UA<V>>(\n\t\tcurrentLevel: U,\n\t\tcolBits: number,\n\t\tcallback: (level: V) => void,\n\t) {\n\t\tthis.forEachKeyInCol(colBits, (key) => {\n\t\t\tconst nextLevel = currentLevel[key];\n\t\t\tif (nextLevel !== undefined) {\n\t\t\t\tcallback(nextLevel);\n\t\t\t}\n\t\t});\n\t}\n\n\t/** Clears the all cells contained within the specified span of rows. */\n\tpublic clearRows(rowStart: number, rowCount: number) {\n\t\tconst rowEnd = rowStart + rowCount;\n\t\tfor (let row = rowStart; row < rowEnd; row++) {\n\t\t\tconst rowHi = r0ToMorton16(row >>> 16);\n\n\t\t\t// The top level of tree is a 64k x 64k tile. We need to scan all 64k entries.\n\t\t\tfor (let colHi = 0; colHi < 0x10000; colHi++) {\n\t\t\t\tconst keyHi = (rowHi | c0ToMorton16(colHi)) >>> 0;\n\t\t\t\tconst level0 = this.root[keyHi];\n\t\t\t\tif (level0 !== undefined) {\n\t\t\t\t\t// The remainder of the tree is divided in 16 x 16 tiles.\n\t\t\t\t\tconst rowLo = r0ToMorton16(row);\n\t\t\t\t\tthis.forEachInRow(level0, byte0(rowLo), (level1) => {\n\t\t\t\t\t\tthis.forEachInRow(level1, byte1(rowLo), (level2) => {\n\t\t\t\t\t\t\tthis.forEachInRow(level2, byte2(rowLo), (level3) => {\n\t\t\t\t\t\t\t\tthis.forEachKeyInRow(byte3(rowLo), (key) => {\n\t\t\t\t\t\t\t\t\tlevel3[key] = undefined;\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Clears the all cells contained within the specifed span of cols. */\n\tpublic clearCols(colStart: number, colCount: number) {\n\t\tconst colEnd = colStart + colCount;\n\t\tfor (let col = colStart; col < colEnd; col++) {\n\t\t\tconst colHi = c0ToMorton16(col >>> 16);\n\n\t\t\t// The top level of tree is a 64k x 64k tile. We need to scan all 64k entries.\n\t\t\tfor (let rowHi = 0; rowHi < 0x10000; rowHi++) {\n\t\t\t\tconst keyHi = (colHi | r0ToMorton16(rowHi)) >>> 0;\n\t\t\t\tconst level0 = this.root[keyHi];\n\t\t\t\tif (level0 !== undefined) {\n\t\t\t\t\t// The remainder of the tree is divided in 16 x 16 tiles.\n\t\t\t\t\tconst colLo = c0ToMorton16(col);\n\t\t\t\t\tthis.forEachInCol(level0, byte0(colLo), (level1) => {\n\t\t\t\t\t\tthis.forEachInCol(level1, byte1(colLo), (level2) => {\n\t\t\t\t\t\t\tthis.forEachInCol(level2, byte2(colLo), (level3) => {\n\t\t\t\t\t\t\t\tthis.forEachKeyInCol(byte3(colLo), (key) => {\n\t\t\t\t\t\t\t\t\tlevel3[key] = undefined;\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate getLevel<T>(parent: UA<UA<T>>, subKey: number) {\n\t\tconst level = parent[subKey];\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\treturn level ?? (parent[subKey] = new Array(256).fill(undefined));\n\t}\n\n\tpublic snapshot() {\n\t\treturn this.root;\n\t}\n\n\tpublic static load<T>(data: RecurArray<T>) {\n\t\treturn new SparseArray2D<T>(nullToUndefined<T>(data) as SparseArray2D<T>[\"root\"]);\n\t}\n}\n"]}
1
+ {"version":3,"file":"sparsearray2d.js","sourceRoot":"","sources":["../src/sparsearray2d.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable no-bitwise */\n\nimport { IMatrixReader, IMatrixWriter } from \"@tiny-calc/nano\";\n\n// Build a lookup table that maps a uint8 to the corresponding uint16 where 0s\n// are interleaved between the original bits. (e.g., 1111... -> 01010101...).\n//\n// (Lookup table ~17% faster than inlining the bit-twiddling on Node v12 x64)\n// (Array<T> ~2% faster than typed array on Node v12 x64)\nconst x8ToInterlacedX16 = new Array(256).fill(0).map((value, i) => {\n\tlet j = i;\n\tj = (j | (j << 4)) & 0x0f0f; // .... 7654 .... 3210\n\tj = (j | (j << 2)) & 0x3333; // ..76 ..54 ..32 ..10\n\tj = (j | (j << 1)) & 0x5555; // .7.6 .5.4 .3.2 .1.0\n\treturn j;\n});\n\n// Selects individual bytes from a given 32b integer. The left shift are used to\n// clear upper bits (faster than using masks on Node 10 x64).\nconst byte0 = (x32: number) => x32 >>> 24;\nconst byte1 = (x32: number) => (x32 << 8) >>> 24;\nconst byte2 = (x32: number) => (x32 << 16) >>> 24;\nconst byte3 = (x32: number) => (x32 << 24) >>> 24;\n\n// Given a uint16 returns the corresponding uint32 integer where 0s are\n// interleaved between the original bits. (e.g., 1111... -> 01010101...).\nconst interlaceBitsX16 = (x16: number) =>\n\t(x8ToInterlacedX16[byte2(x16)] << 16) | x8ToInterlacedX16[byte3(x16)];\n\nconst r0ToMorton16 = (row: number) => (interlaceBitsX16(row) << 1) >>> 0;\nconst c0ToMorton16 = (col: number) => interlaceBitsX16(col) >>> 0;\n\n// Given a 2D uint16 coordinate returns the corresponding unt32 Morton coded\n// coordinate. (See https://en.wikipedia.org/wiki/Z-order_curve)\nconst r0c0ToMorton2x16 = (row: number, col: number) =>\n\t(r0ToMorton16(row) | c0ToMorton16(col)) >>> 0;\n\ntype RecurArrayHelper<T> = RecurArray<T> | T;\ntype RecurArray<T> = RecurArrayHelper<T>[];\n\n/** Undo JSON serialization's coercion of 'undefined' to null. */\n// eslint-disable-next-line @rushstack/no-new-null -- Private use of 'null' to preserve 'undefined'\nconst nullToUndefined = <T>(array: RecurArray<T | null>): RecurArray<T | undefined> =>\n\tarray.map((value) => {\n\t\treturn value === null ? undefined : Array.isArray(value) ? nullToUndefined(value) : value;\n\t});\n\ntype UA<T> = (T | undefined)[];\n\n/**\n * A sparse 4 billion x 4 billion array stored as 16x16 tiles.\n */\nexport class SparseArray2D<T>\n\timplements IMatrixReader<T | undefined>, IMatrixWriter<T | undefined>\n{\n\tconstructor(private readonly root: UA<UA<UA<UA<UA<T>>>>> = [undefined]) {}\n\n\tpublic readonly rowCount = 0xffffffff;\n\tpublic readonly colCount = 0xffffffff;\n\n\tpublic getCell(row: number, col: number): T | undefined {\n\t\tconst keyHi = r0c0ToMorton2x16(row >>> 16, col >>> 16);\n\t\tconst level0 = this.root[keyHi];\n\t\tif (level0 !== undefined) {\n\t\t\tconst keyLo = r0c0ToMorton2x16(row, col);\n\t\t\tconst level1 = level0[byte0(keyLo)];\n\t\t\tif (level1 !== undefined) {\n\t\t\t\tconst level2 = level1[byte1(keyLo)];\n\t\t\t\tif (level2 !== undefined) {\n\t\t\t\t\tconst level3 = level2[byte2(keyLo)];\n\t\t\t\t\tif (level3 !== undefined) {\n\t\t\t\t\t\treturn level3[byte3(keyLo)];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tpublic get matrixProducer() {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\treturn undefined as any;\n\t}\n\n\tpublic setCell(row: number, col: number, value: T | undefined) {\n\t\tconst keyHi = r0c0ToMorton2x16(row >>> 16, col >>> 16);\n\t\tconst keyLo = r0c0ToMorton2x16(row, col);\n\n\t\tconst level0 = this.getLevel(this.root, keyHi);\n\t\tconst level1 = this.getLevel(level0, byte0(keyLo));\n\t\tconst level2 = this.getLevel(level1, byte1(keyLo));\n\t\tconst level3 = this.getLevel(level2, byte2(keyLo));\n\t\tlevel3[byte3(keyLo)] = value;\n\t}\n\n\t/**\n\t * Invokes the given 'callback' for each key in a 16 x 16 tile at the indicated row.\n\t *\n\t * (Note that 'rowBits' is the appropriate byte from 'r0ToMorton16' for the current\n\t * level being traversed.)\n\t */\n\tprivate forEachKeyInRow(rowBits: number, callback: (key: number) => void) {\n\t\tfor (let col = 0; col < 16; col++) {\n\t\t\t// Perf: Potentially faster to replace 'c0ToMorton16()' with a short look up table?\n\t\t\tcallback((rowBits | c0ToMorton16(col)) >>> 0);\n\t\t}\n\t}\n\n\t/**\n\t * Invokes the given 'callback' for each key in a 16 x 16 tile at the indicated col.\n\t *\n\t * (Note that 'colBits' is the appropriate byte from 'c0ToMorton16' for the current\n\t * level being traversed.)\n\t */\n\tprivate forEachKeyInCol(col: number, callback: (key: number) => void) {\n\t\tfor (let row = 0; row < 16; row++) {\n\t\t\t// Perf: Potentially faster to replace 'r0ToMorton16()' with a short look up table?\n\t\t\tcallback((r0ToMorton16(row) | col) >>> 0);\n\t\t}\n\t}\n\n\t/**\n\t * Invokes the give 'callback' with the next 'level' array for each populated region\n\t * of the given row in the 'currentLevel'.\n\t *\n\t * (Note that 'rowBits' is the appropriate byte from 'r0ToMorton16' for the current\n\t * level being traversed.)\n\t */\n\tprivate forEachInRow<V extends UA<any>, U extends UA<V>>(\n\t\tcurrentLevel: U,\n\t\trowBits: number,\n\t\tcallback: (level: V) => void,\n\t) {\n\t\tthis.forEachKeyInRow(rowBits, (key) => {\n\t\t\tconst nextLevel = currentLevel[key];\n\t\t\tif (nextLevel !== undefined) {\n\t\t\t\tcallback(nextLevel);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Invokes the give 'callback' with the next 'level' array for each populated region\n\t * of the given col in the 'currentLevel'.\n\t *\n\t * (Note that 'colBits' is the appropriate byte from 'c0ToMorton16' for the current\n\t * level being traversed.)\n\t */\n\tprivate forEachInCol<V extends UA<any>, U extends UA<V>>(\n\t\tcurrentLevel: U,\n\t\tcolBits: number,\n\t\tcallback: (level: V) => void,\n\t) {\n\t\tthis.forEachKeyInCol(colBits, (key) => {\n\t\t\tconst nextLevel = currentLevel[key];\n\t\t\tif (nextLevel !== undefined) {\n\t\t\t\tcallback(nextLevel);\n\t\t\t}\n\t\t});\n\t}\n\n\t/** Clears the all cells contained within the specified span of rows. */\n\tpublic clearRows(rowStart: number, rowCount: number) {\n\t\tconst rowEnd = rowStart + rowCount;\n\t\tfor (let row = rowStart; row < rowEnd; row++) {\n\t\t\tconst rowHi = r0ToMorton16(row >>> 16);\n\n\t\t\t// The top level of tree is a 64k x 64k tile. We need to scan all 64k entries.\n\t\t\tfor (let colHi = 0; colHi < 0x10000; colHi++) {\n\t\t\t\tconst keyHi = (rowHi | c0ToMorton16(colHi)) >>> 0;\n\t\t\t\tconst level0 = this.root[keyHi];\n\t\t\t\tif (level0 !== undefined) {\n\t\t\t\t\t// The remainder of the tree is divided in 16 x 16 tiles.\n\t\t\t\t\tconst rowLo = r0ToMorton16(row);\n\t\t\t\t\tthis.forEachInRow(level0, byte0(rowLo), (level1) => {\n\t\t\t\t\t\tthis.forEachInRow(level1, byte1(rowLo), (level2) => {\n\t\t\t\t\t\t\tthis.forEachInRow(level2, byte2(rowLo), (level3) => {\n\t\t\t\t\t\t\t\tthis.forEachKeyInRow(byte3(rowLo), (key) => {\n\t\t\t\t\t\t\t\t\tlevel3[key] = undefined;\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Clears the all cells contained within the specifed span of cols. */\n\tpublic clearCols(colStart: number, colCount: number) {\n\t\tconst colEnd = colStart + colCount;\n\t\tfor (let col = colStart; col < colEnd; col++) {\n\t\t\tconst colHi = c0ToMorton16(col >>> 16);\n\n\t\t\t// The top level of tree is a 64k x 64k tile. We need to scan all 64k entries.\n\t\t\tfor (let rowHi = 0; rowHi < 0x10000; rowHi++) {\n\t\t\t\tconst keyHi = (colHi | r0ToMorton16(rowHi)) >>> 0;\n\t\t\t\tconst level0 = this.root[keyHi];\n\t\t\t\tif (level0 !== undefined) {\n\t\t\t\t\t// The remainder of the tree is divided in 16 x 16 tiles.\n\t\t\t\t\tconst colLo = c0ToMorton16(col);\n\t\t\t\t\tthis.forEachInCol(level0, byte0(colLo), (level1) => {\n\t\t\t\t\t\tthis.forEachInCol(level1, byte1(colLo), (level2) => {\n\t\t\t\t\t\t\tthis.forEachInCol(level2, byte2(colLo), (level3) => {\n\t\t\t\t\t\t\t\tthis.forEachKeyInCol(byte3(colLo), (key) => {\n\t\t\t\t\t\t\t\t\tlevel3[key] = undefined;\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate getLevel<T>(parent: UA<UA<T>>, subKey: number) {\n\t\tconst level = parent[subKey];\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\treturn level ?? (parent[subKey] = new Array(256).fill(undefined));\n\t}\n\n\tpublic snapshot() {\n\t\treturn this.root;\n\t}\n\n\tpublic static load<T>(data: RecurArray<T>) {\n\t\treturn new SparseArray2D<T>(nullToUndefined<T>(data) as SparseArray2D<T>[\"root\"]);\n\t}\n}\n"]}
@@ -6,14 +6,6 @@ import { assert } from "@fluidframework/core-utils/internal";
6
6
  import { MergeTreeDeltaType, TrackingGroup, appendToMergeTreeDeltaRevertibles, discardMergeTreeDeltaRevertible, revertMergeTreeDeltaRevertibles, } from "@fluidframework/merge-tree/internal";
7
7
  import { isHandleValid } from "./handletable.js";
8
8
  export class VectorUndoProvider {
9
- manager;
10
- driver;
11
- // 'currentGroup' and 'currentOp' are used while applying an IRevertable.revert() to coalesce
12
- // the recorded into a single IRevertable / tracking group as they move between the undo <->
13
- // redo stacks.
14
- currentGroup;
15
- currentOp;
16
- currentRemoveTrackingGroup;
17
9
  constructor(manager, driver) {
18
10
  this.manager = manager;
19
11
  this.driver = driver;
@@ -58,8 +50,8 @@ export class VectorUndoProvider {
58
50
  // another revertible until `IRevertable.revert()` finishes the current op and clears this
59
51
  // field.
60
52
  if (this.currentGroup !== undefined) {
61
- this.currentOp ??= deltaArgs.operation;
62
- this.currentRemoveTrackingGroup ??= removeTrackingGroup;
53
+ this.currentOp ?? (this.currentOp = deltaArgs.operation);
54
+ this.currentRemoveTrackingGroup ?? (this.currentRemoveTrackingGroup = removeTrackingGroup);
63
55
  }
64
56
  }
65
57
  }
@@ -104,10 +96,6 @@ export class VectorUndoProvider {
104
96
  }
105
97
  }
106
98
  export class MatrixUndoProvider {
107
- consumer;
108
- matrix;
109
- rows;
110
- cols;
111
99
  constructor(consumer, matrix, rows, cols) {
112
100
  this.consumer = consumer;
113
101
  this.matrix = matrix;
@@ -1 +1 @@
1
- {"version":3,"file":"undoprovider.js","sourceRoot":"","sources":["../src/undoprovider.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport {\n\tIMergeTreeDeltaCallbackArgs,\n\tITrackingGroup,\n\tMergeTreeDeltaRevertible,\n\tMergeTreeDeltaType,\n\tMergeTreeRevertibleDriver,\n\tTrackingGroup,\n\tappendToMergeTreeDeltaRevertibles,\n\tdiscardMergeTreeDeltaRevertible,\n\trevertMergeTreeDeltaRevertibles,\n} from \"@fluidframework/merge-tree/internal\";\n\nimport { Handle, isHandleValid } from \"./handletable.js\";\nimport { SharedMatrix } from \"./matrix.js\";\nimport { MatrixItem } from \"./ops.js\";\nimport { PermutationSegment, PermutationVector } from \"./permutationvector.js\";\nimport { IUndoConsumer } from \"./types.js\";\n\nexport class VectorUndoProvider {\n\t// 'currentGroup' and 'currentOp' are used while applying an IRevertable.revert() to coalesce\n\t// the recorded into a single IRevertable / tracking group as they move between the undo <->\n\t// redo stacks.\n\tprivate currentGroup?: MergeTreeDeltaRevertible[];\n\tprivate currentOp?: MergeTreeDeltaType;\n\tprivate currentRemoveTrackingGroup?: TrackingGroup;\n\n\tconstructor(\n\t\tprivate readonly manager: IUndoConsumer,\n\t\tprivate readonly driver: MergeTreeRevertibleDriver,\n\t) {}\n\n\tpublic record(deltaArgs: IMergeTreeDeltaCallbackArgs) {\n\t\tif (deltaArgs.deltaSegments.length > 0) {\n\t\t\t// If we are in the process of reverting, the `IRevertible.revert()` will provide the tracking\n\t\t\t// group so that we can preserve the original segment ranges as a single op/group as we move\n\t\t\t// ops between the undo <-> redo stacks.\n\t\t\tconst revertibles: MergeTreeDeltaRevertible[] = this.currentGroup ?? [];\n\t\t\tappendToMergeTreeDeltaRevertibles(deltaArgs, revertibles);\n\n\t\t\t// For SharedMatrix, each IRevertibles always holds a single row/col operation.\n\t\t\t// Therefore, 'currentOp' must either be undefined or equal to the current op.\n\t\t\tassert(\n\t\t\t\tthis.currentOp === undefined || this.currentOp === deltaArgs.operation,\n\t\t\t\t0x02a /* \"On vector undo, unexpected 'currentOp' type/state!\" */,\n\t\t\t);\n\t\t\tlet removeTrackingGroup: TrackingGroup | undefined;\n\t\t\tif (deltaArgs.operation === MergeTreeDeltaType.REMOVE) {\n\t\t\t\t// for removed segment we need a tracking group.\n\t\t\t\t// this is for a few reason:\n\t\t\t\t// 1. the handle for the row/column on the removed segment is still allocated,\n\t\t\t\t//\t\tand needs to be in order to process unacked ops sent before the remove.\n\t\t\t\t// 2. handles are freed on unlink(zamboni), but that also clears the row/column data.\n\t\t\t\t//\t\twhich we don't want to happen, so we can re-insert the cells when the row/col comes back.\n\t\t\t\t//\t\tthe tracking group prevents unlink.\n\t\t\t\t// 3. when we re-insert we need to find the old segment and clear their handles\n\t\t\t\t//\t\tso the new segment takes them over. there is no efficient look-up for this.\n\t\t\t\t//\t\tthe tracking group provides one.\n\t\t\t\tconst trackingGroup = (removeTrackingGroup =\n\t\t\t\t\tthis.currentRemoveTrackingGroup ?? new TrackingGroup());\n\t\t\t\tdeltaArgs.deltaSegments.forEach((d) =>\n\t\t\t\t\td.segment.trackingCollection.link(trackingGroup),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tswitch (deltaArgs.operation) {\n\t\t\t\tcase MergeTreeDeltaType.REMOVE:\n\t\t\t\tcase MergeTreeDeltaType.INSERT:\n\t\t\t\t\tif (this.currentOp !== deltaArgs.operation) {\n\t\t\t\t\t\tthis.pushRevertible(revertibles, removeTrackingGroup);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Error(\"operation type not revertible\");\n\t\t\t}\n\n\t\t\t// If we are in the process of reverting, set 'currentOp' to remind ourselves not to push\n\t\t\t// another revertible until `IRevertable.revert()` finishes the current op and clears this\n\t\t\t// field.\n\t\t\tif (this.currentGroup !== undefined) {\n\t\t\t\tthis.currentOp ??= deltaArgs.operation;\n\t\t\t\tthis.currentRemoveTrackingGroup ??= removeTrackingGroup;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate pushRevertible(\n\t\trevertibles: MergeTreeDeltaRevertible[],\n\t\tremovedTrackingGroup: ITrackingGroup | undefined,\n\t) {\n\t\tconst reverter = {\n\t\t\trevert: () => {\n\t\t\t\tassert(\n\t\t\t\t\tthis.currentGroup === undefined && this.currentOp === undefined,\n\t\t\t\t\t0x02b /* \"Must not nest calls to IRevertible.revert()\" */,\n\t\t\t\t);\n\n\t\t\t\tthis.currentGroup = [];\n\n\t\t\t\ttry {\n\t\t\t\t\tif (removedTrackingGroup !== undefined) {\n\t\t\t\t\t\twhile (removedTrackingGroup.size > 0) {\n\t\t\t\t\t\t\tconst tracked = removedTrackingGroup.tracked[0];\n\t\t\t\t\t\t\tremovedTrackingGroup.unlink(tracked);\n\t\t\t\t\t\t\t// if there are groups tracked, this in a revert of a remove.\n\t\t\t\t\t\t\t// this means we are about to re-insert the row/column\n\t\t\t\t\t\t\t// with the same handle. We reuse the handle so the row/columns cells\n\t\t\t\t\t\t\t// get re-inserted too.\n\t\t\t\t\t\t\t// since a new segment will have the handle, we need to\n\t\t\t\t\t\t\t// remove it from the removed segment which was tracked\n\t\t\t\t\t\t\t(tracked as PermutationSegment).reset();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\trevertMergeTreeDeltaRevertibles(this.driver, revertibles);\n\t\t\t\t} finally {\n\t\t\t\t\tthis.currentOp = undefined;\n\t\t\t\t\tthis.currentGroup = undefined;\n\t\t\t\t\tthis.currentRemoveTrackingGroup = undefined;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdiscard: () => {\n\t\t\t\tif (removedTrackingGroup !== undefined) {\n\t\t\t\t\twhile (removedTrackingGroup.size > 0) {\n\t\t\t\t\t\tremovedTrackingGroup.unlink(removedTrackingGroup.tracked[0]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdiscardMergeTreeDeltaRevertible(revertibles);\n\t\t\t},\n\t\t};\n\n\t\tthis.manager.pushToCurrentOperation(reverter);\n\n\t\treturn reverter;\n\t}\n}\n\nexport class MatrixUndoProvider<T> {\n\tconstructor(\n\t\tprivate readonly consumer: IUndoConsumer,\n\t\tprivate readonly matrix: SharedMatrix<T>,\n\t\tprivate readonly rows: PermutationVector,\n\t\tprivate readonly cols: PermutationVector,\n\t) {\n\t\trows.undo = new VectorUndoProvider(consumer, {\n\t\t\tannotateRange() {\n\t\t\t\tthrow new Error(\"not implemented\");\n\t\t\t},\n\t\t\tinsertFromSpec(pos, spec) {\n\t\t\t\tmatrix._undoRemoveRows(pos, spec);\n\t\t\t},\n\t\t\tremoveRange(start, end) {\n\t\t\t\tmatrix.removeRows(start, end - start);\n\t\t\t},\n\t\t});\n\t\tcols.undo = new VectorUndoProvider(consumer, {\n\t\t\tannotateRange() {\n\t\t\t\tthrow new Error(\"not implemented\");\n\t\t\t},\n\t\t\tinsertFromSpec(pos, spec) {\n\t\t\t\tmatrix._undoRemoveCols(pos, spec);\n\t\t\t},\n\t\t\tremoveRange(start, end) {\n\t\t\t\tmatrix.removeCols(start, end - start);\n\t\t\t},\n\t\t});\n\t}\n\n\tcellSet(rowHandle: Handle, colHandle: Handle, oldValue: MatrixItem<T>) {\n\t\tassert(\n\t\t\tisHandleValid(rowHandle) && isHandleValid(colHandle),\n\t\t\t0x02c /* \"On cellSet(), invalid row and/or column handles!\" */,\n\t\t);\n\n\t\tif (this.consumer !== undefined) {\n\t\t\tthis.consumer.pushToCurrentOperation({\n\t\t\t\trevert: () => {\n\t\t\t\t\tconst row = this.rows.handleToPosition(rowHandle);\n\t\t\t\t\tconst col = this.cols.handleToPosition(colHandle);\n\t\t\t\t\t// if the row/column no longer exists, we cannot set the cell\n\t\t\t\t\tif (row < this.matrix.rowCount && col < this.matrix.colCount) {\n\t\t\t\t\t\tthis.matrix.setCell(row, col, oldValue);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tdiscard: () => {},\n\t\t\t});\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"undoprovider.js","sourceRoot":"","sources":["../src/undoprovider.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport {\n\tIMergeTreeDeltaCallbackArgs,\n\tITrackingGroup,\n\tMergeTreeDeltaRevertible,\n\tMergeTreeDeltaType,\n\tMergeTreeRevertibleDriver,\n\tTrackingGroup,\n\tappendToMergeTreeDeltaRevertibles,\n\tdiscardMergeTreeDeltaRevertible,\n\trevertMergeTreeDeltaRevertibles,\n} from \"@fluidframework/merge-tree/internal\";\n\nimport { Handle, isHandleValid } from \"./handletable.js\";\nimport { SharedMatrix } from \"./matrix.js\";\nimport { MatrixItem } from \"./ops.js\";\nimport { PermutationSegment, PermutationVector } from \"./permutationvector.js\";\nimport { IUndoConsumer } from \"./types.js\";\n\nexport class VectorUndoProvider {\n\t// 'currentGroup' and 'currentOp' are used while applying an IRevertable.revert() to coalesce\n\t// the recorded into a single IRevertable / tracking group as they move between the undo <->\n\t// redo stacks.\n\tprivate currentGroup?: MergeTreeDeltaRevertible[];\n\tprivate currentOp?: MergeTreeDeltaType;\n\tprivate currentRemoveTrackingGroup?: TrackingGroup;\n\n\tconstructor(\n\t\tprivate readonly manager: IUndoConsumer,\n\t\tprivate readonly driver: MergeTreeRevertibleDriver,\n\t) {}\n\n\tpublic record(deltaArgs: IMergeTreeDeltaCallbackArgs) {\n\t\tif (deltaArgs.deltaSegments.length > 0) {\n\t\t\t// If we are in the process of reverting, the `IRevertible.revert()` will provide the tracking\n\t\t\t// group so that we can preserve the original segment ranges as a single op/group as we move\n\t\t\t// ops between the undo <-> redo stacks.\n\t\t\tconst revertibles: MergeTreeDeltaRevertible[] = this.currentGroup ?? [];\n\t\t\tappendToMergeTreeDeltaRevertibles(deltaArgs, revertibles);\n\n\t\t\t// For SharedMatrix, each IRevertibles always holds a single row/col operation.\n\t\t\t// Therefore, 'currentOp' must either be undefined or equal to the current op.\n\t\t\tassert(\n\t\t\t\tthis.currentOp === undefined || this.currentOp === deltaArgs.operation,\n\t\t\t\t0x02a /* \"On vector undo, unexpected 'currentOp' type/state!\" */,\n\t\t\t);\n\t\t\tlet removeTrackingGroup: TrackingGroup | undefined;\n\t\t\tif (deltaArgs.operation === MergeTreeDeltaType.REMOVE) {\n\t\t\t\t// for removed segment we need a tracking group.\n\t\t\t\t// this is for a few reason:\n\t\t\t\t// 1. the handle for the row/column on the removed segment is still allocated,\n\t\t\t\t//\t\tand needs to be in order to process unacked ops sent before the remove.\n\t\t\t\t// 2. handles are freed on unlink(zamboni), but that also clears the row/column data.\n\t\t\t\t//\t\twhich we don't want to happen, so we can re-insert the cells when the row/col comes back.\n\t\t\t\t//\t\tthe tracking group prevents unlink.\n\t\t\t\t// 3. when we re-insert we need to find the old segment and clear their handles\n\t\t\t\t//\t\tso the new segment takes them over. there is no efficient look-up for this.\n\t\t\t\t//\t\tthe tracking group provides one.\n\t\t\t\tconst trackingGroup = (removeTrackingGroup =\n\t\t\t\t\tthis.currentRemoveTrackingGroup ?? new TrackingGroup());\n\t\t\t\tdeltaArgs.deltaSegments.forEach((d) =>\n\t\t\t\t\td.segment.trackingCollection.link(trackingGroup),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tswitch (deltaArgs.operation) {\n\t\t\t\tcase MergeTreeDeltaType.REMOVE:\n\t\t\t\tcase MergeTreeDeltaType.INSERT:\n\t\t\t\t\tif (this.currentOp !== deltaArgs.operation) {\n\t\t\t\t\t\tthis.pushRevertible(revertibles, removeTrackingGroup);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Error(\"operation type not revertible\");\n\t\t\t}\n\n\t\t\t// If we are in the process of reverting, set 'currentOp' to remind ourselves not to push\n\t\t\t// another revertible until `IRevertable.revert()` finishes the current op and clears this\n\t\t\t// field.\n\t\t\tif (this.currentGroup !== undefined) {\n\t\t\t\tthis.currentOp ??= deltaArgs.operation;\n\t\t\t\tthis.currentRemoveTrackingGroup ??= removeTrackingGroup;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate pushRevertible(\n\t\trevertibles: MergeTreeDeltaRevertible[],\n\t\tremovedTrackingGroup: ITrackingGroup | undefined,\n\t) {\n\t\tconst reverter = {\n\t\t\trevert: () => {\n\t\t\t\tassert(\n\t\t\t\t\tthis.currentGroup === undefined && this.currentOp === undefined,\n\t\t\t\t\t0x02b /* \"Must not nest calls to IRevertible.revert()\" */,\n\t\t\t\t);\n\n\t\t\t\tthis.currentGroup = [];\n\n\t\t\t\ttry {\n\t\t\t\t\tif (removedTrackingGroup !== undefined) {\n\t\t\t\t\t\twhile (removedTrackingGroup.size > 0) {\n\t\t\t\t\t\t\tconst tracked = removedTrackingGroup.tracked[0];\n\t\t\t\t\t\t\tremovedTrackingGroup.unlink(tracked);\n\t\t\t\t\t\t\t// if there are groups tracked, this in a revert of a remove.\n\t\t\t\t\t\t\t// this means we are about to re-insert the row/column\n\t\t\t\t\t\t\t// with the same handle. We reuse the handle so the row/columns cells\n\t\t\t\t\t\t\t// get re-inserted too.\n\t\t\t\t\t\t\t// since a new segment will have the handle, we need to\n\t\t\t\t\t\t\t// remove it from the removed segment which was tracked\n\t\t\t\t\t\t\t(tracked as PermutationSegment).reset();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\trevertMergeTreeDeltaRevertibles(this.driver, revertibles);\n\t\t\t\t} finally {\n\t\t\t\t\tthis.currentOp = undefined;\n\t\t\t\t\tthis.currentGroup = undefined;\n\t\t\t\t\tthis.currentRemoveTrackingGroup = undefined;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdiscard: () => {\n\t\t\t\tif (removedTrackingGroup !== undefined) {\n\t\t\t\t\twhile (removedTrackingGroup.size > 0) {\n\t\t\t\t\t\tremovedTrackingGroup.unlink(removedTrackingGroup.tracked[0]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdiscardMergeTreeDeltaRevertible(revertibles);\n\t\t\t},\n\t\t};\n\n\t\tthis.manager.pushToCurrentOperation(reverter);\n\n\t\treturn reverter;\n\t}\n}\n\nexport class MatrixUndoProvider<T> {\n\tconstructor(\n\t\tprivate readonly consumer: IUndoConsumer,\n\t\tprivate readonly matrix: SharedMatrix<T>,\n\t\tprivate readonly rows: PermutationVector,\n\t\tprivate readonly cols: PermutationVector,\n\t) {\n\t\trows.undo = new VectorUndoProvider(consumer, {\n\t\t\tannotateRange() {\n\t\t\t\tthrow new Error(\"not implemented\");\n\t\t\t},\n\t\t\tinsertFromSpec(pos, spec) {\n\t\t\t\tmatrix._undoRemoveRows(pos, spec);\n\t\t\t},\n\t\t\tremoveRange(start, end) {\n\t\t\t\tmatrix.removeRows(start, end - start);\n\t\t\t},\n\t\t});\n\t\tcols.undo = new VectorUndoProvider(consumer, {\n\t\t\tannotateRange() {\n\t\t\t\tthrow new Error(\"not implemented\");\n\t\t\t},\n\t\t\tinsertFromSpec(pos, spec) {\n\t\t\t\tmatrix._undoRemoveCols(pos, spec);\n\t\t\t},\n\t\t\tremoveRange(start, end) {\n\t\t\t\tmatrix.removeCols(start, end - start);\n\t\t\t},\n\t\t});\n\t}\n\n\tcellSet(rowHandle: Handle, colHandle: Handle, oldValue: MatrixItem<T>) {\n\t\tassert(\n\t\t\tisHandleValid(rowHandle) && isHandleValid(colHandle),\n\t\t\t0x02c /* \"On cellSet(), invalid row and/or column handles!\" */,\n\t\t);\n\n\t\tif (this.consumer !== undefined) {\n\t\t\tthis.consumer.pushToCurrentOperation({\n\t\t\t\trevert: () => {\n\t\t\t\t\tconst row = this.rows.handleToPosition(rowHandle);\n\t\t\t\t\tconst col = this.cols.handleToPosition(colHandle);\n\t\t\t\t\t// if the row/column no longer exists, we cannot set the cell\n\t\t\t\t\tif (row < this.matrix.rowCount && col < this.matrix.colCount) {\n\t\t\t\t\t\tthis.matrix.setCell(row, col, oldValue);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tdiscard: () => {},\n\t\t\t});\n\t\t}\n\t}\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/matrix",
3
- "version": "2.0.0-dev-rc.5.0.0.271045",
3
+ "version": "2.0.0-dev-rc.5.0.0.271717",
4
4
  "description": "Distributed matrix",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -63,17 +63,17 @@
63
63
  "temp-directory": "nyc/.nyc_output"
64
64
  },
65
65
  "dependencies": {
66
- "@fluid-internal/client-utils": "2.0.0-dev-rc.5.0.0.271045",
67
- "@fluidframework/core-interfaces": "2.0.0-dev-rc.5.0.0.271045",
68
- "@fluidframework/core-utils": "2.0.0-dev-rc.5.0.0.271045",
69
- "@fluidframework/datastore-definitions": "2.0.0-dev-rc.5.0.0.271045",
70
- "@fluidframework/driver-definitions": "2.0.0-dev-rc.5.0.0.271045",
71
- "@fluidframework/driver-utils": "2.0.0-dev-rc.5.0.0.271045",
72
- "@fluidframework/merge-tree": "2.0.0-dev-rc.5.0.0.271045",
73
- "@fluidframework/runtime-definitions": "2.0.0-dev-rc.5.0.0.271045",
74
- "@fluidframework/runtime-utils": "2.0.0-dev-rc.5.0.0.271045",
75
- "@fluidframework/shared-object-base": "2.0.0-dev-rc.5.0.0.271045",
76
- "@fluidframework/telemetry-utils": "2.0.0-dev-rc.5.0.0.271045",
66
+ "@fluid-internal/client-utils": "2.0.0-dev-rc.5.0.0.271717",
67
+ "@fluidframework/core-interfaces": "2.0.0-dev-rc.5.0.0.271717",
68
+ "@fluidframework/core-utils": "2.0.0-dev-rc.5.0.0.271717",
69
+ "@fluidframework/datastore-definitions": "2.0.0-dev-rc.5.0.0.271717",
70
+ "@fluidframework/driver-definitions": "2.0.0-dev-rc.5.0.0.271717",
71
+ "@fluidframework/driver-utils": "2.0.0-dev-rc.5.0.0.271717",
72
+ "@fluidframework/merge-tree": "2.0.0-dev-rc.5.0.0.271717",
73
+ "@fluidframework/runtime-definitions": "2.0.0-dev-rc.5.0.0.271717",
74
+ "@fluidframework/runtime-utils": "2.0.0-dev-rc.5.0.0.271717",
75
+ "@fluidframework/shared-object-base": "2.0.0-dev-rc.5.0.0.271717",
76
+ "@fluidframework/telemetry-utils": "2.0.0-dev-rc.5.0.0.271717",
77
77
  "@tiny-calc/nano": "0.0.0-alpha.5",
78
78
  "double-ended-queue": "^2.1.0-0",
79
79
  "tslib": "^1.10.0"
@@ -81,17 +81,17 @@
81
81
  "devDependencies": {
82
82
  "@arethetypeswrong/cli": "^0.15.2",
83
83
  "@biomejs/biome": "^1.7.3",
84
- "@fluid-internal/mocha-test-setup": "2.0.0-dev-rc.5.0.0.271045",
85
- "@fluid-private/stochastic-test-utils": "2.0.0-dev-rc.5.0.0.271045",
86
- "@fluid-private/test-dds-utils": "2.0.0-dev-rc.5.0.0.271045",
84
+ "@fluid-internal/mocha-test-setup": "2.0.0-dev-rc.5.0.0.271717",
85
+ "@fluid-private/stochastic-test-utils": "2.0.0-dev-rc.5.0.0.271717",
86
+ "@fluid-private/test-dds-utils": "2.0.0-dev-rc.5.0.0.271717",
87
87
  "@fluid-tools/benchmark": "^0.48.0",
88
88
  "@fluid-tools/build-cli": "^0.39.0",
89
89
  "@fluidframework/build-common": "^2.0.3",
90
90
  "@fluidframework/build-tools": "^0.39.0",
91
- "@fluidframework/container-definitions": "2.0.0-dev-rc.5.0.0.271045",
91
+ "@fluidframework/container-definitions": "2.0.0-dev-rc.5.0.0.271717",
92
92
  "@fluidframework/eslint-config-fluid": "^5.3.0",
93
93
  "@fluidframework/matrix-previous": "npm:@fluidframework/matrix@2.0.0-rc.4.0.0",
94
- "@fluidframework/test-runtime-utils": "2.0.0-dev-rc.5.0.0.271045",
94
+ "@fluidframework/test-runtime-utils": "2.0.0-dev-rc.5.0.0.271717",
95
95
  "@microsoft/api-extractor": "^7.45.1",
96
96
  "@tiny-calc/micro": "0.0.0-alpha.5",
97
97
  "@types/double-ended-queue": "^2.1.0",
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/matrix";
9
- export const pkgVersion = "2.0.0-dev-rc.5.0.0.271045";
9
+ export const pkgVersion = "2.0.0-dev-rc.5.0.0.271717";