@fluidframework/shared-object-base 2.0.0-rc.3.0.3 → 2.0.0-rc.4.0.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 (58) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/api-report/shared-object-base.api.md +20 -10
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +2 -1
  6. package/dist/index.js.map +1 -1
  7. package/dist/legacy.d.ts +2 -2
  8. package/dist/packageVersion.d.ts +1 -1
  9. package/dist/packageVersion.js +1 -1
  10. package/dist/packageVersion.js.map +1 -1
  11. package/dist/public.d.ts +1 -1
  12. package/dist/remoteObjectHandle.d.ts +5 -5
  13. package/dist/remoteObjectHandle.d.ts.map +1 -1
  14. package/dist/remoteObjectHandle.js +2 -4
  15. package/dist/remoteObjectHandle.js.map +1 -1
  16. package/dist/serializer.d.ts +3 -3
  17. package/dist/serializer.d.ts.map +1 -1
  18. package/dist/serializer.js +5 -4
  19. package/dist/serializer.js.map +1 -1
  20. package/dist/sharedObject.d.ts +18 -16
  21. package/dist/sharedObject.d.ts.map +1 -1
  22. package/dist/sharedObject.js +24 -14
  23. package/dist/sharedObject.js.map +1 -1
  24. package/dist/summarySerializer.d.ts +2 -2
  25. package/dist/summarySerializer.d.ts.map +1 -1
  26. package/dist/summarySerializer.js.map +1 -1
  27. package/lib/index.d.ts +1 -1
  28. package/lib/index.d.ts.map +1 -1
  29. package/lib/index.js +1 -1
  30. package/lib/index.js.map +1 -1
  31. package/lib/legacy.d.ts +2 -2
  32. package/lib/packageVersion.d.ts +1 -1
  33. package/lib/packageVersion.js +1 -1
  34. package/lib/packageVersion.js.map +1 -1
  35. package/lib/public.d.ts +1 -1
  36. package/lib/remoteObjectHandle.d.ts +5 -5
  37. package/lib/remoteObjectHandle.d.ts.map +1 -1
  38. package/lib/remoteObjectHandle.js +3 -5
  39. package/lib/remoteObjectHandle.js.map +1 -1
  40. package/lib/serializer.d.ts +3 -3
  41. package/lib/serializer.d.ts.map +1 -1
  42. package/lib/serializer.js +6 -5
  43. package/lib/serializer.js.map +1 -1
  44. package/lib/sharedObject.d.ts +18 -16
  45. package/lib/sharedObject.d.ts.map +1 -1
  46. package/lib/sharedObject.js +22 -13
  47. package/lib/sharedObject.js.map +1 -1
  48. package/lib/summarySerializer.d.ts +2 -2
  49. package/lib/summarySerializer.d.ts.map +1 -1
  50. package/lib/summarySerializer.js.map +1 -1
  51. package/lib/tsdoc-metadata.json +1 -1
  52. package/package.json +25 -23
  53. package/src/index.ts +6 -1
  54. package/src/packageVersion.ts +1 -1
  55. package/src/remoteObjectHandle.ts +7 -9
  56. package/src/serializer.ts +15 -9
  57. package/src/sharedObject.ts +41 -28
  58. package/src/summarySerializer.ts +2 -2
package/src/serializer.ts CHANGED
@@ -6,10 +6,16 @@
6
6
  // RATIONALE: Many methods consume and return 'any' by necessity.
7
7
  /* eslint-disable @typescript-eslint/no-unsafe-return */
8
8
 
9
- import { IFluidHandle, IFluidHandleContext } from "@fluidframework/core-interfaces";
9
+ import {
10
+ IFluidHandle,
11
+ IFluidHandleContext,
12
+ type IFluidHandleInternal,
13
+ } from "@fluidframework/core-interfaces/internal";
10
14
  import {
11
15
  generateHandleContextPath,
12
16
  isSerializedHandle,
17
+ isFluidHandle,
18
+ toFluidHandleInternal,
13
19
  } from "@fluidframework/runtime-utils/internal";
14
20
 
15
21
  import { RemoteFluidObjectHandle } from "./remoteObjectHandle.js";
@@ -108,8 +114,9 @@ export class FluidSerializer implements IFluidSerializer {
108
114
  : input;
109
115
  }
110
116
 
111
- public stringify(input: any, bind: IFluidHandle) {
112
- return JSON.stringify(input, (key, value) => this.encodeValue(value, bind));
117
+ public stringify(input: unknown, bind: IFluidHandle) {
118
+ const bindInternal = toFluidHandleInternal(bind);
119
+ return JSON.stringify(input, (key, value) => this.encodeValue(value, bindInternal));
113
120
  }
114
121
 
115
122
  // Parses the serialized data - context must match the context with which the JSON was stringified
@@ -119,12 +126,11 @@ export class FluidSerializer implements IFluidSerializer {
119
126
 
120
127
  // If the given 'value' is an IFluidHandle, returns the encoded IFluidHandle.
121
128
  // Otherwise returns the original 'value'. Used by 'encode()' and 'stringify()'.
122
- private readonly encodeValue = (value: any, bind: IFluidHandle) => {
123
- // Detect if 'value' is an IFluidHandle.
124
- const handle = value?.IFluidHandle;
125
-
129
+ private readonly encodeValue = (value: unknown, bind: IFluidHandleInternal) => {
126
130
  // If 'value' is an IFluidHandle return its encoded form.
127
- return handle !== undefined ? this.serializeHandle(handle, bind) : value;
131
+ return isFluidHandle(value)
132
+ ? this.serializeHandle(toFluidHandleInternal(value), bind)
133
+ : value;
128
134
  };
129
135
 
130
136
  // If the given 'value' is an encoded IFluidHandle, returns the decoded IFluidHandle.
@@ -194,7 +200,7 @@ export class FluidSerializer implements IFluidSerializer {
194
200
  return clone ?? input;
195
201
  }
196
202
 
197
- protected serializeHandle(handle: IFluidHandle, bind: IFluidHandle) {
203
+ protected serializeHandle(handle: IFluidHandleInternal, bind: IFluidHandleInternal) {
198
204
  bind.bind(handle);
199
205
  return {
200
206
  type: "__fluid_handle__",
@@ -5,7 +5,11 @@
5
5
 
6
6
  import { EventEmitterEventType } from "@fluid-internal/client-utils";
7
7
  import { AttachState } from "@fluidframework/container-definitions";
8
- import { IFluidHandle, ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
8
+ import {
9
+ IFluidHandle,
10
+ type IFluidHandleInternal,
11
+ ITelemetryBaseProperties,
12
+ } from "@fluidframework/core-interfaces/internal";
9
13
  import { assert } from "@fluidframework/core-utils/internal";
10
14
  import {
11
15
  IChannelAttributes,
@@ -14,7 +18,10 @@ import {
14
18
  IChannelStorageService,
15
19
  IFluidDataStoreRuntime,
16
20
  } from "@fluidframework/datastore-definitions";
17
- import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
21
+ import {
22
+ ISequencedDocumentMessage,
23
+ type IDocumentMessage,
24
+ } from "@fluidframework/protocol-definitions";
18
25
  import {
19
26
  IExperimentalIncrementalSummaryContext,
20
27
  IGarbageCollectionData,
@@ -25,8 +32,8 @@ import {
25
32
  blobCountPropertyName,
26
33
  totalBlobSizePropertyName,
27
34
  } from "@fluidframework/runtime-definitions/internal";
28
- import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
29
35
  import {
36
+ ITelemetryLoggerExt,
30
37
  DataProcessingError,
31
38
  EventEmitterWithErrorHandling,
32
39
  MonitoringContext,
@@ -36,6 +43,8 @@ import {
36
43
  tagCodeArtifacts,
37
44
  } from "@fluidframework/telemetry-utils/internal";
38
45
  import { v4 as uuid } from "uuid";
46
+ import { toDeltaManagerInternal } from "@fluidframework/runtime-utils/internal";
47
+ import type { IDeltaManager } from "@fluidframework/container-definitions/internal";
39
48
 
40
49
  import { SharedObjectHandle } from "./handle.js";
41
50
  import { FluidSerializer, IFluidSerializer } from "./serializer.js";
@@ -61,7 +70,7 @@ export abstract class SharedObjectCore<TEvent extends ISharedObjectEvents = ISha
61
70
  /**
62
71
  * The handle referring to this SharedObject
63
72
  */
64
- public readonly handle: IFluidHandle;
73
+ public readonly handle: IFluidHandleInternal;
65
74
 
66
75
  /**
67
76
  * Telemetry logger for the shared object
@@ -129,6 +138,13 @@ export abstract class SharedObjectCore<TEvent extends ISharedObjectEvents = ISha
129
138
  [this.opProcessingHelper, this.callbacksHelper] = this.setUpSampledTelemetryHelpers();
130
139
  }
131
140
 
141
+ /**
142
+ * Accessor for `this.runtime`'s {@link @fluidframework/datastore-definitions#IFluidDataStoreRuntime.deltaManager} as a {@link @fluidframework/container-definitions/internal#IDeltaManager}
143
+ */
144
+ protected get deltaManager(): IDeltaManager<ISequencedDocumentMessage, IDocumentMessage> {
145
+ return toDeltaManagerInternal(this.runtime.deltaManager);
146
+ }
147
+
132
148
  /**
133
149
  * This function is only supposed to be called from SharedObjectCore's constructor and
134
150
  * depends on a few things being set already. assert() calls make sure of it.
@@ -585,19 +601,7 @@ export abstract class SharedObjectCore<TEvent extends ISharedObjectEvents = ISha
585
601
  */
586
602
  public emit(event: EventEmitterEventType, ...args: any[]): boolean {
587
603
  return this.callbacksHelper.measure(() => {
588
- // Creating ops while handling a DDS event can lead
589
- // to undefined behavior and events observed in the wrong order.
590
- // For example, we have two callbacks registered for a DDS, A and B.
591
- // Then if on change #1 callback A creates change #2, the invocation flow will be:
592
- //
593
- // A because of #1
594
- // A because of #2
595
- // B because of #2
596
- // B because of #1
597
- //
598
- // The runtime must enforce op coherence by not allowing any ops to be created during
599
- // the event handler
600
- return this.runtime.ensureNoDataModelChanges(() => super.emit(event, ...args));
604
+ return super.emit(event, ...args);
601
605
  });
602
606
  }
603
607
 
@@ -794,12 +798,6 @@ export interface ISharedObjectKind<TSharedObject> {
794
798
  * - {@link @fluidframework/fluid-static#IFluidContainer.create} if using `@fluidframework/fluid-static`, for example via `@fluidframework/azure-client`.
795
799
  *
796
800
  * - {@link ISharedObjectKind.create} if using a custom container definitions (and thus not using {@link @fluidframework/fluid-static#IFluidContainer}).
797
- *
798
- * @privateRemarks
799
- * TODO:
800
- * Many tests use this and can't use {@link ISharedObjectKind.create}.
801
- * The docs should make it clear why that's ok, and why {@link ISharedObjectKind.create} isn't in such a way that when reading non app code (like tests in this package)
802
- * someone can tell if the wrong one is being used without running it and seeing if it works.
803
801
  */
804
802
  getFactory(): IChannelFactory<TSharedObject>;
805
803
 
@@ -816,14 +814,29 @@ export interface ISharedObjectKind<TSharedObject> {
816
814
  * const myTree = SharedTree.create(this.runtime, id);
817
815
  * ```
818
816
  * @remarks
817
+ * The created object is local (detached): insert a handle to it into an attached object to share (attach) it.
819
818
  * If using `@fluidframework/fluid-static` (for example via `@fluidframework/azure-client`), use {@link @fluidframework/fluid-static#IFluidContainer.create} instead of calling this directly.
820
819
  *
821
820
  * @privateRemarks
822
- * TODO:
823
- * This returns null when used with MockFluidDataStoreRuntime, so its unclear how tests should create DDS instances unless using `RootDataObject.create` (which most tests shouldn't to minimize dependencies).
824
- * In practice tests either avoid mock runtimes, use getFactory(), or call the DDS constructor directly. It is unclear (from docs) how getFactory().create differs but it does not rely on runtime.createChannel so it works with mock runtimes.
825
- * TODO:
826
- * See note on ISharedObjectKind.getFactory.
821
+ * This can only be used with a `MockFluidDataStoreRuntime` when that mock is created with a `registry` containing a factory for this shared object.
827
822
  */
828
823
  create(runtime: IFluidDataStoreRuntime, id?: string): TSharedObject;
829
824
  }
825
+
826
+ /**
827
+ * Utility for creating ISharedObjectKind instances.
828
+ * @internal
829
+ */
830
+ export function createSharedObjectKind<TSharedObject>(
831
+ factory: (new () => IChannelFactory<TSharedObject>) & { Type: string },
832
+ ): ISharedObjectKind<TSharedObject> {
833
+ return {
834
+ getFactory(): IChannelFactory<TSharedObject> {
835
+ return new factory();
836
+ },
837
+
838
+ create(runtime: IFluidDataStoreRuntime, id?: string): TSharedObject {
839
+ return runtime.createChannel(id, factory.Type) as TSharedObject;
840
+ },
841
+ };
842
+ }
@@ -3,7 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { IFluidHandle } from "@fluidframework/core-interfaces";
6
+ import { type IFluidHandleInternal } from "@fluidframework/core-interfaces/internal";
7
7
 
8
8
  import { FluidSerializer } from "./serializer.js";
9
9
 
@@ -17,7 +17,7 @@ export class SummarySerializer extends FluidSerializer {
17
17
  return Array.from(this.serializedRoutes);
18
18
  }
19
19
 
20
- protected serializeHandle(handle: IFluidHandle, bind: IFluidHandle) {
20
+ protected serializeHandle(handle: IFluidHandleInternal, bind: IFluidHandleInternal) {
21
21
  this.serializedRoutes.add(handle.absolutePath);
22
22
  return super.serializeHandle(handle, bind);
23
23
  }