@fluidframework/routerlicious-driver 2.0.0-dev.3.1.0.125672 → 2.0.0-dev.4.1.0.148229

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 (79) hide show
  1. package/dist/cache.js +2 -2
  2. package/dist/cache.js.map +1 -1
  3. package/dist/documentService.d.ts.map +1 -1
  4. package/dist/documentService.js +9 -3
  5. package/dist/documentService.js.map +1 -1
  6. package/dist/documentServiceFactory.d.ts +0 -1
  7. package/dist/documentServiceFactory.d.ts.map +1 -1
  8. package/dist/documentServiceFactory.js +3 -4
  9. package/dist/documentServiceFactory.js.map +1 -1
  10. package/dist/errorUtils.d.ts +9 -2
  11. package/dist/errorUtils.d.ts.map +1 -1
  12. package/dist/errorUtils.js +15 -8
  13. package/dist/errorUtils.js.map +1 -1
  14. package/dist/index.d.ts +1 -0
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +4 -1
  17. package/dist/index.js.map +1 -1
  18. package/dist/mapWithExpiration.d.ts +34 -0
  19. package/dist/mapWithExpiration.d.ts.map +1 -0
  20. package/dist/mapWithExpiration.js +105 -0
  21. package/dist/mapWithExpiration.js.map +1 -0
  22. package/dist/packageVersion.d.ts +1 -1
  23. package/dist/packageVersion.js +1 -1
  24. package/dist/packageVersion.js.map +1 -1
  25. package/dist/tokens.d.ts +24 -7
  26. package/dist/tokens.d.ts.map +1 -1
  27. package/dist/tokens.js.map +1 -1
  28. package/dist/treeUtils.d.ts +51 -0
  29. package/dist/treeUtils.d.ts.map +1 -0
  30. package/dist/treeUtils.js +85 -0
  31. package/dist/treeUtils.js.map +1 -0
  32. package/dist/wholeSummaryDocumentStorageService.d.ts.map +1 -1
  33. package/dist/wholeSummaryDocumentStorageService.js +5 -6
  34. package/dist/wholeSummaryDocumentStorageService.js.map +1 -1
  35. package/lib/cache.js +1 -1
  36. package/lib/cache.js.map +1 -1
  37. package/lib/documentService.d.ts.map +1 -1
  38. package/lib/documentService.js +11 -5
  39. package/lib/documentService.js.map +1 -1
  40. package/lib/documentServiceFactory.d.ts +0 -1
  41. package/lib/documentServiceFactory.d.ts.map +1 -1
  42. package/lib/documentServiceFactory.js +4 -5
  43. package/lib/documentServiceFactory.js.map +1 -1
  44. package/lib/errorUtils.d.ts +9 -2
  45. package/lib/errorUtils.d.ts.map +1 -1
  46. package/lib/errorUtils.js +14 -7
  47. package/lib/errorUtils.js.map +1 -1
  48. package/lib/index.d.ts +1 -0
  49. package/lib/index.d.ts.map +1 -1
  50. package/lib/index.js +2 -0
  51. package/lib/index.js.map +1 -1
  52. package/lib/mapWithExpiration.d.ts +34 -0
  53. package/lib/mapWithExpiration.d.ts.map +1 -0
  54. package/lib/mapWithExpiration.js +101 -0
  55. package/lib/mapWithExpiration.js.map +1 -0
  56. package/lib/packageVersion.d.ts +1 -1
  57. package/lib/packageVersion.js +1 -1
  58. package/lib/packageVersion.js.map +1 -1
  59. package/lib/tokens.d.ts +24 -7
  60. package/lib/tokens.d.ts.map +1 -1
  61. package/lib/tokens.js.map +1 -1
  62. package/lib/treeUtils.d.ts +51 -0
  63. package/lib/treeUtils.d.ts.map +1 -0
  64. package/lib/treeUtils.js +80 -0
  65. package/lib/treeUtils.js.map +1 -0
  66. package/lib/wholeSummaryDocumentStorageService.d.ts.map +1 -1
  67. package/lib/wholeSummaryDocumentStorageService.js +4 -5
  68. package/lib/wholeSummaryDocumentStorageService.js.map +1 -1
  69. package/package.json +52 -53
  70. package/src/cache.ts +1 -1
  71. package/src/documentService.ts +26 -11
  72. package/src/documentServiceFactory.ts +5 -4
  73. package/src/errorUtils.ts +16 -4
  74. package/src/index.ts +3 -0
  75. package/src/mapWithExpiration.ts +124 -0
  76. package/src/packageVersion.ts +1 -1
  77. package/src/tokens.ts +24 -7
  78. package/src/treeUtils.ts +107 -0
  79. package/src/wholeSummaryDocumentStorageService.ts +7 -5
package/dist/cache.js CHANGED
@@ -5,11 +5,11 @@
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.NullCache = exports.InMemoryCache = void 0;
8
- const driver_utils_1 = require("@fluidframework/driver-utils");
8
+ const mapWithExpiration_1 = require("./mapWithExpiration");
9
9
  /** A basic in-memory cache that optionally supports expiring entries after a period of inactivity */
10
10
  class InMemoryCache {
11
11
  constructor(expirationMs) {
12
- this.cache = expirationMs !== undefined ? new driver_utils_1.MapWithExpiration(expirationMs) : new Map();
12
+ this.cache = expirationMs !== undefined ? new mapWithExpiration_1.MapWithExpiration(expirationMs) : new Map();
13
13
  }
14
14
  async get(key) {
15
15
  return this.cache.get(key);
package/dist/cache.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAAiE;AAOjE,qGAAqG;AACrG,MAAa,aAAa;IAGzB,YAAY,YAAqB;QAChC,IAAI,CAAC,KAAK,GAAG,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,gCAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;IAC3F,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,GAAW;QAC3B,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAQ;QACrC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC5B,CAAC;CACD;AAdD,sCAcC;AAED,yEAAyE;AACzE,MAAa,SAAS;IACd,KAAK,CAAC,GAAG,CAAC,GAAW;QAC3B,OAAO,SAAS,CAAC;IAClB,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAQ,IAAkB,CAAC;CACzD;AAND,8BAMC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { MapWithExpiration } from \"@fluidframework/driver-utils\";\n\nexport interface ICache<T> {\n\tget(key: string): Promise<T | undefined>;\n\tput(key: string, value: T): Promise<void>;\n}\n\n/** A basic in-memory cache that optionally supports expiring entries after a period of inactivity */\nexport class InMemoryCache<T> implements ICache<T> {\n\tprivate readonly cache: Map<string, T>;\n\n\tconstructor(expirationMs?: number) {\n\t\tthis.cache = expirationMs !== undefined ? new MapWithExpiration(expirationMs) : new Map();\n\t}\n\n\tpublic async get(key: string): Promise<T | undefined> {\n\t\treturn this.cache.get(key);\n\t}\n\n\tpublic async put(key: string, value: T): Promise<void> {\n\t\tthis.cache.set(key, value);\n\t}\n}\n\n/** This \"cache\" does nothing on put, and get always returns undefined */\nexport class NullCache<T> implements ICache<T> {\n\tpublic async get(key: string): Promise<T | undefined> {\n\t\treturn undefined;\n\t}\n\n\tpublic async put(key: string, value: T): Promise<void> {}\n}\n"]}
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,2DAAwD;AAOxD,qGAAqG;AACrG,MAAa,aAAa;IAGzB,YAAY,YAAqB;QAChC,IAAI,CAAC,KAAK,GAAG,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,qCAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;IAC3F,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,GAAW;QAC3B,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAQ;QACrC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC5B,CAAC;CACD;AAdD,sCAcC;AAED,yEAAyE;AACzE,MAAa,SAAS;IACd,KAAK,CAAC,GAAG,CAAC,GAAW;QAC3B,OAAO,SAAS,CAAC;IAClB,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAQ,IAAkB,CAAC;CACzD;AAND,8BAMC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { MapWithExpiration } from \"./mapWithExpiration\";\n\nexport interface ICache<T> {\n\tget(key: string): Promise<T | undefined>;\n\tput(key: string, value: T): Promise<void>;\n}\n\n/** A basic in-memory cache that optionally supports expiring entries after a period of inactivity */\nexport class InMemoryCache<T> implements ICache<T> {\n\tprivate readonly cache: Map<string, T>;\n\n\tconstructor(expirationMs?: number) {\n\t\tthis.cache = expirationMs !== undefined ? new MapWithExpiration(expirationMs) : new Map();\n\t}\n\n\tpublic async get(key: string): Promise<T | undefined> {\n\t\treturn this.cache.get(key);\n\t}\n\n\tpublic async put(key: string, value: T): Promise<void> {\n\t\tthis.cache.set(key, value);\n\t}\n}\n\n/** This \"cache\" does nothing on put, and get always returns undefined */\nexport class NullCache<T> implements ICache<T> {\n\tpublic async get(key: string): Promise<T | undefined> {\n\t\treturn undefined;\n\t}\n\n\tpublic async put(key: string, value: T): Promise<void> {}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"documentService.d.ts","sourceRoot":"","sources":["../src/documentService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,GAAG,MAAM,oCAAoC,CAAC;AAE1D,OAAO,EAAE,OAAO,EAAE,MAAM,sCAAsC,CAAC;AAI/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAKtE,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,+BAA+B,EAAmC,MAAM,eAAe,CAAC;AACjG,OAAO,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAUrD;;;GAGG;AAEH,qBAAa,eAAgB,YAAW,GAAG,CAAC,gBAAgB;IAY1D,OAAO,CAAC,YAAY;IACpB,SAAS,CAAC,UAAU,EAAE,MAAM;IAC5B,OAAO,CAAC,eAAe;IACvB,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,SAAS,CAAC,aAAa,EAAE,cAAc;IACvC,SAAS,CAAC,QAAQ,EAAE,MAAM;IAC1B,SAAS,CAAC,UAAU,EAAE,MAAM;IAC5B,SAAS,CAAC,kBAAkB,EAAE,+BAA+B;IAC7D,OAAO,CAAC,QAAQ,CAAC,8BAA8B;IAC/C,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,wBAAwB;IAzB1C,OAAO,CAAC,gBAAgB,CAAsB;IAC9C,OAAO,CAAC,SAAS,CAA4B;IAE7C,OAAO,CAAC,cAAc,CAAyB;IAC/C,OAAO,CAAC,qBAAqB,CAAyB;IAEtD,IAAW,WAAW,qBAErB;gBAGQ,YAAY,EAAE,GAAG,CAAC,YAAY,EAC5B,UAAU,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,EACvB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EACT,MAAM,EAAE,gBAAgB,EAC/B,aAAa,EAAE,cAAc,EAC7B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,kBAAkB,EAAE,+BAA+B,EAC5C,8BAA8B,EAAE,GAAG,CAAC,+BAA+B,EACnE,cAAc,EAAE,4BAA4B,EAC5C,SAAS,EAAE,MAAM,CAAC,eAAe,CAAC,EAClC,iBAAiB,EAAE,MAAM,CAAC,oBAAoB,CAAC,EAC/C,wBAAwB,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAGhF,OAAO,CAAC,sBAAsB,CAAqC;IAE5D,OAAO;IAEd;;;;OAIG;IACU,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC;IA6DrE;;;;OAIG;IACU,qBAAqB,IAAI,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC;IAwC/E;;;;OAIG;IACU,oBAAoB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC;IAgEzF;;OAEG;YACW,gBAAgB;YAahB,oBAAoB;IASlC;;OAEG;IACH,OAAO,CAAC,iCAAiC;CAsBzC"}
1
+ {"version":3,"file":"documentService.d.ts","sourceRoot":"","sources":["../src/documentService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,GAAG,MAAM,oCAAoC,CAAC;AAG1D,OAAO,EAAE,OAAO,EAAE,MAAM,sCAAsC,CAAC;AAI/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAKtE,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,+BAA+B,EAAmC,MAAM,eAAe,CAAC;AACjG,OAAO,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAWrD;;;GAGG;AAEH,qBAAa,eAAgB,YAAW,GAAG,CAAC,gBAAgB;IAY1D,OAAO,CAAC,YAAY;IACpB,SAAS,CAAC,UAAU,EAAE,MAAM;IAC5B,OAAO,CAAC,eAAe;IACvB,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,SAAS,CAAC,aAAa,EAAE,cAAc;IACvC,SAAS,CAAC,QAAQ,EAAE,MAAM;IAC1B,SAAS,CAAC,UAAU,EAAE,MAAM;IAC5B,SAAS,CAAC,kBAAkB,EAAE,+BAA+B;IAC7D,OAAO,CAAC,QAAQ,CAAC,8BAA8B;IAC/C,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,wBAAwB;IAzB1C,OAAO,CAAC,gBAAgB,CAAsB;IAC9C,OAAO,CAAC,SAAS,CAA4B;IAE7C,OAAO,CAAC,cAAc,CAAyB;IAC/C,OAAO,CAAC,qBAAqB,CAAyB;IAEtD,IAAW,WAAW,qBAErB;gBAGQ,YAAY,EAAE,GAAG,CAAC,YAAY,EAC5B,UAAU,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,EACvB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EACT,MAAM,EAAE,gBAAgB,EAC/B,aAAa,EAAE,cAAc,EAC7B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,kBAAkB,EAAE,+BAA+B,EAC5C,8BAA8B,EAAE,GAAG,CAAC,+BAA+B,EACnE,cAAc,EAAE,4BAA4B,EAC5C,SAAS,EAAE,MAAM,CAAC,eAAe,CAAC,EAClC,iBAAiB,EAAE,MAAM,CAAC,oBAAoB,CAAC,EAC/C,wBAAwB,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAGhF,OAAO,CAAC,sBAAsB,CAAqC;IAE5D,OAAO;IAEd;;;;OAIG;IACU,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC;IA6DrE;;;;OAIG;IACU,qBAAqB,IAAI,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC;IAwC/E;;;;OAIG;IACU,oBAAoB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC;IA6EzF;;OAEG;YACW,gBAAgB;YAahB,oBAAoB;IASlC;;OAEG;IACH,OAAO,CAAC,iCAAiC;CAsBzC"}
@@ -9,6 +9,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.DocumentService = void 0;
11
11
  const common_utils_1 = require("@fluidframework/common-utils");
12
+ const driver_definitions_1 = require("@fluidframework/driver-definitions");
12
13
  const driver_utils_1 = require("@fluidframework/driver-utils");
13
14
  const server_services_client_1 = require("@fluidframework/server-services-client");
14
15
  const socket_io_client_1 = __importDefault(require("socket.io-client"));
@@ -18,6 +19,7 @@ const documentStorageService_1 = require("./documentStorageService");
18
19
  const documentDeltaConnection_1 = require("./documentDeltaConnection");
19
20
  const nullBlobStorageService_1 = require("./nullBlobStorageService");
20
21
  const restWrapper_1 = require("./restWrapper");
22
+ const packageVersion_1 = require("./packageVersion");
21
23
  /**
22
24
  * Amount of time between discoveries within which we don't need to rediscover on re-connect.
23
25
  * Currently, R11s defines session length at 10 minutes. To avoid any weird unknown edge-cases though,
@@ -127,11 +129,15 @@ class DocumentService {
127
129
  details: JSON.stringify({
128
130
  refreshToken,
129
131
  }),
130
- }, async () => {
131
- const newOrdererToken = await this.tokenProvider.fetchOrdererToken(this.tenantId, this.documentId, refreshToken);
132
+ }, async () => this.tokenProvider
133
+ .fetchOrdererToken(this.tenantId, this.documentId, refreshToken)
134
+ .then((newOrdererToken) => {
132
135
  this.ordererRestWrapper.setToken(newOrdererToken);
133
136
  return newOrdererToken;
134
- });
137
+ }, (error) => {
138
+ const tokenError = (0, telemetry_utils_1.wrapError)(error, (errorMessage) => new driver_utils_1.NetworkErrorBasic(`The Host-provided token fetcher threw an error`, driver_definitions_1.DriverErrorType.fetchTokenError, (0, driver_utils_1.canRetryOnError)(error), { errorMessage, driverVersion: packageVersion_1.pkgVersion }));
139
+ throw tokenError;
140
+ }));
135
141
  }
136
142
  return telemetry_utils_1.PerformanceEvent.timedExecAsync(this.logger, {
137
143
  eventName: "ConnectToDeltaStream",
@@ -1 +1 @@
1
- {"version":3,"file":"documentService.js","sourceRoot":"","sources":["../src/documentService.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/common-utils\";\nimport * as api from \"@fluidframework/driver-definitions\";\nimport { RateLimiter } from \"@fluidframework/driver-utils\";\nimport { IClient } from \"@fluidframework/protocol-definitions\";\nimport { GitManager, Historian, RestWrapper } from \"@fluidframework/server-services-client\";\nimport io from \"socket.io-client\";\nimport { PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { DeltaStorageService, DocumentDeltaStorageService } from \"./deltaStorageService\";\nimport { DocumentStorageService } from \"./documentStorageService\";\nimport { R11sDocumentDeltaConnection } from \"./documentDeltaConnection\";\nimport { NullBlobStorageService } from \"./nullBlobStorageService\";\nimport { ITokenProvider } from \"./tokens\";\nimport { RouterliciousOrdererRestWrapper, RouterliciousStorageRestWrapper } from \"./restWrapper\";\nimport { IRouterliciousDriverPolicies } from \"./policies\";\nimport { ICache } from \"./cache\";\nimport { ISnapshotTreeVersion } from \"./definitions\";\n\n/**\n * Amount of time between discoveries within which we don't need to rediscover on re-connect.\n * Currently, R11s defines session length at 10 minutes. To avoid any weird unknown edge-cases though,\n * we set the limit to 5 minutes here.\n * In the future, we likely want to retrieve this information from service's \"inactive session\" definition.\n */\nconst RediscoverAfterTimeSinceDiscoveryMs = 5 * 60000; // 5 minute\n\n/**\n * The DocumentService manages the Socket.IO connection and manages routing requests to connected\n * clients.\n */\n// eslint-disable-next-line import/namespace\nexport class DocumentService implements api.IDocumentService {\n\tprivate lastDiscoveredAt: number = Date.now();\n\tprivate discoverP: Promise<void> | undefined;\n\n\tprivate storageManager: GitManager | undefined;\n\tprivate noCacheStorageManager: GitManager | undefined;\n\n\tpublic get resolvedUrl() {\n\t\treturn this._resolvedUrl;\n\t}\n\n\tconstructor(\n\t\tprivate _resolvedUrl: api.IResolvedUrl,\n\t\tprotected ordererUrl: string,\n\t\tprivate deltaStorageUrl: string,\n\t\tprivate deltaStreamUrl: string,\n\t\tprivate storageUrl: string,\n\t\tprivate readonly logger: ITelemetryLogger,\n\t\tprotected tokenProvider: ITokenProvider,\n\t\tprotected tenantId: string,\n\t\tprotected documentId: string,\n\t\tprotected ordererRestWrapper: RouterliciousOrdererRestWrapper,\n\t\tprivate readonly documentStorageServicePolicies: api.IDocumentStorageServicePolicies,\n\t\tprivate readonly driverPolicies: IRouterliciousDriverPolicies,\n\t\tprivate readonly blobCache: ICache<ArrayBufferLike>,\n\t\tprivate readonly snapshotTreeCache: ICache<ISnapshotTreeVersion>,\n\t\tprivate readonly discoverFluidResolvedUrl: () => Promise<api.IFluidResolvedUrl>,\n\t) {}\n\n\tprivate documentStorageService: DocumentStorageService | undefined;\n\n\tpublic dispose() {}\n\n\t/**\n\t * Connects to a storage endpoint for snapshot service.\n\t *\n\t * @returns returns the document storage service for routerlicious driver.\n\t */\n\tpublic async connectToStorage(): Promise<api.IDocumentStorageService> {\n\t\tif (this.documentStorageService !== undefined) {\n\t\t\treturn this.documentStorageService;\n\t\t}\n\n\t\tif (this.storageUrl === undefined) {\n\t\t\treturn new NullBlobStorageService();\n\t\t}\n\n\t\tconst getStorageManager = async (disableCache?: boolean): Promise<GitManager> => {\n\t\t\tconst shouldUpdateDiscoveredSessionInfo = this.shouldUpdateDiscoveredSessionInfo();\n\t\t\tif (shouldUpdateDiscoveredSessionInfo) {\n\t\t\t\tawait this.refreshDiscovery();\n\t\t\t}\n\t\t\tif (\n\t\t\t\t!this.storageManager ||\n\t\t\t\t!this.noCacheStorageManager ||\n\t\t\t\tshouldUpdateDiscoveredSessionInfo\n\t\t\t) {\n\t\t\t\tconst rateLimiter = new RateLimiter(\n\t\t\t\t\tthis.driverPolicies.maxConcurrentStorageRequests,\n\t\t\t\t);\n\t\t\t\tconst storageRestWrapper = await RouterliciousStorageRestWrapper.load(\n\t\t\t\t\tthis.tenantId,\n\t\t\t\t\tthis.documentId,\n\t\t\t\t\tthis.tokenProvider,\n\t\t\t\t\tthis.logger,\n\t\t\t\t\trateLimiter,\n\t\t\t\t\tthis.driverPolicies.enableRestLess,\n\t\t\t\t\tthis.storageUrl,\n\t\t\t\t);\n\t\t\t\tconst historian = new Historian(this.storageUrl, true, false, storageRestWrapper);\n\t\t\t\tthis.storageManager = new GitManager(historian);\n\t\t\t\tconst noCacheHistorian = new Historian(\n\t\t\t\t\tthis.storageUrl,\n\t\t\t\t\ttrue,\n\t\t\t\t\ttrue,\n\t\t\t\t\tstorageRestWrapper,\n\t\t\t\t);\n\t\t\t\tthis.noCacheStorageManager = new GitManager(noCacheHistorian);\n\t\t\t}\n\n\t\t\treturn disableCache ? this.noCacheStorageManager : this.storageManager;\n\t\t};\n\t\t// Initialize storageManager and noCacheStorageManager\n\t\tconst storageManager = await getStorageManager();\n\t\tconst noCacheStorageManager = await getStorageManager(true);\n\t\tthis.documentStorageService = new DocumentStorageService(\n\t\t\tthis.documentId,\n\t\t\tstorageManager,\n\t\t\tthis.logger,\n\t\t\tthis.documentStorageServicePolicies,\n\t\t\tthis.driverPolicies,\n\t\t\tthis.blobCache,\n\t\t\tthis.snapshotTreeCache,\n\t\t\tnoCacheStorageManager,\n\t\t\tgetStorageManager,\n\t\t);\n\t\treturn this.documentStorageService;\n\t}\n\n\t/**\n\t * Connects to a delta storage endpoint for getting ops between a range.\n\t *\n\t * @returns returns the document delta storage service for routerlicious driver.\n\t */\n\tpublic async connectToDeltaStorage(): Promise<api.IDocumentDeltaStorageService> {\n\t\tawait this.connectToStorage();\n\t\tassert(!!this.documentStorageService, 0x0b1 /* \"Storage service not initialized\" */);\n\n\t\tconst getRestWrapper = async (): Promise<RestWrapper> => {\n\t\t\tconst shouldUpdateDiscoveredSessionInfo = this.shouldUpdateDiscoveredSessionInfo();\n\n\t\t\tif (shouldUpdateDiscoveredSessionInfo) {\n\t\t\t\tawait this.refreshDiscovery();\n\t\t\t\tconst rateLimiter = new RateLimiter(\n\t\t\t\t\tthis.driverPolicies.maxConcurrentOrdererRequests,\n\t\t\t\t);\n\t\t\t\tthis.ordererRestWrapper = await RouterliciousOrdererRestWrapper.load(\n\t\t\t\t\tthis.tenantId,\n\t\t\t\t\tthis.documentId,\n\t\t\t\t\tthis.tokenProvider,\n\t\t\t\t\tthis.logger,\n\t\t\t\t\trateLimiter,\n\t\t\t\t\tthis.driverPolicies.enableRestLess,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn this.ordererRestWrapper;\n\t\t};\n\t\tconst restWrapper = await getRestWrapper();\n\t\tconst deltaStorageService = new DeltaStorageService(\n\t\t\tthis.deltaStorageUrl,\n\t\t\trestWrapper,\n\t\t\tthis.logger,\n\t\t\tgetRestWrapper,\n\t\t\t() => this.deltaStorageUrl,\n\t\t);\n\t\treturn new DocumentDeltaStorageService(\n\t\t\tthis.tenantId,\n\t\t\tthis.documentId,\n\t\t\tdeltaStorageService,\n\t\t\tthis.documentStorageService,\n\t\t\tthis.logger,\n\t\t);\n\t}\n\n\t/**\n\t * Connects to a delta stream endpoint for emitting ops.\n\t *\n\t * @returns returns the document delta stream service for routerlicious driver.\n\t */\n\tpublic async connectToDeltaStream(client: IClient): Promise<api.IDocumentDeltaConnection> {\n\t\tconst connect = async (refreshToken?: boolean) => {\n\t\t\tlet ordererToken = this.ordererRestWrapper.getToken();\n\t\t\tif (this.shouldUpdateDiscoveredSessionInfo()) {\n\t\t\t\tawait this.refreshDiscovery();\n\t\t\t}\n\n\t\t\tif (refreshToken) {\n\t\t\t\tordererToken = await PerformanceEvent.timedExecAsync(\n\t\t\t\t\tthis.logger,\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GetDeltaStreamToken\",\n\t\t\t\t\t\tdocId: this.documentId,\n\t\t\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\t}),\n\t\t\t\t\t},\n\t\t\t\t\tasync () => {\n\t\t\t\t\t\tconst newOrdererToken = await this.tokenProvider.fetchOrdererToken(\n\t\t\t\t\t\t\tthis.tenantId,\n\t\t\t\t\t\t\tthis.documentId,\n\t\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tthis.ordererRestWrapper.setToken(newOrdererToken);\n\t\t\t\t\t\treturn newOrdererToken;\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn PerformanceEvent.timedExecAsync(\n\t\t\t\tthis.logger,\n\t\t\t\t{\n\t\t\t\t\teventName: \"ConnectToDeltaStream\",\n\t\t\t\t\tdocId: this.documentId,\n\t\t\t\t},\n\t\t\t\tasync () => {\n\t\t\t\t\treturn R11sDocumentDeltaConnection.create(\n\t\t\t\t\t\tthis.tenantId,\n\t\t\t\t\t\tthis.documentId,\n\t\t\t\t\t\tordererToken.jwt,\n\t\t\t\t\t\tio,\n\t\t\t\t\t\tclient,\n\t\t\t\t\t\tthis.deltaStreamUrl,\n\t\t\t\t\t\tthis.logger,\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t);\n\t\t};\n\n\t\t// Attempt to establish connection.\n\t\t// Retry with new token on authorization error; otherwise, allow container layer to handle.\n\t\ttry {\n\t\t\tconst connection = await connect();\n\t\t\treturn connection;\n\t\t} catch (error: any) {\n\t\t\tif (error?.statusCode === 401) {\n\t\t\t\t// Fetch new token and retry once,\n\t\t\t\t// otherwise 401 will be bubbled up as non-retriable AuthorizationError.\n\t\t\t\treturn connect(true /* refreshToken */);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Re-discover session URLs if necessary.\n\t */\n\tprivate async refreshDiscovery(): Promise<void> {\n\t\tif (!this.discoverP) {\n\t\t\tthis.discoverP = PerformanceEvent.timedExecAsync(\n\t\t\t\tthis.logger,\n\t\t\t\t{\n\t\t\t\t\teventName: \"RefreshDiscovery\",\n\t\t\t\t},\n\t\t\t\tasync () => this.refreshDiscoveryCore(),\n\t\t\t);\n\t\t}\n\t\treturn this.discoverP;\n\t}\n\n\tprivate async refreshDiscoveryCore(): Promise<void> {\n\t\tconst fluidResolvedUrl = await this.discoverFluidResolvedUrl();\n\t\tthis._resolvedUrl = fluidResolvedUrl;\n\t\tthis.storageUrl = fluidResolvedUrl.endpoints.storageUrl;\n\t\tthis.ordererUrl = fluidResolvedUrl.endpoints.ordererUrl;\n\t\tthis.deltaStorageUrl = fluidResolvedUrl.endpoints.deltaStorageUrl;\n\t\tthis.deltaStreamUrl = fluidResolvedUrl.endpoints.deltaStreamUrl || this.ordererUrl;\n\t}\n\n\t/**\n\t * Whether enough time has passed since last disconnect to warrant a new discovery call on reconnect.\n\t */\n\tprivate shouldUpdateDiscoveredSessionInfo(): boolean {\n\t\tif (!this.driverPolicies.enableDiscovery) {\n\t\t\treturn false;\n\t\t}\n\t\tconst now = Date.now();\n\t\t// When connection is disconnected, we cannot know if session has moved or document has been deleted\n\t\t// without re-doing discovery on the next attempt to connect.\n\t\t// Disconnect event is not so reliable in local testing. To ensure re-discovery when necessary,\n\t\t// re-discover if enough time has passed since last discovery.\n\t\tconst pastLastDiscoveryTimeThreshold =\n\t\t\tnow - this.lastDiscoveredAt > RediscoverAfterTimeSinceDiscoveryMs;\n\t\tif (pastLastDiscoveryTimeThreshold) {\n\t\t\t// Reset discover promise and refresh discovery.\n\t\t\tthis.lastDiscoveredAt = Date.now();\n\t\t\tthis.discoverP = undefined;\n\t\t\tthis.refreshDiscovery().catch(() => {\n\t\t\t\t// Undo discovery time set on failure, so that next check refreshes.\n\t\t\t\tthis.lastDiscoveredAt = 0;\n\t\t\t});\n\t\t}\n\t\treturn pastLastDiscoveryTimeThreshold;\n\t}\n}\n"]}
1
+ {"version":3,"file":"documentService.js","sourceRoot":"","sources":["../src/documentService.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/common-utils\";\nimport * as api from \"@fluidframework/driver-definitions\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport { RateLimiter, NetworkErrorBasic, canRetryOnError } from \"@fluidframework/driver-utils\";\nimport { IClient } from \"@fluidframework/protocol-definitions\";\nimport { GitManager, Historian, RestWrapper } from \"@fluidframework/server-services-client\";\nimport io from \"socket.io-client\";\nimport { PerformanceEvent, wrapError } from \"@fluidframework/telemetry-utils\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { DeltaStorageService, DocumentDeltaStorageService } from \"./deltaStorageService\";\nimport { DocumentStorageService } from \"./documentStorageService\";\nimport { R11sDocumentDeltaConnection } from \"./documentDeltaConnection\";\nimport { NullBlobStorageService } from \"./nullBlobStorageService\";\nimport { ITokenProvider } from \"./tokens\";\nimport { RouterliciousOrdererRestWrapper, RouterliciousStorageRestWrapper } from \"./restWrapper\";\nimport { IRouterliciousDriverPolicies } from \"./policies\";\nimport { ICache } from \"./cache\";\nimport { ISnapshotTreeVersion } from \"./definitions\";\nimport { pkgVersion as driverVersion } from \"./packageVersion\";\n\n/**\n * Amount of time between discoveries within which we don't need to rediscover on re-connect.\n * Currently, R11s defines session length at 10 minutes. To avoid any weird unknown edge-cases though,\n * we set the limit to 5 minutes here.\n * In the future, we likely want to retrieve this information from service's \"inactive session\" definition.\n */\nconst RediscoverAfterTimeSinceDiscoveryMs = 5 * 60000; // 5 minute\n\n/**\n * The DocumentService manages the Socket.IO connection and manages routing requests to connected\n * clients.\n */\n// eslint-disable-next-line import/namespace\nexport class DocumentService implements api.IDocumentService {\n\tprivate lastDiscoveredAt: number = Date.now();\n\tprivate discoverP: Promise<void> | undefined;\n\n\tprivate storageManager: GitManager | undefined;\n\tprivate noCacheStorageManager: GitManager | undefined;\n\n\tpublic get resolvedUrl() {\n\t\treturn this._resolvedUrl;\n\t}\n\n\tconstructor(\n\t\tprivate _resolvedUrl: api.IResolvedUrl,\n\t\tprotected ordererUrl: string,\n\t\tprivate deltaStorageUrl: string,\n\t\tprivate deltaStreamUrl: string,\n\t\tprivate storageUrl: string,\n\t\tprivate readonly logger: ITelemetryLogger,\n\t\tprotected tokenProvider: ITokenProvider,\n\t\tprotected tenantId: string,\n\t\tprotected documentId: string,\n\t\tprotected ordererRestWrapper: RouterliciousOrdererRestWrapper,\n\t\tprivate readonly documentStorageServicePolicies: api.IDocumentStorageServicePolicies,\n\t\tprivate readonly driverPolicies: IRouterliciousDriverPolicies,\n\t\tprivate readonly blobCache: ICache<ArrayBufferLike>,\n\t\tprivate readonly snapshotTreeCache: ICache<ISnapshotTreeVersion>,\n\t\tprivate readonly discoverFluidResolvedUrl: () => Promise<api.IFluidResolvedUrl>,\n\t) {}\n\n\tprivate documentStorageService: DocumentStorageService | undefined;\n\n\tpublic dispose() {}\n\n\t/**\n\t * Connects to a storage endpoint for snapshot service.\n\t *\n\t * @returns returns the document storage service for routerlicious driver.\n\t */\n\tpublic async connectToStorage(): Promise<api.IDocumentStorageService> {\n\t\tif (this.documentStorageService !== undefined) {\n\t\t\treturn this.documentStorageService;\n\t\t}\n\n\t\tif (this.storageUrl === undefined) {\n\t\t\treturn new NullBlobStorageService();\n\t\t}\n\n\t\tconst getStorageManager = async (disableCache?: boolean): Promise<GitManager> => {\n\t\t\tconst shouldUpdateDiscoveredSessionInfo = this.shouldUpdateDiscoveredSessionInfo();\n\t\t\tif (shouldUpdateDiscoveredSessionInfo) {\n\t\t\t\tawait this.refreshDiscovery();\n\t\t\t}\n\t\t\tif (\n\t\t\t\t!this.storageManager ||\n\t\t\t\t!this.noCacheStorageManager ||\n\t\t\t\tshouldUpdateDiscoveredSessionInfo\n\t\t\t) {\n\t\t\t\tconst rateLimiter = new RateLimiter(\n\t\t\t\t\tthis.driverPolicies.maxConcurrentStorageRequests,\n\t\t\t\t);\n\t\t\t\tconst storageRestWrapper = await RouterliciousStorageRestWrapper.load(\n\t\t\t\t\tthis.tenantId,\n\t\t\t\t\tthis.documentId,\n\t\t\t\t\tthis.tokenProvider,\n\t\t\t\t\tthis.logger,\n\t\t\t\t\trateLimiter,\n\t\t\t\t\tthis.driverPolicies.enableRestLess,\n\t\t\t\t\tthis.storageUrl,\n\t\t\t\t);\n\t\t\t\tconst historian = new Historian(this.storageUrl, true, false, storageRestWrapper);\n\t\t\t\tthis.storageManager = new GitManager(historian);\n\t\t\t\tconst noCacheHistorian = new Historian(\n\t\t\t\t\tthis.storageUrl,\n\t\t\t\t\ttrue,\n\t\t\t\t\ttrue,\n\t\t\t\t\tstorageRestWrapper,\n\t\t\t\t);\n\t\t\t\tthis.noCacheStorageManager = new GitManager(noCacheHistorian);\n\t\t\t}\n\n\t\t\treturn disableCache ? this.noCacheStorageManager : this.storageManager;\n\t\t};\n\t\t// Initialize storageManager and noCacheStorageManager\n\t\tconst storageManager = await getStorageManager();\n\t\tconst noCacheStorageManager = await getStorageManager(true);\n\t\tthis.documentStorageService = new DocumentStorageService(\n\t\t\tthis.documentId,\n\t\t\tstorageManager,\n\t\t\tthis.logger,\n\t\t\tthis.documentStorageServicePolicies,\n\t\t\tthis.driverPolicies,\n\t\t\tthis.blobCache,\n\t\t\tthis.snapshotTreeCache,\n\t\t\tnoCacheStorageManager,\n\t\t\tgetStorageManager,\n\t\t);\n\t\treturn this.documentStorageService;\n\t}\n\n\t/**\n\t * Connects to a delta storage endpoint for getting ops between a range.\n\t *\n\t * @returns returns the document delta storage service for routerlicious driver.\n\t */\n\tpublic async connectToDeltaStorage(): Promise<api.IDocumentDeltaStorageService> {\n\t\tawait this.connectToStorage();\n\t\tassert(!!this.documentStorageService, 0x0b1 /* \"Storage service not initialized\" */);\n\n\t\tconst getRestWrapper = async (): Promise<RestWrapper> => {\n\t\t\tconst shouldUpdateDiscoveredSessionInfo = this.shouldUpdateDiscoveredSessionInfo();\n\n\t\t\tif (shouldUpdateDiscoveredSessionInfo) {\n\t\t\t\tawait this.refreshDiscovery();\n\t\t\t\tconst rateLimiter = new RateLimiter(\n\t\t\t\t\tthis.driverPolicies.maxConcurrentOrdererRequests,\n\t\t\t\t);\n\t\t\t\tthis.ordererRestWrapper = await RouterliciousOrdererRestWrapper.load(\n\t\t\t\t\tthis.tenantId,\n\t\t\t\t\tthis.documentId,\n\t\t\t\t\tthis.tokenProvider,\n\t\t\t\t\tthis.logger,\n\t\t\t\t\trateLimiter,\n\t\t\t\t\tthis.driverPolicies.enableRestLess,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn this.ordererRestWrapper;\n\t\t};\n\t\tconst restWrapper = await getRestWrapper();\n\t\tconst deltaStorageService = new DeltaStorageService(\n\t\t\tthis.deltaStorageUrl,\n\t\t\trestWrapper,\n\t\t\tthis.logger,\n\t\t\tgetRestWrapper,\n\t\t\t() => this.deltaStorageUrl,\n\t\t);\n\t\treturn new DocumentDeltaStorageService(\n\t\t\tthis.tenantId,\n\t\t\tthis.documentId,\n\t\t\tdeltaStorageService,\n\t\t\tthis.documentStorageService,\n\t\t\tthis.logger,\n\t\t);\n\t}\n\n\t/**\n\t * Connects to a delta stream endpoint for emitting ops.\n\t *\n\t * @returns returns the document delta stream service for routerlicious driver.\n\t */\n\tpublic async connectToDeltaStream(client: IClient): Promise<api.IDocumentDeltaConnection> {\n\t\tconst connect = async (refreshToken?: boolean) => {\n\t\t\tlet ordererToken = this.ordererRestWrapper.getToken();\n\t\t\tif (this.shouldUpdateDiscoveredSessionInfo()) {\n\t\t\t\tawait this.refreshDiscovery();\n\t\t\t}\n\n\t\t\tif (refreshToken) {\n\t\t\t\tordererToken = await PerformanceEvent.timedExecAsync(\n\t\t\t\t\tthis.logger,\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GetDeltaStreamToken\",\n\t\t\t\t\t\tdocId: this.documentId,\n\t\t\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\t}),\n\t\t\t\t\t},\n\t\t\t\t\tasync () =>\n\t\t\t\t\t\tthis.tokenProvider\n\t\t\t\t\t\t\t.fetchOrdererToken(this.tenantId, this.documentId, refreshToken)\n\t\t\t\t\t\t\t.then(\n\t\t\t\t\t\t\t\t(newOrdererToken) => {\n\t\t\t\t\t\t\t\t\tthis.ordererRestWrapper.setToken(newOrdererToken);\n\t\t\t\t\t\t\t\t\treturn newOrdererToken;\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t(error) => {\n\t\t\t\t\t\t\t\t\tconst tokenError = wrapError(\n\t\t\t\t\t\t\t\t\t\terror,\n\t\t\t\t\t\t\t\t\t\t(errorMessage) =>\n\t\t\t\t\t\t\t\t\t\t\tnew NetworkErrorBasic(\n\t\t\t\t\t\t\t\t\t\t\t\t`The Host-provided token fetcher threw an error`,\n\t\t\t\t\t\t\t\t\t\t\t\tDriverErrorType.fetchTokenError,\n\t\t\t\t\t\t\t\t\t\t\t\tcanRetryOnError(error),\n\t\t\t\t\t\t\t\t\t\t\t\t{ errorMessage, driverVersion },\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\tthrow tokenError;\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn PerformanceEvent.timedExecAsync(\n\t\t\t\tthis.logger,\n\t\t\t\t{\n\t\t\t\t\teventName: \"ConnectToDeltaStream\",\n\t\t\t\t\tdocId: this.documentId,\n\t\t\t\t},\n\t\t\t\tasync () => {\n\t\t\t\t\treturn R11sDocumentDeltaConnection.create(\n\t\t\t\t\t\tthis.tenantId,\n\t\t\t\t\t\tthis.documentId,\n\t\t\t\t\t\tordererToken.jwt,\n\t\t\t\t\t\tio,\n\t\t\t\t\t\tclient,\n\t\t\t\t\t\tthis.deltaStreamUrl,\n\t\t\t\t\t\tthis.logger,\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t);\n\t\t};\n\n\t\t// Attempt to establish connection.\n\t\t// Retry with new token on authorization error; otherwise, allow container layer to handle.\n\t\ttry {\n\t\t\tconst connection = await connect();\n\t\t\treturn connection;\n\t\t} catch (error: any) {\n\t\t\tif (error?.statusCode === 401) {\n\t\t\t\t// Fetch new token and retry once,\n\t\t\t\t// otherwise 401 will be bubbled up as non-retriable AuthorizationError.\n\t\t\t\treturn connect(true /* refreshToken */);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Re-discover session URLs if necessary.\n\t */\n\tprivate async refreshDiscovery(): Promise<void> {\n\t\tif (!this.discoverP) {\n\t\t\tthis.discoverP = PerformanceEvent.timedExecAsync(\n\t\t\t\tthis.logger,\n\t\t\t\t{\n\t\t\t\t\teventName: \"RefreshDiscovery\",\n\t\t\t\t},\n\t\t\t\tasync () => this.refreshDiscoveryCore(),\n\t\t\t);\n\t\t}\n\t\treturn this.discoverP;\n\t}\n\n\tprivate async refreshDiscoveryCore(): Promise<void> {\n\t\tconst fluidResolvedUrl = await this.discoverFluidResolvedUrl();\n\t\tthis._resolvedUrl = fluidResolvedUrl;\n\t\tthis.storageUrl = fluidResolvedUrl.endpoints.storageUrl;\n\t\tthis.ordererUrl = fluidResolvedUrl.endpoints.ordererUrl;\n\t\tthis.deltaStorageUrl = fluidResolvedUrl.endpoints.deltaStorageUrl;\n\t\tthis.deltaStreamUrl = fluidResolvedUrl.endpoints.deltaStreamUrl || this.ordererUrl;\n\t}\n\n\t/**\n\t * Whether enough time has passed since last disconnect to warrant a new discovery call on reconnect.\n\t */\n\tprivate shouldUpdateDiscoveredSessionInfo(): boolean {\n\t\tif (!this.driverPolicies.enableDiscovery) {\n\t\t\treturn false;\n\t\t}\n\t\tconst now = Date.now();\n\t\t// When connection is disconnected, we cannot know if session has moved or document has been deleted\n\t\t// without re-doing discovery on the next attempt to connect.\n\t\t// Disconnect event is not so reliable in local testing. To ensure re-discovery when necessary,\n\t\t// re-discover if enough time has passed since last discovery.\n\t\tconst pastLastDiscoveryTimeThreshold =\n\t\t\tnow - this.lastDiscoveredAt > RediscoverAfterTimeSinceDiscoveryMs;\n\t\tif (pastLastDiscoveryTimeThreshold) {\n\t\t\t// Reset discover promise and refresh discovery.\n\t\t\tthis.lastDiscoveredAt = Date.now();\n\t\t\tthis.discoverP = undefined;\n\t\t\tthis.refreshDiscovery().catch(() => {\n\t\t\t\t// Undo discovery time set on failure, so that next check refreshes.\n\t\t\t\tthis.lastDiscoveredAt = 0;\n\t\t\t});\n\t\t}\n\t\treturn pastLastDiscoveryTimeThreshold;\n\t}\n}\n"]}
@@ -14,7 +14,6 @@ import { ITokenProvider } from "./tokens";
14
14
  */
15
15
  export declare class RouterliciousDocumentServiceFactory implements IDocumentServiceFactory {
16
16
  private readonly tokenProvider;
17
- readonly protocolName = "fluid:";
18
17
  private readonly driverPolicies;
19
18
  private readonly blobCache;
20
19
  private readonly snapshotTreeCache;
@@ -1 +1 @@
1
- {"version":3,"file":"documentServiceFactory.d.ts","sourceRoot":"","sources":["../src/documentServiceFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAEN,gBAAgB,EAChB,uBAAuB,EAGvB,YAAY,EAEZ,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AAQpE,OAAO,EAAE,QAAQ,EAAE,MAAM,wCAAwC,CAAC;AAElE,OAAO,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAqB1C;;;GAGG;AACH,qBAAa,mCAAoC,YAAW,uBAAuB;IAOjF,OAAO,CAAC,QAAQ,CAAC,aAAa;IAN/B,SAAgB,YAAY,YAAY;IACxC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA+B;IAC9D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;IACpD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA+B;gBAG/C,aAAa,EAAE,cAAc,EAC9C,cAAc,GAAE,OAAO,CAAC,4BAA4B,CAAM;IAe3D;;;;;OAKG;IACU,eAAe,CAC3B,gBAAgB,EAAE,YAAY,GAAG,SAAS,EAC1C,WAAW,EAAE,YAAY,EACzB,MAAM,CAAC,EAAE,oBAAoB,EAC7B,kBAAkB,CAAC,EAAE,OAAO,GAC1B,OAAO,CAAC,gBAAgB,CAAC;IA4H5B;;;;OAIG;IACU,qBAAqB,CACjC,WAAW,EAAE,YAAY,EACzB,MAAM,CAAC,EAAE,oBAAoB,EAC7B,kBAAkB,CAAC,EAAE,OAAO,EAC5B,OAAO,CAAC,EAAE,QAAQ,GAChB,OAAO,CAAC,gBAAgB,CAAC;CAoF5B;AAED;;;;;;;;;;GAUG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;IAEhD;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,UAAU;;IAH3B;;OAEG;IACc,UAAU,EAAE,KAAK;IAKnC,SAAgB,IAAI,6BAA6B;IAEjD,IAAW,KAAK,uBAEf;CACD"}
1
+ {"version":3,"file":"documentServiceFactory.d.ts","sourceRoot":"","sources":["../src/documentServiceFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAEN,gBAAgB,EAChB,uBAAuB,EAGvB,YAAY,EAEZ,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AASpE,OAAO,EAAE,QAAQ,EAAE,MAAM,wCAAwC,CAAC;AAElE,OAAO,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAqB1C;;;GAGG;AACH,qBAAa,mCAAoC,YAAW,uBAAuB;IAMjF,OAAO,CAAC,QAAQ,CAAC,aAAa;IAL/B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA+B;IAC9D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;IACpD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA+B;gBAG/C,aAAa,EAAE,cAAc,EAC9C,cAAc,GAAE,OAAO,CAAC,4BAA4B,CAAM;IAe3D;;;;;OAKG;IACU,eAAe,CAC3B,gBAAgB,EAAE,YAAY,GAAG,SAAS,EAC1C,WAAW,EAAE,YAAY,EACzB,MAAM,CAAC,EAAE,oBAAoB,EAC7B,kBAAkB,CAAC,EAAE,OAAO,GAC1B,OAAO,CAAC,gBAAgB,CAAC;IA6H5B;;;;OAIG;IACU,qBAAqB,CACjC,WAAW,EAAE,YAAY,EACzB,MAAM,CAAC,EAAE,oBAAoB,EAC7B,kBAAkB,CAAC,EAAE,OAAO,EAC5B,OAAO,CAAC,EAAE,QAAQ,GAChB,OAAO,CAAC,gBAAgB,CAAC;CAoF5B;AAED;;;;;;;;;;GAUG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;IAEhD;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,UAAU;;IAH3B;;OAEG;IACc,UAAU,EAAE,KAAK;IAKnC,SAAgB,IAAI,6BAA6B;IAEjD,IAAW,KAAK,uBAEf;CACD"}
@@ -33,7 +33,6 @@ const defaultRouterliciousDriverPolicies = {
33
33
  class RouterliciousDocumentServiceFactory {
34
34
  constructor(tokenProvider, driverPolicies = {}) {
35
35
  this.tokenProvider = tokenProvider;
36
- this.protocolName = "fluid:";
37
36
  // Use the maximum allowed by the policy (IDocumentStorageServicePolicies.maximumCacheDurationMs set below)
38
37
  const snapshotCacheExpiryMs = maximumSnapshotCacheDurationMs;
39
38
  this.driverPolicies = Object.assign(Object.assign({}, defaultRouterliciousDriverPolicies), driverPolicies);
@@ -59,11 +58,11 @@ class RouterliciousDocumentServiceFactory {
59
58
  throw new Error("Parsed url should contain tenant and doc Id!!");
60
59
  }
61
60
  const [, tenantId] = parsedUrl.pathname.split("/");
62
- const protocolSummary = createNewSummary.tree[".protocol"];
63
- const appSummary = createNewSummary.tree[".app"];
64
- if (!(protocolSummary && appSummary)) {
61
+ if (!(0, driver_utils_1.isCombinedAppAndProtocolSummary)(createNewSummary)) {
65
62
  throw new Error("Protocol and App Summary required in the full summary");
66
63
  }
64
+ const protocolSummary = createNewSummary.tree[".protocol"];
65
+ const appSummary = createNewSummary.tree[".app"];
67
66
  const documentAttributes = (0, driver_utils_1.getDocAttributesFromProtocolSummary)(protocolSummary);
68
67
  const quorumValues = (0, driver_utils_1.getQuorumValuesFromProtocolSummary)(protocolSummary);
69
68
  const logger2 = telemetry_utils_1.ChildLogger.create(logger, "RouterliciousDriver");
@@ -1 +1 @@
1
- {"version":3,"file":"documentServiceFactory.js","sourceRoot":"","sources":["../src/documentServiceFactory.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/common-utils\";\nimport {\n\tFiveDaysMs,\n\tIDocumentService,\n\tIDocumentServiceFactory,\n\tIDocumentStorageServicePolicies,\n\tIFluidResolvedUrl,\n\tIResolvedUrl,\n\tLoaderCachingPolicy,\n} from \"@fluidframework/driver-definitions\";\nimport { ITelemetryBaseLogger } from \"@fluidframework/common-definitions\";\nimport { ISummaryTree } from \"@fluidframework/protocol-definitions\";\nimport {\n\tensureFluidResolvedUrl,\n\tgetDocAttributesFromProtocolSummary,\n\tgetQuorumValuesFromProtocolSummary,\n\tRateLimiter,\n} from \"@fluidframework/driver-utils\";\nimport { ChildLogger, PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport { ISession } from \"@fluidframework/server-services-client\";\nimport { DocumentService } from \"./documentService\";\nimport { IRouterliciousDriverPolicies } from \"./policies\";\nimport { ITokenProvider } from \"./tokens\";\nimport { RouterliciousOrdererRestWrapper } from \"./restWrapper\";\nimport { convertSummaryToCreateNewSummary } from \"./createNewUtils\";\nimport { parseFluidUrl, replaceDocumentIdInPath, getDiscoveredFluidResolvedUrl } from \"./urlUtils\";\nimport { ICache, InMemoryCache, NullCache } from \"./cache\";\nimport { pkgVersion as driverVersion } from \"./packageVersion\";\nimport { ISnapshotTreeVersion } from \"./definitions\";\n\nconst maximumSnapshotCacheDurationMs: FiveDaysMs = 432_000_000; // 5 days in ms\n\nconst defaultRouterliciousDriverPolicies: IRouterliciousDriverPolicies = {\n\tenablePrefetch: true,\n\tmaxConcurrentStorageRequests: 100,\n\tmaxConcurrentOrdererRequests: 100,\n\taggregateBlobsSmallerThanBytes: undefined,\n\tenableDiscovery: false,\n\tenableWholeSummaryUpload: false,\n\tenableRestLess: true,\n\tenableInternalSummaryCaching: true,\n};\n\n/**\n * Factory for creating the routerlicious document service. Use this if you want to\n * use the routerlicious implementation.\n */\nexport class RouterliciousDocumentServiceFactory implements IDocumentServiceFactory {\n\tpublic readonly protocolName = \"fluid:\";\n\tprivate readonly driverPolicies: IRouterliciousDriverPolicies;\n\tprivate readonly blobCache: ICache<ArrayBufferLike>;\n\tprivate readonly snapshotTreeCache: ICache<ISnapshotTreeVersion>;\n\n\tconstructor(\n\t\tprivate readonly tokenProvider: ITokenProvider,\n\t\tdriverPolicies: Partial<IRouterliciousDriverPolicies> = {},\n\t) {\n\t\t// Use the maximum allowed by the policy (IDocumentStorageServicePolicies.maximumCacheDurationMs set below)\n\t\tconst snapshotCacheExpiryMs: FiveDaysMs = maximumSnapshotCacheDurationMs;\n\n\t\tthis.driverPolicies = {\n\t\t\t...defaultRouterliciousDriverPolicies,\n\t\t\t...driverPolicies,\n\t\t};\n\t\tthis.blobCache = new InMemoryCache<ArrayBufferLike>();\n\t\tthis.snapshotTreeCache = this.driverPolicies.enableInternalSummaryCaching\n\t\t\t? new InMemoryCache<ISnapshotTreeVersion>(snapshotCacheExpiryMs)\n\t\t\t: new NullCache<ISnapshotTreeVersion>();\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/driver-definitions#IDocumentServiceFactory.createContainer}\n\t *\n\t * @throws {@link DocumentPostCreateError}\n\t * If an exception is thrown while invoking the provided {@link ITokenProvider.documentPostCreateCallback}.\n\t */\n\tpublic async createContainer(\n\t\tcreateNewSummary: ISummaryTree | undefined,\n\t\tresolvedUrl: IResolvedUrl,\n\t\tlogger?: ITelemetryBaseLogger,\n\t\tclientIsSummarizer?: boolean,\n\t): Promise<IDocumentService> {\n\t\tensureFluidResolvedUrl(resolvedUrl);\n\t\tif (createNewSummary === undefined) {\n\t\t\tthrow new Error(\"Empty file summary creation isn't supported in this driver.\");\n\t\t}\n\t\tassert(!!resolvedUrl.endpoints.ordererUrl, 0x0b2 /* \"Missing orderer URL!\" */);\n\t\tlet parsedUrl = parseFluidUrl(resolvedUrl.url);\n\t\tif (!parsedUrl.pathname) {\n\t\t\tthrow new Error(\"Parsed url should contain tenant and doc Id!!\");\n\t\t}\n\t\tconst [, tenantId] = parsedUrl.pathname.split(\"/\");\n\n\t\tconst protocolSummary = createNewSummary.tree[\".protocol\"] as ISummaryTree;\n\t\tconst appSummary = createNewSummary.tree[\".app\"] as ISummaryTree;\n\t\tif (!(protocolSummary && appSummary)) {\n\t\t\tthrow new Error(\"Protocol and App Summary required in the full summary\");\n\t\t}\n\t\tconst documentAttributes = getDocAttributesFromProtocolSummary(protocolSummary);\n\t\tconst quorumValues = getQuorumValuesFromProtocolSummary(protocolSummary);\n\n\t\tconst logger2 = ChildLogger.create(logger, \"RouterliciousDriver\");\n\t\tconst rateLimiter = new RateLimiter(this.driverPolicies.maxConcurrentOrdererRequests);\n\t\tconst ordererRestWrapper = await RouterliciousOrdererRestWrapper.load(\n\t\t\ttenantId,\n\t\t\tundefined,\n\t\t\tthis.tokenProvider,\n\t\t\tlogger2,\n\t\t\trateLimiter,\n\t\t\tthis.driverPolicies.enableRestLess,\n\t\t\tresolvedUrl.endpoints.ordererUrl,\n\t\t);\n\n\t\tconst res = await PerformanceEvent.timedExecAsync(\n\t\t\tlogger2,\n\t\t\t{\n\t\t\t\teventName: \"CreateNew\",\n\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\tenableDiscovery: this.driverPolicies.enableDiscovery,\n\t\t\t\t\tsequenceNumber: documentAttributes.sequenceNumber,\n\t\t\t\t}),\n\t\t\t},\n\t\t\tasync (event) => {\n\t\t\t\t// @TODO: Remove returned \"string\" type when removing back-compat code\n\t\t\t\tconst postRes = await ordererRestWrapper.post<\n\t\t\t\t\t{ id: string; token?: string; session?: ISession } | string\n\t\t\t\t>(`/documents/${tenantId}`, {\n\t\t\t\t\tsummary: convertSummaryToCreateNewSummary(appSummary),\n\t\t\t\t\tsequenceNumber: documentAttributes.sequenceNumber,\n\t\t\t\t\tvalues: quorumValues,\n\t\t\t\t\tenableDiscovery: this.driverPolicies.enableDiscovery,\n\t\t\t\t\tgenerateToken: this.tokenProvider.documentPostCreateCallback !== undefined,\n\t\t\t\t});\n\n\t\t\t\tevent.end({\n\t\t\t\t\tdocId: typeof postRes === \"string\" ? postRes : postRes.id,\n\t\t\t\t});\n\t\t\t\treturn postRes;\n\t\t\t},\n\t\t);\n\n\t\t// For supporting backward compatibility, when the request has generateToken === true, it will return\n\t\t// an object instead of string\n\t\t// @TODO: Remove the logic when no need to support back-compat\n\n\t\tlet documentId: string;\n\t\tlet token: string | undefined;\n\t\tlet session: ISession | undefined;\n\t\tif (typeof res === \"string\") {\n\t\t\tdocumentId = res;\n\t\t} else {\n\t\t\tdocumentId = res.id;\n\t\t\ttoken = res.token;\n\t\t\tsession = this.driverPolicies.enableDiscovery ? res.session : undefined;\n\t\t}\n\t\tparsedUrl = parseFluidUrl(resolvedUrl.url);\n\n\t\t// @TODO: Remove token from the condition, checking the documentPostCreateCallback !== undefined\n\t\t// is sufficient to determine if the token will be undefined or not.\n\t\ttry {\n\t\t\tawait PerformanceEvent.timedExecAsync(\n\t\t\t\tlogger2,\n\t\t\t\t{\n\t\t\t\t\teventName: \"DocPostCreateCallback\",\n\t\t\t\t\tdocId: documentId,\n\t\t\t\t},\n\t\t\t\tasync () => {\n\t\t\t\t\tif (token && this.tokenProvider.documentPostCreateCallback !== undefined) {\n\t\t\t\t\t\treturn this.tokenProvider.documentPostCreateCallback(documentId, token);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\t\t} catch (error: any) {\n\t\t\tthrow new DocumentPostCreateError(error);\n\t\t}\n\n\t\tparsedUrl.set(\"pathname\", replaceDocumentIdInPath(parsedUrl.pathname, documentId));\n\t\tconst deltaStorageUrl = resolvedUrl.endpoints.deltaStorageUrl;\n\t\tif (!deltaStorageUrl) {\n\t\t\tthrow new Error(\n\t\t\t\t`All endpoints urls must be provided. [deltaStorageUrl:${deltaStorageUrl}]`,\n\t\t\t);\n\t\t}\n\t\tconst parsedDeltaStorageUrl = new URL(deltaStorageUrl);\n\t\tparsedDeltaStorageUrl.pathname = replaceDocumentIdInPath(\n\t\t\tparsedDeltaStorageUrl.pathname,\n\t\t\tdocumentId,\n\t\t);\n\n\t\treturn this.createDocumentService(\n\t\t\t{\n\t\t\t\t...resolvedUrl,\n\t\t\t\turl: parsedUrl.toString(),\n\t\t\t\tid: documentId,\n\t\t\t\tendpoints: {\n\t\t\t\t\t...resolvedUrl.endpoints,\n\t\t\t\t\tdeltaStorageUrl: parsedDeltaStorageUrl.toString(),\n\t\t\t\t},\n\t\t\t},\n\t\t\tlogger,\n\t\t\tclientIsSummarizer,\n\t\t\tsession,\n\t\t);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/driver-definitions#IDocumentServiceFactory.createDocumentService}\n\t *\n\t * @returns Routerlicious document service.\n\t */\n\tpublic async createDocumentService(\n\t\tresolvedUrl: IResolvedUrl,\n\t\tlogger?: ITelemetryBaseLogger,\n\t\tclientIsSummarizer?: boolean,\n\t\tsession?: ISession,\n\t): Promise<IDocumentService> {\n\t\tensureFluidResolvedUrl(resolvedUrl);\n\t\tconst parsedUrl = parseFluidUrl(resolvedUrl.url);\n\t\tconst [, tenantId, documentId] = parsedUrl.pathname.split(\"/\");\n\t\tif (!documentId || !tenantId) {\n\t\t\tthrow new Error(\n\t\t\t\t`Couldn't parse documentId and/or tenantId. [documentId:${documentId}][tenantId:${tenantId}]`,\n\t\t\t);\n\t\t}\n\t\tconst logger2 = ChildLogger.create(logger, \"RouterliciousDriver\", {\n\t\t\tall: { driverVersion },\n\t\t});\n\n\t\tconst rateLimiter = new RateLimiter(this.driverPolicies.maxConcurrentOrdererRequests);\n\t\tconst ordererRestWrapper = await RouterliciousOrdererRestWrapper.load(\n\t\t\ttenantId,\n\t\t\tdocumentId,\n\t\t\tthis.tokenProvider,\n\t\t\tlogger2,\n\t\t\trateLimiter,\n\t\t\tthis.driverPolicies.enableRestLess,\n\t\t);\n\n\t\tconst discoverFluidResolvedUrl = async (): Promise<IFluidResolvedUrl> => {\n\t\t\tif (!this.driverPolicies.enableDiscovery) {\n\t\t\t\treturn resolvedUrl;\n\t\t\t}\n\n\t\t\tconst discoveredSession = await PerformanceEvent.timedExecAsync(\n\t\t\t\tlogger2,\n\t\t\t\t{\n\t\t\t\t\teventName: \"DiscoverSession\",\n\t\t\t\t\tdocId: documentId,\n\t\t\t\t},\n\t\t\t\tasync () => {\n\t\t\t\t\t// The service responds with the current document session associated with the container.\n\t\t\t\t\treturn ordererRestWrapper.get<ISession>(\n\t\t\t\t\t\t`${resolvedUrl.endpoints.ordererUrl}/documents/${tenantId}/session/${documentId}`,\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t);\n\t\t\treturn getDiscoveredFluidResolvedUrl(resolvedUrl, discoveredSession);\n\t\t};\n\t\tconst fluidResolvedUrl: IFluidResolvedUrl =\n\t\t\tsession !== undefined\n\t\t\t\t? getDiscoveredFluidResolvedUrl(resolvedUrl, session)\n\t\t\t\t: await discoverFluidResolvedUrl();\n\n\t\tconst storageUrl = fluidResolvedUrl.endpoints.storageUrl;\n\t\tconst ordererUrl = fluidResolvedUrl.endpoints.ordererUrl;\n\t\tconst deltaStorageUrl = fluidResolvedUrl.endpoints.deltaStorageUrl;\n\t\tconst deltaStreamUrl = fluidResolvedUrl.endpoints.deltaStreamUrl || ordererUrl; // backward compatibility\n\t\tif (!ordererUrl || !deltaStorageUrl) {\n\t\t\tthrow new Error(\n\t\t\t\t`All endpoints urls must be provided. [ordererUrl:${ordererUrl}][deltaStorageUrl:${deltaStorageUrl}]`,\n\t\t\t);\n\t\t}\n\n\t\tconst documentStorageServicePolicies: IDocumentStorageServicePolicies = {\n\t\t\tcaching: this.driverPolicies.enablePrefetch\n\t\t\t\t? LoaderCachingPolicy.Prefetch\n\t\t\t\t: LoaderCachingPolicy.NoCaching,\n\t\t\tminBlobSize: this.driverPolicies.aggregateBlobsSmallerThanBytes,\n\t\t\tmaximumCacheDurationMs: maximumSnapshotCacheDurationMs,\n\t\t};\n\n\t\treturn new DocumentService(\n\t\t\tfluidResolvedUrl,\n\t\t\tordererUrl,\n\t\t\tdeltaStorageUrl,\n\t\t\tdeltaStreamUrl,\n\t\t\tstorageUrl,\n\t\t\tlogger2,\n\t\t\tthis.tokenProvider,\n\t\t\ttenantId,\n\t\t\tdocumentId,\n\t\t\tordererRestWrapper,\n\t\t\tdocumentStorageServicePolicies,\n\t\t\tthis.driverPolicies,\n\t\t\tthis.blobCache,\n\t\t\tthis.snapshotTreeCache,\n\t\t\tdiscoverFluidResolvedUrl,\n\t\t);\n\t}\n}\n\n/**\n * Error returned by {@link RouterliciousDocumentServiceFactory.createContainer} when an error is thrown\n * in {@link ITokenProvider.documentPostCreateCallback}.\n * It is the consumer's responsibility to ensure that any state related to container creation is appropriately\n * cleaned up in the event of failure.\n * This includes the document itself, which will have been created by the time this error was thrown.\n *\n * @remarks TODO: examples of suggested actions for recovery.\n * - How would a user delete the created document?\n * - What would a retry pattern look like here?\n */\nexport class DocumentPostCreateError extends Error {\n\tpublic constructor(\n\t\t/**\n\t\t * Inner error being wrapped.\n\t\t */\n\t\tprivate readonly innerError: Error,\n\t) {\n\t\tsuper(innerError.message);\n\t}\n\n\tpublic readonly name = \"DocumentPostCreateError\";\n\n\tpublic get stack() {\n\t\treturn this.innerError.stack;\n\t}\n}\n"]}
1
+ {"version":3,"file":"documentServiceFactory.js","sourceRoot":"","sources":["../src/documentServiceFactory.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/common-utils\";\nimport {\n\tFiveDaysMs,\n\tIDocumentService,\n\tIDocumentServiceFactory,\n\tIDocumentStorageServicePolicies,\n\tIFluidResolvedUrl,\n\tIResolvedUrl,\n\tLoaderCachingPolicy,\n} from \"@fluidframework/driver-definitions\";\nimport { ITelemetryBaseLogger } from \"@fluidframework/common-definitions\";\nimport { ISummaryTree } from \"@fluidframework/protocol-definitions\";\nimport {\n\tensureFluidResolvedUrl,\n\tgetDocAttributesFromProtocolSummary,\n\tgetQuorumValuesFromProtocolSummary,\n\tisCombinedAppAndProtocolSummary,\n\tRateLimiter,\n} from \"@fluidframework/driver-utils\";\nimport { ChildLogger, PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport { ISession } from \"@fluidframework/server-services-client\";\nimport { DocumentService } from \"./documentService\";\nimport { IRouterliciousDriverPolicies } from \"./policies\";\nimport { ITokenProvider } from \"./tokens\";\nimport { RouterliciousOrdererRestWrapper } from \"./restWrapper\";\nimport { convertSummaryToCreateNewSummary } from \"./createNewUtils\";\nimport { parseFluidUrl, replaceDocumentIdInPath, getDiscoveredFluidResolvedUrl } from \"./urlUtils\";\nimport { ICache, InMemoryCache, NullCache } from \"./cache\";\nimport { pkgVersion as driverVersion } from \"./packageVersion\";\nimport { ISnapshotTreeVersion } from \"./definitions\";\n\nconst maximumSnapshotCacheDurationMs: FiveDaysMs = 432_000_000; // 5 days in ms\n\nconst defaultRouterliciousDriverPolicies: IRouterliciousDriverPolicies = {\n\tenablePrefetch: true,\n\tmaxConcurrentStorageRequests: 100,\n\tmaxConcurrentOrdererRequests: 100,\n\taggregateBlobsSmallerThanBytes: undefined,\n\tenableDiscovery: false,\n\tenableWholeSummaryUpload: false,\n\tenableRestLess: true,\n\tenableInternalSummaryCaching: true,\n};\n\n/**\n * Factory for creating the routerlicious document service. Use this if you want to\n * use the routerlicious implementation.\n */\nexport class RouterliciousDocumentServiceFactory implements IDocumentServiceFactory {\n\tprivate readonly driverPolicies: IRouterliciousDriverPolicies;\n\tprivate readonly blobCache: ICache<ArrayBufferLike>;\n\tprivate readonly snapshotTreeCache: ICache<ISnapshotTreeVersion>;\n\n\tconstructor(\n\t\tprivate readonly tokenProvider: ITokenProvider,\n\t\tdriverPolicies: Partial<IRouterliciousDriverPolicies> = {},\n\t) {\n\t\t// Use the maximum allowed by the policy (IDocumentStorageServicePolicies.maximumCacheDurationMs set below)\n\t\tconst snapshotCacheExpiryMs: FiveDaysMs = maximumSnapshotCacheDurationMs;\n\n\t\tthis.driverPolicies = {\n\t\t\t...defaultRouterliciousDriverPolicies,\n\t\t\t...driverPolicies,\n\t\t};\n\t\tthis.blobCache = new InMemoryCache<ArrayBufferLike>();\n\t\tthis.snapshotTreeCache = this.driverPolicies.enableInternalSummaryCaching\n\t\t\t? new InMemoryCache<ISnapshotTreeVersion>(snapshotCacheExpiryMs)\n\t\t\t: new NullCache<ISnapshotTreeVersion>();\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/driver-definitions#IDocumentServiceFactory.createContainer}\n\t *\n\t * @throws {@link DocumentPostCreateError}\n\t * If an exception is thrown while invoking the provided {@link ITokenProvider.documentPostCreateCallback}.\n\t */\n\tpublic async createContainer(\n\t\tcreateNewSummary: ISummaryTree | undefined,\n\t\tresolvedUrl: IResolvedUrl,\n\t\tlogger?: ITelemetryBaseLogger,\n\t\tclientIsSummarizer?: boolean,\n\t): Promise<IDocumentService> {\n\t\tensureFluidResolvedUrl(resolvedUrl);\n\t\tif (createNewSummary === undefined) {\n\t\t\tthrow new Error(\"Empty file summary creation isn't supported in this driver.\");\n\t\t}\n\t\tassert(!!resolvedUrl.endpoints.ordererUrl, 0x0b2 /* \"Missing orderer URL!\" */);\n\t\tlet parsedUrl = parseFluidUrl(resolvedUrl.url);\n\t\tif (!parsedUrl.pathname) {\n\t\t\tthrow new Error(\"Parsed url should contain tenant and doc Id!!\");\n\t\t}\n\t\tconst [, tenantId] = parsedUrl.pathname.split(\"/\");\n\n\t\tif (!isCombinedAppAndProtocolSummary(createNewSummary)) {\n\t\t\tthrow new Error(\"Protocol and App Summary required in the full summary\");\n\t\t}\n\t\tconst protocolSummary = createNewSummary.tree[\".protocol\"];\n\t\tconst appSummary = createNewSummary.tree[\".app\"];\n\n\t\tconst documentAttributes = getDocAttributesFromProtocolSummary(protocolSummary);\n\t\tconst quorumValues = getQuorumValuesFromProtocolSummary(protocolSummary);\n\n\t\tconst logger2 = ChildLogger.create(logger, \"RouterliciousDriver\");\n\t\tconst rateLimiter = new RateLimiter(this.driverPolicies.maxConcurrentOrdererRequests);\n\t\tconst ordererRestWrapper = await RouterliciousOrdererRestWrapper.load(\n\t\t\ttenantId,\n\t\t\tundefined,\n\t\t\tthis.tokenProvider,\n\t\t\tlogger2,\n\t\t\trateLimiter,\n\t\t\tthis.driverPolicies.enableRestLess,\n\t\t\tresolvedUrl.endpoints.ordererUrl,\n\t\t);\n\n\t\tconst res = await PerformanceEvent.timedExecAsync(\n\t\t\tlogger2,\n\t\t\t{\n\t\t\t\teventName: \"CreateNew\",\n\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\tenableDiscovery: this.driverPolicies.enableDiscovery,\n\t\t\t\t\tsequenceNumber: documentAttributes.sequenceNumber,\n\t\t\t\t}),\n\t\t\t},\n\t\t\tasync (event) => {\n\t\t\t\t// @TODO: Remove returned \"string\" type when removing back-compat code\n\t\t\t\tconst postRes = await ordererRestWrapper.post<\n\t\t\t\t\t{ id: string; token?: string; session?: ISession } | string\n\t\t\t\t>(`/documents/${tenantId}`, {\n\t\t\t\t\tsummary: convertSummaryToCreateNewSummary(appSummary),\n\t\t\t\t\tsequenceNumber: documentAttributes.sequenceNumber,\n\t\t\t\t\tvalues: quorumValues,\n\t\t\t\t\tenableDiscovery: this.driverPolicies.enableDiscovery,\n\t\t\t\t\tgenerateToken: this.tokenProvider.documentPostCreateCallback !== undefined,\n\t\t\t\t});\n\n\t\t\t\tevent.end({\n\t\t\t\t\tdocId: typeof postRes === \"string\" ? postRes : postRes.id,\n\t\t\t\t});\n\t\t\t\treturn postRes;\n\t\t\t},\n\t\t);\n\n\t\t// For supporting backward compatibility, when the request has generateToken === true, it will return\n\t\t// an object instead of string\n\t\t// @TODO: Remove the logic when no need to support back-compat\n\n\t\tlet documentId: string;\n\t\tlet token: string | undefined;\n\t\tlet session: ISession | undefined;\n\t\tif (typeof res === \"string\") {\n\t\t\tdocumentId = res;\n\t\t} else {\n\t\t\tdocumentId = res.id;\n\t\t\ttoken = res.token;\n\t\t\tsession = this.driverPolicies.enableDiscovery ? res.session : undefined;\n\t\t}\n\t\tparsedUrl = parseFluidUrl(resolvedUrl.url);\n\n\t\t// @TODO: Remove token from the condition, checking the documentPostCreateCallback !== undefined\n\t\t// is sufficient to determine if the token will be undefined or not.\n\t\ttry {\n\t\t\tawait PerformanceEvent.timedExecAsync(\n\t\t\t\tlogger2,\n\t\t\t\t{\n\t\t\t\t\teventName: \"DocPostCreateCallback\",\n\t\t\t\t\tdocId: documentId,\n\t\t\t\t},\n\t\t\t\tasync () => {\n\t\t\t\t\tif (token && this.tokenProvider.documentPostCreateCallback !== undefined) {\n\t\t\t\t\t\treturn this.tokenProvider.documentPostCreateCallback(documentId, token);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\t\t} catch (error: any) {\n\t\t\tthrow new DocumentPostCreateError(error);\n\t\t}\n\n\t\tparsedUrl.set(\"pathname\", replaceDocumentIdInPath(parsedUrl.pathname, documentId));\n\t\tconst deltaStorageUrl = resolvedUrl.endpoints.deltaStorageUrl;\n\t\tif (!deltaStorageUrl) {\n\t\t\tthrow new Error(\n\t\t\t\t`All endpoints urls must be provided. [deltaStorageUrl:${deltaStorageUrl}]`,\n\t\t\t);\n\t\t}\n\t\tconst parsedDeltaStorageUrl = new URL(deltaStorageUrl);\n\t\tparsedDeltaStorageUrl.pathname = replaceDocumentIdInPath(\n\t\t\tparsedDeltaStorageUrl.pathname,\n\t\t\tdocumentId,\n\t\t);\n\n\t\treturn this.createDocumentService(\n\t\t\t{\n\t\t\t\t...resolvedUrl,\n\t\t\t\turl: parsedUrl.toString(),\n\t\t\t\tid: documentId,\n\t\t\t\tendpoints: {\n\t\t\t\t\t...resolvedUrl.endpoints,\n\t\t\t\t\tdeltaStorageUrl: parsedDeltaStorageUrl.toString(),\n\t\t\t\t},\n\t\t\t},\n\t\t\tlogger,\n\t\t\tclientIsSummarizer,\n\t\t\tsession,\n\t\t);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/driver-definitions#IDocumentServiceFactory.createDocumentService}\n\t *\n\t * @returns Routerlicious document service.\n\t */\n\tpublic async createDocumentService(\n\t\tresolvedUrl: IResolvedUrl,\n\t\tlogger?: ITelemetryBaseLogger,\n\t\tclientIsSummarizer?: boolean,\n\t\tsession?: ISession,\n\t): Promise<IDocumentService> {\n\t\tensureFluidResolvedUrl(resolvedUrl);\n\t\tconst parsedUrl = parseFluidUrl(resolvedUrl.url);\n\t\tconst [, tenantId, documentId] = parsedUrl.pathname.split(\"/\");\n\t\tif (!documentId || !tenantId) {\n\t\t\tthrow new Error(\n\t\t\t\t`Couldn't parse documentId and/or tenantId. [documentId:${documentId}][tenantId:${tenantId}]`,\n\t\t\t);\n\t\t}\n\t\tconst logger2 = ChildLogger.create(logger, \"RouterliciousDriver\", {\n\t\t\tall: { driverVersion },\n\t\t});\n\n\t\tconst rateLimiter = new RateLimiter(this.driverPolicies.maxConcurrentOrdererRequests);\n\t\tconst ordererRestWrapper = await RouterliciousOrdererRestWrapper.load(\n\t\t\ttenantId,\n\t\t\tdocumentId,\n\t\t\tthis.tokenProvider,\n\t\t\tlogger2,\n\t\t\trateLimiter,\n\t\t\tthis.driverPolicies.enableRestLess,\n\t\t);\n\n\t\tconst discoverFluidResolvedUrl = async (): Promise<IFluidResolvedUrl> => {\n\t\t\tif (!this.driverPolicies.enableDiscovery) {\n\t\t\t\treturn resolvedUrl;\n\t\t\t}\n\n\t\t\tconst discoveredSession = await PerformanceEvent.timedExecAsync(\n\t\t\t\tlogger2,\n\t\t\t\t{\n\t\t\t\t\teventName: \"DiscoverSession\",\n\t\t\t\t\tdocId: documentId,\n\t\t\t\t},\n\t\t\t\tasync () => {\n\t\t\t\t\t// The service responds with the current document session associated with the container.\n\t\t\t\t\treturn ordererRestWrapper.get<ISession>(\n\t\t\t\t\t\t`${resolvedUrl.endpoints.ordererUrl}/documents/${tenantId}/session/${documentId}`,\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t);\n\t\t\treturn getDiscoveredFluidResolvedUrl(resolvedUrl, discoveredSession);\n\t\t};\n\t\tconst fluidResolvedUrl: IFluidResolvedUrl =\n\t\t\tsession !== undefined\n\t\t\t\t? getDiscoveredFluidResolvedUrl(resolvedUrl, session)\n\t\t\t\t: await discoverFluidResolvedUrl();\n\n\t\tconst storageUrl = fluidResolvedUrl.endpoints.storageUrl;\n\t\tconst ordererUrl = fluidResolvedUrl.endpoints.ordererUrl;\n\t\tconst deltaStorageUrl = fluidResolvedUrl.endpoints.deltaStorageUrl;\n\t\tconst deltaStreamUrl = fluidResolvedUrl.endpoints.deltaStreamUrl || ordererUrl; // backward compatibility\n\t\tif (!ordererUrl || !deltaStorageUrl) {\n\t\t\tthrow new Error(\n\t\t\t\t`All endpoints urls must be provided. [ordererUrl:${ordererUrl}][deltaStorageUrl:${deltaStorageUrl}]`,\n\t\t\t);\n\t\t}\n\n\t\tconst documentStorageServicePolicies: IDocumentStorageServicePolicies = {\n\t\t\tcaching: this.driverPolicies.enablePrefetch\n\t\t\t\t? LoaderCachingPolicy.Prefetch\n\t\t\t\t: LoaderCachingPolicy.NoCaching,\n\t\t\tminBlobSize: this.driverPolicies.aggregateBlobsSmallerThanBytes,\n\t\t\tmaximumCacheDurationMs: maximumSnapshotCacheDurationMs,\n\t\t};\n\n\t\treturn new DocumentService(\n\t\t\tfluidResolvedUrl,\n\t\t\tordererUrl,\n\t\t\tdeltaStorageUrl,\n\t\t\tdeltaStreamUrl,\n\t\t\tstorageUrl,\n\t\t\tlogger2,\n\t\t\tthis.tokenProvider,\n\t\t\ttenantId,\n\t\t\tdocumentId,\n\t\t\tordererRestWrapper,\n\t\t\tdocumentStorageServicePolicies,\n\t\t\tthis.driverPolicies,\n\t\t\tthis.blobCache,\n\t\t\tthis.snapshotTreeCache,\n\t\t\tdiscoverFluidResolvedUrl,\n\t\t);\n\t}\n}\n\n/**\n * Error returned by {@link RouterliciousDocumentServiceFactory.createContainer} when an error is thrown\n * in {@link ITokenProvider.documentPostCreateCallback}.\n * It is the consumer's responsibility to ensure that any state related to container creation is appropriately\n * cleaned up in the event of failure.\n * This includes the document itself, which will have been created by the time this error was thrown.\n *\n * @remarks TODO: examples of suggested actions for recovery.\n * - How would a user delete the created document?\n * - What would a retry pattern look like here?\n */\nexport class DocumentPostCreateError extends Error {\n\tpublic constructor(\n\t\t/**\n\t\t * Inner error being wrapped.\n\t\t */\n\t\tprivate readonly innerError: Error,\n\t) {\n\t\tsuper(innerError.message);\n\t}\n\n\tpublic readonly name = \"DocumentPostCreateError\";\n\n\tpublic get stack() {\n\t\treturn this.innerError.stack;\n\t}\n}\n"]}
@@ -3,7 +3,14 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import { DriverError } from "@fluidframework/driver-definitions";
6
- export declare enum R11sErrorType {
6
+ /**
7
+ * Routerlicious Error types
8
+ * Different error types that may be thrown by the routerlicious driver
9
+ */
10
+ export declare enum RouterliciousErrorType {
11
+ /**
12
+ * File not found, or file deleted during session
13
+ */
7
14
  fileNotFoundOrAccessDeniedError = "fileNotFoundOrAccessDeniedError",
8
15
  sslCertError = "sslCertError"
9
16
  }
@@ -34,7 +41,7 @@ export interface IR11sSocketError {
34
41
  retryAfterMs?: number;
35
42
  }
36
43
  export interface IR11sError {
37
- readonly errorType: R11sErrorType;
44
+ readonly errorType: RouterliciousErrorType;
38
45
  readonly message: string;
39
46
  canRetry: boolean;
40
47
  }
@@ -1 +1 @@
1
- {"version":3,"file":"errorUtils.d.ts","sourceRoot":"","sources":["../src/errorUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AASjE,oBAAY,aAAa;IACxB,+BAA+B,oCAAoC;IACnE,YAAY,iBAAiB;CAC7B;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAChC;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED,oBAAY,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC;AAEjD,wBAAgB,sBAAsB,CACrC,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,MAAM,EACnB,YAAY,CAAC,EAAE,MAAM,GACnB,SAAS,CAkCX;AAED,wBAAgB,qBAAqB,CACpC,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,MAAM,EACnB,YAAY,CAAC,EAAE,MAAM,GACnB,KAAK,CAKP;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACzC,WAAW,EAAE,gBAAgB,EAC7B,OAAO,EAAE,MAAM,GACb,SAAS,CAIX"}
1
+ {"version":3,"file":"errorUtils.d.ts","sourceRoot":"","sources":["../src/errorUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AASjE;;;GAGG;AACH,oBAAY,sBAAsB;IACjC;;OAEG;IACH,+BAA+B,oCAAoC;IAEnE,YAAY,iBAAiB;CAC7B;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAChC;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,SAAS,EAAE,sBAAsB,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED,oBAAY,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC;AAEjD,wBAAgB,sBAAsB,CACrC,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,MAAM,EACnB,YAAY,CAAC,EAAE,MAAM,GACnB,SAAS,CAsCX;AAED,wBAAgB,qBAAqB,CACpC,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,MAAM,EACnB,YAAY,CAAC,EAAE,MAAM,GACnB,KAAK,CAKP;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACzC,WAAW,EAAE,gBAAgB,EAC7B,OAAO,EAAE,MAAM,GACb,SAAS,CAIX"}
@@ -4,14 +4,21 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.errorObjectFromSocketError = exports.throwR11sNetworkError = exports.createR11sNetworkError = exports.R11sErrorType = void 0;
7
+ exports.errorObjectFromSocketError = exports.throwR11sNetworkError = exports.createR11sNetworkError = exports.RouterliciousErrorType = void 0;
8
8
  const driver_utils_1 = require("@fluidframework/driver-utils");
9
9
  const packageVersion_1 = require("./packageVersion");
10
- var R11sErrorType;
11
- (function (R11sErrorType) {
12
- R11sErrorType["fileNotFoundOrAccessDeniedError"] = "fileNotFoundOrAccessDeniedError";
13
- R11sErrorType["sslCertError"] = "sslCertError";
14
- })(R11sErrorType = exports.R11sErrorType || (exports.R11sErrorType = {}));
10
+ /**
11
+ * Routerlicious Error types
12
+ * Different error types that may be thrown by the routerlicious driver
13
+ */
14
+ var RouterliciousErrorType;
15
+ (function (RouterliciousErrorType) {
16
+ /**
17
+ * File not found, or file deleted during session
18
+ */
19
+ RouterliciousErrorType["fileNotFoundOrAccessDeniedError"] = "fileNotFoundOrAccessDeniedError";
20
+ RouterliciousErrorType["sslCertError"] = "sslCertError";
21
+ })(RouterliciousErrorType = exports.RouterliciousErrorType || (exports.RouterliciousErrorType = {}));
15
22
  function createR11sNetworkError(errorMessage, statusCode, retryAfterMs) {
16
23
  const props = { statusCode, driverVersion: packageVersion_1.pkgVersion };
17
24
  switch (statusCode) {
@@ -22,7 +29,7 @@ function createR11sNetworkError(errorMessage, statusCode, retryAfterMs) {
22
29
  // If there exists a self-signed SSL certificates error, throw a NonRetryableError
23
30
  // TODO: instead of relying on string matching, filter error based on the error code like we do for websocket connections
24
31
  if (errorMessage.includes("failed, reason: self signed certificate")) {
25
- return new driver_utils_1.NonRetryableError(errorMessage, R11sErrorType.sslCertError, props);
32
+ return new driver_utils_1.NonRetryableError(errorMessage, RouterliciousErrorType.sslCertError, props);
26
33
  }
27
34
  return new driver_utils_1.GenericNetworkError(errorMessage, errorMessage.startsWith("NetworkError"), props);
28
35
  case 401:
@@ -31,7 +38,7 @@ function createR11sNetworkError(errorMessage, statusCode, retryAfterMs) {
31
38
  case 403:
32
39
  return new driver_utils_1.AuthorizationError(errorMessage, undefined, undefined, props);
33
40
  case 404:
34
- const errorType = R11sErrorType.fileNotFoundOrAccessDeniedError;
41
+ const errorType = RouterliciousErrorType.fileNotFoundOrAccessDeniedError;
35
42
  return new driver_utils_1.NonRetryableError(errorMessage, errorType, props);
36
43
  case 429:
37
44
  return (0, driver_utils_1.createGenericNetworkError)(errorMessage, { canRetry: true, retryAfterMs }, props);
@@ -1 +1 @@
1
- {"version":3,"file":"errorUtils.js","sourceRoot":"","sources":["../src/errorUtils.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,+DAKsC;AACtC,qDAA+D;AAE/D,IAAY,aAGX;AAHD,WAAY,aAAa;IACxB,oFAAmE,CAAA;IACnE,8CAA6B,CAAA;AAC9B,CAAC,EAHW,aAAa,GAAb,qBAAa,KAAb,qBAAa,QAGxB;AAwCD,SAAgB,sBAAsB,CACrC,YAAoB,EACpB,UAAmB,EACnB,YAAqB;IAErB,MAAM,KAAK,GAAG,EAAE,UAAU,EAAE,aAAa,EAAb,2BAAa,EAAE,CAAC;IAC5C,QAAQ,UAAU,EAAE;QACnB,KAAK,SAAS;YACb,kGAAkG;YAClG,wFAAwF;YACxF,8EAA8E;YAC9E,kFAAkF;YAClF,yHAAyH;YACzH,IAAI,YAAY,CAAC,QAAQ,CAAC,yCAAyC,CAAC,EAAE;gBACrE,OAAO,IAAI,gCAAiB,CAAC,YAAY,EAAE,aAAa,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;aAC9E;YACD,OAAO,IAAI,kCAAmB,CAC7B,YAAY,EACZ,YAAY,CAAC,UAAU,CAAC,cAAc,CAAC,EACvC,KAAK,CACL,CAAC;QACH,KAAK,GAAG,CAAC;QACT,wFAAwF;QACxF,2CAA2C;QAC3C,KAAK,GAAG;YACP,OAAO,IAAI,iCAAkB,CAAC,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QAC1E,KAAK,GAAG;YACP,MAAM,SAAS,GAAG,aAAa,CAAC,+BAA+B,CAAC;YAChE,OAAO,IAAI,gCAAiB,CAAC,YAAY,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QAC9D,KAAK,GAAG;YACP,OAAO,IAAA,wCAAyB,EAAC,YAAY,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,KAAK,CAAC,CAAC;QACzF,KAAK,GAAG,CAAC;QACT,KAAK,GAAG;YACP,OAAO,IAAI,kCAAmB,CAAC,YAAY,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAC3D;YACC,MAAM,SAAS,GAAG,EAAE,QAAQ,EAAE,YAAY,KAAK,SAAS,EAAE,YAAY,EAAE,CAAC;YACzE,OAAO,IAAA,wCAAyB,EAAC,YAAY,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;KAClE;AACF,CAAC;AAtCD,wDAsCC;AAED,SAAgB,qBAAqB,CACpC,YAAoB,EACpB,UAAmB,EACnB,YAAqB;IAErB,MAAM,YAAY,GAAG,sBAAsB,CAAC,YAAY,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;IAEpF,+DAA+D;IAC/D,MAAM,YAAY,CAAC;AACpB,CAAC;AATD,sDASC;AAED;;GAEG;AACH,SAAgB,0BAA0B,CACzC,WAA6B,EAC7B,OAAe;IAEf,iDAAiD;IACjD,MAAM,OAAO,GAAG,sBAAsB,OAAO,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC;IACzE,OAAO,sBAAsB,CAAC,OAAO,EAAE,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC;AACpF,CAAC;AAPD,gEAOC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { DriverError } from \"@fluidframework/driver-definitions\";\nimport {\n\tNonRetryableError,\n\tGenericNetworkError,\n\tcreateGenericNetworkError,\n\tAuthorizationError,\n} from \"@fluidframework/driver-utils\";\nimport { pkgVersion as driverVersion } from \"./packageVersion\";\n\nexport enum R11sErrorType {\n\tfileNotFoundOrAccessDeniedError = \"fileNotFoundOrAccessDeniedError\",\n\tsslCertError = \"sslCertError\",\n}\n\n/**\n * Interface for error responses for the WebSocket connection\n * Intended to be compatible with output from {@link NetworkError.toJSON}\n */\nexport interface IR11sSocketError {\n\t/**\n\t * An error code number for the error that occurred.\n\t * It will be a valid HTTP status code.\n\t */\n\tcode: number;\n\n\t/**\n\t * A message about the error that occurred for debugging / logging purposes.\n\t * This should not be displayed to the user directly.\n\t */\n\tmessage: string;\n\n\t/**\n\t * Optional Retry-After time in seconds.\n\t * The client should wait this many seconds before retrying its request.\n\t */\n\tretryAfter?: number;\n\n\t/**\n\t * Optional Retry-After time in milliseconds.\n\t * The client should wait this many milliseconds before retrying its request.\n\t */\n\tretryAfterMs?: number;\n}\n\nexport interface IR11sError {\n\treadonly errorType: R11sErrorType;\n\treadonly message: string;\n\tcanRetry: boolean;\n}\n\nexport type R11sError = DriverError | IR11sError;\n\nexport function createR11sNetworkError(\n\terrorMessage: string,\n\tstatusCode?: number,\n\tretryAfterMs?: number,\n): R11sError {\n\tconst props = { statusCode, driverVersion };\n\tswitch (statusCode) {\n\t\tcase undefined:\n\t\t\t// If a service is temporarily down or a browser resource limit is reached, RestWrapper will throw\n\t\t\t// a network error with no status code (e.g. err:ERR_CONN_REFUSED or err:ERR_FAILED) and\n\t\t\t// the error message will start with NetworkError as defined in restWrapper.ts\n\t\t\t// If there exists a self-signed SSL certificates error, throw a NonRetryableError\n\t\t\t// TODO: instead of relying on string matching, filter error based on the error code like we do for websocket connections\n\t\t\tif (errorMessage.includes(\"failed, reason: self signed certificate\")) {\n\t\t\t\treturn new NonRetryableError(errorMessage, R11sErrorType.sslCertError, props);\n\t\t\t}\n\t\t\treturn new GenericNetworkError(\n\t\t\t\terrorMessage,\n\t\t\t\terrorMessage.startsWith(\"NetworkError\"),\n\t\t\t\tprops,\n\t\t\t);\n\t\tcase 401:\n\t\t// The first 401 is manually retried in RouterliciousRestWrapper with a refreshed token,\n\t\t// so we treat repeat 401s the same as 403.\n\t\tcase 403:\n\t\t\treturn new AuthorizationError(errorMessage, undefined, undefined, props);\n\t\tcase 404:\n\t\t\tconst errorType = R11sErrorType.fileNotFoundOrAccessDeniedError;\n\t\t\treturn new NonRetryableError(errorMessage, errorType, props);\n\t\tcase 429:\n\t\t\treturn createGenericNetworkError(errorMessage, { canRetry: true, retryAfterMs }, props);\n\t\tcase 500:\n\t\tcase 502:\n\t\t\treturn new GenericNetworkError(errorMessage, true, props);\n\t\tdefault:\n\t\t\tconst retryInfo = { canRetry: retryAfterMs !== undefined, retryAfterMs };\n\t\t\treturn createGenericNetworkError(errorMessage, retryInfo, props);\n\t}\n}\n\nexport function throwR11sNetworkError(\n\terrorMessage: string,\n\tstatusCode?: number,\n\tretryAfterMs?: number,\n): never {\n\tconst networkError = createR11sNetworkError(errorMessage, statusCode, retryAfterMs);\n\n\t// eslint-disable-next-line @typescript-eslint/no-throw-literal\n\tthrow networkError;\n}\n\n/**\n * Returns network error based on error object from R11s socket (IR11sSocketError)\n */\nexport function errorObjectFromSocketError(\n\tsocketError: IR11sSocketError,\n\thandler: string,\n): R11sError {\n\t// pre-0.58 error message prefix: R11sSocketError\n\tconst message = `R11s socket error (${handler}): ${socketError.message}`;\n\treturn createR11sNetworkError(message, socketError.code, socketError.retryAfterMs);\n}\n"]}
1
+ {"version":3,"file":"errorUtils.js","sourceRoot":"","sources":["../src/errorUtils.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,+DAKsC;AACtC,qDAA+D;AAE/D;;;GAGG;AACH,IAAY,sBAOX;AAPD,WAAY,sBAAsB;IACjC;;OAEG;IACH,6FAAmE,CAAA;IAEnE,uDAA6B,CAAA;AAC9B,CAAC,EAPW,sBAAsB,GAAtB,8BAAsB,KAAtB,8BAAsB,QAOjC;AAwCD,SAAgB,sBAAsB,CACrC,YAAoB,EACpB,UAAmB,EACnB,YAAqB;IAErB,MAAM,KAAK,GAAG,EAAE,UAAU,EAAE,aAAa,EAAb,2BAAa,EAAE,CAAC;IAC5C,QAAQ,UAAU,EAAE;QACnB,KAAK,SAAS;YACb,kGAAkG;YAClG,wFAAwF;YACxF,8EAA8E;YAC9E,kFAAkF;YAClF,yHAAyH;YACzH,IAAI,YAAY,CAAC,QAAQ,CAAC,yCAAyC,CAAC,EAAE;gBACrE,OAAO,IAAI,gCAAiB,CAC3B,YAAY,EACZ,sBAAsB,CAAC,YAAY,EACnC,KAAK,CACL,CAAC;aACF;YACD,OAAO,IAAI,kCAAmB,CAC7B,YAAY,EACZ,YAAY,CAAC,UAAU,CAAC,cAAc,CAAC,EACvC,KAAK,CACL,CAAC;QACH,KAAK,GAAG,CAAC;QACT,wFAAwF;QACxF,2CAA2C;QAC3C,KAAK,GAAG;YACP,OAAO,IAAI,iCAAkB,CAAC,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QAC1E,KAAK,GAAG;YACP,MAAM,SAAS,GAAG,sBAAsB,CAAC,+BAA+B,CAAC;YACzE,OAAO,IAAI,gCAAiB,CAAC,YAAY,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QAC9D,KAAK,GAAG;YACP,OAAO,IAAA,wCAAyB,EAAC,YAAY,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,KAAK,CAAC,CAAC;QACzF,KAAK,GAAG,CAAC;QACT,KAAK,GAAG;YACP,OAAO,IAAI,kCAAmB,CAAC,YAAY,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAC3D;YACC,MAAM,SAAS,GAAG,EAAE,QAAQ,EAAE,YAAY,KAAK,SAAS,EAAE,YAAY,EAAE,CAAC;YACzE,OAAO,IAAA,wCAAyB,EAAC,YAAY,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;KAClE;AACF,CAAC;AA1CD,wDA0CC;AAED,SAAgB,qBAAqB,CACpC,YAAoB,EACpB,UAAmB,EACnB,YAAqB;IAErB,MAAM,YAAY,GAAG,sBAAsB,CAAC,YAAY,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;IAEpF,+DAA+D;IAC/D,MAAM,YAAY,CAAC;AACpB,CAAC;AATD,sDASC;AAED;;GAEG;AACH,SAAgB,0BAA0B,CACzC,WAA6B,EAC7B,OAAe;IAEf,iDAAiD;IACjD,MAAM,OAAO,GAAG,sBAAsB,OAAO,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC;IACzE,OAAO,sBAAsB,CAAC,OAAO,EAAE,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC;AACpF,CAAC;AAPD,gEAOC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { DriverError } from \"@fluidframework/driver-definitions\";\nimport {\n\tNonRetryableError,\n\tGenericNetworkError,\n\tcreateGenericNetworkError,\n\tAuthorizationError,\n} from \"@fluidframework/driver-utils\";\nimport { pkgVersion as driverVersion } from \"./packageVersion\";\n\n/**\n * Routerlicious Error types\n * Different error types that may be thrown by the routerlicious driver\n */\nexport enum RouterliciousErrorType {\n\t/**\n\t * File not found, or file deleted during session\n\t */\n\tfileNotFoundOrAccessDeniedError = \"fileNotFoundOrAccessDeniedError\",\n\n\tsslCertError = \"sslCertError\",\n}\n\n/**\n * Interface for error responses for the WebSocket connection\n * Intended to be compatible with output from {@link NetworkError.toJSON}\n */\nexport interface IR11sSocketError {\n\t/**\n\t * An error code number for the error that occurred.\n\t * It will be a valid HTTP status code.\n\t */\n\tcode: number;\n\n\t/**\n\t * A message about the error that occurred for debugging / logging purposes.\n\t * This should not be displayed to the user directly.\n\t */\n\tmessage: string;\n\n\t/**\n\t * Optional Retry-After time in seconds.\n\t * The client should wait this many seconds before retrying its request.\n\t */\n\tretryAfter?: number;\n\n\t/**\n\t * Optional Retry-After time in milliseconds.\n\t * The client should wait this many milliseconds before retrying its request.\n\t */\n\tretryAfterMs?: number;\n}\n\nexport interface IR11sError {\n\treadonly errorType: RouterliciousErrorType;\n\treadonly message: string;\n\tcanRetry: boolean;\n}\n\nexport type R11sError = DriverError | IR11sError;\n\nexport function createR11sNetworkError(\n\terrorMessage: string,\n\tstatusCode?: number,\n\tretryAfterMs?: number,\n): R11sError {\n\tconst props = { statusCode, driverVersion };\n\tswitch (statusCode) {\n\t\tcase undefined:\n\t\t\t// If a service is temporarily down or a browser resource limit is reached, RestWrapper will throw\n\t\t\t// a network error with no status code (e.g. err:ERR_CONN_REFUSED or err:ERR_FAILED) and\n\t\t\t// the error message will start with NetworkError as defined in restWrapper.ts\n\t\t\t// If there exists a self-signed SSL certificates error, throw a NonRetryableError\n\t\t\t// TODO: instead of relying on string matching, filter error based on the error code like we do for websocket connections\n\t\t\tif (errorMessage.includes(\"failed, reason: self signed certificate\")) {\n\t\t\t\treturn new NonRetryableError(\n\t\t\t\t\terrorMessage,\n\t\t\t\t\tRouterliciousErrorType.sslCertError,\n\t\t\t\t\tprops,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn new GenericNetworkError(\n\t\t\t\terrorMessage,\n\t\t\t\terrorMessage.startsWith(\"NetworkError\"),\n\t\t\t\tprops,\n\t\t\t);\n\t\tcase 401:\n\t\t// The first 401 is manually retried in RouterliciousRestWrapper with a refreshed token,\n\t\t// so we treat repeat 401s the same as 403.\n\t\tcase 403:\n\t\t\treturn new AuthorizationError(errorMessage, undefined, undefined, props);\n\t\tcase 404:\n\t\t\tconst errorType = RouterliciousErrorType.fileNotFoundOrAccessDeniedError;\n\t\t\treturn new NonRetryableError(errorMessage, errorType, props);\n\t\tcase 429:\n\t\t\treturn createGenericNetworkError(errorMessage, { canRetry: true, retryAfterMs }, props);\n\t\tcase 500:\n\t\tcase 502:\n\t\t\treturn new GenericNetworkError(errorMessage, true, props);\n\t\tdefault:\n\t\t\tconst retryInfo = { canRetry: retryAfterMs !== undefined, retryAfterMs };\n\t\t\treturn createGenericNetworkError(errorMessage, retryInfo, props);\n\t}\n}\n\nexport function throwR11sNetworkError(\n\terrorMessage: string,\n\tstatusCode?: number,\n\tretryAfterMs?: number,\n): never {\n\tconst networkError = createR11sNetworkError(errorMessage, statusCode, retryAfterMs);\n\n\t// eslint-disable-next-line @typescript-eslint/no-throw-literal\n\tthrow networkError;\n}\n\n/**\n * Returns network error based on error object from R11s socket (IR11sSocketError)\n */\nexport function errorObjectFromSocketError(\n\tsocketError: IR11sSocketError,\n\thandler: string,\n): R11sError {\n\t// pre-0.58 error message prefix: R11sSocketError\n\tconst message = `R11s socket error (${handler}): ${socketError.message}`;\n\treturn createR11sNetworkError(message, socketError.code, socketError.retryAfterMs);\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@
4
4
  */
5
5
  export { DefaultTokenProvider } from "./defaultTokenProvider";
6
6
  export { ITokenProvider, ITokenResponse, ITokenService } from "./tokens";
7
+ export { RouterliciousErrorType } from "./errorUtils";
7
8
  export { DocumentPostCreateError, RouterliciousDocumentServiceFactory, } from "./documentServiceFactory";
8
9
  export { IRouterliciousDriverPolicies } from "./policies";
9
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzE,OAAO,EACN,uBAAuB,EACvB,mCAAmC,GACnC,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAGtD,OAAO,EACN,uBAAuB,EACvB,mCAAmC,GACnC,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -4,10 +4,13 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.RouterliciousDocumentServiceFactory = exports.DocumentPostCreateError = exports.DefaultTokenProvider = void 0;
7
+ exports.RouterliciousDocumentServiceFactory = exports.DocumentPostCreateError = exports.RouterliciousErrorType = exports.DefaultTokenProvider = void 0;
8
8
  // Tokens
9
9
  var defaultTokenProvider_1 = require("./defaultTokenProvider");
10
10
  Object.defineProperty(exports, "DefaultTokenProvider", { enumerable: true, get: function () { return defaultTokenProvider_1.DefaultTokenProvider; } });
11
+ // Errors
12
+ var errorUtils_1 = require("./errorUtils");
13
+ Object.defineProperty(exports, "RouterliciousErrorType", { enumerable: true, get: function () { return errorUtils_1.RouterliciousErrorType; } });
11
14
  // Factory
12
15
  var documentServiceFactory_1 = require("./documentServiceFactory");
13
16
  Object.defineProperty(exports, "DocumentPostCreateError", { enumerable: true, get: function () { return documentServiceFactory_1.DocumentPostCreateError; } });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,SAAS;AACT,+DAA8D;AAArD,4HAAA,oBAAoB,OAAA;AAG7B,UAAU;AACV,mEAGkC;AAFjC,iIAAA,uBAAuB,OAAA;AACvB,6IAAA,mCAAmC,OAAA","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n// Tokens\nexport { DefaultTokenProvider } from \"./defaultTokenProvider\";\nexport { ITokenProvider, ITokenResponse, ITokenService } from \"./tokens\";\n\n// Factory\nexport {\n\tDocumentPostCreateError,\n\tRouterliciousDocumentServiceFactory,\n} from \"./documentServiceFactory\";\n\n// Configuration\nexport { IRouterliciousDriverPolicies } from \"./policies\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,SAAS;AACT,+DAA8D;AAArD,4HAAA,oBAAoB,OAAA;AAG7B,SAAS;AACT,2CAAsD;AAA7C,oHAAA,sBAAsB,OAAA;AAE/B,UAAU;AACV,mEAGkC;AAFjC,iIAAA,uBAAuB,OAAA;AACvB,6IAAA,mCAAmC,OAAA","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n// Tokens\nexport { DefaultTokenProvider } from \"./defaultTokenProvider\";\nexport { ITokenProvider, ITokenResponse, ITokenService } from \"./tokens\";\n\n// Errors\nexport { RouterliciousErrorType } from \"./errorUtils\";\n\n// Factory\nexport {\n\tDocumentPostCreateError,\n\tRouterliciousDocumentServiceFactory,\n} from \"./documentServiceFactory\";\n\n// Configuration\nexport { IRouterliciousDriverPolicies } from \"./policies\";\n"]}
@@ -0,0 +1,34 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ /**
6
+ * An extension of Map that expires (deletes) entries after a period of inactivity.
7
+ * The policy is based on the last time a key was written to.
8
+ */
9
+ export declare class MapWithExpiration<TKey = any, TValue = any> extends Map<TKey, TValue> {
10
+ private readonly expiryMs;
11
+ /** Timestamps (as epoch ms numbers) of when each key was last refreshed */
12
+ private readonly lastRefreshedTimes;
13
+ constructor(expiryMs: number);
14
+ private refresh;
15
+ /**
16
+ * Returns true if the key is present and expired, false if it's not expired, and undefined if it's not found
17
+ * If cleanUp is passed as true, then delete any expired entry before returning.
18
+ */
19
+ private checkExpiry;
20
+ private clearExpiredEntries;
21
+ get size(): number;
22
+ has(key: TKey): boolean;
23
+ get(key: TKey): TValue | undefined;
24
+ set(key: TKey, value: TValue): this;
25
+ delete(key: TKey): boolean;
26
+ clear(): void;
27
+ forEach(callbackfn: (value: TValue, key: TKey, map: Map<TKey, TValue>) => void, thisArg?: any): void;
28
+ entries(): IterableIterator<[TKey, TValue]>;
29
+ keys(): IterableIterator<TKey>;
30
+ values(): IterableIterator<TValue>;
31
+ [Symbol.iterator](): IterableIterator<[TKey, TValue]>;
32
+ valueOf(): Object;
33
+ }
34
+ //# sourceMappingURL=mapWithExpiration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapWithExpiration.d.ts","sourceRoot":"","sources":["../src/mapWithExpiration.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;GAGG;AACH,qBAAa,iBAAiB,CAAC,IAAI,GAAG,GAAG,EAAE,MAAM,GAAG,GAAG,CAAE,SAAQ,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC;IAIrE,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAHrC,2EAA2E;IAC3E,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA2B;gBAEjC,QAAQ,EAAE,MAAM;IAI7C,OAAO,CAAC,OAAO;IAIf;;;OAGG;IACH,OAAO,CAAC,WAAW;IAiBnB,OAAO,CAAC,mBAAmB;IAK3B,IAAI,IAAI,IAAI,MAAM,CAGjB;IAED,GAAG,CAAC,GAAG,EAAE,IAAI,GAAG,OAAO;IAKvB,GAAG,CAAC,GAAG,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS;IAKlC,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAMnC,MAAM,CAAC,GAAG,EAAE,IAAI,GAAG,OAAO;IAK1B,KAAK,IAAI,IAAI;IAKb,OAAO,CACN,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,IAAI,EACtE,OAAO,CAAC,EAAE,GAAG,GACX,IAAI;IAmBP,OAAO,IAAI,gBAAgB,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAI3C,IAAI,IAAI,gBAAgB,CAAC,IAAI,CAAC;IAI9B,MAAM,IAAI,gBAAgB,CAAC,MAAM,CAAC;IAIlC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,gBAAgB,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAKrD,OAAO;CAIP"}
@@ -0,0 +1,105 @@
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.MapWithExpiration = void 0;
8
+ const common_utils_1 = require("@fluidframework/common-utils");
9
+ /**
10
+ * An extension of Map that expires (deletes) entries after a period of inactivity.
11
+ * The policy is based on the last time a key was written to.
12
+ */
13
+ class MapWithExpiration extends Map {
14
+ constructor(expiryMs) {
15
+ super();
16
+ this.expiryMs = expiryMs;
17
+ /** Timestamps (as epoch ms numbers) of when each key was last refreshed */
18
+ this.lastRefreshedTimes = new Map();
19
+ }
20
+ refresh(key) {
21
+ this.lastRefreshedTimes.set(key, new Date().valueOf());
22
+ }
23
+ /**
24
+ * Returns true if the key is present and expired, false if it's not expired, and undefined if it's not found
25
+ * If cleanUp is passed as true, then delete any expired entry before returning.
26
+ */
27
+ checkExpiry(key, cleanUp = false) {
28
+ const refreshTime = this.lastRefreshedTimes.get(key);
29
+ (0, common_utils_1.assert)((refreshTime !== undefined) === super.has(key), 0x50c /* freshness map out of sync */);
30
+ if (refreshTime === undefined) {
31
+ return undefined;
32
+ }
33
+ const expired = new Date().valueOf() - refreshTime >= this.expiryMs;
34
+ if (expired && cleanUp) {
35
+ this.delete(key);
36
+ }
37
+ return expired;
38
+ }
39
+ clearExpiredEntries() {
40
+ // forEach clears out any expired entries
41
+ this.forEach(() => { });
42
+ }
43
+ get size() {
44
+ this.clearExpiredEntries();
45
+ return super.size;
46
+ }
47
+ has(key) {
48
+ this.checkExpiry(key, true /* cleanUp */);
49
+ return super.has(key);
50
+ }
51
+ get(key) {
52
+ this.checkExpiry(key, true /* cleanUp */);
53
+ return super.get(key);
54
+ }
55
+ set(key, value) {
56
+ // Sliding window expiration policy (on write)
57
+ this.refresh(key);
58
+ return super.set(key, value);
59
+ }
60
+ delete(key) {
61
+ this.lastRefreshedTimes.delete(key);
62
+ return super.delete(key);
63
+ }
64
+ clear() {
65
+ this.lastRefreshedTimes.clear();
66
+ super.clear();
67
+ }
68
+ forEach(callbackfn, thisArg) {
69
+ const expiredKeys = [];
70
+ super.forEach((v, k, m) => {
71
+ if (this.checkExpiry(k) === true) {
72
+ expiredKeys.push(k);
73
+ }
74
+ else {
75
+ callbackfn.bind(thisArg)(v, k, m);
76
+ }
77
+ });
78
+ // Clean up keys we know are expired now that we're done iterating
79
+ expiredKeys.forEach((key) => {
80
+ this.delete(key);
81
+ });
82
+ }
83
+ entries() {
84
+ this.clearExpiredEntries();
85
+ return super.entries();
86
+ }
87
+ keys() {
88
+ this.clearExpiredEntries();
89
+ return super.keys();
90
+ }
91
+ values() {
92
+ this.clearExpiredEntries();
93
+ return super.values();
94
+ }
95
+ [Symbol.iterator]() {
96
+ this.clearExpiredEntries();
97
+ return super[Symbol.iterator]();
98
+ }
99
+ valueOf() {
100
+ this.clearExpiredEntries();
101
+ return super.valueOf();
102
+ }
103
+ }
104
+ exports.MapWithExpiration = MapWithExpiration;
105
+ //# sourceMappingURL=mapWithExpiration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapWithExpiration.js","sourceRoot":"","sources":["../src/mapWithExpiration.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/common-utils\";\n\n/**\n * An extension of Map that expires (deletes) entries after a period of inactivity.\n * The policy is based on the last time a key was written to.\n */\nexport class MapWithExpiration<TKey = any, TValue = any> extends Map<TKey, TValue> {\n\t/** Timestamps (as epoch ms numbers) of when each key was last refreshed */\n\tprivate readonly lastRefreshedTimes = new Map<TKey, number>();\n\n\tconstructor(private readonly expiryMs: number) {\n\t\tsuper();\n\t}\n\n\tprivate refresh(key: TKey): void {\n\t\tthis.lastRefreshedTimes.set(key, new Date().valueOf());\n\t}\n\n\t/**\n\t * Returns true if the key is present and expired, false if it's not expired, and undefined if it's not found\n\t * If cleanUp is passed as true, then delete any expired entry before returning.\n\t */\n\tprivate checkExpiry(key: TKey, cleanUp: boolean = false): boolean | undefined {\n\t\tconst refreshTime = this.lastRefreshedTimes.get(key);\n\t\tassert(\n\t\t\t(refreshTime !== undefined) === super.has(key),\n\t\t\t0x50c /* freshness map out of sync */,\n\t\t);\n\n\t\tif (refreshTime === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst expired = new Date().valueOf() - refreshTime >= this.expiryMs;\n\t\tif (expired && cleanUp) {\n\t\t\tthis.delete(key);\n\t\t}\n\t\treturn expired;\n\t}\n\n\tprivate clearExpiredEntries() {\n\t\t// forEach clears out any expired entries\n\t\tthis.forEach(() => {});\n\t}\n\n\tget size(): number {\n\t\tthis.clearExpiredEntries();\n\t\treturn super.size;\n\t}\n\n\thas(key: TKey): boolean {\n\t\tthis.checkExpiry(key, true /* cleanUp */);\n\t\treturn super.has(key);\n\t}\n\n\tget(key: TKey): TValue | undefined {\n\t\tthis.checkExpiry(key, true /* cleanUp */);\n\t\treturn super.get(key);\n\t}\n\n\tset(key: TKey, value: TValue): this {\n\t\t// Sliding window expiration policy (on write)\n\t\tthis.refresh(key);\n\t\treturn super.set(key, value);\n\t}\n\n\tdelete(key: TKey): boolean {\n\t\tthis.lastRefreshedTimes.delete(key);\n\t\treturn super.delete(key);\n\t}\n\n\tclear(): void {\n\t\tthis.lastRefreshedTimes.clear();\n\t\tsuper.clear();\n\t}\n\n\tforEach(\n\t\tcallbackfn: (value: TValue, key: TKey, map: Map<TKey, TValue>) => void,\n\t\tthisArg?: any,\n\t): void {\n\t\tconst expiredKeys: TKey[] = [];\n\t\tsuper.forEach(\n\t\t\t(v, k, m) => {\n\t\t\t\tif (this.checkExpiry(k) === true) {\n\t\t\t\t\texpiredKeys.push(k);\n\t\t\t\t} else {\n\t\t\t\t\tcallbackfn.bind(thisArg)(v, k, m);\n\t\t\t\t}\n\t\t\t},\n\t\t\t// Note we don't pass thisArg here, since we bind it directly to callbackFn and don't need it otherwise\n\t\t);\n\n\t\t// Clean up keys we know are expired now that we're done iterating\n\t\texpiredKeys.forEach((key: TKey) => {\n\t\t\tthis.delete(key);\n\t\t});\n\t}\n\n\tentries(): IterableIterator<[TKey, TValue]> {\n\t\tthis.clearExpiredEntries();\n\t\treturn super.entries();\n\t}\n\tkeys(): IterableIterator<TKey> {\n\t\tthis.clearExpiredEntries();\n\t\treturn super.keys();\n\t}\n\tvalues(): IterableIterator<TValue> {\n\t\tthis.clearExpiredEntries();\n\t\treturn super.values();\n\t}\n\t[Symbol.iterator](): IterableIterator<[TKey, TValue]> {\n\t\tthis.clearExpiredEntries();\n\t\treturn super[Symbol.iterator]();\n\t}\n\n\tvalueOf() {\n\t\tthis.clearExpiredEntries();\n\t\treturn super.valueOf();\n\t}\n}\n"]}