@fluidframework/core-interfaces 2.41.0-338401 → 2.42.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 (72) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/api-report/core-interfaces.legacy.alpha.api.md +6 -0
  3. package/dist/brandedType.d.ts +41 -0
  4. package/dist/brandedType.d.ts.map +1 -0
  5. package/dist/brandedType.js +7 -0
  6. package/dist/brandedType.js.map +1 -0
  7. package/dist/exposedInternalUtilityTypes.d.ts +64 -6
  8. package/dist/exposedInternalUtilityTypes.d.ts.map +1 -1
  9. package/dist/exposedInternalUtilityTypes.js.map +1 -1
  10. package/dist/exposedUtilityTypes.d.ts +1 -0
  11. package/dist/exposedUtilityTypes.d.ts.map +1 -1
  12. package/dist/exposedUtilityTypes.js.map +1 -1
  13. package/dist/index.d.ts +2 -1
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js.map +1 -1
  16. package/dist/internal.d.ts +11 -0
  17. package/dist/internal.d.ts.map +1 -1
  18. package/dist/internal.js.map +1 -1
  19. package/dist/jsonSerializable.d.ts +2 -2
  20. package/dist/jsonSerializable.js.map +1 -1
  21. package/dist/jsonUtils.d.ts +70 -0
  22. package/dist/jsonUtils.d.ts.map +1 -0
  23. package/dist/jsonUtils.js +7 -0
  24. package/dist/jsonUtils.js.map +1 -0
  25. package/dist/legacy.d.ts +2 -1
  26. package/dist/messages.d.ts +22 -5
  27. package/dist/messages.d.ts.map +1 -1
  28. package/dist/messages.js.map +1 -1
  29. package/dist/opaqueJson.d.ts +60 -0
  30. package/dist/opaqueJson.d.ts.map +1 -0
  31. package/dist/opaqueJson.js +8 -0
  32. package/dist/opaqueJson.js.map +1 -0
  33. package/lib/brandedType.d.ts +41 -0
  34. package/lib/brandedType.d.ts.map +1 -0
  35. package/lib/brandedType.js +6 -0
  36. package/lib/brandedType.js.map +1 -0
  37. package/lib/exposedInternalUtilityTypes.d.ts +64 -6
  38. package/lib/exposedInternalUtilityTypes.d.ts.map +1 -1
  39. package/lib/exposedInternalUtilityTypes.js.map +1 -1
  40. package/lib/exposedUtilityTypes.d.ts +1 -0
  41. package/lib/exposedUtilityTypes.d.ts.map +1 -1
  42. package/lib/exposedUtilityTypes.js.map +1 -1
  43. package/lib/index.d.ts +2 -1
  44. package/lib/index.d.ts.map +1 -1
  45. package/lib/index.js.map +1 -1
  46. package/lib/internal.d.ts +11 -0
  47. package/lib/internal.d.ts.map +1 -1
  48. package/lib/internal.js.map +1 -1
  49. package/lib/jsonSerializable.d.ts +2 -2
  50. package/lib/jsonSerializable.js.map +1 -1
  51. package/lib/jsonUtils.d.ts +70 -0
  52. package/lib/jsonUtils.d.ts.map +1 -0
  53. package/lib/jsonUtils.js +6 -0
  54. package/lib/jsonUtils.js.map +1 -0
  55. package/lib/legacy.d.ts +2 -1
  56. package/lib/messages.d.ts +22 -5
  57. package/lib/messages.d.ts.map +1 -1
  58. package/lib/messages.js.map +1 -1
  59. package/lib/opaqueJson.d.ts +60 -0
  60. package/lib/opaqueJson.d.ts.map +1 -0
  61. package/lib/opaqueJson.js +6 -0
  62. package/lib/opaqueJson.js.map +1 -0
  63. package/package.json +3 -3
  64. package/src/brandedType.ts +43 -0
  65. package/src/exposedInternalUtilityTypes.ts +200 -87
  66. package/src/exposedUtilityTypes.ts +1 -0
  67. package/src/index.ts +3 -1
  68. package/src/internal.ts +26 -0
  69. package/src/jsonSerializable.ts +2 -2
  70. package/src/jsonUtils.ts +90 -0
  71. package/src/messages.ts +24 -6
  72. package/src/opaqueJson.ts +87 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonUtils.js","sourceRoot":"","sources":["../src/jsonUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { JsonDeserialized } from \"./jsonDeserialized.js\";\nimport type { JsonSerializable, JsonSerializableOptions } from \"./jsonSerializable.js\";\nimport type { OpaqueJsonDeserialized, OpaqueJsonSerializable } from \"./opaqueJson.js\";\n\n/**\n * Helper to return an Opaque Json type version of Json type\n *\n * @remarks\n * To use this helper, create a helper function that filters type `T` through at\n * least {@link JsonSerializable} and optionally {@link JsonDeserialized}. Then\n * cast value through `unknown as JsonTypeToOpaqueJson<T, Options>`, where\n * `Options` reflects the serialization capabilities of that area.\n *\n * @example\n * ```ts\n * function castToOpaqueJson<T>(value: JsonSerializable<T>): JsonTypeToOpaqueJson<T> {\n * return value as unknown as JsonTypeToOpaqueJson<T>;\n * }\n * ```\n *\n * @internal\n */\nexport type JsonTypeToOpaqueJson<\n\tT,\n\tOptions extends JsonSerializableOptions = {\n\t\tAllowExactly: [];\n\t\tAllowExtensionOf: never;\n\t},\n> = T extends JsonSerializable<T, Options> & JsonDeserialized<T, Options>\n\t? OpaqueJsonSerializable<\n\t\t\tT,\n\t\t\tOptions extends { AllowExactly: unknown[] } ? Options[\"AllowExactly\"] : [],\n\t\t\tOptions extends { AllowExtensionOf: unknown } ? Options[\"AllowExtensionOf\"] : never\n\t\t> &\n\t\t\tOpaqueJsonDeserialized<\n\t\t\t\tT,\n\t\t\t\tOptions extends { AllowExactly: unknown[] } ? Options[\"AllowExactly\"] : [],\n\t\t\t\tOptions extends { AllowExtensionOf: unknown } ? Options[\"AllowExtensionOf\"] : never\n\t\t\t>\n\t: T extends JsonDeserialized<T, Options>\n\t\t? OpaqueJsonDeserialized<\n\t\t\t\tT,\n\t\t\t\tOptions extends { AllowExactly: unknown[] } ? Options[\"AllowExactly\"] : [],\n\t\t\t\tOptions extends { AllowExtensionOf: unknown } ? Options[\"AllowExtensionOf\"] : never\n\t\t\t>\n\t\t: T extends JsonSerializable<T, Options>\n\t\t\t? OpaqueJsonSerializable<\n\t\t\t\t\tT,\n\t\t\t\t\tOptions extends { AllowExactly: unknown[] } ? Options[\"AllowExactly\"] : [],\n\t\t\t\t\tOptions extends { AllowExtensionOf: unknown } ? Options[\"AllowExtensionOf\"] : never\n\t\t\t\t>\n\t\t\t: never;\n\n/**\n * Helper to extract Json type from an Opaque Json type\n *\n * @remarks\n * This type only works with basic serialization capabilities (options).\n * Attempts to make `Options` generic resulted in infinite recursion\n * in TypeScript compiler that was not understood, so this type only\n * supports TJson (value type) variance.\n *\n * To use this helper, create a helper function that accepts\n * `OpaqueJsonSerializable<unknown> | OpaqueJsonDeserialized<unknown>`.\n *\n * @example\n * ```ts\n * function exposeFromOpaqueJson<TOpaque extends OpaqueJsonSerializable<unknown> | OpaqueJsonDeserialized<unknown>>(\n *\t opaque: TOpaque,\n * ): OpaqueJsonToJsonType<TOpaque> {\n * return opaque as unknown as OpaqueJsonToJsonType<TOpaque>;\n * }\n * ```\n *\n * @internal\n */\nexport type OpaqueJsonToJsonType<\n\tTOpaque extends OpaqueJsonSerializable<unknown> | OpaqueJsonDeserialized<unknown>,\n> = TOpaque extends OpaqueJsonSerializable<infer TJson> & OpaqueJsonDeserialized<infer TJson>\n\t? JsonSerializable<TJson> & JsonDeserialized<TJson>\n\t: TOpaque extends OpaqueJsonDeserialized<infer TJson>\n\t\t? JsonDeserialized<TJson>\n\t\t: TOpaque extends OpaqueJsonSerializable<infer TJson>\n\t\t\t? JsonSerializable<TJson>\n\t\t\t: never;\n"]}
package/lib/legacy.d.ts CHANGED
@@ -57,5 +57,6 @@ export {
57
57
  IProvideFluidHandle,
58
58
  IProvideFluidHandleContext,
59
59
  IThrottlingWarning,
60
- PayloadState
60
+ PayloadState,
61
+ TypedMessage
61
62
  } from "./index.js";
package/lib/messages.d.ts CHANGED
@@ -2,6 +2,26 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
+ /**
6
+ * A message that has a string `type` associated with `content`.
7
+ *
8
+ * @remarks
9
+ * This type is meant to be used indirectly. Most commonly as a constraint
10
+ * for generics of message structures.
11
+ *
12
+ * @legacy
13
+ * @alpha
14
+ */
15
+ export interface TypedMessage {
16
+ /**
17
+ * The type of the message.
18
+ */
19
+ type: string;
20
+ /**
21
+ * The contents of the message.
22
+ */
23
+ content: unknown;
24
+ }
5
25
  /**
6
26
  * @internal
7
27
  *
@@ -12,7 +32,7 @@
12
32
  *
13
33
  * See at `server/routerlicious/packages/lambdas/src/utils/messageGenerator.ts`.
14
34
  */
15
- export interface ISignalEnvelope {
35
+ export interface ISignalEnvelope<TMessage extends TypedMessage = TypedMessage> {
16
36
  /**
17
37
  * The target for the envelope, undefined for the container
18
38
  */
@@ -24,9 +44,6 @@ export interface ISignalEnvelope {
24
44
  /**
25
45
  * The contents of the envelope
26
46
  */
27
- contents: {
28
- type: string;
29
- content: any;
30
- };
47
+ contents: TMessage;
31
48
  }
32
49
  //# sourceMappingURL=messages.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;GASG;AACH,MAAM,WAAW,eAAe;IAC/B;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,mCAAmC,CAAC,EAAE,MAAM,CAAC;IAE7C;;OAEG;IACH,QAAQ,EAAE;QACT,IAAI,EAAE,MAAM,CAAC;QAEb,OAAO,EAAE,GAAG,CAAC;KACb,CAAC;CACF"}
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAY;IAC5B;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,eAAe,CAAC,QAAQ,SAAS,YAAY,GAAG,YAAY;IAC5E;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,mCAAmC,CAAC,EAAE,MAAM,CAAC;IAE7C;;OAEG;IACH,QAAQ,EAAE,QAAQ,CAAC;CACnB"}
@@ -1 +1 @@
1
- {"version":3,"file":"messages.js","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * @internal\n *\n * @privateRemarks\n * `IRuntimeSignalEnvelope` is an interface that mirrors `ISignalEnvelope` for signals that come from an external\n * caller (not sent by a client—so no `clientBroadcastSignalSequenceNumber`) and are always addressed\n * to the Container (so no `address`).\n *\n * See at `server/routerlicious/packages/lambdas/src/utils/messageGenerator.ts`.\n */\nexport interface ISignalEnvelope {\n\t/**\n\t * The target for the envelope, undefined for the container\n\t */\n\taddress?: string;\n\n\t/**\n\t * Signal tracking identifier for self submitted broadcast signals.\n\t */\n\tclientBroadcastSignalSequenceNumber?: number;\n\n\t/**\n\t * The contents of the envelope\n\t */\n\tcontents: {\n\t\ttype: string;\n\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\tcontent: any;\n\t};\n}\n"]}
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * A message that has a string `type` associated with `content`.\n *\n * @remarks\n * This type is meant to be used indirectly. Most commonly as a constraint\n * for generics of message structures.\n *\n * @legacy\n * @alpha\n */\nexport interface TypedMessage {\n\t/**\n\t * The type of the message.\n\t */\n\ttype: string;\n\n\t/**\n\t * The contents of the message.\n\t */\n\tcontent: unknown;\n}\n\n/**\n * @internal\n *\n * @privateRemarks\n * `IRuntimeSignalEnvelope` is an interface that mirrors `ISignalEnvelope` for signals that come from an external\n * caller (not sent by a client—so no `clientBroadcastSignalSequenceNumber`) and are always addressed\n * to the Container (so no `address`).\n *\n * See at `server/routerlicious/packages/lambdas/src/utils/messageGenerator.ts`.\n */\nexport interface ISignalEnvelope<TMessage extends TypedMessage = TypedMessage> {\n\t/**\n\t * The target for the envelope, undefined for the container\n\t */\n\taddress?: string;\n\n\t/**\n\t * Signal tracking identifier for self submitted broadcast signals.\n\t */\n\tclientBroadcastSignalSequenceNumber?: number;\n\n\t/**\n\t * The contents of the envelope\n\t */\n\tcontents: TMessage;\n}\n"]}
@@ -0,0 +1,60 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { BrandedType } from "./brandedType.js";
6
+ /**
7
+ * Placeholder for value that is known to be JSON because it has been
8
+ * deserialized (`T` filtered through {@link JsonDeserialized} as out value).
9
+ *
10
+ * @remarks
11
+ * Usage:
12
+ *
13
+ * - Cast to with `as unknown as OpaqueJsonDeserialized<T>` when value `T`
14
+ * has been filtered through {@link JsonDeserialized}.
15
+ *
16
+ * - Cast from with `as unknown as JsonDeserialized<T>` when "instance" will
17
+ * be read.
18
+ *
19
+ * @sealed
20
+ * @beta
21
+ */
22
+ export declare class OpaqueJsonDeserialized<T, in out Option_AllowExactly extends unknown[] = [], out Option_AllowExtensionOf = never> extends BrandedType<"JsonDeserialized"> {
23
+ protected readonly JsonDeserialized: {
24
+ Type: T;
25
+ Options: {
26
+ AllowExactly: Option_AllowExactly;
27
+ AllowExtensionOf: Option_AllowExtensionOf;
28
+ };
29
+ };
30
+ protected readonly Option_AllowExactly_Invariance: (Option_AllowExactly: Option_AllowExactly) => void;
31
+ private constructor();
32
+ }
33
+ /**
34
+ * Placeholder for value that is known to be JSON because it will have been
35
+ * serialized checked (`T` filtered through {@link JsonSerializable} before "created").
36
+ *
37
+ * @remarks
38
+ * Usage:
39
+ *
40
+ * - Cast to with `as unknown as OpaqueJsonSerializable<T>` when value `T`
41
+ * has been filtered through {@link JsonSerializable}.
42
+ *
43
+ * - Cast from with `as unknown as JsonSerializable<T>` or `as unknown as T`
44
+ * when "instance" will be forwarded along.
45
+ *
46
+ * @sealed
47
+ * @beta
48
+ */
49
+ export declare class OpaqueJsonSerializable<T, in out Option_AllowExactly extends unknown[] = [], out Option_AllowExtensionOf = never> extends BrandedType<"JsonSerializable"> {
50
+ protected readonly JsonSerializable: {
51
+ Type: T;
52
+ Options: {
53
+ AllowExactly: Option_AllowExactly;
54
+ AllowExtensionOf: Option_AllowExtensionOf;
55
+ };
56
+ };
57
+ protected readonly Option_AllowExactly_Invariance: (Option_AllowExactly: Option_AllowExactly) => void;
58
+ private constructor();
59
+ }
60
+ //# sourceMappingURL=opaqueJson.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opaqueJson.d.ts","sourceRoot":"","sources":["../src/opaqueJson.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,OAAO,OAAO,sBAAsB,CAC1C,CAAC,EAMD,EAAE,CAAC,GAAG,CAAC,mBAAmB,SAAS,OAAO,EAAE,GAAG,EAAE,EACjD,GAAG,CAAC,uBAAuB,GAAG,KAAK,CAClC,SAAQ,WAAW,CAAC,kBAAkB,CAAC;IACxC,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE;QACpC,IAAI,EAAE,CAAC,CAAC;QACR,OAAO,EAAE;YACR,YAAY,EAAE,mBAAmB,CAAC;YAClC,gBAAgB,EAAE,uBAAuB,CAAC;SAC1C,CAAC;KACF,CAAC;IAEF,SAAS,CAAC,QAAQ,CAAC,8BAA8B,EAAE,CAClD,mBAAmB,EAAE,mBAAmB,KACpC,IAAI,CAAC;IACV,OAAO;CACP;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,OAAO,OAAO,sBAAsB,CAC1C,CAAC,EAMD,EAAE,CAAC,GAAG,CAAC,mBAAmB,SAAS,OAAO,EAAE,GAAG,EAAE,EACjD,GAAG,CAAC,uBAAuB,GAAG,KAAK,CAElC,SAAQ,WAAW,CAAC,kBAAkB,CAAC;IACxC,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE;QACpC,IAAI,EAAE,CAAC,CAAC;QACR,OAAO,EAAE;YACR,YAAY,EAAE,mBAAmB,CAAC;YAClC,gBAAgB,EAAE,uBAAuB,CAAC;SAC1C,CAAC;KACF,CAAC;IAEF,SAAS,CAAC,QAAQ,CAAC,8BAA8B,EAAE,CAClD,mBAAmB,EAAE,mBAAmB,KACpC,IAAI,CAAC;IACV,OAAO;CACP"}
@@ -0,0 +1,6 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { BrandedType } from "./brandedType.js";
6
+ //# sourceMappingURL=opaqueJson.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opaqueJson.js","sourceRoot":"","sources":["../src/opaqueJson.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { BrandedType } from \"./brandedType.js\";\n\n/**\n * Placeholder for value that is known to be JSON because it has been\n * deserialized (`T` filtered through {@link JsonDeserialized} as out value).\n *\n * @remarks\n * Usage:\n *\n * - Cast to with `as unknown as OpaqueJsonDeserialized<T>` when value `T`\n * has been filtered through {@link JsonDeserialized}.\n *\n * - Cast from with `as unknown as JsonDeserialized<T>` when \"instance\" will\n * be read.\n *\n * @sealed\n * @beta\n */\nexport declare class OpaqueJsonDeserialized<\n\tT,\n\t// These options are split from typical `JsonDeserializedOptions` as this type\n\t// requires correct variance per the two options and AllowExactly has special\n\t// variance and must be treated as invariant. In actuality, each member of the\n\t// AllowExactly tuple is invariant, but tuple as a set is covariant. This is not\n\t// expressible in TypeScript.\n\tin out Option_AllowExactly extends unknown[] = [],\n\tout Option_AllowExtensionOf = never,\n> extends BrandedType<\"JsonDeserialized\"> {\n\tprotected readonly JsonDeserialized: {\n\t\tType: T;\n\t\tOptions: {\n\t\t\tAllowExactly: Option_AllowExactly;\n\t\t\tAllowExtensionOf: Option_AllowExtensionOf;\n\t\t};\n\t};\n\t// Option_AllowExactly is covariant from above. This removes covariance, leaving only invariance.\n\tprotected readonly Option_AllowExactly_Invariance: (\n\t\tOption_AllowExactly: Option_AllowExactly,\n\t) => void;\n\tprivate constructor();\n}\n\n/**\n * Placeholder for value that is known to be JSON because it will have been\n * serialized checked (`T` filtered through {@link JsonSerializable} before \"created\").\n *\n * @remarks\n * Usage:\n *\n * - Cast to with `as unknown as OpaqueJsonSerializable<T>` when value `T`\n * has been filtered through {@link JsonSerializable}.\n *\n * - Cast from with `as unknown as JsonSerializable<T>` or `as unknown as T`\n * when \"instance\" will be forwarded along.\n *\n * @sealed\n * @beta\n */\nexport declare class OpaqueJsonSerializable<\n\tT,\n\t// These options are split from typical `JsonSerializableOptions` as this type\n\t// requires correct variance per the two options and AllowExactly has special\n\t// variance and must be treated as invariant. In actuality, each member of the\n\t// AllowExactly tuple is invariant, but tuple as a set is covariant. This is not\n\t// expressible in TypeScript.\n\tin out Option_AllowExactly extends unknown[] = [],\n\tout Option_AllowExtensionOf = never,\n\t// JsonSerializableOptions.IgnoreInaccessibleMembers is ignored\n> extends BrandedType<\"JsonSerializable\"> {\n\tprotected readonly JsonSerializable: {\n\t\tType: T;\n\t\tOptions: {\n\t\t\tAllowExactly: Option_AllowExactly;\n\t\t\tAllowExtensionOf: Option_AllowExtensionOf;\n\t\t};\n\t};\n\t// Option_AllowExactly is covariant from above. This removes covariance, leaving only invariance.\n\tprotected readonly Option_AllowExactly_Invariance: (\n\t\tOption_AllowExactly: Option_AllowExactly,\n\t) => void;\n\tprivate constructor();\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/core-interfaces",
3
- "version": "2.41.0-338401",
3
+ "version": "2.42.0",
4
4
  "description": "Fluid object interfaces",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -76,8 +76,8 @@
76
76
  "@fluid-tools/build-cli": "^0.55.0",
77
77
  "@fluidframework/build-common": "^2.0.3",
78
78
  "@fluidframework/build-tools": "^0.55.0",
79
- "@fluidframework/core-interfaces-previous": "npm:@fluidframework/core-interfaces@2.40.0",
80
- "@fluidframework/eslint-config-fluid": "^5.7.3",
79
+ "@fluidframework/core-interfaces-previous": "npm:@fluidframework/core-interfaces@2.41.0",
80
+ "@fluidframework/eslint-config-fluid": "^5.7.4",
81
81
  "@microsoft/api-extractor": "7.52.8",
82
82
  "@types/mocha": "^10.0.10",
83
83
  "@types/node": "^18.19.0",
@@ -0,0 +1,43 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ /**
7
+ * Base branded type which can be used to annotate other type.
8
+ *
9
+ * @remarks
10
+ * To use derive another class declaration and ideally add additional private
11
+ * properties to further distinguish the type.
12
+ *
13
+ * Since branded types are not real value types, they will always need to be
14
+ * created using `as` syntax and very often `as unknown` first.
15
+ *
16
+ * This class should never exist at runtime, so it is only declared.
17
+ *
18
+ * @sealed
19
+ * @internal
20
+ */
21
+ export declare class BrandedType<out Brand> {
22
+ /**
23
+ * Compile time only marker to make type checking more strict.
24
+ * This method will not exist at runtime and accessing it is invalid.
25
+ *
26
+ * @privateRemarks
27
+ * `Brand` is used as the return type of a method rather than a simple
28
+ * readonly property as this allows types with two brands to be
29
+ * intersected without getting `never`.
30
+ * The method takes in `never` to help emphasize that it's not callable.
31
+ */
32
+ protected readonly brand: (dummy: never) => Brand;
33
+
34
+ protected constructor();
35
+
36
+ /**
37
+ * Since this class is a compile time only type brand, `instanceof` will
38
+ * never work with it. * This `Symbol.hasInstance` implementation ensures
39
+ * that `instanceof` will error if used, and in TypeScript 5.3 and newer
40
+ * will produce a compile time error if used.
41
+ */
42
+ public static [Symbol.hasInstance](value: never): value is never;
43
+ }
@@ -12,6 +12,7 @@ import type {
12
12
  SerializationErrorPerUndefinedArrayElement,
13
13
  } from "./jsonSerializationErrors.js";
14
14
  import type { JsonTypeWith, NonNullJsonObjectWith, ReadonlyJsonTypeWith } from "./jsonType.js";
15
+ import type { OpaqueJsonDeserialized, OpaqueJsonSerializable } from "./opaqueJson.js";
15
16
 
16
17
  /**
17
18
  * Unique symbol for recursion meta-typing.
@@ -535,20 +536,41 @@ export namespace InternalUtilityTypes {
535
536
  */
536
537
  export type IsExactlyObject<T extends object> = IsSameType<T, object>;
537
538
 
539
+ /**
540
+ * Any Record type.
541
+ *
542
+ * @system
543
+ */
544
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- `any` for property types is required to avoid "Index signature for type 'string' is missing in type" in some outside `FlattenIntersection` uses.
545
+ export type AnyRecord = Record<keyof any, any>;
546
+
538
547
  /**
539
548
  * Creates a simple object type from an intersection of multiple.
540
549
  * @privateRemarks
541
- * `T extends Record` within the implementation encourages tsc to process
550
+ * `T extends AnyRecord` within the implementation encourages tsc to process
542
551
  * intersections within unions.
543
552
  *
544
553
  * @system
545
554
  */
546
- export type FlattenIntersection<T extends Record<string | number | symbol, unknown>> =
547
- T extends Record<string | number | symbol, unknown>
548
- ? {
549
- [K in keyof T]: T[K];
550
- }
551
- : T;
555
+ export type FlattenIntersection<T extends AnyRecord> = T extends AnyRecord
556
+ ? {
557
+ [K in keyof T]: T[K];
558
+ }
559
+ : T;
560
+
561
+ /**
562
+ * Convenience constraint for any Opaque Json type.
563
+ *
564
+ * @remarks
565
+ * Use in extends check: `T extends AnyOpaqueJsonType`
566
+ *
567
+ * @system
568
+ */
569
+ export type AnyOpaqueJsonType =
570
+ /* eslint-disable @typescript-eslint/no-explicit-any -- must use `any` for invariant constraint override */
571
+ | OpaqueJsonSerializable<unknown, any, unknown>
572
+ | OpaqueJsonDeserialized<unknown, any, unknown>;
573
+ /* eslint-enable @typescript-eslint/no-explicit-any */
552
574
 
553
575
  /**
554
576
  * Extracts Function portion from an intersection (&) type returning
@@ -768,15 +790,23 @@ export namespace InternalUtilityTypes {
768
790
  AllowExtensionOf: Options extends { AllowExtensionOf: unknown }
769
791
  ? Options["AllowExtensionOf"]
770
792
  : never;
771
- // There Substitute type could be extracted to helper type, but are kept explicit here
772
- // to make JsonTypeWith show explicitly in results for users, rather
773
- // than either the helper type name or a partially unrolled version.
774
- DegenerateSubstitute: JsonTypeWith<
775
- | (Options extends { AllowExactly: unknown[] }
776
- ? TupleToUnion<Options["AllowExactly"]>
777
- : never)
778
- | (Options extends { AllowExtensionOf: unknown } ? Options["AllowExtensionOf"] : never)
779
- >;
793
+ // The Substitute type could be extracted to helper type, but is kept explicit here
794
+ // to make JsonTypeWith and OpaqueJsonSerializable show explicitly in results for
795
+ // users, rather than either the helper type name or a partially unrolled version.
796
+ DegenerateSubstitute:
797
+ | JsonTypeWith<
798
+ | (Options extends { AllowExactly: unknown[] }
799
+ ? TupleToUnion<Options["AllowExactly"]>
800
+ : never)
801
+ | (Options extends { AllowExtensionOf: unknown }
802
+ ? Options["AllowExtensionOf"]
803
+ : never)
804
+ >
805
+ | OpaqueJsonSerializable<
806
+ unknown,
807
+ Options extends { AllowExactly: unknown[] } ? Options["AllowExactly"] : [],
808
+ Options extends { AllowExtensionOf: unknown } ? Options["AllowExtensionOf"] : never
809
+ >;
780
810
  } extends infer Controls
781
811
  ? /* Controls should always satisfy FilterControlsWithSubstitution, but Typescript wants a check */
782
812
  Controls extends FilterControlsWithSubstitution
@@ -789,8 +819,14 @@ export namespace InternalUtilityTypes {
789
819
  T,
790
820
  {
791
821
  AllowExactly: Controls["AllowExactly"];
792
- // Add in primitives that may be branded to ignore intersection classes
793
- AllowExtensionOf: Controls["AllowExtensionOf"] | boolean | number | string;
822
+ AllowExtensionOf:
823
+ | Controls["AllowExtensionOf"]
824
+ // Add in primitives that may be branded to ignore intersection classes
825
+ | boolean
826
+ | number
827
+ | string
828
+ // Add in Opaque Json types
829
+ | AnyOpaqueJsonType;
794
830
  DegenerateSubstitute: Controls["DegenerateSubstitute"];
795
831
  },
796
832
  "found non-publics",
@@ -818,6 +854,47 @@ export namespace InternalUtilityTypes {
818
854
  : never /* FilterControlsWithSubstitution assert else; should never be reached */
819
855
  : never /* unreachable else for infer */;
820
856
 
857
+ /**
858
+ * Handle Opaque Json types for {@link JsonSerializable}.
859
+ *
860
+ * @remarks
861
+ * {@link OpaqueJsonSerializable} and {@link OpaqueJsonDeserialized} instances
862
+ * are limited to `Controls` given context supports.
863
+ * `T` from the original Opaque type is preserved. In the case that this now
864
+ * produces an improper type such as a `bigint` being let through that is no
865
+ * longer supported, then the variance of `Controls` is expected to raise
866
+ * the incompatibility error.
867
+ *
868
+ * @privateRemarks
869
+ * Additional intersections beyond {@link OpaqueJsonSerializable},
870
+ * {@link OpaqueJsonDeserialized}, or intersected matching opaque pair are
871
+ * not correctly filtered as need is not expected.
872
+ *
873
+ * @system
874
+ */
875
+ export type JsonSerializableOpaqueAllowances<
876
+ T extends AnyOpaqueJsonType,
877
+ Controls extends FilterControlsWithSubstitution,
878
+ > = /* eslint-disable @typescript-eslint/no-explicit-any -- must use `any` for invariant constraint override */
879
+ /* infer underlying data type */ T extends
880
+ | OpaqueJsonSerializable<infer TData, any, unknown>
881
+ | OpaqueJsonDeserialized<infer TData, any, unknown>
882
+ ? T extends OpaqueJsonSerializable<TData, any, unknown> &
883
+ OpaqueJsonDeserialized<TData, any, unknown>
884
+ ? OpaqueJsonSerializable<TData, Controls["AllowExactly"], Controls["AllowExtensionOf"]> &
885
+ OpaqueJsonDeserialized<TData, Controls["AllowExactly"], Controls["AllowExtensionOf"]>
886
+ : T extends OpaqueJsonSerializable<TData, any, unknown>
887
+ ? OpaqueJsonSerializable<TData, Controls["AllowExactly"], Controls["AllowExtensionOf"]>
888
+ : T extends OpaqueJsonDeserialized<TData, any, unknown>
889
+ ? OpaqueJsonDeserialized<
890
+ TData,
891
+ Controls["AllowExactly"],
892
+ Controls["AllowExtensionOf"]
893
+ >
894
+ : "internal error: failed to determine Opaque Json type"
895
+ : never;
896
+ /* eslint-enable @typescript-eslint/no-explicit-any */
897
+
821
898
  /**
822
899
  * Essentially a check for a template literal that has $\{string\} or
823
900
  * $\{number\} in the pattern. Just `string` and/or `number` also match.
@@ -926,45 +1003,50 @@ export namespace InternalUtilityTypes {
926
1003
  >
927
1004
  : /* test for enum like types */ IfEnumLike<T> extends never
928
1005
  ? /* enum or similar simple type (return as-is) => */ T
929
- : /* property bag => */ FlattenIntersection<
930
- {
931
- /* required properties are recursed and may not have undefined values. */
932
- [K in keyof T as RequiredNonSymbolKeysOf<
933
- T,
934
- K
935
- >]-?: IfPossiblyUndefinedProperty<
936
- K,
937
- T[K],
938
- {
939
- IfPossiblyUndefined: {
940
- ["error required property may not allow `undefined` value"]: never;
941
- };
942
- IfUnknownNonIndexed: {
943
- ["error required property may not allow `unknown` value"]: never;
944
- };
945
- Otherwise: JsonSerializableFilter<
946
- T[K],
947
- Controls,
948
- [TNextAncestor, ...TAncestorTypes]
949
- >;
950
- }
951
- >;
952
- } & {
953
- /* optional properties are recursed and, when exactOptionalPropertyTypes is
1006
+ : /* test for Opaque Json types */ T extends AnyOpaqueJsonType
1007
+ ? /* Opaque Json type => */ JsonSerializableOpaqueAllowances<
1008
+ T,
1009
+ Controls
1010
+ >
1011
+ : /* property bag => */ FlattenIntersection<
1012
+ {
1013
+ /* required properties are recursed and may not have undefined values. */
1014
+ [K in keyof T as RequiredNonSymbolKeysOf<
1015
+ T,
1016
+ K
1017
+ >]-?: IfPossiblyUndefinedProperty<
1018
+ K,
1019
+ T[K],
1020
+ {
1021
+ IfPossiblyUndefined: {
1022
+ ["error required property may not allow `undefined` value"]: never;
1023
+ };
1024
+ IfUnknownNonIndexed: {
1025
+ ["error required property may not allow `unknown` value"]: never;
1026
+ };
1027
+ Otherwise: JsonSerializableFilter<
1028
+ T[K],
1029
+ Controls,
1030
+ [TNextAncestor, ...TAncestorTypes]
1031
+ >;
1032
+ }
1033
+ >;
1034
+ } & {
1035
+ /* optional properties are recursed and, when exactOptionalPropertyTypes is
954
1036
  false, are allowed to preserve undefined value type. */
955
- [K in keyof T as OptionalNonSymbolKeysOf<
956
- T,
957
- K
958
- >]?: JsonSerializableFilter<
959
- T[K],
960
- Controls,
961
- [TNextAncestor, ...TAncestorTypes]
962
- >;
963
- } & {
964
- /* symbol properties are rejected */
965
- [K in keyof T & symbol]: never;
966
- }
967
- >
1037
+ [K in keyof T as OptionalNonSymbolKeysOf<
1038
+ T,
1039
+ K
1040
+ >]?: JsonSerializableFilter<
1041
+ T[K],
1042
+ Controls,
1043
+ [TNextAncestor, ...TAncestorTypes]
1044
+ >;
1045
+ } & {
1046
+ /* symbol properties are rejected */
1047
+ [K in keyof T & symbol]: never;
1048
+ }
1049
+ >
968
1050
  : /* not an object => */ never
969
1051
  : /* function => */ never;
970
1052
 
@@ -1008,7 +1090,7 @@ export namespace InternalUtilityTypes {
1008
1090
  AllowExtensionOf: Options extends { AllowExtensionOf: unknown }
1009
1091
  ? Options["AllowExtensionOf"]
1010
1092
  : never;
1011
- // There Substitute types could be extracted to helper type, but are kept explicit here
1093
+ // The Substitute types could be extracted to helper type, but are kept explicit here
1012
1094
  // to make JsonTypeWith/NonNullJsonObjectWith show explicitly in results for users, rather
1013
1095
  // than either the helper type name or a partially unrolled version.
1014
1096
  DegenerateSubstitute: JsonTypeWith<
@@ -1102,6 +1184,35 @@ export namespace InternalUtilityTypes {
1102
1184
  : Controls["DegenerateSubstitute"]
1103
1185
  : JsonDeserializedFilter<T, Controls, RecurseLimit, TAncestorTypes | T>;
1104
1186
 
1187
+ /**
1188
+ * Handle Opaque Json types for {@link JsonDeserialized}.
1189
+ *
1190
+ * @remarks
1191
+ * {@link OpaqueJsonSerializable} instances are converted to {@link OpaqueJsonDeserialized}.
1192
+ * The `AllowExactly` and `AllowExtensionOf` properties are set to match the given `Controls`.
1193
+ * The data type is kept exactly as-is to avoid processing in generic contexts that can't
1194
+ * produce a meaningful result. The data type should always be filtered through
1195
+ * {@link JsonDeserialized} when {@link OpaqueJsonDeserialized} is cracked open. So, really
1196
+ * the filtering is just deferred.
1197
+ *
1198
+ * @privateRemarks
1199
+ * Additional intersections beyond {@link OpaqueJsonSerializable},
1200
+ * {@link OpaqueJsonDeserialized}, or intersected matching opaque pair are
1201
+ * not correctly filtered as need is not expected.
1202
+ *
1203
+ * @system
1204
+ */
1205
+ export type JsonDeserializedOpaqueConversion<
1206
+ T extends AnyOpaqueJsonType,
1207
+ Controls extends FilterControls,
1208
+ > = /* eslint-disable @typescript-eslint/no-explicit-any -- must use `any` for invariant constraint override */
1209
+ T extends
1210
+ | OpaqueJsonSerializable<infer TData, any, unknown>
1211
+ | OpaqueJsonDeserialized<infer TData, any, unknown>
1212
+ ? OpaqueJsonDeserialized<TData, Controls["AllowExactly"], Controls["AllowExtensionOf"]>
1213
+ : "internal error: failed to determine Opaque Json type";
1214
+ /* eslint-enable @typescript-eslint/no-explicit-any */
1215
+
1105
1216
  /**
1106
1217
  * Core implementation of {@link JsonDeserialized}.
1107
1218
  *
@@ -1150,36 +1261,38 @@ export namespace InternalUtilityTypes {
1150
1261
  ? /* `object` => */ Controls["DegenerateNonNullObjectSubstitute"]
1151
1262
  : /* test for enum like types */ IfEnumLike<T> extends never
1152
1263
  ? /* enum or similar simple type (return as-is) => */ T
1153
- : /* property bag => */ FlattenIntersection<
1154
- /* properties with symbol keys or wholly unsupported values are removed */
1155
- {
1156
- /* properties with defined values are recursed */
1157
- [K in keyof T as NonSymbolWithDeserializablePropertyOf<
1158
- T,
1159
- Controls["AllowExactly"],
1160
- Controls["AllowExtensionOf"],
1161
- K
1162
- >]: JsonDeserializedRecursion<
1163
- T[K],
1164
- Controls,
1165
- RecurseLimit,
1166
- TAncestorTypes
1167
- >;
1168
- } & {
1169
- /* properties that may have undefined values are optional */
1170
- [K in keyof T as NonSymbolWithPossiblyDeserializablePropertyOf<
1171
- T,
1172
- Controls["AllowExactly"],
1173
- Controls["AllowExtensionOf"],
1174
- K
1175
- >]?: JsonDeserializedRecursion<
1176
- T[K],
1177
- Controls,
1178
- RecurseLimit,
1179
- TAncestorTypes
1180
- >;
1181
- }
1182
- >
1264
+ : /* test for matching Opaque Json types */ T extends AnyOpaqueJsonType
1265
+ ? /* Opaque Json type => */ JsonDeserializedOpaqueConversion<T, Controls>
1266
+ : /* property bag => */ FlattenIntersection<
1267
+ /* properties with symbol keys or wholly unsupported values are removed */
1268
+ {
1269
+ /* properties with defined values are recursed */
1270
+ [K in keyof T as NonSymbolWithDeserializablePropertyOf<
1271
+ T,
1272
+ Controls["AllowExactly"],
1273
+ Controls["AllowExtensionOf"],
1274
+ K
1275
+ >]: JsonDeserializedRecursion<
1276
+ T[K],
1277
+ Controls,
1278
+ RecurseLimit,
1279
+ TAncestorTypes
1280
+ >;
1281
+ } & {
1282
+ /* properties that may have undefined values are optional */
1283
+ [K in keyof T as NonSymbolWithPossiblyDeserializablePropertyOf<
1284
+ T,
1285
+ Controls["AllowExactly"],
1286
+ Controls["AllowExtensionOf"],
1287
+ K
1288
+ >]?: JsonDeserializedRecursion<
1289
+ T[K],
1290
+ Controls,
1291
+ RecurseLimit,
1292
+ TAncestorTypes
1293
+ >;
1294
+ }
1295
+ >
1183
1296
  : /* not an object => */ never;
1184
1297
 
1185
1298
  // #endregion
@@ -21,6 +21,7 @@ export type {
21
21
  NonNullJsonObjectWith,
22
22
  ReadonlyJsonTypeWith,
23
23
  } from "./jsonType.js";
24
+ export type { OpaqueJsonDeserialized, OpaqueJsonSerializable } from "./opaqueJson.js";
24
25
  export type { ShallowReadonly } from "./shallowReadonly.js";
25
26
 
26
27
  export type {
package/src/index.ts CHANGED
@@ -3,6 +3,8 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
+ export type { BrandedType } from "./brandedType.js";
7
+
6
8
  export type { IDisposable } from "./disposable.js";
7
9
 
8
10
  export type { IErrorBase, IGenericError, IUsageError, IThrottlingWarning } from "./error.js";
@@ -52,7 +54,7 @@ export type {
52
54
  export { LogLevel } from "./logger.js";
53
55
  export type { FluidObjectProviderKeys, FluidObject, FluidObjectKeys } from "./provider.js";
54
56
  export type { ConfigTypes, IConfigProviderBase } from "./config.js";
55
- export type { ISignalEnvelope } from "./messages.js";
57
+ export type { ISignalEnvelope, TypedMessage } from "./messages.js";
56
58
  export type { ErasedType } from "./erasedType.js";
57
59
 
58
60
  export type {