@fluidframework/legacy-dds 2.53.1 → 2.60.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.
Files changed (67) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/api-report/{legacy-dds.legacy.alpha.api.md → legacy-dds.legacy.beta.api.md} +20 -20
  3. package/dist/array/interfaces.d.ts +4 -8
  4. package/dist/array/interfaces.d.ts.map +1 -1
  5. package/dist/array/interfaces.js.map +1 -1
  6. package/dist/array/sharedArray.d.ts +8 -0
  7. package/dist/array/sharedArray.d.ts.map +1 -1
  8. package/dist/array/sharedArray.js +108 -8
  9. package/dist/array/sharedArray.js.map +1 -1
  10. package/dist/array/sharedArrayFactory.d.ts +2 -4
  11. package/dist/array/sharedArrayFactory.d.ts.map +1 -1
  12. package/dist/array/sharedArrayFactory.js +2 -4
  13. package/dist/array/sharedArrayFactory.js.map +1 -1
  14. package/dist/array/sharedArrayOperations.d.ts +9 -18
  15. package/dist/array/sharedArrayOperations.d.ts.map +1 -1
  16. package/dist/array/sharedArrayOperations.js +1 -2
  17. package/dist/array/sharedArrayOperations.js.map +1 -1
  18. package/dist/packageVersion.d.ts +1 -1
  19. package/dist/packageVersion.js +1 -1
  20. package/dist/packageVersion.js.map +1 -1
  21. package/dist/signal/interfaces.d.ts +3 -6
  22. package/dist/signal/interfaces.d.ts.map +1 -1
  23. package/dist/signal/interfaces.js.map +1 -1
  24. package/dist/signal/sharedSignal.d.ts.map +1 -1
  25. package/dist/signal/sharedSignal.js +19 -9
  26. package/dist/signal/sharedSignal.js.map +1 -1
  27. package/dist/signal/sharedSignalFactory.d.ts +1 -2
  28. package/dist/signal/sharedSignalFactory.d.ts.map +1 -1
  29. package/dist/signal/sharedSignalFactory.js +1 -2
  30. package/dist/signal/sharedSignalFactory.js.map +1 -1
  31. package/lib/array/interfaces.d.ts +4 -8
  32. package/lib/array/interfaces.d.ts.map +1 -1
  33. package/lib/array/interfaces.js.map +1 -1
  34. package/lib/array/sharedArray.d.ts +8 -0
  35. package/lib/array/sharedArray.d.ts.map +1 -1
  36. package/lib/array/sharedArray.js +108 -8
  37. package/lib/array/sharedArray.js.map +1 -1
  38. package/lib/array/sharedArrayFactory.d.ts +2 -4
  39. package/lib/array/sharedArrayFactory.d.ts.map +1 -1
  40. package/lib/array/sharedArrayFactory.js +2 -4
  41. package/lib/array/sharedArrayFactory.js.map +1 -1
  42. package/lib/array/sharedArrayOperations.d.ts +9 -18
  43. package/lib/array/sharedArrayOperations.d.ts.map +1 -1
  44. package/lib/array/sharedArrayOperations.js +1 -2
  45. package/lib/array/sharedArrayOperations.js.map +1 -1
  46. package/lib/packageVersion.d.ts +1 -1
  47. package/lib/packageVersion.js +1 -1
  48. package/lib/packageVersion.js.map +1 -1
  49. package/lib/signal/interfaces.d.ts +3 -6
  50. package/lib/signal/interfaces.d.ts.map +1 -1
  51. package/lib/signal/interfaces.js.map +1 -1
  52. package/lib/signal/sharedSignal.d.ts.map +1 -1
  53. package/lib/signal/sharedSignal.js +11 -1
  54. package/lib/signal/sharedSignal.js.map +1 -1
  55. package/lib/signal/sharedSignalFactory.d.ts +1 -2
  56. package/lib/signal/sharedSignalFactory.d.ts.map +1 -1
  57. package/lib/signal/sharedSignalFactory.js +1 -2
  58. package/lib/signal/sharedSignalFactory.js.map +1 -1
  59. package/package.json +16 -16
  60. package/src/array/interfaces.ts +4 -8
  61. package/src/array/sharedArray.ts +120 -10
  62. package/src/array/sharedArrayFactory.ts +2 -4
  63. package/src/array/sharedArrayOperations.ts +9 -18
  64. package/src/packageVersion.ts +1 -1
  65. package/src/signal/interfaces.ts +3 -6
  66. package/src/signal/sharedSignal.ts +11 -2
  67. package/src/signal/sharedSignalFactory.ts +1 -2
@@ -34,8 +34,7 @@ SharedSignalFactory.Attributes = {
34
34
  };
35
35
  /**
36
36
  * Entrypoint for {@link ISharedSignal} creation.
37
- * @legacy
38
- * @alpha
37
+ * @legacy @beta
39
38
  */
40
39
  export const SharedSignal = createSharedObjectKind(SharedSignalFactory);
41
40
  //# sourceMappingURL=sharedSignalFactory.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sharedSignalFactory.js","sourceRoot":"","sources":["../../src/signal/sharedSignalFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AAErF,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGlD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;GAEG;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;IAEM,KAAK,CAAC,IAAI,CAChB,OAA+B,EAC/B,EAAU,EACV,QAA0B,EAC1B,UAA8B;QAE9B,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,EAAE,EAAE,OAAO,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,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACpE,MAAM,CAAC,eAAe,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC;IACf,CAAC;;AA/BsB,wBAAI,GAAW,0CAA0C,CAAC;AAE1D,8BAAU,GAAuB;IACvD,IAAI,EAAE,mBAAmB,CAAC,IAAI;IAC9B,qBAAqB,EAAE,KAAK;IAC5B,cAAc,EAAE,UAAU;CAC1B,CAAC;AA4BH;;;;GAIG;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 type {\n\tIChannelAttributes,\n\tIFluidDataStoreRuntime,\n\tIChannelFactory,\n\tIChannelServices,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { createSharedObjectKind } from \"@fluidframework/shared-object-base/internal\";\n\nimport { pkgVersion } from \"../packageVersion.js\";\n\nimport type { ISharedSignal } from \"./interfaces.js\";\nimport { SharedSignalClass } from \"./sharedSignal.js\";\n\n/**\n * @internal\n */\nexport class SharedSignalFactory implements IChannelFactory<ISharedSignal> {\n\tpublic static readonly Type: string = \"https://graph.microsoft.com/types/signal\";\n\n\tpublic static readonly Attributes: IChannelAttributes = {\n\t\ttype: SharedSignalFactory.Type,\n\t\tsnapshotFormatVersion: \"0.1\",\n\t\tpackageVersion: pkgVersion,\n\t};\n\n\tpublic get type(): string {\n\t\treturn SharedSignalFactory.Type;\n\t}\n\n\tpublic get attributes(): IChannelAttributes {\n\t\treturn SharedSignalFactory.Attributes;\n\t}\n\n\tpublic async load(\n\t\truntime: IFluidDataStoreRuntime,\n\t\tid: string,\n\t\tservices: IChannelServices,\n\t\tattributes: IChannelAttributes,\n\t): Promise<ISharedSignal> {\n\t\tconst signal = new SharedSignalClass(id, runtime, attributes);\n\t\tawait signal.load(services);\n\t\treturn signal;\n\t}\n\n\tpublic create(document: IFluidDataStoreRuntime, id: string): ISharedSignal {\n\t\tconst signal = new SharedSignalClass(id, document, this.attributes);\n\t\tsignal.initializeLocal();\n\t\treturn signal;\n\t}\n}\n\n/**\n * Entrypoint for {@link ISharedSignal} creation.\n * @legacy\n * @alpha\n */\nexport const SharedSignal = createSharedObjectKind<ISharedSignal>(SharedSignalFactory);\n"]}
1
+ {"version":3,"file":"sharedSignalFactory.js","sourceRoot":"","sources":["../../src/signal/sharedSignalFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AAErF,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGlD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;GAEG;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;IAEM,KAAK,CAAC,IAAI,CAChB,OAA+B,EAC/B,EAAU,EACV,QAA0B,EAC1B,UAA8B;QAE9B,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,EAAE,EAAE,OAAO,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,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACpE,MAAM,CAAC,eAAe,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC;IACf,CAAC;;AA/BsB,wBAAI,GAAW,0CAA0C,CAAC;AAE1D,8BAAU,GAAuB;IACvD,IAAI,EAAE,mBAAmB,CAAC,IAAI;IAC9B,qBAAqB,EAAE,KAAK;IAC5B,cAAc,EAAE,UAAU;CAC1B,CAAC;AA4BH;;;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 type {\n\tIChannelAttributes,\n\tIFluidDataStoreRuntime,\n\tIChannelFactory,\n\tIChannelServices,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { createSharedObjectKind } from \"@fluidframework/shared-object-base/internal\";\n\nimport { pkgVersion } from \"../packageVersion.js\";\n\nimport type { ISharedSignal } from \"./interfaces.js\";\nimport { SharedSignalClass } from \"./sharedSignal.js\";\n\n/**\n * @internal\n */\nexport class SharedSignalFactory implements IChannelFactory<ISharedSignal> {\n\tpublic static readonly Type: string = \"https://graph.microsoft.com/types/signal\";\n\n\tpublic static readonly Attributes: IChannelAttributes = {\n\t\ttype: SharedSignalFactory.Type,\n\t\tsnapshotFormatVersion: \"0.1\",\n\t\tpackageVersion: pkgVersion,\n\t};\n\n\tpublic get type(): string {\n\t\treturn SharedSignalFactory.Type;\n\t}\n\n\tpublic get attributes(): IChannelAttributes {\n\t\treturn SharedSignalFactory.Attributes;\n\t}\n\n\tpublic async load(\n\t\truntime: IFluidDataStoreRuntime,\n\t\tid: string,\n\t\tservices: IChannelServices,\n\t\tattributes: IChannelAttributes,\n\t): Promise<ISharedSignal> {\n\t\tconst signal = new SharedSignalClass(id, runtime, attributes);\n\t\tawait signal.load(services);\n\t\treturn signal;\n\t}\n\n\tpublic create(document: IFluidDataStoreRuntime, id: string): ISharedSignal {\n\t\tconst signal = new SharedSignalClass(id, document, this.attributes);\n\t\tsignal.initializeLocal();\n\t\treturn signal;\n\t}\n}\n\n/**\n * Entrypoint for {@link ISharedSignal} creation.\n * @legacy @beta\n */\nexport const SharedSignal = createSharedObjectKind<ISharedSignal>(SharedSignalFactory);\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/legacy-dds",
3
- "version": "2.53.1",
3
+ "version": "2.60.0",
4
4
  "description": "Legacy DDSs for the Fluid Framework. These are not intended for use in new code.",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -81,29 +81,29 @@
81
81
  "temp-directory": "nyc/.nyc_output"
82
82
  },
83
83
  "dependencies": {
84
- "@fluid-internal/client-utils": "~2.53.1",
85
- "@fluidframework/core-interfaces": "~2.53.1",
86
- "@fluidframework/core-utils": "~2.53.1",
87
- "@fluidframework/datastore-definitions": "~2.53.1",
88
- "@fluidframework/driver-definitions": "~2.53.1",
89
- "@fluidframework/driver-utils": "~2.53.1",
90
- "@fluidframework/runtime-definitions": "~2.53.1",
91
- "@fluidframework/runtime-utils": "~2.53.1",
92
- "@fluidframework/shared-object-base": "~2.53.1",
84
+ "@fluid-internal/client-utils": "~2.60.0",
85
+ "@fluidframework/core-interfaces": "~2.60.0",
86
+ "@fluidframework/core-utils": "~2.60.0",
87
+ "@fluidframework/datastore-definitions": "~2.60.0",
88
+ "@fluidframework/driver-definitions": "~2.60.0",
89
+ "@fluidframework/driver-utils": "~2.60.0",
90
+ "@fluidframework/runtime-definitions": "~2.60.0",
91
+ "@fluidframework/runtime-utils": "~2.60.0",
92
+ "@fluidframework/shared-object-base": "~2.60.0",
93
93
  "uuid": "^11.1.0"
94
94
  },
95
95
  "devDependencies": {
96
96
  "@arethetypeswrong/cli": "^0.17.1",
97
97
  "@biomejs/biome": "~1.9.3",
98
- "@fluid-internal/mocha-test-setup": "~2.53.1",
99
- "@fluid-private/stochastic-test-utils": "~2.53.1",
100
- "@fluid-private/test-dds-utils": "~2.53.1",
98
+ "@fluid-internal/mocha-test-setup": "~2.60.0",
99
+ "@fluid-private/stochastic-test-utils": "~2.60.0",
100
+ "@fluid-private/test-dds-utils": "~2.60.0",
101
101
  "@fluid-tools/build-cli": "^0.57.0",
102
102
  "@fluidframework/build-common": "^2.0.3",
103
103
  "@fluidframework/build-tools": "^0.57.0",
104
- "@fluidframework/container-definitions": "~2.53.1",
105
- "@fluidframework/eslint-config-fluid": "^5.7.4",
106
- "@fluidframework/test-runtime-utils": "~2.53.1",
104
+ "@fluidframework/container-definitions": "~2.60.0",
105
+ "@fluidframework/eslint-config-fluid": "^6.0.0",
106
+ "@fluidframework/test-runtime-utils": "~2.60.0",
107
107
  "@microsoft/api-extractor": "7.52.8",
108
108
  "@types/jest": "29.5.3",
109
109
  "@types/mocha": "^10.0.10",
@@ -16,8 +16,7 @@ import type { ISharedArrayOperation } from "./sharedArrayOperations.js";
16
16
  * It can be used as a generic constraint (`extends SerializableTypeForSharedArray`) but is
17
17
  * *never* meant to be a concrete/real type on its own.
18
18
  *
19
- * @legacy
20
- * @alpha
19
+ * @legacy @beta
21
20
  */
22
21
  export type SerializableTypeForSharedArray = boolean | number | string | object | IFluidHandle;
23
22
 
@@ -25,8 +24,7 @@ export type SerializableTypeForSharedArray = boolean | number | string | object
25
24
  * Interface defining the events that can be emitted by the SharedArray DDS
26
25
  * and the events that can be listened to by the SharedArray DDS
27
26
  *
28
- * @legacy
29
- * @alpha
27
+ * @legacy @beta
30
28
  */
31
29
  export interface ISharedArrayEvents extends ISharedObjectEvents {
32
30
  /**
@@ -62,8 +60,7 @@ export interface ISharedArrayEvents extends ISharedObjectEvents {
62
60
  *
63
61
  * @typeParam T - The type of the SharedArray
64
62
  *
65
- * @legacy
66
- * @alpha
63
+ * @legacy @beta
67
64
  */
68
65
  export interface ISharedArray<T extends SerializableTypeForSharedArray>
69
66
  extends ISharedObject<ISharedArrayEvents> {
@@ -160,8 +157,7 @@ export interface SnapshotFormat<T> {
160
157
  }
161
158
 
162
159
  /**
163
- * @legacy
164
- * @alpha
160
+ * @legacy @beta
165
161
  */
166
162
  export interface IRevertible {
167
163
  revert(): void;
@@ -68,6 +68,13 @@ export class SharedArrayClass<T extends SerializableTypeForSharedArray>
68
68
  */
69
69
  private readonly idToEntryMap: Map<string, SharedArrayEntry<T>>;
70
70
 
71
+ /**
72
+ * Set of entry IDs that are marked for deletion by remote clients, but have local pending deletes.
73
+ * Used to prevent resuscitating entries while rolling back a delete operation.
74
+ * We should not rollback to life an entry that was deleted by remote clients.
75
+ */
76
+ private readonly remoteDeleteWithLocalPendingDelete: Set<string> = new Set<string>();
77
+
71
78
  /**
72
79
  * Create a new shared array
73
80
  *
@@ -350,7 +357,6 @@ export class SharedArrayClass<T extends SerializableTypeForSharedArray>
350
357
 
351
358
  this.submitLocalMessage(op);
352
359
  }
353
-
354
360
  /**
355
361
  * Method to do undo/redo of move operation. All entries of the same payload/value are stored
356
362
  * in the same doubly linked skip list. This skip list is updated upon every move by adding the
@@ -386,6 +392,68 @@ export class SharedArrayClass<T extends SerializableTypeForSharedArray>
386
392
  this.submitLocalMessage(op);
387
393
  }
388
394
 
395
+ public rollback(op: unknown, _localOpMetadata: unknown): void {
396
+ const arrayOp = op as ISharedArrayOperation<T>;
397
+ switch (arrayOp.type) {
398
+ case OperationType.insertEntry: {
399
+ const liveEntry = this.getLiveEntry(arrayOp.entryId);
400
+ liveEntry.isDeleted = true;
401
+ const deleteOp: IDeleteOperation = {
402
+ type: OperationType.deleteEntry,
403
+ entryId: arrayOp.entryId,
404
+ };
405
+ this.emitValueChangedEvent(deleteOp, true /* isLocal */);
406
+ break;
407
+ }
408
+ case OperationType.deleteEntry: {
409
+ if (this.remoteDeleteWithLocalPendingDelete.has(arrayOp.entryId)) {
410
+ // If remote already deleted the entry, we should not resurrect it.
411
+ // Just remove the local pending delete.
412
+ this.remoteDeleteWithLocalPendingDelete.delete(arrayOp.entryId);
413
+ } else {
414
+ const liveEntry = this.getLiveEntry(arrayOp.entryId);
415
+ liveEntry.isDeleted = false;
416
+ const insertOp = {
417
+ type: OperationType.insertEntry,
418
+ entryId: arrayOp.entryId,
419
+ value: liveEntry.value,
420
+ };
421
+ this.emitValueChangedEvent(insertOp, true /* isLocal */);
422
+ const entry = this.getEntryForId(arrayOp.entryId);
423
+ if (entry !== undefined && entry.isLocalPendingDelete > 0) {
424
+ entry.isLocalPendingDelete -= 1;
425
+ }
426
+ }
427
+ break;
428
+ }
429
+ case OperationType.moveEntry: {
430
+ const { entryId: oldEntryId, changedToEntryId: newEntryId } = arrayOp;
431
+ if (this.getEntryForId(newEntryId).isDeleted) {
432
+ return;
433
+ }
434
+ this.updateLiveEntry(newEntryId, oldEntryId);
435
+ const inputEntry = this.getEntryForId(oldEntryId);
436
+ inputEntry.prevEntryId = undefined;
437
+ inputEntry.nextEntryId = undefined;
438
+ inputEntry.isLocalPendingMove = 0;
439
+ const moveOp: IMoveOperation = {
440
+ type: OperationType.moveEntry,
441
+ entryId: newEntryId,
442
+ changedToEntryId: oldEntryId,
443
+ };
444
+ this.emitValueChangedEvent(moveOp, true /* isLocal */);
445
+ break;
446
+ }
447
+ case OperationType.toggle:
448
+ case OperationType.toggleMove: {
449
+ throw new Error(`Rollback not implemented for ${arrayOp.type} operations`);
450
+ }
451
+ default: {
452
+ unreachableCase(arrayOp);
453
+ }
454
+ }
455
+ }
456
+
389
457
  /**
390
458
  * Load share array from snapshot
391
459
  *
@@ -541,9 +609,11 @@ export class SharedArrayClass<T extends SerializableTypeForSharedArray>
541
609
  if (local) {
542
610
  // Decrementing local pending counter as op is already applied to local state
543
611
  opEntry.isLocalPendingDelete -= 1;
612
+ this.remoteDeleteWithLocalPendingDelete.delete(op.entryId);
544
613
  } else {
545
- // If local pending, then ignore else apply the remote op
546
- if (!this.isLocalPending(op.entryId, "isLocalPendingDelete")) {
614
+ if (this.isLocalPending(op.entryId, "isLocalPendingDelete")) {
615
+ this.remoteDeleteWithLocalPendingDelete.add(op.entryId);
616
+ } else {
547
617
  // last element in skip list is the most recent and live entry, so marking it deleted
548
618
  this.getLiveEntry(op.entryId).isDeleted = true;
549
619
  }
@@ -841,33 +911,73 @@ export class SharedArrayClass<T extends SerializableTypeForSharedArray>
841
911
  deadEntry.isDeleted = true;
842
912
  }
843
913
 
914
+ private handleStashedInsert(
915
+ entryId: string,
916
+ insertAfterEntryId: string | undefined,
917
+ value: Serializable<SerializableTypeForSharedArray> & T,
918
+ ): void {
919
+ let index = 0;
920
+ if (insertAfterEntryId !== undefined) {
921
+ index = this.findIndexOfEntryId(insertAfterEntryId) + 1;
922
+ }
923
+ const newEntry = this.createNewEntry<SerializableTypeForSharedArray>(entryId, value);
924
+ newEntry.isAckPending = true;
925
+ this.addEntry(index, newEntry);
926
+ }
927
+
844
928
  protected applyStashedOp(content: unknown): void {
845
929
  const op = content as ISharedArrayOperation<T>;
846
930
 
847
931
  switch (op.type) {
848
932
  case OperationType.insertEntry: {
849
- this.handleInsertOp<SerializableTypeForSharedArray>(
933
+ this.handleStashedInsert(
850
934
  op.entryId,
851
935
  op.insertAfterEntryId,
852
- false, // treat it as remote op
853
- op.value,
936
+ op.value as Serializable<SerializableTypeForSharedArray> & T,
854
937
  );
855
938
  break;
856
939
  }
857
940
  case OperationType.deleteEntry: {
858
- this.handleDeleteOp(op, false /* local - treat as remote op */);
941
+ this.getLiveEntry(op.entryId).isDeleted = true;
942
+ this.getEntryForId(op.entryId).isLocalPendingDelete += 1;
859
943
  break;
860
944
  }
861
945
  case OperationType.moveEntry: {
862
- this.handleMoveOp(op, false /* local - treat as remote op */);
946
+ const opEntry = this.getEntryForId(op.entryId);
947
+ this.handleStashedInsert(
948
+ op.changedToEntryId,
949
+ op.insertAfterEntryId,
950
+ opEntry.value as Serializable<SerializableTypeForSharedArray> & T,
951
+ );
952
+
953
+ const newElementEntryId = op.changedToEntryId;
954
+ const newElement = this.getEntryForId(newElementEntryId);
955
+ if (
956
+ this.isLocalPending(op.entryId, "isLocalPendingDelete") ||
957
+ this.isLocalPending(op.entryId, "isLocalPendingMove")
958
+ ) {
959
+ this.updateDeadEntry(op.entryId, newElementEntryId);
960
+ } else {
961
+ // move the element
962
+ const liveEntry = this.getLiveEntry(op.entryId);
963
+ const isDeleted = liveEntry.isDeleted;
964
+ this.updateLiveEntry(liveEntry.entryId, newElementEntryId);
965
+ // mark newly added element as deleted if existing live element was already deleted
966
+ if (isDeleted) {
967
+ newElement.isDeleted = isDeleted;
968
+ }
969
+ }
970
+ newElement.isLocalPendingMove += 1;
863
971
  break;
864
972
  }
865
973
  case OperationType.toggle: {
866
- this.handleToggleOp(op, false /* local - treat as remote op */);
974
+ this.getLiveEntry(op.entryId).isDeleted = op.isDeleted;
975
+ this.getEntryForId(op.entryId).isLocalPendingDelete += 1;
867
976
  break;
868
977
  }
869
978
  case OperationType.toggleMove: {
870
- this.handleToggleMoveOp(op, false /* local - treat as remote op */);
979
+ this.updateLiveEntry(this.getLiveEntry(op.entryId).entryId, op.entryId);
980
+ this.getEntryForId(op.entryId).isLocalPendingMove += 1;
871
981
  break;
872
982
  }
873
983
  default: {
@@ -68,8 +68,7 @@ export class SharedArrayFactory<T extends SerializableTypeForSharedArray>
68
68
 
69
69
  /**
70
70
  * Entrypoint for {@link ISharedArray} creation.
71
- * @legacy
72
- * @alpha
71
+ * @legacy @beta
73
72
  */
74
73
  export const SharedArray: ISharedObjectKind<ISharedArray<SerializableTypeForSharedArray>> &
75
74
  SharedObjectKind<ISharedArray<SerializableTypeForSharedArray>> =
@@ -77,8 +76,7 @@ export const SharedArray: ISharedObjectKind<ISharedArray<SerializableTypeForShar
77
76
 
78
77
  /**
79
78
  * Entrypoint for {@link ISharedArray} creation.
80
- * @legacy
81
- * @alpha
79
+ * @legacy @beta
82
80
  */
83
81
  export const SharedArrayBuilder = <
84
82
  T extends SerializableTypeForSharedArray,
@@ -4,8 +4,7 @@
4
4
  */
5
5
 
6
6
  /**
7
- * @legacy
8
- * @alpha
7
+ * @legacy @beta
9
8
  */
10
9
  export const OperationType = {
11
10
  insertEntry: 0,
@@ -16,14 +15,12 @@ export const OperationType = {
16
15
  } as const;
17
16
 
18
17
  /**
19
- * @legacy
20
- * @alpha
18
+ * @legacy @beta
21
19
  */
22
20
  export type OperationType = (typeof OperationType)[keyof typeof OperationType];
23
21
 
24
22
  /**
25
- * @legacy
26
- * @alpha
23
+ * @legacy @beta
27
24
  */
28
25
  export interface IInsertOperation<T = unknown> {
29
26
  type: typeof OperationType.insertEntry;
@@ -33,8 +30,7 @@ export interface IInsertOperation<T = unknown> {
33
30
  }
34
31
 
35
32
  /**
36
- * @legacy
37
- * @alpha
33
+ * @legacy @beta
38
34
  */
39
35
  export interface IDeleteOperation {
40
36
  type: typeof OperationType.deleteEntry;
@@ -42,8 +38,7 @@ export interface IDeleteOperation {
42
38
  }
43
39
 
44
40
  /**
45
- * @legacy
46
- * @alpha
41
+ * @legacy @beta
47
42
  */
48
43
  export interface IMoveOperation {
49
44
  type: typeof OperationType.moveEntry;
@@ -53,8 +48,7 @@ export interface IMoveOperation {
53
48
  }
54
49
 
55
50
  /**
56
- * @legacy
57
- * @alpha
51
+ * @legacy @beta
58
52
  */
59
53
  export interface IToggleOperation {
60
54
  type: typeof OperationType.toggle;
@@ -63,8 +57,7 @@ export interface IToggleOperation {
63
57
  }
64
58
 
65
59
  /**
66
- * @legacy
67
- * @alpha
60
+ * @legacy @beta
68
61
  */
69
62
  export interface IToggleMoveOperation {
70
63
  type: typeof OperationType.toggleMove;
@@ -73,14 +66,12 @@ export interface IToggleMoveOperation {
73
66
  }
74
67
 
75
68
  /**
76
- * @legacy
77
- * @alpha
69
+ * @legacy @beta
78
70
  */
79
71
  export type ISharedArrayRevertibleOperation = IToggleOperation | IToggleMoveOperation;
80
72
 
81
73
  /**
82
- * @legacy
83
- * @alpha
74
+ * @legacy @beta
84
75
  */
85
76
  export type ISharedArrayOperation<T = unknown> =
86
77
  | IInsertOperation<T>
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/legacy-dds";
9
- export const pkgVersion = "2.53.1";
9
+ export const pkgVersion = "2.60.0";
@@ -13,8 +13,7 @@ import type {
13
13
  * Basic types for the SharedSignal DDS
14
14
  * It can be used as a generic constraint (`extends SerializableTypeForSharedSignal`) but is
15
15
  * *never* meant to be a concrete/real type on its own.
16
- * @legacy
17
- * @alpha
16
+ * @legacy @beta
18
17
  */
19
18
  export type SerializableTypeForSharedSignal =
20
19
  | boolean
@@ -24,8 +23,7 @@ export type SerializableTypeForSharedSignal =
24
23
  | object;
25
24
 
26
25
  /**
27
- * @legacy
28
- * @alpha
26
+ * @legacy @beta
29
27
  */
30
28
  export interface ISharedSignalEvents<T extends SerializableTypeForSharedSignal>
31
29
  extends ISharedObjectEvents {
@@ -35,8 +33,7 @@ export interface ISharedSignalEvents<T extends SerializableTypeForSharedSignal>
35
33
  }
36
34
 
37
35
  /**
38
- * @legacy
39
- * @alpha
36
+ * @legacy @beta
40
37
  */
41
38
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
42
39
  export interface ISharedSignal<T extends SerializableTypeForSharedSignal = any>
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  /* eslint-disable @typescript-eslint/no-explicit-any */
7
-
7
+ import { unreachableCase } from "@fluidframework/core-utils/internal";
8
8
  import type {
9
9
  IChannelAttributes,
10
10
  IFluidDataStoreRuntime,
@@ -164,6 +164,15 @@ export class SharedSignalClass<T extends SerializableTypeForSharedSignal = any>
164
164
  }
165
165
 
166
166
  protected applyStashedOp(_content: unknown): void {
167
- throw new Error("Not implemented");
167
+ const op = _content as ISignalOperation<T>;
168
+
169
+ switch (op.type) {
170
+ case "signal": {
171
+ break;
172
+ }
173
+ default: {
174
+ unreachableCase(op as never);
175
+ }
176
+ }
168
177
  }
169
178
  }
@@ -56,7 +56,6 @@ export class SharedSignalFactory implements IChannelFactory<ISharedSignal> {
56
56
 
57
57
  /**
58
58
  * Entrypoint for {@link ISharedSignal} creation.
59
- * @legacy
60
- * @alpha
59
+ * @legacy @beta
61
60
  */
62
61
  export const SharedSignal = createSharedObjectKind<ISharedSignal>(SharedSignalFactory);