@fluidframework/map 2.43.0 → 2.50.0
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.
- package/CHANGELOG.md +4 -0
- package/dist/map.js +1 -1
- package/dist/map.js.map +1 -1
- package/dist/mapKernel.d.ts +7 -3
- package/dist/mapKernel.d.ts.map +1 -1
- package/dist/mapKernel.js +64 -44
- package/dist/mapKernel.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/lib/map.js +1 -1
- package/lib/map.js.map +1 -1
- package/lib/mapKernel.d.ts +7 -3
- package/lib/mapKernel.d.ts.map +1 -1
- package/lib/mapKernel.js +65 -45
- package/lib/mapKernel.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/package.json +18 -18
- package/src/map.ts +1 -1
- package/src/mapKernel.ts +124 -67
- package/src/packageVersion.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/map",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.50.0",
|
|
4
4
|
"description": "Distributed map",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -81,33 +81,33 @@
|
|
|
81
81
|
"temp-directory": "nyc/.nyc_output"
|
|
82
82
|
},
|
|
83
83
|
"dependencies": {
|
|
84
|
-
"@fluid-internal/client-utils": "~2.
|
|
85
|
-
"@fluidframework/core-interfaces": "~2.
|
|
86
|
-
"@fluidframework/core-utils": "~2.
|
|
87
|
-
"@fluidframework/datastore-definitions": "~2.
|
|
88
|
-
"@fluidframework/driver-definitions": "~2.
|
|
89
|
-
"@fluidframework/driver-utils": "~2.
|
|
90
|
-
"@fluidframework/merge-tree": "~2.
|
|
91
|
-
"@fluidframework/runtime-definitions": "~2.
|
|
92
|
-
"@fluidframework/runtime-utils": "~2.
|
|
93
|
-
"@fluidframework/shared-object-base": "~2.
|
|
94
|
-
"@fluidframework/telemetry-utils": "~2.
|
|
84
|
+
"@fluid-internal/client-utils": "~2.50.0",
|
|
85
|
+
"@fluidframework/core-interfaces": "~2.50.0",
|
|
86
|
+
"@fluidframework/core-utils": "~2.50.0",
|
|
87
|
+
"@fluidframework/datastore-definitions": "~2.50.0",
|
|
88
|
+
"@fluidframework/driver-definitions": "~2.50.0",
|
|
89
|
+
"@fluidframework/driver-utils": "~2.50.0",
|
|
90
|
+
"@fluidframework/merge-tree": "~2.50.0",
|
|
91
|
+
"@fluidframework/runtime-definitions": "~2.50.0",
|
|
92
|
+
"@fluidframework/runtime-utils": "~2.50.0",
|
|
93
|
+
"@fluidframework/shared-object-base": "~2.50.0",
|
|
94
|
+
"@fluidframework/telemetry-utils": "~2.50.0",
|
|
95
95
|
"path-browserify": "^1.0.1"
|
|
96
96
|
},
|
|
97
97
|
"devDependencies": {
|
|
98
98
|
"@arethetypeswrong/cli": "^0.17.1",
|
|
99
99
|
"@biomejs/biome": "~1.9.3",
|
|
100
|
-
"@fluid-internal/mocha-test-setup": "~2.
|
|
101
|
-
"@fluid-private/stochastic-test-utils": "~2.
|
|
102
|
-
"@fluid-private/test-dds-utils": "~2.
|
|
100
|
+
"@fluid-internal/mocha-test-setup": "~2.50.0",
|
|
101
|
+
"@fluid-private/stochastic-test-utils": "~2.50.0",
|
|
102
|
+
"@fluid-private/test-dds-utils": "~2.50.0",
|
|
103
103
|
"@fluid-tools/benchmark": "^0.51.0",
|
|
104
104
|
"@fluid-tools/build-cli": "^0.56.0",
|
|
105
105
|
"@fluidframework/build-common": "^2.0.3",
|
|
106
106
|
"@fluidframework/build-tools": "^0.56.0",
|
|
107
|
-
"@fluidframework/container-definitions": "~2.
|
|
107
|
+
"@fluidframework/container-definitions": "~2.50.0",
|
|
108
108
|
"@fluidframework/eslint-config-fluid": "^5.7.4",
|
|
109
|
-
"@fluidframework/map-previous": "npm:@fluidframework/map@2.
|
|
110
|
-
"@fluidframework/test-runtime-utils": "~2.
|
|
109
|
+
"@fluidframework/map-previous": "npm:@fluidframework/map@2.43.0",
|
|
110
|
+
"@fluidframework/test-runtime-utils": "~2.50.0",
|
|
111
111
|
"@microsoft/api-extractor": "7.52.8",
|
|
112
112
|
"@types/mocha": "^10.0.10",
|
|
113
113
|
"@types/node": "^18.19.0",
|
package/src/map.ts
CHANGED
|
@@ -275,7 +275,7 @@ export class SharedMap extends SharedObject<ISharedMapEvents> implements IShared
|
|
|
275
275
|
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.reSubmitCore}
|
|
276
276
|
*/
|
|
277
277
|
protected override reSubmitCore(content: unknown, localOpMetadata: unknown): void {
|
|
278
|
-
this.kernel.
|
|
278
|
+
this.kernel.tryResubmitMessage(content as IMapOperation, localOpMetadata);
|
|
279
279
|
}
|
|
280
280
|
|
|
281
281
|
/**
|
package/src/mapKernel.ts
CHANGED
|
@@ -5,7 +5,12 @@
|
|
|
5
5
|
|
|
6
6
|
import type { TypedEventEmitter } from "@fluid-internal/client-utils";
|
|
7
7
|
import type { IFluidHandle } from "@fluidframework/core-interfaces";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
assert,
|
|
10
|
+
DoublyLinkedList,
|
|
11
|
+
type ListNode,
|
|
12
|
+
unreachableCase,
|
|
13
|
+
} from "@fluidframework/core-utils/internal";
|
|
9
14
|
import type { IFluidSerializer } from "@fluidframework/shared-object-base/internal";
|
|
10
15
|
import { ValueType } from "@fluidframework/shared-object-base/internal";
|
|
11
16
|
|
|
@@ -28,7 +33,7 @@ import {
|
|
|
28
33
|
} from "./localValues.js";
|
|
29
34
|
|
|
30
35
|
/**
|
|
31
|
-
* Defines the means to process and
|
|
36
|
+
* Defines the means to process and resubmit a given op on a map.
|
|
32
37
|
*/
|
|
33
38
|
interface IMapMessageHandler {
|
|
34
39
|
/**
|
|
@@ -38,14 +43,18 @@ interface IMapMessageHandler {
|
|
|
38
43
|
* @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.
|
|
39
44
|
* For messages from a remote client, this will be undefined.
|
|
40
45
|
*/
|
|
41
|
-
process(
|
|
46
|
+
process(
|
|
47
|
+
op: IMapOperation,
|
|
48
|
+
local: boolean,
|
|
49
|
+
localOpMetadata: ListNode<MapLocalOpMetadata> | undefined,
|
|
50
|
+
): void;
|
|
42
51
|
|
|
43
52
|
/**
|
|
44
|
-
*
|
|
45
|
-
* @param op - The map operation to
|
|
46
|
-
* @param localOpMetadata - The metadata
|
|
53
|
+
* Resubmit a previously submitted operation that was not delivered.
|
|
54
|
+
* @param op - The map operation to resubmit
|
|
55
|
+
* @param localOpMetadata - The metadata that was originally submitted with the message.
|
|
47
56
|
*/
|
|
48
|
-
|
|
57
|
+
resubmit(op: IMapOperation, localOpMetadata: ListNode<MapLocalOpMetadata>): void;
|
|
49
58
|
}
|
|
50
59
|
|
|
51
60
|
/**
|
|
@@ -95,14 +104,6 @@ function isClearLocalOpMetadata(metadata: any): metadata is IMapClearLocalOpMeta
|
|
|
95
104
|
);
|
|
96
105
|
}
|
|
97
106
|
|
|
98
|
-
function isMapLocalOpMetadata(metadata: any): metadata is MapLocalOpMetadata {
|
|
99
|
-
return (
|
|
100
|
-
metadata !== undefined &&
|
|
101
|
-
typeof metadata.pendingMessageId === "number" &&
|
|
102
|
-
(metadata.type === "add" || metadata.type === "edit" || metadata.type === "clear")
|
|
103
|
-
);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
107
|
/* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */
|
|
107
108
|
|
|
108
109
|
function createClearLocalOpMetadata(
|
|
@@ -160,6 +161,12 @@ export class MapKernel {
|
|
|
160
161
|
*/
|
|
161
162
|
private nextPendingMessageId: number = 0;
|
|
162
163
|
|
|
164
|
+
/**
|
|
165
|
+
* The pending metadata for any local operations that have not yet been ack'd from the server, in order.
|
|
166
|
+
*/
|
|
167
|
+
private readonly pendingMapLocalOpMetadata: DoublyLinkedList<MapLocalOpMetadata> =
|
|
168
|
+
new DoublyLinkedList<MapLocalOpMetadata>();
|
|
169
|
+
|
|
163
170
|
/**
|
|
164
171
|
* The pending ids of any clears that have been performed locally but not yet ack'd from the server
|
|
165
172
|
*/
|
|
@@ -370,19 +377,19 @@ export class MapKernel {
|
|
|
370
377
|
}
|
|
371
378
|
|
|
372
379
|
/**
|
|
373
|
-
*
|
|
380
|
+
* Resubmit the given op if a handler is registered.
|
|
374
381
|
* @param op - The operation to attempt to submit
|
|
375
382
|
* @param localOpMetadata - The local metadata associated with the op. This is kept locally by the runtime
|
|
376
383
|
* and not sent to the server. This will be sent back when this message is received back from the server. This is
|
|
377
384
|
* also sent if we are asked to resubmit the message.
|
|
378
385
|
* @returns True if the operation was submitted, false otherwise.
|
|
379
386
|
*/
|
|
380
|
-
public
|
|
387
|
+
public tryResubmitMessage(op: IMapOperation, localOpMetadata: unknown): boolean {
|
|
381
388
|
const handler = this.messageHandlers.get(op.type);
|
|
382
389
|
if (handler === undefined) {
|
|
383
390
|
return false;
|
|
384
391
|
}
|
|
385
|
-
handler.
|
|
392
|
+
handler.resubmit(op, localOpMetadata as ListNode<MapLocalOpMetadata>);
|
|
386
393
|
return true;
|
|
387
394
|
}
|
|
388
395
|
|
|
@@ -431,65 +438,68 @@ export class MapKernel {
|
|
|
431
438
|
if (handler === undefined) {
|
|
432
439
|
return false;
|
|
433
440
|
}
|
|
434
|
-
handler.process(op, local, localOpMetadata as MapLocalOpMetadata);
|
|
441
|
+
handler.process(op, local, localOpMetadata as ListNode<MapLocalOpMetadata> | undefined);
|
|
435
442
|
return true;
|
|
436
443
|
}
|
|
437
444
|
|
|
438
|
-
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
439
|
-
|
|
440
445
|
/**
|
|
441
446
|
* Rollback a local op
|
|
442
447
|
* @param op - The operation to rollback
|
|
443
448
|
* @param localOpMetadata - The local metadata associated with the op.
|
|
444
449
|
*/
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
+
public rollback(op: unknown, localOpMetadata: unknown): void {
|
|
451
|
+
const mapOp: IMapOperation = op as IMapOperation;
|
|
452
|
+
const listNodeLocalOpMetadata = localOpMetadata as ListNode<MapLocalOpMetadata>;
|
|
453
|
+
const removedLocalOpMetadata = this.pendingMapLocalOpMetadata.pop();
|
|
454
|
+
assert(
|
|
455
|
+
removedLocalOpMetadata !== undefined &&
|
|
456
|
+
removedLocalOpMetadata === listNodeLocalOpMetadata,
|
|
457
|
+
0xbcb /* Rolling back unexpected op */,
|
|
458
|
+
);
|
|
450
459
|
|
|
451
|
-
if (
|
|
452
|
-
if (
|
|
460
|
+
if (mapOp.type === "clear" && listNodeLocalOpMetadata.data.type === "clear") {
|
|
461
|
+
if (listNodeLocalOpMetadata.data.previousMap === undefined) {
|
|
453
462
|
throw new Error("Cannot rollback without previous map");
|
|
454
463
|
}
|
|
455
|
-
for (const [key, localValue] of
|
|
464
|
+
for (const [key, localValue] of listNodeLocalOpMetadata.data.previousMap.entries()) {
|
|
456
465
|
this.setCore(key, localValue, true);
|
|
457
466
|
}
|
|
458
467
|
|
|
459
468
|
const lastPendingClearId = this.pendingClearMessageIds.pop();
|
|
460
469
|
if (
|
|
461
470
|
lastPendingClearId === undefined ||
|
|
462
|
-
lastPendingClearId !==
|
|
471
|
+
lastPendingClearId !== listNodeLocalOpMetadata.data.pendingMessageId
|
|
463
472
|
) {
|
|
464
473
|
throw new Error("Rollback op does match last clear");
|
|
465
474
|
}
|
|
466
|
-
} else if (
|
|
467
|
-
if (
|
|
468
|
-
this.deleteCore(
|
|
475
|
+
} else if (mapOp.type === "delete" || mapOp.type === "set") {
|
|
476
|
+
if (listNodeLocalOpMetadata.data.type === "add") {
|
|
477
|
+
this.deleteCore(mapOp.key, true);
|
|
469
478
|
} else if (
|
|
470
|
-
|
|
471
|
-
|
|
479
|
+
listNodeLocalOpMetadata.data.type === "edit" &&
|
|
480
|
+
listNodeLocalOpMetadata.data.previousValue !== undefined
|
|
472
481
|
) {
|
|
473
|
-
this.setCore(
|
|
482
|
+
this.setCore(mapOp.key, listNodeLocalOpMetadata.data.previousValue, true);
|
|
474
483
|
} else {
|
|
475
484
|
throw new Error("Cannot rollback without previous value");
|
|
476
485
|
}
|
|
477
486
|
|
|
478
|
-
const pendingMessageIds = this.pendingKeys.get(
|
|
487
|
+
const pendingMessageIds = this.pendingKeys.get(mapOp.key);
|
|
479
488
|
const lastPendingMessageId = pendingMessageIds?.pop();
|
|
480
|
-
if (
|
|
489
|
+
if (
|
|
490
|
+
!pendingMessageIds ||
|
|
491
|
+
lastPendingMessageId !== listNodeLocalOpMetadata.data.pendingMessageId
|
|
492
|
+
) {
|
|
481
493
|
throw new Error("Rollback op does not match last pending");
|
|
482
494
|
}
|
|
483
495
|
if (pendingMessageIds.length === 0) {
|
|
484
|
-
this.pendingKeys.delete(
|
|
496
|
+
this.pendingKeys.delete(mapOp.key);
|
|
485
497
|
}
|
|
486
498
|
} else {
|
|
487
499
|
throw new Error("Unsupported op for rollback");
|
|
488
500
|
}
|
|
489
501
|
}
|
|
490
502
|
|
|
491
|
-
/* eslint-enable @typescript-eslint/no-unsafe-member-access */
|
|
492
|
-
|
|
493
503
|
/**
|
|
494
504
|
* Set implementation used for both locally sourced sets as well as incoming remote sets.
|
|
495
505
|
* @param key - The key being set
|
|
@@ -562,7 +572,7 @@ export class MapKernel {
|
|
|
562
572
|
private needProcessKeyOperation(
|
|
563
573
|
op: IMapKeyOperation,
|
|
564
574
|
local: boolean,
|
|
565
|
-
localOpMetadata: MapLocalOpMetadata,
|
|
575
|
+
localOpMetadata: MapLocalOpMetadata | undefined,
|
|
566
576
|
): boolean {
|
|
567
577
|
if (this.pendingClearMessageIds[0] !== undefined) {
|
|
568
578
|
if (local) {
|
|
@@ -609,15 +619,24 @@ export class MapKernel {
|
|
|
609
619
|
private getMessageHandlers(): Map<string, IMapMessageHandler> {
|
|
610
620
|
const messageHandlers = new Map<string, IMapMessageHandler>();
|
|
611
621
|
messageHandlers.set("clear", {
|
|
612
|
-
process: (
|
|
622
|
+
process: (
|
|
623
|
+
op: IMapClearOperation,
|
|
624
|
+
local: boolean,
|
|
625
|
+
localOpMetadata: ListNode<MapLocalOpMetadata> | undefined,
|
|
626
|
+
) => {
|
|
613
627
|
if (local) {
|
|
628
|
+
const removedLocalOpMetadata = this.pendingMapLocalOpMetadata.shift();
|
|
629
|
+
assert(
|
|
630
|
+
removedLocalOpMetadata !== undefined && removedLocalOpMetadata === localOpMetadata,
|
|
631
|
+
0xbcc /* Processing unexpected local clear op */,
|
|
632
|
+
);
|
|
614
633
|
assert(
|
|
615
|
-
isClearLocalOpMetadata(localOpMetadata),
|
|
634
|
+
isClearLocalOpMetadata(localOpMetadata.data),
|
|
616
635
|
0x015 /* "pendingMessageId is missing from the local client's clear operation" */,
|
|
617
636
|
);
|
|
618
637
|
const pendingClearMessageId = this.pendingClearMessageIds.shift();
|
|
619
638
|
assert(
|
|
620
|
-
pendingClearMessageId === localOpMetadata.pendingMessageId,
|
|
639
|
+
pendingClearMessageId === localOpMetadata.data.pendingMessageId,
|
|
621
640
|
0x2fb /* pendingMessageId does not match */,
|
|
622
641
|
);
|
|
623
642
|
return;
|
|
@@ -628,34 +647,66 @@ export class MapKernel {
|
|
|
628
647
|
}
|
|
629
648
|
this.clearCore(local);
|
|
630
649
|
},
|
|
631
|
-
|
|
650
|
+
resubmit: (op: IMapClearOperation, localOpMetadata: ListNode<MapLocalOpMetadata>) => {
|
|
651
|
+
const removedLocalOpMetadata = localOpMetadata.remove()?.data;
|
|
652
|
+
assert(
|
|
653
|
+
removedLocalOpMetadata !== undefined,
|
|
654
|
+
0xbcd /* Resubmitting unexpected local clear op */,
|
|
655
|
+
);
|
|
632
656
|
assert(
|
|
633
|
-
isClearLocalOpMetadata(localOpMetadata),
|
|
657
|
+
isClearLocalOpMetadata(localOpMetadata.data),
|
|
634
658
|
0x2fc /* Invalid localOpMetadata for clear */,
|
|
635
659
|
);
|
|
636
660
|
// We don't reuse the metadata pendingMessageId but send a new one on each submit.
|
|
637
661
|
const pendingClearMessageId = this.pendingClearMessageIds.shift();
|
|
638
662
|
assert(
|
|
639
|
-
pendingClearMessageId === localOpMetadata.pendingMessageId,
|
|
663
|
+
pendingClearMessageId === localOpMetadata.data.pendingMessageId,
|
|
640
664
|
0x2fd /* pendingMessageId does not match */,
|
|
641
665
|
);
|
|
642
|
-
this.submitMapClearMessage(op, localOpMetadata.previousMap);
|
|
666
|
+
this.submitMapClearMessage(op, localOpMetadata.data.previousMap);
|
|
643
667
|
},
|
|
644
668
|
});
|
|
645
669
|
messageHandlers.set("delete", {
|
|
646
|
-
process: (
|
|
647
|
-
|
|
670
|
+
process: (
|
|
671
|
+
op: IMapDeleteOperation,
|
|
672
|
+
local: boolean,
|
|
673
|
+
localOpMetadata: ListNode<MapLocalOpMetadata> | undefined,
|
|
674
|
+
) => {
|
|
675
|
+
if (local) {
|
|
676
|
+
const removedLocalOpMetadata = this.pendingMapLocalOpMetadata.shift();
|
|
677
|
+
assert(
|
|
678
|
+
removedLocalOpMetadata !== undefined && removedLocalOpMetadata === localOpMetadata,
|
|
679
|
+
0xbce /* Processing unexpected local delete op */,
|
|
680
|
+
);
|
|
681
|
+
}
|
|
682
|
+
if (!this.needProcessKeyOperation(op, local, localOpMetadata?.data)) {
|
|
648
683
|
return;
|
|
649
684
|
}
|
|
650
685
|
this.deleteCore(op.key, local);
|
|
651
686
|
},
|
|
652
|
-
|
|
653
|
-
|
|
687
|
+
resubmit: (op: IMapDeleteOperation, localOpMetadata: ListNode<MapLocalOpMetadata>) => {
|
|
688
|
+
const removedLocalOpMetadata = localOpMetadata.remove()?.data;
|
|
689
|
+
assert(
|
|
690
|
+
removedLocalOpMetadata !== undefined,
|
|
691
|
+
0xbcf /* Resubmitting unexpected local delete op */,
|
|
692
|
+
);
|
|
693
|
+
this.resubmitMapKeyMessage(op, localOpMetadata.data);
|
|
654
694
|
},
|
|
655
695
|
});
|
|
656
696
|
messageHandlers.set("set", {
|
|
657
|
-
process: (
|
|
658
|
-
|
|
697
|
+
process: (
|
|
698
|
+
op: IMapSetOperation,
|
|
699
|
+
local: boolean,
|
|
700
|
+
localOpMetadata: ListNode<MapLocalOpMetadata> | undefined,
|
|
701
|
+
) => {
|
|
702
|
+
if (local) {
|
|
703
|
+
const removedLocalOpMetadata = this.pendingMapLocalOpMetadata.shift();
|
|
704
|
+
assert(
|
|
705
|
+
removedLocalOpMetadata !== undefined && removedLocalOpMetadata === localOpMetadata,
|
|
706
|
+
0xbd0 /* Processing unexpected local set op */,
|
|
707
|
+
);
|
|
708
|
+
}
|
|
709
|
+
if (!this.needProcessKeyOperation(op, local, localOpMetadata?.data)) {
|
|
659
710
|
return;
|
|
660
711
|
}
|
|
661
712
|
|
|
@@ -663,8 +714,13 @@ export class MapKernel {
|
|
|
663
714
|
migrateIfSharedSerializable(op.value, this.serializer, this.handle);
|
|
664
715
|
this.setCore(op.key, { value: op.value.value }, local);
|
|
665
716
|
},
|
|
666
|
-
|
|
667
|
-
|
|
717
|
+
resubmit: (op: IMapSetOperation, localOpMetadata: ListNode<MapLocalOpMetadata>) => {
|
|
718
|
+
const removedLocalOpMetadata = localOpMetadata.remove()?.data;
|
|
719
|
+
assert(
|
|
720
|
+
removedLocalOpMetadata !== undefined,
|
|
721
|
+
0xbd1 /* Resubmitting unexpected local set op */,
|
|
722
|
+
);
|
|
723
|
+
this.resubmitMapKeyMessage(op, localOpMetadata.data);
|
|
668
724
|
},
|
|
669
725
|
});
|
|
670
726
|
|
|
@@ -685,8 +741,10 @@ export class MapKernel {
|
|
|
685
741
|
op: IMapClearOperation,
|
|
686
742
|
previousMap?: Map<string, ILocalValue>,
|
|
687
743
|
): void {
|
|
688
|
-
const
|
|
689
|
-
|
|
744
|
+
const pendingMessageId = this.getMapClearMessageId();
|
|
745
|
+
const localMetadata = createClearLocalOpMetadata(op, pendingMessageId, previousMap);
|
|
746
|
+
const listNode = this.pendingMapLocalOpMetadata.push(localMetadata).first;
|
|
747
|
+
this.submitMessage(op, listNode);
|
|
690
748
|
}
|
|
691
749
|
|
|
692
750
|
private getMapKeyMessageId(op: IMapKeyOperation): number {
|
|
@@ -706,12 +764,10 @@ export class MapKernel {
|
|
|
706
764
|
* @param previousValue - The value of the key before this op
|
|
707
765
|
*/
|
|
708
766
|
private submitMapKeyMessage(op: IMapKeyOperation, previousValue?: ILocalValue): void {
|
|
709
|
-
const
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
);
|
|
714
|
-
this.submitMessage(op, localMetadata);
|
|
767
|
+
const pendingMessageId = this.getMapKeyMessageId(op);
|
|
768
|
+
const localMetadata = createKeyLocalOpMetadata(op, pendingMessageId, previousValue);
|
|
769
|
+
const listNode = this.pendingMapLocalOpMetadata.push(localMetadata).first;
|
|
770
|
+
this.submitMessage(op, listNode);
|
|
715
771
|
}
|
|
716
772
|
|
|
717
773
|
/**
|
|
@@ -746,10 +802,11 @@ export class MapKernel {
|
|
|
746
802
|
|
|
747
803
|
// We don't reuse the metadata pendingMessageId but send a new one on each submit.
|
|
748
804
|
const pendingMessageId = this.getMapKeyMessageId(op);
|
|
749
|
-
const localMetadata =
|
|
805
|
+
const localMetadata: MapKeyLocalOpMetadata =
|
|
750
806
|
localOpMetadata.type === "edit"
|
|
751
807
|
? { type: "edit", pendingMessageId, previousValue: localOpMetadata.previousValue }
|
|
752
808
|
: { type: "add", pendingMessageId };
|
|
753
|
-
this.
|
|
809
|
+
const listNode = this.pendingMapLocalOpMetadata.push(localMetadata).first;
|
|
810
|
+
this.submitMessage(op, listNode);
|
|
754
811
|
}
|
|
755
812
|
}
|
package/src/packageVersion.ts
CHANGED