@fluidframework/container-loader 2.0.0-dev.6.4.0.191515 → 2.0.0-dev.7.2.0.203917

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 (146) hide show
  1. package/CHANGELOG.md +122 -0
  2. package/api-extractor.json +9 -1
  3. package/api-report/container-loader.api.md +153 -0
  4. package/dist/catchUpMonitor.d.ts +2 -2
  5. package/dist/catchUpMonitor.d.ts.map +1 -1
  6. package/dist/connectionManager.d.ts +2 -15
  7. package/dist/connectionManager.d.ts.map +1 -1
  8. package/dist/connectionManager.js +110 -98
  9. package/dist/connectionManager.js.map +1 -1
  10. package/dist/connectionState.js +1 -1
  11. package/dist/connectionState.js.map +1 -1
  12. package/dist/connectionStateHandler.js +9 -9
  13. package/dist/connectionStateHandler.js.map +1 -1
  14. package/dist/container-loader-alpha.d.ts +333 -0
  15. package/dist/container-loader-beta.d.ts +333 -0
  16. package/dist/container-loader-public.d.ts +333 -0
  17. package/dist/container-loader-untrimmed.d.ts +333 -0
  18. package/dist/container.d.ts +22 -2
  19. package/dist/container.d.ts.map +1 -1
  20. package/dist/container.js +235 -222
  21. package/dist/container.js.map +1 -1
  22. package/dist/containerContext.js +16 -16
  23. package/dist/containerContext.js.map +1 -1
  24. package/dist/containerStorageAdapter.d.ts +1 -1
  25. package/dist/containerStorageAdapter.d.ts.map +1 -1
  26. package/dist/containerStorageAdapter.js +9 -11
  27. package/dist/containerStorageAdapter.js.map +1 -1
  28. package/dist/contracts.d.ts +5 -4
  29. package/dist/contracts.d.ts.map +1 -1
  30. package/dist/contracts.js +1 -1
  31. package/dist/contracts.js.map +1 -1
  32. package/dist/debugLogger.d.ts.map +1 -1
  33. package/dist/debugLogger.js +5 -4
  34. package/dist/debugLogger.js.map +1 -1
  35. package/dist/deltaManager.d.ts.map +1 -1
  36. package/dist/deltaManager.js +92 -96
  37. package/dist/deltaManager.js.map +1 -1
  38. package/dist/deltaQueue.js +14 -14
  39. package/dist/deltaQueue.js.map +1 -1
  40. package/dist/index.d.ts +2 -0
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +6 -1
  43. package/dist/index.js.map +1 -1
  44. package/dist/loader.d.ts +6 -9
  45. package/dist/loader.d.ts.map +1 -1
  46. package/dist/loader.js +26 -91
  47. package/dist/loader.js.map +1 -1
  48. package/dist/location-redirection-utilities/index.d.ts +6 -0
  49. package/dist/location-redirection-utilities/index.d.ts.map +1 -0
  50. package/dist/location-redirection-utilities/index.js +11 -0
  51. package/dist/location-redirection-utilities/index.js.map +1 -0
  52. package/dist/location-redirection-utilities/resolveWithLocationRedirection.d.ts +22 -0
  53. package/dist/location-redirection-utilities/resolveWithLocationRedirection.d.ts.map +1 -0
  54. package/dist/location-redirection-utilities/resolveWithLocationRedirection.js +51 -0
  55. package/dist/location-redirection-utilities/resolveWithLocationRedirection.js.map +1 -0
  56. package/dist/packageVersion.d.ts +1 -1
  57. package/dist/packageVersion.js +1 -1
  58. package/dist/packageVersion.js.map +1 -1
  59. package/dist/protocol.d.ts +1 -2
  60. package/dist/protocol.d.ts.map +1 -1
  61. package/dist/protocol.js +3 -5
  62. package/dist/protocol.js.map +1 -1
  63. package/dist/retriableDocumentStorageService.d.ts +3 -2
  64. package/dist/retriableDocumentStorageService.d.ts.map +1 -1
  65. package/dist/retriableDocumentStorageService.js +18 -11
  66. package/dist/retriableDocumentStorageService.js.map +1 -1
  67. package/dist/tsdoc-metadata.json +1 -1
  68. package/dist/utils.d.ts +23 -1
  69. package/dist/utils.d.ts.map +1 -1
  70. package/dist/utils.js +11 -3
  71. package/dist/utils.js.map +1 -1
  72. package/lib/catchUpMonitor.d.ts +2 -2
  73. package/lib/catchUpMonitor.d.ts.map +1 -1
  74. package/lib/connectionManager.d.ts +2 -15
  75. package/lib/connectionManager.d.ts.map +1 -1
  76. package/lib/connectionManager.js +113 -99
  77. package/lib/connectionManager.js.map +1 -1
  78. package/lib/connectionStateHandler.js +9 -9
  79. package/lib/connectionStateHandler.js.map +1 -1
  80. package/lib/container.d.ts +22 -2
  81. package/lib/container.d.ts.map +1 -1
  82. package/lib/container.js +236 -223
  83. package/lib/container.js.map +1 -1
  84. package/lib/containerContext.js +16 -16
  85. package/lib/containerContext.js.map +1 -1
  86. package/lib/containerStorageAdapter.d.ts +1 -1
  87. package/lib/containerStorageAdapter.d.ts.map +1 -1
  88. package/lib/containerStorageAdapter.js +9 -11
  89. package/lib/containerStorageAdapter.js.map +1 -1
  90. package/lib/contracts.d.ts +5 -4
  91. package/lib/contracts.d.ts.map +1 -1
  92. package/lib/contracts.js.map +1 -1
  93. package/lib/debugLogger.d.ts.map +1 -1
  94. package/lib/debugLogger.js +5 -4
  95. package/lib/debugLogger.js.map +1 -1
  96. package/lib/deltaManager.d.ts.map +1 -1
  97. package/lib/deltaManager.js +92 -96
  98. package/lib/deltaManager.js.map +1 -1
  99. package/lib/deltaQueue.js +14 -14
  100. package/lib/deltaQueue.js.map +1 -1
  101. package/lib/index.d.ts +2 -0
  102. package/lib/index.d.ts.map +1 -1
  103. package/lib/index.js +2 -0
  104. package/lib/index.js.map +1 -1
  105. package/lib/loader.d.ts +6 -9
  106. package/lib/loader.d.ts.map +1 -1
  107. package/lib/loader.js +27 -92
  108. package/lib/loader.js.map +1 -1
  109. package/lib/location-redirection-utilities/index.d.ts +6 -0
  110. package/lib/location-redirection-utilities/index.d.ts.map +1 -0
  111. package/lib/location-redirection-utilities/index.js +6 -0
  112. package/lib/location-redirection-utilities/index.js.map +1 -0
  113. package/lib/location-redirection-utilities/resolveWithLocationRedirection.d.ts +22 -0
  114. package/lib/location-redirection-utilities/resolveWithLocationRedirection.d.ts.map +1 -0
  115. package/lib/location-redirection-utilities/resolveWithLocationRedirection.js +46 -0
  116. package/lib/location-redirection-utilities/resolveWithLocationRedirection.js.map +1 -0
  117. package/lib/packageVersion.d.ts +1 -1
  118. package/lib/packageVersion.js +1 -1
  119. package/lib/packageVersion.js.map +1 -1
  120. package/lib/protocol.d.ts +1 -2
  121. package/lib/protocol.d.ts.map +1 -1
  122. package/lib/protocol.js +1 -3
  123. package/lib/protocol.js.map +1 -1
  124. package/lib/retriableDocumentStorageService.d.ts +3 -2
  125. package/lib/retriableDocumentStorageService.d.ts.map +1 -1
  126. package/lib/retriableDocumentStorageService.js +18 -11
  127. package/lib/retriableDocumentStorageService.js.map +1 -1
  128. package/lib/utils.d.ts +23 -1
  129. package/lib/utils.d.ts.map +1 -1
  130. package/lib/utils.js +9 -1
  131. package/lib/utils.js.map +1 -1
  132. package/package.json +24 -26
  133. package/src/connectionManager.ts +58 -31
  134. package/src/container.ts +48 -30
  135. package/src/containerStorageAdapter.ts +3 -9
  136. package/src/contracts.ts +8 -4
  137. package/src/debugLogger.ts +5 -1
  138. package/src/deltaManager.ts +16 -31
  139. package/src/index.ts +5 -0
  140. package/src/loader.ts +31 -99
  141. package/src/location-redirection-utilities/index.ts +9 -0
  142. package/src/location-redirection-utilities/resolveWithLocationRedirection.ts +59 -0
  143. package/src/packageVersion.ts +1 -1
  144. package/src/protocol.ts +2 -6
  145. package/src/retriableDocumentStorageService.ts +29 -15
  146. package/src/utils.ts +23 -1
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ /*!
3
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
+ * Licensed under the MIT License.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.resolveWithLocationRedirectionHandling = exports.isLocationRedirectionError = void 0;
8
+ const driver_definitions_1 = require("@fluidframework/driver-definitions");
9
+ const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
10
+ /**
11
+ * Checks if the error is location redirection error.
12
+ * @param error - error whose type is to be determined.
13
+ * @returns `true` is the error is location redirection error, otherwise `false`.
14
+ */
15
+ function isLocationRedirectionError(error) {
16
+ return (typeof error === "object" &&
17
+ error !== null &&
18
+ error.errorType === driver_definitions_1.DriverErrorTypes.locationRedirection);
19
+ }
20
+ exports.isLocationRedirectionError = isLocationRedirectionError;
21
+ /**
22
+ * Handles location redirection while fulfilling the loader request.
23
+ * @param api - Callback in which user can wrap the loader.resolve or loader.request call.
24
+ * @param request - request to be resolved.
25
+ * @param urlResolver - resolver used to resolve the url.
26
+ * @param logger - logger to send events.
27
+ * @returns Response from the API call.
28
+ */
29
+ async function resolveWithLocationRedirectionHandling(api, request, urlResolver, logger) {
30
+ let req = request;
31
+ const childLogger = (0, telemetry_utils_1.createChildLogger)({ logger, namespace: "LocationRedirection" });
32
+ for (;;) {
33
+ try {
34
+ return await api(req);
35
+ }
36
+ catch (error) {
37
+ if (!isLocationRedirectionError(error)) {
38
+ throw error;
39
+ }
40
+ childLogger.sendTelemetryEvent({ eventName: "LocationRedirectionError" });
41
+ const resolvedUrl = error.redirectUrl;
42
+ // Generate the new request with new location details from the resolved url. For datastore/relative path,
43
+ // we don't need to pass "/" as host could have asked for a specific data store. So driver need to
44
+ // extract it from the resolved url.
45
+ const absoluteUrl = await urlResolver.getAbsoluteUrl(resolvedUrl, "", undefined);
46
+ req = { url: absoluteUrl, headers: req.headers };
47
+ }
48
+ }
49
+ }
50
+ exports.resolveWithLocationRedirectionHandling = resolveWithLocationRedirectionHandling;
51
+ //# sourceMappingURL=resolveWithLocationRedirection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveWithLocationRedirection.js","sourceRoot":"","sources":["../../src/location-redirection-utilities/resolveWithLocationRedirection.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,2EAI4C;AAC5C,qEAAoE;AAEpE;;;;GAIG;AACH,SAAgB,0BAA0B,CAAC,KAAU;IACpD,OAAO,CACN,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,KAAK,CAAC,SAAS,KAAK,qCAAgB,CAAC,mBAAmB,CACxD,CAAC;AACH,CAAC;AAND,gEAMC;AAED;;;;;;;GAOG;AACI,KAAK,UAAU,sCAAsC,CAC3D,GAAsC,EACtC,OAAiB,EACjB,WAAyB,EACzB,MAA6B;IAE7B,IAAI,GAAG,GAAa,OAAO,CAAC;IAC5B,MAAM,WAAW,GAAG,IAAA,mCAAiB,EAAC,EAAE,MAAM,EAAE,SAAS,EAAE,qBAAqB,EAAE,CAAC,CAAC;IACpF,SAAS;QACR,IAAI;YACH,OAAO,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC;SACtB;QAAC,OAAO,KAAU,EAAE;YACpB,IAAI,CAAC,0BAA0B,CAAC,KAAK,CAAC,EAAE;gBACvC,MAAM,KAAK,CAAC;aACZ;YACD,WAAW,CAAC,kBAAkB,CAAC,EAAE,SAAS,EAAE,0BAA0B,EAAE,CAAC,CAAC;YAC1E,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;YACtC,yGAAyG;YACzG,kGAAkG;YAClG,oCAAoC;YACpC,MAAM,WAAW,GAAG,MAAM,WAAW,CAAC,cAAc,CAAC,WAAW,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC;YACjF,GAAG,GAAG,EAAE,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;SACjD;KACD;AACF,CAAC;AAxBD,wFAwBC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryBaseLogger, IRequest } from \"@fluidframework/core-interfaces\";\nimport {\n\tDriverErrorTypes,\n\tILocationRedirectionError,\n\tIUrlResolver,\n} from \"@fluidframework/driver-definitions\";\nimport { createChildLogger } from \"@fluidframework/telemetry-utils\";\n\n/**\n * Checks if the error is location redirection error.\n * @param error - error whose type is to be determined.\n * @returns `true` is the error is location redirection error, otherwise `false`.\n */\nexport function isLocationRedirectionError(error: any): error is ILocationRedirectionError {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\terror.errorType === DriverErrorTypes.locationRedirection\n\t);\n}\n\n/**\n * Handles location redirection while fulfilling the loader request.\n * @param api - Callback in which user can wrap the loader.resolve or loader.request call.\n * @param request - request to be resolved.\n * @param urlResolver - resolver used to resolve the url.\n * @param logger - logger to send events.\n * @returns Response from the API call.\n */\nexport async function resolveWithLocationRedirectionHandling<T>(\n\tapi: (request: IRequest) => Promise<T>,\n\trequest: IRequest,\n\turlResolver: IUrlResolver,\n\tlogger?: ITelemetryBaseLogger,\n): Promise<T> {\n\tlet req: IRequest = request;\n\tconst childLogger = createChildLogger({ logger, namespace: \"LocationRedirection\" });\n\tfor (;;) {\n\t\ttry {\n\t\t\treturn await api(req);\n\t\t} catch (error: any) {\n\t\t\tif (!isLocationRedirectionError(error)) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tchildLogger.sendTelemetryEvent({ eventName: \"LocationRedirectionError\" });\n\t\t\tconst resolvedUrl = error.redirectUrl;\n\t\t\t// Generate the new request with new location details from the resolved url. For datastore/relative path,\n\t\t\t// we don't need to pass \"/\" as host could have asked for a specific data store. So driver need to\n\t\t\t// extract it from the resolved url.\n\t\t\tconst absoluteUrl = await urlResolver.getAbsoluteUrl(resolvedUrl, \"\", undefined);\n\t\t\treq = { url: absoluteUrl, headers: req.headers };\n\t\t}\n\t}\n}\n"]}
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export declare const pkgName = "@fluidframework/container-loader";
8
- export declare const pkgVersion = "2.0.0-dev.6.4.0.191515";
8
+ export declare const pkgVersion = "2.0.0-dev.7.2.0.203917";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -8,5 +8,5 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.pkgVersion = exports.pkgName = void 0;
10
10
  exports.pkgName = "@fluidframework/container-loader";
11
- exports.pkgVersion = "2.0.0-dev.6.4.0.191515";
11
+ exports.pkgVersion = "2.0.0-dev.7.2.0.203917";
12
12
  //# sourceMappingURL=packageVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,kCAAkC,CAAC;AAC7C,QAAA,UAAU,GAAG,wBAAwB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/container-loader\";\nexport const pkgVersion = \"2.0.0-dev.6.4.0.191515\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,kCAAkC,CAAC;AAC7C,QAAA,UAAU,GAAG,wBAAwB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/container-loader\";\nexport const pkgVersion = \"2.0.0-dev.7.2.0.203917\";\n"]}
@@ -5,7 +5,6 @@
5
5
  import { IAudienceOwner } from "@fluidframework/container-definitions";
6
6
  import { IProtocolHandler as IBaseProtocolHandler, IQuorumSnapshot, ProtocolOpHandler } from "@fluidframework/protocol-base";
7
7
  import { IDocumentAttributes, IProcessMessageResult, ISequencedDocumentMessage, ISignalMessage } from "@fluidframework/protocol-definitions";
8
- export declare const OnlyValidTermValue: 1;
9
8
  export declare enum SignalType {
10
9
  ClientJoin = "join",
11
10
  ClientLeave = "leave",
@@ -14,7 +13,7 @@ export declare enum SignalType {
14
13
  /**
15
14
  * Function to be used for creating a protocol handler.
16
15
  */
17
- export declare type ProtocolHandlerBuilder = (attributes: IDocumentAttributes, snapshot: IQuorumSnapshot, sendProposal: (key: string, value: any) => number) => IProtocolHandler;
16
+ export type ProtocolHandlerBuilder = (attributes: IDocumentAttributes, snapshot: IQuorumSnapshot, sendProposal: (key: string, value: any) => number) => IProtocolHandler;
18
17
  export interface IProtocolHandler extends IBaseProtocolHandler {
19
18
  readonly audience: IAudienceOwner;
20
19
  processSignal(message: ISignalMessage): any;
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAEvE,OAAO,EACN,gBAAgB,IAAI,oBAAoB,EACxC,eAAe,EACf,iBAAiB,EACjB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACN,mBAAmB,EACnB,qBAAqB,EAErB,yBAAyB,EAEzB,cAAc,EAEd,MAAM,sCAAsC,CAAC;AAG9C,eAAO,MAAM,kBAAkB,GAAa,CAAC;AAG7C,oBAAY,UAAU;IACrB,UAAU,SAAS;IACnB,WAAW,UAAU;IACrB,KAAK,UAAU;CACf;AAED;;GAEG;AACH,oBAAY,sBAAsB,GAAG,CACpC,UAAU,EAAE,mBAAmB,EAC/B,QAAQ,EAAE,eAAe,EACzB,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,MAAM,KAC7C,gBAAgB,CAAC;AAEtB,MAAM,WAAW,gBAAiB,SAAQ,oBAAoB;IAC7D,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,aAAa,CAAC,OAAO,EAAE,cAAc,OAAE;CACvC;AAED,qBAAa,eAAgB,SAAQ,iBAAkB,YAAW,gBAAgB;aAKhE,QAAQ,EAAE,cAAc;IACxC,OAAO,CAAC,QAAQ,CAAC,oBAAoB;gBAJrC,UAAU,EAAE,mBAAmB,EAC/B,cAAc,EAAE,eAAe,EAC/B,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,MAAM,EACjC,QAAQ,EAAE,cAAc,EACvB,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO;IAqB9D,cAAc,CACpB,OAAO,EAAE,yBAAyB,EAClC,KAAK,EAAE,OAAO,GACZ,qBAAqB;IAuBjB,aAAa,CAAC,OAAO,EAAE,cAAc;CAgC5C;AAED;;;;GAIG;AACH,wBAAgB,kCAAkC,CAAC,OAAO,EAAE,cAAc,WAWzE"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAEvE,OAAO,EACN,gBAAgB,IAAI,oBAAoB,EACxC,eAAe,EACf,iBAAiB,EACjB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACN,mBAAmB,EACnB,qBAAqB,EACrB,yBAAyB,EAEzB,cAAc,EAEd,MAAM,sCAAsC,CAAC;AAG9C,oBAAY,UAAU;IACrB,UAAU,SAAS;IACnB,WAAW,UAAU;IACrB,KAAK,UAAU;CACf;AAED;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,CACpC,UAAU,EAAE,mBAAmB,EAC/B,QAAQ,EAAE,eAAe,EACzB,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,MAAM,KAC7C,gBAAgB,CAAC;AAEtB,MAAM,WAAW,gBAAiB,SAAQ,oBAAoB;IAC7D,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,aAAa,CAAC,OAAO,EAAE,cAAc,OAAE;CACvC;AAED,qBAAa,eAAgB,SAAQ,iBAAkB,YAAW,gBAAgB;aAKhE,QAAQ,EAAE,cAAc;IACxC,OAAO,CAAC,QAAQ,CAAC,oBAAoB;gBAJrC,UAAU,EAAE,mBAAmB,EAC/B,cAAc,EAAE,eAAe,EAC/B,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,MAAM,EACjC,QAAQ,EAAE,cAAc,EACvB,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO;IAqB9D,cAAc,CACpB,OAAO,EAAE,yBAAyB,EAClC,KAAK,EAAE,OAAO,GACZ,qBAAqB;IAuBjB,aAAa,CAAC,OAAO,EAAE,cAAc;CAgC5C;AAED;;;;GAIG;AACH,wBAAgB,kCAAkC,CAAC,OAAO,EAAE,cAAc,WAWzE"}
package/dist/protocol.js CHANGED
@@ -4,19 +4,17 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.protocolHandlerShouldProcessSignal = exports.ProtocolHandler = exports.SignalType = exports.OnlyValidTermValue = void 0;
7
+ exports.protocolHandlerShouldProcessSignal = exports.ProtocolHandler = exports.SignalType = void 0;
8
8
  const driver_utils_1 = require("@fluidframework/driver-utils");
9
9
  const protocol_base_1 = require("@fluidframework/protocol-base");
10
10
  const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
11
- // "term" was an experimental feature that is being removed. The only safe value to use is 1.
12
- exports.OnlyValidTermValue = 1;
13
11
  // ADO: #1986: Start using enum from protocol-base.
14
12
  var SignalType;
15
13
  (function (SignalType) {
16
14
  SignalType["ClientJoin"] = "join";
17
15
  SignalType["ClientLeave"] = "leave";
18
16
  SignalType["Clear"] = "clear";
19
- })(SignalType = exports.SignalType || (exports.SignalType = {}));
17
+ })(SignalType || (exports.SignalType = SignalType = {}));
20
18
  class ProtocolHandler extends protocol_base_1.ProtocolOpHandler {
21
19
  constructor(attributes, quorumSnapshot, sendProposal, audience, shouldClientHaveLeft) {
22
20
  super(attributes.minimumSequenceNumber, attributes.sequenceNumber, quorumSnapshot.members, quorumSnapshot.proposals, quorumSnapshot.values, sendProposal);
@@ -30,10 +28,10 @@ class ProtocolHandler extends protocol_base_1.ProtocolOpHandler {
30
28
  }
31
29
  }
32
30
  processMessage(message, local) {
33
- const client = this.quorum.getMember(message.clientId);
34
31
  // Check and report if we're getting messages from a clientId that we previously
35
32
  // flagged as shouldHaveLeft, or from a client that's not in the quorum but should be
36
33
  if (message.clientId != null) {
34
+ const client = this.quorum.getMember(message.clientId);
37
35
  if (client === undefined && message.type !== protocol_definitions_1.MessageType.ClientJoin) {
38
36
  // pre-0.58 error message: messageClientIdMissingFromQuorum
39
37
  throw new Error("Remote message's clientId is missing from the quorum");
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IAudienceOwner } from \"@fluidframework/container-definitions\";\nimport { canBeCoalescedByService } from \"@fluidframework/driver-utils\";\nimport {\n\tIProtocolHandler as IBaseProtocolHandler,\n\tIQuorumSnapshot,\n\tProtocolOpHandler,\n} from \"@fluidframework/protocol-base\";\nimport {\n\tIDocumentAttributes,\n\tIProcessMessageResult,\n\tISequencedClient,\n\tISequencedDocumentMessage,\n\tISignalClient,\n\tISignalMessage,\n\tMessageType,\n} from \"@fluidframework/protocol-definitions\";\n\n// \"term\" was an experimental feature that is being removed. The only safe value to use is 1.\nexport const OnlyValidTermValue = 1 as const;\n\n// ADO: #1986: Start using enum from protocol-base.\nexport enum SignalType {\n\tClientJoin = \"join\", // same value as MessageType.ClientJoin,\n\tClientLeave = \"leave\", // same value as MessageType.ClientLeave,\n\tClear = \"clear\", // used only by client for synthetic signals\n}\n\n/**\n * Function to be used for creating a protocol handler.\n */\nexport type ProtocolHandlerBuilder = (\n\tattributes: IDocumentAttributes,\n\tsnapshot: IQuorumSnapshot,\n\tsendProposal: (key: string, value: any) => number,\n) => IProtocolHandler;\n\nexport interface IProtocolHandler extends IBaseProtocolHandler {\n\treadonly audience: IAudienceOwner;\n\tprocessSignal(message: ISignalMessage);\n}\n\nexport class ProtocolHandler extends ProtocolOpHandler implements IProtocolHandler {\n\tconstructor(\n\t\tattributes: IDocumentAttributes,\n\t\tquorumSnapshot: IQuorumSnapshot,\n\t\tsendProposal: (key: string, value: any) => number,\n\t\tpublic readonly audience: IAudienceOwner,\n\t\tprivate readonly shouldClientHaveLeft: (clientId: string) => boolean,\n\t) {\n\t\tsuper(\n\t\t\tattributes.minimumSequenceNumber,\n\t\t\tattributes.sequenceNumber,\n\t\t\tquorumSnapshot.members,\n\t\t\tquorumSnapshot.proposals,\n\t\t\tquorumSnapshot.values,\n\t\t\tsendProposal,\n\t\t);\n\n\t\t// Join / leave signals are ignored for \"write\" clients in favor of join / leave ops\n\t\tthis.quorum.on(\"addMember\", (clientId, details) =>\n\t\t\taudience.addMember(clientId, details.client),\n\t\t);\n\t\tthis.quorum.on(\"removeMember\", (clientId) => audience.removeMember(clientId));\n\t\tfor (const [clientId, details] of this.quorum.getMembers()) {\n\t\t\tthis.audience.addMember(clientId, details.client);\n\t\t}\n\t}\n\n\tpublic processMessage(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t): IProcessMessageResult {\n\t\tconst client: ISequencedClient | undefined = this.quorum.getMember(message.clientId);\n\n\t\t// Check and report if we're getting messages from a clientId that we previously\n\t\t// flagged as shouldHaveLeft, or from a client that's not in the quorum but should be\n\t\tif (message.clientId != null) {\n\t\t\tif (client === undefined && message.type !== MessageType.ClientJoin) {\n\t\t\t\t// pre-0.58 error message: messageClientIdMissingFromQuorum\n\t\t\t\tthrow new Error(\"Remote message's clientId is missing from the quorum\");\n\t\t\t}\n\n\t\t\t// Here checking canBeCoalescedByService is used as an approximation of \"is benign to process despite being unexpected\".\n\t\t\t// It's still not good to see these messages from unexpected clientIds, but since they don't harm the integrity of the\n\t\t\t// document we don't need to blow up aggressively.\n\t\t\tif (this.shouldClientHaveLeft(message.clientId) && !canBeCoalescedByService(message)) {\n\t\t\t\t// pre-0.58 error message: messageClientIdShouldHaveLeft\n\t\t\t\tthrow new Error(\"Remote message's clientId already should have left\");\n\t\t\t}\n\t\t}\n\n\t\treturn super.processMessage(message, local);\n\t}\n\n\tpublic processSignal(message: ISignalMessage) {\n\t\tconst innerContent = message.content as { content: any; type: string };\n\t\tswitch (innerContent.type) {\n\t\t\tcase SignalType.Clear: {\n\t\t\t\tconst members = this.audience.getMembers();\n\t\t\t\tfor (const [clientId, client] of members) {\n\t\t\t\t\tif (client.mode === \"read\") {\n\t\t\t\t\t\tthis.audience.removeMember(clientId);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SignalType.ClientJoin: {\n\t\t\t\tconst newClient = innerContent.content as ISignalClient;\n\t\t\t\t// Ignore write clients - quorum will control such clients.\n\t\t\t\tif (newClient.client.mode === \"read\") {\n\t\t\t\t\tthis.audience.addMember(newClient.clientId, newClient.client);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SignalType.ClientLeave: {\n\t\t\t\tconst leftClientId = innerContent.content as string;\n\t\t\t\t// Ignore write clients - quorum will control such clients.\n\t\t\t\tif (this.audience.getMember(leftClientId)?.mode === \"read\") {\n\t\t\t\t\tthis.audience.removeMember(leftClientId);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/**\n * Function to check whether the protocol handler should process the Signal.\n * The protocol handler should strictly handle only ClientJoin, ClientLeave\n * and Clear signal types.\n */\nexport function protocolHandlerShouldProcessSignal(message: ISignalMessage) {\n\t// Signal originates from server\n\tif (message.clientId === null) {\n\t\tconst innerContent = message.content as { content: unknown; type: string };\n\t\treturn (\n\t\t\tinnerContent.type === SignalType.Clear ||\n\t\t\tinnerContent.type === SignalType.ClientJoin ||\n\t\t\tinnerContent.type === SignalType.ClientLeave\n\t\t);\n\t}\n\treturn false;\n}\n"]}
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IAudienceOwner } from \"@fluidframework/container-definitions\";\nimport { canBeCoalescedByService } from \"@fluidframework/driver-utils\";\nimport {\n\tIProtocolHandler as IBaseProtocolHandler,\n\tIQuorumSnapshot,\n\tProtocolOpHandler,\n} from \"@fluidframework/protocol-base\";\nimport {\n\tIDocumentAttributes,\n\tIProcessMessageResult,\n\tISequencedDocumentMessage,\n\tISignalClient,\n\tISignalMessage,\n\tMessageType,\n} from \"@fluidframework/protocol-definitions\";\n\n// ADO: #1986: Start using enum from protocol-base.\nexport enum SignalType {\n\tClientJoin = \"join\", // same value as MessageType.ClientJoin,\n\tClientLeave = \"leave\", // same value as MessageType.ClientLeave,\n\tClear = \"clear\", // used only by client for synthetic signals\n}\n\n/**\n * Function to be used for creating a protocol handler.\n */\nexport type ProtocolHandlerBuilder = (\n\tattributes: IDocumentAttributes,\n\tsnapshot: IQuorumSnapshot,\n\tsendProposal: (key: string, value: any) => number,\n) => IProtocolHandler;\n\nexport interface IProtocolHandler extends IBaseProtocolHandler {\n\treadonly audience: IAudienceOwner;\n\tprocessSignal(message: ISignalMessage);\n}\n\nexport class ProtocolHandler extends ProtocolOpHandler implements IProtocolHandler {\n\tconstructor(\n\t\tattributes: IDocumentAttributes,\n\t\tquorumSnapshot: IQuorumSnapshot,\n\t\tsendProposal: (key: string, value: any) => number,\n\t\tpublic readonly audience: IAudienceOwner,\n\t\tprivate readonly shouldClientHaveLeft: (clientId: string) => boolean,\n\t) {\n\t\tsuper(\n\t\t\tattributes.minimumSequenceNumber,\n\t\t\tattributes.sequenceNumber,\n\t\t\tquorumSnapshot.members,\n\t\t\tquorumSnapshot.proposals,\n\t\t\tquorumSnapshot.values,\n\t\t\tsendProposal,\n\t\t);\n\n\t\t// Join / leave signals are ignored for \"write\" clients in favor of join / leave ops\n\t\tthis.quorum.on(\"addMember\", (clientId, details) =>\n\t\t\taudience.addMember(clientId, details.client),\n\t\t);\n\t\tthis.quorum.on(\"removeMember\", (clientId) => audience.removeMember(clientId));\n\t\tfor (const [clientId, details] of this.quorum.getMembers()) {\n\t\t\tthis.audience.addMember(clientId, details.client);\n\t\t}\n\t}\n\n\tpublic processMessage(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t): IProcessMessageResult {\n\t\t// Check and report if we're getting messages from a clientId that we previously\n\t\t// flagged as shouldHaveLeft, or from a client that's not in the quorum but should be\n\t\tif (message.clientId != null) {\n\t\t\tconst client = this.quorum.getMember(message.clientId);\n\n\t\t\tif (client === undefined && message.type !== MessageType.ClientJoin) {\n\t\t\t\t// pre-0.58 error message: messageClientIdMissingFromQuorum\n\t\t\t\tthrow new Error(\"Remote message's clientId is missing from the quorum\");\n\t\t\t}\n\n\t\t\t// Here checking canBeCoalescedByService is used as an approximation of \"is benign to process despite being unexpected\".\n\t\t\t// It's still not good to see these messages from unexpected clientIds, but since they don't harm the integrity of the\n\t\t\t// document we don't need to blow up aggressively.\n\t\t\tif (this.shouldClientHaveLeft(message.clientId) && !canBeCoalescedByService(message)) {\n\t\t\t\t// pre-0.58 error message: messageClientIdShouldHaveLeft\n\t\t\t\tthrow new Error(\"Remote message's clientId already should have left\");\n\t\t\t}\n\t\t}\n\n\t\treturn super.processMessage(message, local);\n\t}\n\n\tpublic processSignal(message: ISignalMessage) {\n\t\tconst innerContent = message.content as { content: any; type: string };\n\t\tswitch (innerContent.type) {\n\t\t\tcase SignalType.Clear: {\n\t\t\t\tconst members = this.audience.getMembers();\n\t\t\t\tfor (const [clientId, client] of members) {\n\t\t\t\t\tif (client.mode === \"read\") {\n\t\t\t\t\t\tthis.audience.removeMember(clientId);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SignalType.ClientJoin: {\n\t\t\t\tconst newClient = innerContent.content as ISignalClient;\n\t\t\t\t// Ignore write clients - quorum will control such clients.\n\t\t\t\tif (newClient.client.mode === \"read\") {\n\t\t\t\t\tthis.audience.addMember(newClient.clientId, newClient.client);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SignalType.ClientLeave: {\n\t\t\t\tconst leftClientId = innerContent.content as string;\n\t\t\t\t// Ignore write clients - quorum will control such clients.\n\t\t\t\tif (this.audience.getMember(leftClientId)?.mode === \"read\") {\n\t\t\t\t\tthis.audience.removeMember(leftClientId);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/**\n * Function to check whether the protocol handler should process the Signal.\n * The protocol handler should strictly handle only ClientJoin, ClientLeave\n * and Clear signal types.\n */\nexport function protocolHandlerShouldProcessSignal(message: ISignalMessage) {\n\t// Signal originates from server\n\tif (message.clientId === null) {\n\t\tconst innerContent = message.content as { content: unknown; type: string };\n\t\treturn (\n\t\t\tinnerContent.type === SignalType.Clear ||\n\t\t\tinnerContent.type === SignalType.ClientJoin ||\n\t\t\tinnerContent.type === SignalType.ClientLeave\n\t\t);\n\t}\n\treturn false;\n}\n"]}
@@ -7,10 +7,11 @@ import { ICreateBlobResponse, ISnapshotTree, ISummaryHandle, ISummaryTree, IVers
7
7
  import { IDisposable } from "@fluidframework/core-interfaces";
8
8
  import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
9
9
  export declare class RetriableDocumentStorageService implements IDocumentStorageService, IDisposable {
10
- private readonly internalStorageService;
10
+ private readonly internalStorageServiceP;
11
11
  private readonly logger;
12
12
  private _disposed;
13
- constructor(internalStorageService: IDocumentStorageService, logger: ITelemetryLoggerExt);
13
+ private internalStorageService;
14
+ constructor(internalStorageServiceP: Promise<IDocumentStorageService>, logger: ITelemetryLoggerExt);
14
15
  get policies(): IDocumentStorageServicePolicies | undefined;
15
16
  get disposed(): boolean;
16
17
  dispose(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"retriableDocumentStorageService.d.ts","sourceRoot":"","sources":["../src/retriableDocumentStorageService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACN,WAAW,EACX,uBAAuB,EACvB,+BAA+B,EAC/B,eAAe,EACf,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACN,mBAAmB,EACnB,aAAa,EACb,cAAc,EACd,YAAY,EACZ,QAAQ,EACR,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAgB,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAGpF,qBAAa,+BAAgC,YAAW,uBAAuB,EAAE,WAAW;IAG1F,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHxB,OAAO,CAAC,SAAS,CAAS;gBAER,sBAAsB,EAAE,uBAAuB,EAC/C,MAAM,EAAE,mBAAmB;IAG7C,IAAW,QAAQ,IAAI,+BAA+B,GAAG,SAAS,CAEjE;IACD,IAAW,QAAQ,YAElB;IACM,OAAO;IAId,IAAW,aAAa,IAAI,MAAM,CAEjC;IAEY,eAAe,CAC3B,OAAO,CAAC,EAAE,QAAQ,EAClB,YAAY,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAOnB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAO9C,WAAW,CACvB,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,KAAK,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,EACrB,WAAW,CAAC,EAAE,WAAW,GACvB,OAAO,CAAC,QAAQ,EAAE,CAAC;IAaT,wBAAwB,CACpC,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,eAAe,GACtB,OAAO,CAAC,MAAM,CAAC;IAyBL,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;IAO9D,UAAU,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAO5E,OAAO,CAAC,oBAAoB;YAiBd,YAAY;CAM1B"}
1
+ {"version":3,"file":"retriableDocumentStorageService.d.ts","sourceRoot":"","sources":["../src/retriableDocumentStorageService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACN,WAAW,EACX,uBAAuB,EACvB,+BAA+B,EAC/B,eAAe,EACf,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACN,mBAAmB,EACnB,aAAa,EACb,cAAc,EACd,YAAY,EACZ,QAAQ,EACR,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAgB,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAGpF,qBAAa,+BAAgC,YAAW,uBAAuB,EAAE,WAAW;IAI1F,OAAO,CAAC,QAAQ,CAAC,uBAAuB;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJxB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,sBAAsB,CAAsC;gBAElD,uBAAuB,EAAE,OAAO,CAAC,uBAAuB,CAAC,EACzD,MAAM,EAAE,mBAAmB;IAK7C,IAAW,QAAQ,IAAI,+BAA+B,GAAG,SAAS,CAKjE;IACD,IAAW,QAAQ,YAElB;IACM,OAAO;IAId,IAAW,aAAa,IAAI,MAAM,CAKjC;IAEY,eAAe,CAC3B,OAAO,CAAC,EAAE,QAAQ,EAClB,YAAY,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAUnB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAO9C,WAAW,CACvB,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,KAAK,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,EACrB,WAAW,CAAC,EAAE,WAAW,GACvB,OAAO,CAAC,QAAQ,EAAE,CAAC;IAUT,wBAAwB,CACpC,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,eAAe,GACtB,OAAO,CAAC,MAAM,CAAC;IA8BL,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;IAO9D,UAAU,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAO5E,OAAO,CAAC,oBAAoB;YAiBd,YAAY;CAM1B"}
@@ -9,13 +9,17 @@ const core_utils_1 = require("@fluidframework/core-utils");
9
9
  const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
10
10
  const driver_utils_1 = require("@fluidframework/driver-utils");
11
11
  class RetriableDocumentStorageService {
12
- constructor(internalStorageService, logger) {
13
- this.internalStorageService = internalStorageService;
12
+ constructor(internalStorageServiceP, logger) {
13
+ this.internalStorageServiceP = internalStorageServiceP;
14
14
  this.logger = logger;
15
15
  this._disposed = false;
16
+ this.internalStorageServiceP.then((s) => (this.internalStorageService = s)).catch(() => { });
16
17
  }
17
18
  get policies() {
18
- return this.internalStorageService.policies;
19
+ if (this.internalStorageService) {
20
+ return this.internalStorageService.policies;
21
+ }
22
+ throw new Error("storage service not yet instantiated");
19
23
  }
20
24
  get disposed() {
21
25
  return this._disposed;
@@ -24,16 +28,19 @@ class RetriableDocumentStorageService {
24
28
  this._disposed = true;
25
29
  }
26
30
  get repositoryUrl() {
27
- return this.internalStorageService.repositoryUrl;
31
+ if (this.internalStorageService) {
32
+ return this.internalStorageService.repositoryUrl;
33
+ }
34
+ throw new Error("storage service not yet instantiated");
28
35
  }
29
36
  async getSnapshotTree(version, scenarioName) {
30
- return this.runWithRetry(async () => this.internalStorageService.getSnapshotTree(version, scenarioName), "storage_getSnapshotTree");
37
+ return this.runWithRetry(async () => this.internalStorageServiceP.then(async (s) => s.getSnapshotTree(version, scenarioName)), "storage_getSnapshotTree");
31
38
  }
32
39
  async readBlob(id) {
33
- return this.runWithRetry(async () => this.internalStorageService.readBlob(id), "storage_readBlob");
40
+ return this.runWithRetry(async () => this.internalStorageServiceP.then(async (s) => s.readBlob(id)), "storage_readBlob");
34
41
  }
35
42
  async getVersions(versionId, count, scenarioName, fetchSource) {
36
- return this.runWithRetry(async () => this.internalStorageService.getVersions(versionId, count, scenarioName, fetchSource), "storage_getVersions");
43
+ return this.runWithRetry(async () => this.internalStorageServiceP.then(async (s) => s.getVersions(versionId, count, scenarioName, fetchSource)), "storage_getVersions");
37
44
  }
38
45
  async uploadSummaryWithContext(summary, context) {
39
46
  // Not using retry loop here. Couple reasons:
@@ -47,16 +54,16 @@ class RetriableDocumentStorageService {
47
54
  // But retry loop is required for creation flow (Container.attach)
48
55
  (0, core_utils_1.assert)((context.referenceSequenceNumber === 0) === (context.ackHandle === undefined), 0x251 /* "creation summary has to have seq=0 && handle === undefined" */);
49
56
  if (context.referenceSequenceNumber !== 0) {
50
- return this.internalStorageService.uploadSummaryWithContext(summary, context);
57
+ return this.internalStorageServiceP.then(async (s) => s.uploadSummaryWithContext(summary, context));
51
58
  }
52
59
  // Creation flow with attachment blobs - need to do retries!
53
- return this.runWithRetry(async () => this.internalStorageService.uploadSummaryWithContext(summary, context), "storage_uploadSummaryWithContext");
60
+ return this.runWithRetry(async () => this.internalStorageServiceP.then(async (s) => s.uploadSummaryWithContext(summary, context)), "storage_uploadSummaryWithContext");
54
61
  }
55
62
  async downloadSummary(handle) {
56
- return this.runWithRetry(async () => this.internalStorageService.downloadSummary(handle), "storage_downloadSummary");
63
+ return this.runWithRetry(async () => this.internalStorageServiceP.then(async (s) => s.downloadSummary(handle)), "storage_downloadSummary");
57
64
  }
58
65
  async createBlob(file) {
59
- return this.runWithRetry(async () => this.internalStorageService.createBlob(file), "storage_createBlob");
66
+ return this.runWithRetry(async () => this.internalStorageServiceP.then(async (s) => s.createBlob(file)), "storage_createBlob");
60
67
  }
61
68
  checkStorageDisposed(callName, error) {
62
69
  if (this._disposed) {
@@ -1 +1 @@
1
- {"version":3,"file":"retriableDocumentStorageService.js","sourceRoot":"","sources":["../src/retriableDocumentStorageService.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils\";\nimport {\n\tFetchSource,\n\tIDocumentStorageService,\n\tIDocumentStorageServicePolicies,\n\tISummaryContext,\n} from \"@fluidframework/driver-definitions\";\nimport {\n\tICreateBlobResponse,\n\tISnapshotTree,\n\tISummaryHandle,\n\tISummaryTree,\n\tIVersion,\n} from \"@fluidframework/protocol-definitions\";\nimport { IDisposable } from \"@fluidframework/core-interfaces\";\nimport { GenericError, ITelemetryLoggerExt } from \"@fluidframework/telemetry-utils\";\nimport { runWithRetry } from \"@fluidframework/driver-utils\";\n\nexport class RetriableDocumentStorageService implements IDocumentStorageService, IDisposable {\n\tprivate _disposed = false;\n\tconstructor(\n\t\tprivate readonly internalStorageService: IDocumentStorageService,\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t) {}\n\n\tpublic get policies(): IDocumentStorageServicePolicies | undefined {\n\t\treturn this.internalStorageService.policies;\n\t}\n\tpublic get disposed() {\n\t\treturn this._disposed;\n\t}\n\tpublic dispose() {\n\t\tthis._disposed = true;\n\t}\n\n\tpublic get repositoryUrl(): string {\n\t\treturn this.internalStorageService.repositoryUrl;\n\t}\n\n\tpublic async getSnapshotTree(\n\t\tversion?: IVersion,\n\t\tscenarioName?: string,\n\t): Promise<ISnapshotTree | null> {\n\t\treturn this.runWithRetry(\n\t\t\tasync () => this.internalStorageService.getSnapshotTree(version, scenarioName),\n\t\t\t\"storage_getSnapshotTree\",\n\t\t);\n\t}\n\n\tpublic async readBlob(id: string): Promise<ArrayBufferLike> {\n\t\treturn this.runWithRetry(\n\t\t\tasync () => this.internalStorageService.readBlob(id),\n\t\t\t\"storage_readBlob\",\n\t\t);\n\t}\n\n\tpublic async getVersions(\n\t\tversionId: string | null,\n\t\tcount: number,\n\t\tscenarioName?: string,\n\t\tfetchSource?: FetchSource,\n\t): Promise<IVersion[]> {\n\t\treturn this.runWithRetry(\n\t\t\tasync () =>\n\t\t\t\tthis.internalStorageService.getVersions(\n\t\t\t\t\tversionId,\n\t\t\t\t\tcount,\n\t\t\t\t\tscenarioName,\n\t\t\t\t\tfetchSource,\n\t\t\t\t),\n\t\t\t\"storage_getVersions\",\n\t\t);\n\t}\n\n\tpublic async uploadSummaryWithContext(\n\t\tsummary: ISummaryTree,\n\t\tcontext: ISummaryContext,\n\t): Promise<string> {\n\t\t// Not using retry loop here. Couple reasons:\n\t\t// 1. If client lost connectivity, then retry loop will result in uploading stale summary\n\t\t// by stale summarizer after connectivity comes back. It will cause failures for this client and for\n\t\t// real (new) summarizer. This problem in particular should be solved in future by supplying abort handle\n\t\t// on all APIs and caller (ContainerRuntime.submitSummary) aborting call on loss of connectivity\n\t\t// 2. Similar, if we get 429 with retryAfter = 10 minutes, it's likely not the right call to retry summary\n\t\t// upload in 10 minutes - it's better to keep processing ops and retry later. Though caller needs to take\n\t\t// retryAfter into account!\n\t\t// But retry loop is required for creation flow (Container.attach)\n\t\tassert(\n\t\t\t(context.referenceSequenceNumber === 0) === (context.ackHandle === undefined),\n\t\t\t0x251 /* \"creation summary has to have seq=0 && handle === undefined\" */,\n\t\t);\n\t\tif (context.referenceSequenceNumber !== 0) {\n\t\t\treturn this.internalStorageService.uploadSummaryWithContext(summary, context);\n\t\t}\n\n\t\t// Creation flow with attachment blobs - need to do retries!\n\t\treturn this.runWithRetry(\n\t\t\tasync () => this.internalStorageService.uploadSummaryWithContext(summary, context),\n\t\t\t\"storage_uploadSummaryWithContext\",\n\t\t);\n\t}\n\n\tpublic async downloadSummary(handle: ISummaryHandle): Promise<ISummaryTree> {\n\t\treturn this.runWithRetry(\n\t\t\tasync () => this.internalStorageService.downloadSummary(handle),\n\t\t\t\"storage_downloadSummary\",\n\t\t);\n\t}\n\n\tpublic async createBlob(file: ArrayBufferLike): Promise<ICreateBlobResponse> {\n\t\treturn this.runWithRetry(\n\t\t\tasync () => this.internalStorageService.createBlob(file),\n\t\t\t\"storage_createBlob\",\n\t\t);\n\t}\n\n\tprivate checkStorageDisposed(callName: string, error: unknown) {\n\t\tif (this._disposed) {\n\t\t\tthis.logger.sendTelemetryEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: `${callName}_abortedStorageDisposed`,\n\t\t\t\t\tfetchCallName: callName, // fetchCallName matches logs in runWithRetry.ts\n\t\t\t\t},\n\t\t\t\terror,\n\t\t\t);\n\t\t\t// pre-0.58 error message: storageServiceDisposedCannotRetry\n\t\t\tthrow new GenericError(\"Storage Service is disposed. Cannot retry\", {\n\t\t\t\tcanRetry: false,\n\t\t\t});\n\t\t}\n\t\treturn;\n\t}\n\n\tprivate async runWithRetry<T>(api: () => Promise<T>, callName: string): Promise<T> {\n\t\treturn runWithRetry(api, callName, this.logger, {\n\t\t\tonRetry: (_delayInMs: number, error: unknown) =>\n\t\t\t\tthis.checkStorageDisposed(callName, error),\n\t\t});\n\t}\n}\n"]}
1
+ {"version":3,"file":"retriableDocumentStorageService.js","sourceRoot":"","sources":["../src/retriableDocumentStorageService.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils\";\nimport {\n\tFetchSource,\n\tIDocumentStorageService,\n\tIDocumentStorageServicePolicies,\n\tISummaryContext,\n} from \"@fluidframework/driver-definitions\";\nimport {\n\tICreateBlobResponse,\n\tISnapshotTree,\n\tISummaryHandle,\n\tISummaryTree,\n\tIVersion,\n} from \"@fluidframework/protocol-definitions\";\nimport { IDisposable } from \"@fluidframework/core-interfaces\";\nimport { GenericError, ITelemetryLoggerExt } from \"@fluidframework/telemetry-utils\";\nimport { runWithRetry } from \"@fluidframework/driver-utils\";\n\nexport class RetriableDocumentStorageService implements IDocumentStorageService, IDisposable {\n\tprivate _disposed = false;\n\tprivate internalStorageService: IDocumentStorageService | undefined;\n\tconstructor(\n\t\tprivate readonly internalStorageServiceP: Promise<IDocumentStorageService>,\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t) {\n\t\tthis.internalStorageServiceP.then((s) => (this.internalStorageService = s)).catch(() => {});\n\t}\n\n\tpublic get policies(): IDocumentStorageServicePolicies | undefined {\n\t\tif (this.internalStorageService) {\n\t\t\treturn this.internalStorageService.policies;\n\t\t}\n\t\tthrow new Error(\"storage service not yet instantiated\");\n\t}\n\tpublic get disposed() {\n\t\treturn this._disposed;\n\t}\n\tpublic dispose() {\n\t\tthis._disposed = true;\n\t}\n\n\tpublic get repositoryUrl(): string {\n\t\tif (this.internalStorageService) {\n\t\t\treturn this.internalStorageService.repositoryUrl;\n\t\t}\n\t\tthrow new Error(\"storage service not yet instantiated\");\n\t}\n\n\tpublic async getSnapshotTree(\n\t\tversion?: IVersion,\n\t\tscenarioName?: string,\n\t): Promise<ISnapshotTree | null> {\n\t\treturn this.runWithRetry(\n\t\t\tasync () =>\n\t\t\t\tthis.internalStorageServiceP.then(async (s) =>\n\t\t\t\t\ts.getSnapshotTree(version, scenarioName),\n\t\t\t\t),\n\t\t\t\"storage_getSnapshotTree\",\n\t\t);\n\t}\n\n\tpublic async readBlob(id: string): Promise<ArrayBufferLike> {\n\t\treturn this.runWithRetry(\n\t\t\tasync () => this.internalStorageServiceP.then(async (s) => s.readBlob(id)),\n\t\t\t\"storage_readBlob\",\n\t\t);\n\t}\n\n\tpublic async getVersions(\n\t\tversionId: string | null,\n\t\tcount: number,\n\t\tscenarioName?: string,\n\t\tfetchSource?: FetchSource,\n\t): Promise<IVersion[]> {\n\t\treturn this.runWithRetry(\n\t\t\tasync () =>\n\t\t\t\tthis.internalStorageServiceP.then(async (s) =>\n\t\t\t\t\ts.getVersions(versionId, count, scenarioName, fetchSource),\n\t\t\t\t),\n\t\t\t\"storage_getVersions\",\n\t\t);\n\t}\n\n\tpublic async uploadSummaryWithContext(\n\t\tsummary: ISummaryTree,\n\t\tcontext: ISummaryContext,\n\t): Promise<string> {\n\t\t// Not using retry loop here. Couple reasons:\n\t\t// 1. If client lost connectivity, then retry loop will result in uploading stale summary\n\t\t// by stale summarizer after connectivity comes back. It will cause failures for this client and for\n\t\t// real (new) summarizer. This problem in particular should be solved in future by supplying abort handle\n\t\t// on all APIs and caller (ContainerRuntime.submitSummary) aborting call on loss of connectivity\n\t\t// 2. Similar, if we get 429 with retryAfter = 10 minutes, it's likely not the right call to retry summary\n\t\t// upload in 10 minutes - it's better to keep processing ops and retry later. Though caller needs to take\n\t\t// retryAfter into account!\n\t\t// But retry loop is required for creation flow (Container.attach)\n\t\tassert(\n\t\t\t(context.referenceSequenceNumber === 0) === (context.ackHandle === undefined),\n\t\t\t0x251 /* \"creation summary has to have seq=0 && handle === undefined\" */,\n\t\t);\n\t\tif (context.referenceSequenceNumber !== 0) {\n\t\t\treturn this.internalStorageServiceP.then(async (s) =>\n\t\t\t\ts.uploadSummaryWithContext(summary, context),\n\t\t\t);\n\t\t}\n\n\t\t// Creation flow with attachment blobs - need to do retries!\n\t\treturn this.runWithRetry(\n\t\t\tasync () =>\n\t\t\t\tthis.internalStorageServiceP.then(async (s) =>\n\t\t\t\t\ts.uploadSummaryWithContext(summary, context),\n\t\t\t\t),\n\t\t\t\"storage_uploadSummaryWithContext\",\n\t\t);\n\t}\n\n\tpublic async downloadSummary(handle: ISummaryHandle): Promise<ISummaryTree> {\n\t\treturn this.runWithRetry(\n\t\t\tasync () => this.internalStorageServiceP.then(async (s) => s.downloadSummary(handle)),\n\t\t\t\"storage_downloadSummary\",\n\t\t);\n\t}\n\n\tpublic async createBlob(file: ArrayBufferLike): Promise<ICreateBlobResponse> {\n\t\treturn this.runWithRetry(\n\t\t\tasync () => this.internalStorageServiceP.then(async (s) => s.createBlob(file)),\n\t\t\t\"storage_createBlob\",\n\t\t);\n\t}\n\n\tprivate checkStorageDisposed(callName: string, error: unknown) {\n\t\tif (this._disposed) {\n\t\t\tthis.logger.sendTelemetryEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: `${callName}_abortedStorageDisposed`,\n\t\t\t\t\tfetchCallName: callName, // fetchCallName matches logs in runWithRetry.ts\n\t\t\t\t},\n\t\t\t\terror,\n\t\t\t);\n\t\t\t// pre-0.58 error message: storageServiceDisposedCannotRetry\n\t\t\tthrow new GenericError(\"Storage Service is disposed. Cannot retry\", {\n\t\t\t\tcanRetry: false,\n\t\t\t});\n\t\t}\n\t\treturn;\n\t}\n\n\tprivate async runWithRetry<T>(api: () => Promise<T>, callName: string): Promise<T> {\n\t\treturn runWithRetry(api, callName, this.logger, {\n\t\t\tonRetry: (_delayInMs: number, error: unknown) =>\n\t\t\t\tthis.checkStorageDisposed(callName, error),\n\t\t});\n\t}\n}\n"]}
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.34.9"
8
+ "packageVersion": "7.38.0"
9
9
  }
10
10
  ]
11
11
  }
package/dist/utils.d.ts CHANGED
@@ -12,9 +12,23 @@ export interface ISnapshotTreeWithBlobContents extends ISnapshotTree {
12
12
  [path: string]: ISnapshotTreeWithBlobContents;
13
13
  };
14
14
  }
15
+ /**
16
+ * Interface to represent the parsed parts of IResolvedUrl.url to help
17
+ * in getting info about different parts of the url.
18
+ * May not be compatible or relevant for any Url Resolver
19
+ */
15
20
  export interface IParsedUrl {
21
+ /**
22
+ * It is combination of tenantid/docId part of the url.
23
+ */
16
24
  id: string;
25
+ /**
26
+ * It is the deep link path in the url.
27
+ */
17
28
  path: string;
29
+ /**
30
+ * Query string part of the url.
31
+ */
18
32
  query: string;
19
33
  /**
20
34
  * Null means do not use snapshots, undefined means load latest snapshot
@@ -23,7 +37,15 @@ export interface IParsedUrl {
23
37
  */
24
38
  version: string | null | undefined;
25
39
  }
26
- export declare function parseUrl(url: string): IParsedUrl | undefined;
40
+ /**
41
+ * Utility api to parse the IResolvedUrl.url into specific parts like querystring, path to get
42
+ * deep link info etc.
43
+ * Warning - This function may not be compatible with any Url Resolver's resolved url. It works
44
+ * with urls of type: protocol://<string>/.../..?<querystring>
45
+ * @param url - This is the IResolvedUrl.url part of the resolved url.
46
+ * @returns The IParsedUrl representing the input URL, or undefined if the format was not supported
47
+ */
48
+ export declare function tryParseCompatibleResolvedUrl(url: string): IParsedUrl | undefined;
27
49
  /**
28
50
  * Combine the app summary and protocol summary in 1 tree.
29
51
  * @param appSummary - Summary of the app.
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAe,MAAM,sCAAsC,CAAC;AAEhG,OAAO,EACN,6BAA6B,EAC7B,mCAAmC,EAEnC,MAAM,8BAA8B,CAAC;AAKtC,MAAM,WAAW,6BAA8B,SAAQ,aAAa;IACnE,aAAa,EAAE;QAAE,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAAA;KAAE,CAAC;IACnD,KAAK,EAAE;QAAE,CAAC,IAAI,EAAE,MAAM,GAAG,6BAA6B,CAAA;KAAE,CAAC;CACzD;AAED,MAAM,WAAW,UAAU;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACnC;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAW5D;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC3C,UAAU,EAAE,YAAY,EACxB,eAAe,EAAE,YAAY,GAC3B,6BAA6B,CAiB/B;AA0DD;;;;GAIG;AACH,wBAAgB,0CAA0C,CACzD,mBAAmB,EAAE,YAAY,EACjC,cAAc,EAAE,YAAY,GAC1B,6BAA6B,CAW/B;AAID,eAAO,MAAM,sCAAsC,8BACvB,YAAY,KACrC,6BAYF,CAAC;AAEF,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,aAAa,GAAG,aAAa,CAE9E;AAED,wBAAgB,qCAAqC,CACpD,KAAK,EAAE,GAAG,GACR,KAAK,IAAI,mCAAmC,CAM9C"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAe,MAAM,sCAAsC,CAAC;AAEhG,OAAO,EACN,6BAA6B,EAC7B,mCAAmC,EAEnC,MAAM,8BAA8B,CAAC;AAKtC,MAAM,WAAW,6BAA8B,SAAQ,aAAa;IACnE,aAAa,EAAE;QAAE,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAAA;KAAE,CAAC;IACnD,KAAK,EAAE;QAAE,CAAC,IAAI,EAAE,MAAM,GAAG,6BAA6B,CAAA;KAAE,CAAC;CACzD;AAED;;;;GAIG;AACH,MAAM,WAAW,UAAU;IAC1B;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IACX;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACnC;AAED;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAWjF;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC3C,UAAU,EAAE,YAAY,EACxB,eAAe,EAAE,YAAY,GAC3B,6BAA6B,CAiB/B;AA0DD;;;;GAIG;AACH,wBAAgB,0CAA0C,CACzD,mBAAmB,EAAE,YAAY,EACjC,cAAc,EAAE,YAAY,GAC1B,6BAA6B,CAW/B;AAID,eAAO,MAAM,sCAAsC,8BACvB,YAAY,KACrC,6BAYF,CAAC;AAEF,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,aAAa,GAAG,aAAa,CAE9E;AAED,wBAAgB,qCAAqC,CACpD,KAAK,EAAE,GAAG,GACR,KAAK,IAAI,mCAAmC,CAM9C"}
package/dist/utils.js CHANGED
@@ -4,7 +4,7 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.isDeltaStreamConnectionForbiddenError = exports.getProtocolSnapshotTree = exports.getSnapshotTreeFromSerializedContainer = exports.convertProtocolAndAppSummaryToSnapshotTree = exports.combineAppAndProtocolSummary = exports.parseUrl = void 0;
7
+ exports.isDeltaStreamConnectionForbiddenError = exports.getProtocolSnapshotTree = exports.getSnapshotTreeFromSerializedContainer = exports.convertProtocolAndAppSummaryToSnapshotTree = exports.combineAppAndProtocolSummary = exports.tryParseCompatibleResolvedUrl = void 0;
8
8
  const url_1 = require("url");
9
9
  const uuid_1 = require("uuid");
10
10
  const client_utils_1 = require("@fluid-internal/client-utils");
@@ -13,7 +13,15 @@ const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
13
13
  const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
14
14
  const driver_utils_1 = require("@fluidframework/driver-utils");
15
15
  const driver_definitions_1 = require("@fluidframework/driver-definitions");
16
- function parseUrl(url) {
16
+ /**
17
+ * Utility api to parse the IResolvedUrl.url into specific parts like querystring, path to get
18
+ * deep link info etc.
19
+ * Warning - This function may not be compatible with any Url Resolver's resolved url. It works
20
+ * with urls of type: protocol://<string>/.../..?<querystring>
21
+ * @param url - This is the IResolvedUrl.url part of the resolved url.
22
+ * @returns The IParsedUrl representing the input URL, or undefined if the format was not supported
23
+ */
24
+ function tryParseCompatibleResolvedUrl(url) {
17
25
  const parsed = (0, url_1.parse)(url, true);
18
26
  if (typeof parsed.pathname !== "string") {
19
27
  throw new telemetry_utils_1.LoggingError("Failed to parse pathname");
@@ -25,7 +33,7 @@ function parseUrl(url) {
25
33
  ? { id: match[1], path: match[2], query, version: parsed.query.version }
26
34
  : undefined;
27
35
  }
28
- exports.parseUrl = parseUrl;
36
+ exports.tryParseCompatibleResolvedUrl = tryParseCompatibleResolvedUrl;
29
37
  /**
30
38
  * Combine the app summary and protocol summary in 1 tree.
31
39
  * @param appSummary - Summary of the app.
package/dist/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { parse } from \"url\";\nimport { v4 as uuid } from \"uuid\";\nimport { stringToBuffer, Uint8ArrayToArrayBuffer } from \"@fluid-internal/client-utils\";\nimport { assert, unreachableCase } from \"@fluidframework/core-utils\";\nimport { ISummaryTree, ISnapshotTree, SummaryType } from \"@fluidframework/protocol-definitions\";\nimport { LoggingError } from \"@fluidframework/telemetry-utils\";\nimport {\n\tCombinedAppAndProtocolSummary,\n\tDeltaStreamConnectionForbiddenError,\n\tisCombinedAppAndProtocolSummary,\n} from \"@fluidframework/driver-utils\";\nimport { DriverErrorTypes } from \"@fluidframework/driver-definitions\";\n\n// This is used when we rehydrate a container from the snapshot. Here we put the blob contents\n// in separate property: blobContents.\nexport interface ISnapshotTreeWithBlobContents extends ISnapshotTree {\n\tblobsContents: { [path: string]: ArrayBufferLike };\n\ttrees: { [path: string]: ISnapshotTreeWithBlobContents };\n}\n\nexport interface IParsedUrl {\n\tid: string;\n\tpath: string;\n\tquery: string;\n\t/**\n\t * Null means do not use snapshots, undefined means load latest snapshot\n\t * otherwise it's version ID passed to IDocumentStorageService.getVersions() to figure out what snapshot to use.\n\t * If needed, can add undefined which is treated by Container.load() as load latest snapshot.\n\t */\n\tversion: string | null | undefined;\n}\n\nexport function parseUrl(url: string): IParsedUrl | undefined {\n\tconst parsed = parse(url, true);\n\tif (typeof parsed.pathname !== \"string\") {\n\t\tthrow new LoggingError(\"Failed to parse pathname\");\n\t}\n\tconst query = parsed.search ?? \"\";\n\tconst regex = /^\\/([^/]*\\/[^/]*)(\\/?.*)$/;\n\tconst match = regex.exec(parsed.pathname);\n\treturn match?.length === 3\n\t\t? { id: match[1], path: match[2], query, version: parsed.query.version as string }\n\t\t: undefined;\n}\n\n/**\n * Combine the app summary and protocol summary in 1 tree.\n * @param appSummary - Summary of the app.\n * @param protocolSummary - Summary of the protocol.\n * @internal\n */\nexport function combineAppAndProtocolSummary(\n\tappSummary: ISummaryTree,\n\tprotocolSummary: ISummaryTree,\n): CombinedAppAndProtocolSummary {\n\tassert(\n\t\t!isCombinedAppAndProtocolSummary(appSummary),\n\t\t0x5a8 /* app summary is already a combined tree! */,\n\t);\n\tassert(\n\t\t!isCombinedAppAndProtocolSummary(protocolSummary),\n\t\t0x5a9 /* protocol summary is already a combined tree! */,\n\t);\n\tconst createNewSummary: CombinedAppAndProtocolSummary = {\n\t\ttype: SummaryType.Tree,\n\t\ttree: {\n\t\t\t\".protocol\": protocolSummary,\n\t\t\t\".app\": appSummary,\n\t\t},\n\t};\n\treturn createNewSummary;\n}\n\n/**\n * Converts summary tree (for upload) to snapshot tree (for download).\n * Summary tree blobs contain contents, but snapshot tree blobs normally\n * contain IDs pointing to storage. This will create 2 blob entries in the\n * snapshot tree for each blob in the summary tree. One will be the regular\n * path pointing to a uniquely generated ID. Then there will be another\n * entry with the path as that uniquely generated ID, and value as the\n * blob contents as a base-64 string.\n * @param summary - summary to convert\n */\nfunction convertSummaryToSnapshotWithEmbeddedBlobContents(\n\tsummary: ISummaryTree,\n): ISnapshotTreeWithBlobContents {\n\tconst treeNode: ISnapshotTreeWithBlobContents = {\n\t\tblobs: {},\n\t\tblobsContents: {},\n\t\ttrees: {},\n\t\tid: uuid(),\n\t\tunreferenced: summary.unreferenced,\n\t};\n\tconst keys = Object.keys(summary.tree);\n\tfor (const key of keys) {\n\t\tconst summaryObject = summary.tree[key];\n\n\t\tswitch (summaryObject.type) {\n\t\t\tcase SummaryType.Tree: {\n\t\t\t\ttreeNode.trees[key] =\n\t\t\t\t\tconvertSummaryToSnapshotWithEmbeddedBlobContents(summaryObject);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SummaryType.Attachment:\n\t\t\t\ttreeNode.blobs[key] = summaryObject.id;\n\t\t\t\tbreak;\n\t\t\tcase SummaryType.Blob: {\n\t\t\t\tconst blobId = uuid();\n\t\t\t\ttreeNode.blobs[key] = blobId;\n\t\t\t\tconst contentBuffer =\n\t\t\t\t\ttypeof summaryObject.content === \"string\"\n\t\t\t\t\t\t? stringToBuffer(summaryObject.content, \"utf8\")\n\t\t\t\t\t\t: Uint8ArrayToArrayBuffer(summaryObject.content);\n\t\t\t\ttreeNode.blobsContents[blobId] = contentBuffer;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SummaryType.Handle:\n\t\t\t\tthrow new LoggingError(\n\t\t\t\t\t\"No handles should be there in summary in detached container!!\",\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tdefault: {\n\t\t\t\tunreachableCase(summaryObject, `Unknown tree type ${(summaryObject as any).type}`);\n\t\t\t}\n\t\t}\n\t}\n\treturn treeNode;\n}\n\n/**\n * Combine and convert protocol and app summary tree to format which is readable by container while rehydrating.\n * @param protocolSummaryTree - Protocol Summary Tree\n * @param appSummaryTree - App Summary Tree\n */\nexport function convertProtocolAndAppSummaryToSnapshotTree(\n\tprotocolSummaryTree: ISummaryTree,\n\tappSummaryTree: ISummaryTree,\n): ISnapshotTreeWithBlobContents {\n\t// Shallow copy is fine, since we are doing a deep clone below.\n\tconst combinedSummary: ISummaryTree = {\n\t\ttype: SummaryType.Tree,\n\t\ttree: { ...appSummaryTree.tree },\n\t};\n\n\tcombinedSummary.tree[\".protocol\"] = protocolSummaryTree;\n\tconst snapshotTreeWithBlobContents =\n\t\tconvertSummaryToSnapshotWithEmbeddedBlobContents(combinedSummary);\n\treturn snapshotTreeWithBlobContents;\n}\n\n// This function converts the snapshot taken in detached container(by serialize api) to snapshotTree with which\n// a detached container can be rehydrated.\nexport const getSnapshotTreeFromSerializedContainer = (\n\tdetachedContainerSnapshot: ISummaryTree,\n): ISnapshotTreeWithBlobContents => {\n\tassert(\n\t\tisCombinedAppAndProtocolSummary(detachedContainerSnapshot),\n\t\t0x1e0 /* \"Protocol and App summary trees should be present\" */,\n\t);\n\tconst protocolSummaryTree = detachedContainerSnapshot.tree[\".protocol\"];\n\tconst appSummaryTree = detachedContainerSnapshot.tree[\".app\"];\n\tconst snapshotTreeWithBlobContents = convertProtocolAndAppSummaryToSnapshotTree(\n\t\tprotocolSummaryTree,\n\t\tappSummaryTree,\n\t);\n\treturn snapshotTreeWithBlobContents;\n};\n\nexport function getProtocolSnapshotTree(snapshot: ISnapshotTree): ISnapshotTree {\n\treturn \".protocol\" in snapshot.trees ? snapshot.trees[\".protocol\"] : snapshot;\n}\n\nexport function isDeltaStreamConnectionForbiddenError(\n\terror: any,\n): error is DeltaStreamConnectionForbiddenError {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\terror?.errorType === DriverErrorTypes.deltaStreamConnectionForbidden\n\t);\n}\n"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { parse } from \"url\";\nimport { v4 as uuid } from \"uuid\";\nimport { stringToBuffer, Uint8ArrayToArrayBuffer } from \"@fluid-internal/client-utils\";\nimport { assert, unreachableCase } from \"@fluidframework/core-utils\";\nimport { ISummaryTree, ISnapshotTree, SummaryType } from \"@fluidframework/protocol-definitions\";\nimport { LoggingError } from \"@fluidframework/telemetry-utils\";\nimport {\n\tCombinedAppAndProtocolSummary,\n\tDeltaStreamConnectionForbiddenError,\n\tisCombinedAppAndProtocolSummary,\n} from \"@fluidframework/driver-utils\";\nimport { DriverErrorTypes } from \"@fluidframework/driver-definitions\";\n\n// This is used when we rehydrate a container from the snapshot. Here we put the blob contents\n// in separate property: blobContents.\nexport interface ISnapshotTreeWithBlobContents extends ISnapshotTree {\n\tblobsContents: { [path: string]: ArrayBufferLike };\n\ttrees: { [path: string]: ISnapshotTreeWithBlobContents };\n}\n\n/**\n * Interface to represent the parsed parts of IResolvedUrl.url to help\n * in getting info about different parts of the url.\n * May not be compatible or relevant for any Url Resolver\n */\nexport interface IParsedUrl {\n\t/**\n\t * It is combination of tenantid/docId part of the url.\n\t */\n\tid: string;\n\t/**\n\t * It is the deep link path in the url.\n\t */\n\tpath: string;\n\t/**\n\t * Query string part of the url.\n\t */\n\tquery: string;\n\t/**\n\t * Null means do not use snapshots, undefined means load latest snapshot\n\t * otherwise it's version ID passed to IDocumentStorageService.getVersions() to figure out what snapshot to use.\n\t * If needed, can add undefined which is treated by Container.load() as load latest snapshot.\n\t */\n\tversion: string | null | undefined;\n}\n\n/**\n * Utility api to parse the IResolvedUrl.url into specific parts like querystring, path to get\n * deep link info etc.\n * Warning - This function may not be compatible with any Url Resolver's resolved url. It works\n * with urls of type: protocol://<string>/.../..?<querystring>\n * @param url - This is the IResolvedUrl.url part of the resolved url.\n * @returns The IParsedUrl representing the input URL, or undefined if the format was not supported\n */\nexport function tryParseCompatibleResolvedUrl(url: string): IParsedUrl | undefined {\n\tconst parsed = parse(url, true);\n\tif (typeof parsed.pathname !== \"string\") {\n\t\tthrow new LoggingError(\"Failed to parse pathname\");\n\t}\n\tconst query = parsed.search ?? \"\";\n\tconst regex = /^\\/([^/]*\\/[^/]*)(\\/?.*)$/;\n\tconst match = regex.exec(parsed.pathname);\n\treturn match?.length === 3\n\t\t? { id: match[1], path: match[2], query, version: parsed.query.version as string }\n\t\t: undefined;\n}\n\n/**\n * Combine the app summary and protocol summary in 1 tree.\n * @param appSummary - Summary of the app.\n * @param protocolSummary - Summary of the protocol.\n * @internal\n */\nexport function combineAppAndProtocolSummary(\n\tappSummary: ISummaryTree,\n\tprotocolSummary: ISummaryTree,\n): CombinedAppAndProtocolSummary {\n\tassert(\n\t\t!isCombinedAppAndProtocolSummary(appSummary),\n\t\t0x5a8 /* app summary is already a combined tree! */,\n\t);\n\tassert(\n\t\t!isCombinedAppAndProtocolSummary(protocolSummary),\n\t\t0x5a9 /* protocol summary is already a combined tree! */,\n\t);\n\tconst createNewSummary: CombinedAppAndProtocolSummary = {\n\t\ttype: SummaryType.Tree,\n\t\ttree: {\n\t\t\t\".protocol\": protocolSummary,\n\t\t\t\".app\": appSummary,\n\t\t},\n\t};\n\treturn createNewSummary;\n}\n\n/**\n * Converts summary tree (for upload) to snapshot tree (for download).\n * Summary tree blobs contain contents, but snapshot tree blobs normally\n * contain IDs pointing to storage. This will create 2 blob entries in the\n * snapshot tree for each blob in the summary tree. One will be the regular\n * path pointing to a uniquely generated ID. Then there will be another\n * entry with the path as that uniquely generated ID, and value as the\n * blob contents as a base-64 string.\n * @param summary - summary to convert\n */\nfunction convertSummaryToSnapshotWithEmbeddedBlobContents(\n\tsummary: ISummaryTree,\n): ISnapshotTreeWithBlobContents {\n\tconst treeNode: ISnapshotTreeWithBlobContents = {\n\t\tblobs: {},\n\t\tblobsContents: {},\n\t\ttrees: {},\n\t\tid: uuid(),\n\t\tunreferenced: summary.unreferenced,\n\t};\n\tconst keys = Object.keys(summary.tree);\n\tfor (const key of keys) {\n\t\tconst summaryObject = summary.tree[key];\n\n\t\tswitch (summaryObject.type) {\n\t\t\tcase SummaryType.Tree: {\n\t\t\t\ttreeNode.trees[key] =\n\t\t\t\t\tconvertSummaryToSnapshotWithEmbeddedBlobContents(summaryObject);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SummaryType.Attachment:\n\t\t\t\ttreeNode.blobs[key] = summaryObject.id;\n\t\t\t\tbreak;\n\t\t\tcase SummaryType.Blob: {\n\t\t\t\tconst blobId = uuid();\n\t\t\t\ttreeNode.blobs[key] = blobId;\n\t\t\t\tconst contentBuffer =\n\t\t\t\t\ttypeof summaryObject.content === \"string\"\n\t\t\t\t\t\t? stringToBuffer(summaryObject.content, \"utf8\")\n\t\t\t\t\t\t: Uint8ArrayToArrayBuffer(summaryObject.content);\n\t\t\t\ttreeNode.blobsContents[blobId] = contentBuffer;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SummaryType.Handle:\n\t\t\t\tthrow new LoggingError(\n\t\t\t\t\t\"No handles should be there in summary in detached container!!\",\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tdefault: {\n\t\t\t\tunreachableCase(summaryObject, `Unknown tree type ${(summaryObject as any).type}`);\n\t\t\t}\n\t\t}\n\t}\n\treturn treeNode;\n}\n\n/**\n * Combine and convert protocol and app summary tree to format which is readable by container while rehydrating.\n * @param protocolSummaryTree - Protocol Summary Tree\n * @param appSummaryTree - App Summary Tree\n */\nexport function convertProtocolAndAppSummaryToSnapshotTree(\n\tprotocolSummaryTree: ISummaryTree,\n\tappSummaryTree: ISummaryTree,\n): ISnapshotTreeWithBlobContents {\n\t// Shallow copy is fine, since we are doing a deep clone below.\n\tconst combinedSummary: ISummaryTree = {\n\t\ttype: SummaryType.Tree,\n\t\ttree: { ...appSummaryTree.tree },\n\t};\n\n\tcombinedSummary.tree[\".protocol\"] = protocolSummaryTree;\n\tconst snapshotTreeWithBlobContents =\n\t\tconvertSummaryToSnapshotWithEmbeddedBlobContents(combinedSummary);\n\treturn snapshotTreeWithBlobContents;\n}\n\n// This function converts the snapshot taken in detached container(by serialize api) to snapshotTree with which\n// a detached container can be rehydrated.\nexport const getSnapshotTreeFromSerializedContainer = (\n\tdetachedContainerSnapshot: ISummaryTree,\n): ISnapshotTreeWithBlobContents => {\n\tassert(\n\t\tisCombinedAppAndProtocolSummary(detachedContainerSnapshot),\n\t\t0x1e0 /* \"Protocol and App summary trees should be present\" */,\n\t);\n\tconst protocolSummaryTree = detachedContainerSnapshot.tree[\".protocol\"];\n\tconst appSummaryTree = detachedContainerSnapshot.tree[\".app\"];\n\tconst snapshotTreeWithBlobContents = convertProtocolAndAppSummaryToSnapshotTree(\n\t\tprotocolSummaryTree,\n\t\tappSummaryTree,\n\t);\n\treturn snapshotTreeWithBlobContents;\n};\n\nexport function getProtocolSnapshotTree(snapshot: ISnapshotTree): ISnapshotTree {\n\treturn \".protocol\" in snapshot.trees ? snapshot.trees[\".protocol\"] : snapshot;\n}\n\nexport function isDeltaStreamConnectionForbiddenError(\n\terror: any,\n): error is DeltaStreamConnectionForbiddenError {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\terror?.errorType === DriverErrorTypes.deltaStreamConnectionForbidden\n\t);\n}\n"]}
@@ -5,9 +5,9 @@
5
5
  import { IDisposable } from "@fluidframework/core-interfaces";
6
6
  import { IDeltaManager } from "@fluidframework/container-definitions";
7
7
  /** @see CatchUpMonitor for usage */
8
- declare type CaughtUpListener = () => void;
8
+ type CaughtUpListener = () => void;
9
9
  /** Monitor that emits an event when a Container has caught up to a given point in the op stream */
10
- export declare type ICatchUpMonitor = IDisposable;
10
+ export type ICatchUpMonitor = IDisposable;
11
11
  /**
12
12
  * Monitors a Container's DeltaManager, notifying listeners when all ops have been processed
13
13
  * that were known at the time the monitor was created.
@@ -1 +1 @@
1
- {"version":3,"file":"catchUpMonitor.d.ts","sourceRoot":"","sources":["../src/catchUpMonitor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAE9D,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AAGtE,oCAAoC;AACpC,aAAK,gBAAgB,GAAG,MAAM,IAAI,CAAC;AAEnC,mGAAmG;AACnG,oBAAY,eAAe,GAAG,WAAW,CAAC;AAE1C;;;GAGG;AACH,qBAAa,cAAe,YAAW,eAAe;IAepD,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAf1B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAkB;IAElC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAKxB;IAEF;;OAEG;gBAEe,YAAY,EAAE,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,EACrC,QAAQ,EAAE,gBAAgB;IAerC,QAAQ,EAAE,OAAO,CAAS;IAC1B,OAAO;CAQd"}
1
+ {"version":3,"file":"catchUpMonitor.d.ts","sourceRoot":"","sources":["../src/catchUpMonitor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAE9D,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AAGtE,oCAAoC;AACpC,KAAK,gBAAgB,GAAG,MAAM,IAAI,CAAC;AAEnC,mGAAmG;AACnG,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC;AAE1C;;;GAGG;AACH,qBAAa,cAAe,YAAW,eAAe;IAepD,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAf1B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAkB;IAElC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAKxB;IAEF;;OAEG;gBAEe,YAAY,EAAE,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,EACrC,QAAQ,EAAE,gBAAgB;IAerC,QAAQ,EAAE,OAAO,CAAS;IAC1B,OAAO;CAQd"}
@@ -93,21 +93,7 @@ export declare class ConnectionManager implements IConnectionManager {
93
93
  */
94
94
  setAutoReconnect(mode: ReconnectMode, reason: IConnectionStateChangeReason): void;
95
95
  /**
96
- * Sends signal to runtime (and data stores) to be read-only.
97
- * Hosts may have read only views, indicating to data stores that no edits are allowed.
98
- * This is independent from this._readonlyPermissions (permissions) and this.connectionMode
99
- * (server can return "write" mode even when asked for "read")
100
- * Leveraging same "readonly" event as runtime & data stores should behave the same in such case
101
- * as in read-only permissions.
102
- * But this.active can be used by some DDSes to figure out if ops can be sent
103
- * (for example, read-only view still participates in code proposals / upgrades decisions)
104
- *
105
- * Forcing Readonly does not prevent DDS from generating ops. It is up to user code to honour
106
- * the readonly flag. If ops are generated, they will accumulate locally and not be sent. If
107
- * there are pending in the outbound queue, it will stop sending until force readonly is
108
- * cleared.
109
- *
110
- * @param readonly - set or clear force readonly.
96
+ * {@inheritDoc Container.forceReadonly}
111
97
  */
112
98
  forceReadonly(readonly: boolean): void;
113
99
  private set_readonlyPermissions;
@@ -157,6 +143,7 @@ export declare class ConnectionManager implements IConnectionManager {
157
143
  sendMessages(messages: IDocumentMessage[]): void;
158
144
  beforeProcessingIncomingOp(message: ISequencedDocumentMessage): void;
159
145
  private readonly opHandler;
146
+ private readonly signalHandler;
160
147
  private readonly nackHandler;
161
148
  private readonly disconnectHandlerInternal;
162
149
  private readonly errorHandler;
@@ -1 +1 @@
1
- {"version":3,"file":"connectionManager.d.ts","sourceRoot":"","sources":["../src/connectionManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"connectionManager.d.ts","sourceRoot":"","sources":["../src/connectionManager.ts"],"names":[],"mappings":"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"}