@fluidframework/routerlicious-driver 0.59.2000-61729 → 0.59.2000-63294

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/dist/documentDeltaConnection.js +1 -1
  2. package/dist/documentDeltaConnection.js.map +1 -1
  3. package/dist/documentService.d.ts.map +1 -1
  4. package/dist/documentService.js +3 -1
  5. package/dist/documentService.js.map +1 -1
  6. package/dist/documentServiceFactory.d.ts +1 -1
  7. package/dist/documentServiceFactory.d.ts.map +1 -1
  8. package/dist/documentServiceFactory.js +33 -12
  9. package/dist/documentServiceFactory.js.map +1 -1
  10. package/dist/documentStorageService.d.ts +2 -1
  11. package/dist/documentStorageService.d.ts.map +1 -1
  12. package/dist/documentStorageService.js +5 -4
  13. package/dist/documentStorageService.js.map +1 -1
  14. package/dist/errorUtils.d.ts +6 -0
  15. package/dist/errorUtils.d.ts.map +1 -1
  16. package/dist/errorUtils.js +2 -0
  17. package/dist/errorUtils.js.map +1 -1
  18. package/dist/packageVersion.d.ts +1 -1
  19. package/dist/packageVersion.js +1 -1
  20. package/dist/packageVersion.js.map +1 -1
  21. package/dist/policies.d.ts +5 -0
  22. package/dist/policies.d.ts.map +1 -1
  23. package/dist/policies.js.map +1 -1
  24. package/dist/urlUtils.d.ts +3 -0
  25. package/dist/urlUtils.d.ts.map +1 -1
  26. package/dist/urlUtils.js +28 -1
  27. package/dist/urlUtils.js.map +1 -1
  28. package/dist/wholeSummaryDocumentStorageService.d.ts +4 -1
  29. package/dist/wholeSummaryDocumentStorageService.d.ts.map +1 -1
  30. package/dist/wholeSummaryDocumentStorageService.js +11 -4
  31. package/dist/wholeSummaryDocumentStorageService.js.map +1 -1
  32. package/lib/documentDeltaConnection.js +1 -1
  33. package/lib/documentDeltaConnection.js.map +1 -1
  34. package/lib/documentService.d.ts.map +1 -1
  35. package/lib/documentService.js +3 -1
  36. package/lib/documentService.js.map +1 -1
  37. package/lib/documentServiceFactory.d.ts +1 -1
  38. package/lib/documentServiceFactory.d.ts.map +1 -1
  39. package/lib/documentServiceFactory.js +34 -13
  40. package/lib/documentServiceFactory.js.map +1 -1
  41. package/lib/documentStorageService.d.ts +2 -1
  42. package/lib/documentStorageService.d.ts.map +1 -1
  43. package/lib/documentStorageService.js +5 -4
  44. package/lib/documentStorageService.js.map +1 -1
  45. package/lib/errorUtils.d.ts +6 -0
  46. package/lib/errorUtils.d.ts.map +1 -1
  47. package/lib/errorUtils.js +2 -0
  48. package/lib/errorUtils.js.map +1 -1
  49. package/lib/packageVersion.d.ts +1 -1
  50. package/lib/packageVersion.js +1 -1
  51. package/lib/packageVersion.js.map +1 -1
  52. package/lib/policies.d.ts +5 -0
  53. package/lib/policies.d.ts.map +1 -1
  54. package/lib/policies.js.map +1 -1
  55. package/lib/urlUtils.d.ts +3 -0
  56. package/lib/urlUtils.d.ts.map +1 -1
  57. package/lib/urlUtils.js +26 -0
  58. package/lib/urlUtils.js.map +1 -1
  59. package/lib/wholeSummaryDocumentStorageService.d.ts +4 -1
  60. package/lib/wholeSummaryDocumentStorageService.d.ts.map +1 -1
  61. package/lib/wholeSummaryDocumentStorageService.js +11 -4
  62. package/lib/wholeSummaryDocumentStorageService.js.map +1 -1
  63. package/package.json +21 -17
  64. package/src/documentDeltaConnection.ts +1 -1
  65. package/src/documentService.ts +9 -2
  66. package/src/documentServiceFactory.ts +50 -19
  67. package/src/documentStorageService.ts +7 -2
  68. package/src/errorUtils.ts +9 -0
  69. package/src/packageVersion.ts +1 -1
  70. package/src/policies.ts +5 -0
  71. package/src/urlUtils.ts +31 -0
  72. package/src/wholeSummaryDocumentStorageService.ts +13 -6
@@ -1 +1 @@
1
- {"version":3,"file":"errorUtils.js","sourceRoot":"","sources":["../src/errorUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACH,iBAAiB,EACjB,mBAAmB,EACnB,yBAAyB,EACzB,kBAAkB,GACrB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,UAAU,IAAI,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE/D,MAAM,CAAN,IAAY,aAEX;AAFD,WAAY,aAAa;IACrB,oFAAmE,CAAA;AACvE,CAAC,EAFW,aAAa,KAAb,aAAa,QAExB;AAiCD,MAAM,UAAU,sBAAsB,CAClC,YAAoB,EACpB,UAAmB,EACnB,YAAqB;IAErB,MAAM,KAAK,GAAG,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5C,QAAQ,UAAU,EAAE;QAChB,KAAK,SAAS;YACV,kGAAkG;YAClG,wFAAwF;YACxF,8EAA8E;YAC9E,OAAO,IAAI,mBAAmB,CAC1B,YAAY,EAAE,YAAY,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,CAAC,CAAC;QACtE,KAAK,GAAG,CAAC;QACT,KAAK,GAAG;YACJ,OAAO,IAAI,kBAAkB,CACzB,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QACnD,KAAK,GAAG;YACJ,MAAM,SAAS,GAAG,aAAa,CAAC,+BAA+B,CAAC;YAChE,OAAO,IAAI,iBAAiB,CAAC,YAAY,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QACjE,KAAK,GAAG;YACJ,OAAO,yBAAyB,CAC5B,YAAY,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,KAAK,CAAC,CAAC;QAC/D,KAAK,GAAG,CAAC;QACT,KAAK,GAAG;YACJ,OAAO,IAAI,mBAAmB,CAAC,YAAY,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAC9D;YACI,MAAM,SAAS,GAAG,EAAE,QAAQ,EAAE,YAAY,KAAK,SAAS,EAAE,YAAY,EAAE,CAAC;YACzE,OAAO,yBAAyB,CAAC,YAAY,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;KACxE;AACL,CAAC;AAED,MAAM,UAAU,qBAAqB,CACjC,YAAoB,EACpB,UAAmB,EACnB,YAAqB;IAErB,MAAM,YAAY,GAAG,sBAAsB,CACvC,YAAY,EACZ,UAAU,EACV,YAAY,CAAC,CAAC;IAElB,+DAA+D;IAC/D,MAAM,YAAY,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,0BAA0B,CAAC,WAA6B,EAAE,OAAe;IACrF,iDAAiD;IACjD,MAAM,OAAO,GAAG,sBAAsB,OAAO,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC;IACzE,OAAO,sBAAsB,CACzB,OAAO,EACP,WAAW,CAAC,IAAI,EAChB,WAAW,CAAC,YAAY,CAC3B,CAAC;AACN,CAAC","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 NonRetryableError,\n GenericNetworkError,\n createGenericNetworkError,\n AuthorizationError,\n} from \"@fluidframework/driver-utils\";\nimport { pkgVersion as driverVersion } from \"./packageVersion\";\n\nexport enum R11sErrorType {\n fileNotFoundOrAccessDeniedError = \"fileNotFoundOrAccessDeniedError\",\n}\n\n/**\n * Interface for error responses for the WebSocket connection\n */\nexport interface IR11sSocketError {\n /**\n * An error code number for the error that occurred.\n * It will be a valid HTTP status code.\n */\n code: number;\n\n /**\n * A message about the error that occurred for debugging / logging purposes.\n * This should not be displayed to the user directly.\n */\n message: string;\n\n /**\n * Optional Retry-After time in seconds.\n * The client should wait this many seconds before retrying its request.\n */\n retryAfterMs?: number;\n}\n\nexport interface IR11sError {\n readonly errorType: R11sErrorType;\n readonly message: string;\n canRetry: boolean;\n}\n\nexport type R11sError = DriverError | IR11sError;\n\nexport function createR11sNetworkError(\n errorMessage: string,\n statusCode?: number,\n retryAfterMs?: number,\n): R11sError {\n const props = { statusCode, driverVersion };\n switch (statusCode) {\n case undefined:\n // If a service is temporarily down or a browser resource limit is reached, RestWrapper will throw\n // a network error with no status code (e.g. err:ERR_CONN_REFUSED or err:ERR_FAILED) and\n // the error message will start with NetworkError as defined in restWrapper.ts\n return new GenericNetworkError(\n errorMessage, errorMessage.startsWith(\"NetworkError\"), props);\n case 401:\n case 403:\n return new AuthorizationError(\n errorMessage, undefined, undefined, props);\n case 404:\n const errorType = R11sErrorType.fileNotFoundOrAccessDeniedError;\n return new NonRetryableError(errorMessage, errorType, props);\n case 429:\n return createGenericNetworkError(\n errorMessage, { canRetry: true, retryAfterMs }, props);\n case 500:\n case 502:\n return new GenericNetworkError(errorMessage, true, props);\n default:\n const retryInfo = { canRetry: retryAfterMs !== undefined, retryAfterMs };\n return createGenericNetworkError(errorMessage, retryInfo, props);\n }\n}\n\nexport function throwR11sNetworkError(\n errorMessage: string,\n statusCode?: number,\n retryAfterMs?: number,\n): never {\n const networkError = createR11sNetworkError(\n errorMessage,\n statusCode,\n retryAfterMs);\n\n // eslint-disable-next-line @typescript-eslint/no-throw-literal\n throw networkError;\n}\n\n/**\n * Returns network error based on error object from R11s socket (IR11sSocketError)\n */\nexport function errorObjectFromSocketError(socketError: IR11sSocketError, handler: string): R11sError {\n // pre-0.58 error message prefix: R11sSocketError\n const message = `R11s socket error (${handler}): ${socketError.message}`;\n return createR11sNetworkError(\n message,\n socketError.code,\n socketError.retryAfterMs,\n );\n}\n"]}
1
+ {"version":3,"file":"errorUtils.js","sourceRoot":"","sources":["../src/errorUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACH,iBAAiB,EACjB,mBAAmB,EACnB,yBAAyB,EACzB,kBAAkB,GACrB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,UAAU,IAAI,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE/D,MAAM,CAAN,IAAY,aAEX;AAFD,WAAY,aAAa;IACrB,oFAAmE,CAAA;AACvE,CAAC,EAFW,aAAa,KAAb,aAAa,QAExB;AAwCD,MAAM,UAAU,sBAAsB,CAClC,YAAoB,EACpB,UAAmB,EACnB,YAAqB;IAErB,MAAM,KAAK,GAAG,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5C,QAAQ,UAAU,EAAE;QAChB,KAAK,SAAS;YACV,kGAAkG;YAClG,wFAAwF;YACxF,8EAA8E;YAC9E,OAAO,IAAI,mBAAmB,CAC1B,YAAY,EAAE,YAAY,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,CAAC,CAAC;QACtE,KAAK,GAAG,CAAC;QACL,wFAAwF;QACxF,2CAA2C;QAC/C,KAAK,GAAG;YACJ,OAAO,IAAI,kBAAkB,CACzB,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QACnD,KAAK,GAAG;YACJ,MAAM,SAAS,GAAG,aAAa,CAAC,+BAA+B,CAAC;YAChE,OAAO,IAAI,iBAAiB,CAAC,YAAY,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QACjE,KAAK,GAAG;YACJ,OAAO,yBAAyB,CAC5B,YAAY,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,KAAK,CAAC,CAAC;QAC/D,KAAK,GAAG,CAAC;QACT,KAAK,GAAG;YACJ,OAAO,IAAI,mBAAmB,CAAC,YAAY,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAC9D;YACI,MAAM,SAAS,GAAG,EAAE,QAAQ,EAAE,YAAY,KAAK,SAAS,EAAE,YAAY,EAAE,CAAC;YACzE,OAAO,yBAAyB,CAAC,YAAY,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;KACxE;AACL,CAAC;AAED,MAAM,UAAU,qBAAqB,CACjC,YAAoB,EACpB,UAAmB,EACnB,YAAqB;IAErB,MAAM,YAAY,GAAG,sBAAsB,CACvC,YAAY,EACZ,UAAU,EACV,YAAY,CAAC,CAAC;IAElB,+DAA+D;IAC/D,MAAM,YAAY,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,0BAA0B,CAAC,WAA6B,EAAE,OAAe;IACrF,iDAAiD;IACjD,MAAM,OAAO,GAAG,sBAAsB,OAAO,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC;IACzE,OAAO,sBAAsB,CACzB,OAAO,EACP,WAAW,CAAC,IAAI,EAChB,WAAW,CAAC,YAAY,CAC3B,CAAC;AACN,CAAC","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 NonRetryableError,\n GenericNetworkError,\n createGenericNetworkError,\n AuthorizationError,\n} from \"@fluidframework/driver-utils\";\nimport { pkgVersion as driverVersion } from \"./packageVersion\";\n\nexport enum R11sErrorType {\n fileNotFoundOrAccessDeniedError = \"fileNotFoundOrAccessDeniedError\",\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 /**\n * An error code number for the error that occurred.\n * It will be a valid HTTP status code.\n */\n code: number;\n\n /**\n * A message about the error that occurred for debugging / logging purposes.\n * This should not be displayed to the user directly.\n */\n message: string;\n\n /**\n * Optional Retry-After time in seconds.\n * The client should wait this many seconds before retrying its request.\n */\n retryAfter?: number;\n\n /**\n * Optional Retry-After time in milliseconds.\n * The client should wait this many milliseconds before retrying its request.\n */\n retryAfterMs?: number;\n}\n\nexport interface IR11sError {\n readonly errorType: R11sErrorType;\n readonly message: string;\n canRetry: boolean;\n}\n\nexport type R11sError = DriverError | IR11sError;\n\nexport function createR11sNetworkError(\n errorMessage: string,\n statusCode?: number,\n retryAfterMs?: number,\n): R11sError {\n const props = { statusCode, driverVersion };\n switch (statusCode) {\n case undefined:\n // If a service is temporarily down or a browser resource limit is reached, RestWrapper will throw\n // a network error with no status code (e.g. err:ERR_CONN_REFUSED or err:ERR_FAILED) and\n // the error message will start with NetworkError as defined in restWrapper.ts\n return new GenericNetworkError(\n errorMessage, errorMessage.startsWith(\"NetworkError\"), props);\n case 401:\n // The first 401 is manually retried in RouterliciousRestWrapper with a refreshed token,\n // so we treat repeat 401s the same as 403.\n case 403:\n return new AuthorizationError(\n errorMessage, undefined, undefined, props);\n case 404:\n const errorType = R11sErrorType.fileNotFoundOrAccessDeniedError;\n return new NonRetryableError(errorMessage, errorType, props);\n case 429:\n return createGenericNetworkError(\n errorMessage, { canRetry: true, retryAfterMs }, props);\n case 500:\n case 502:\n return new GenericNetworkError(errorMessage, true, props);\n default:\n const retryInfo = { canRetry: retryAfterMs !== undefined, retryAfterMs };\n return createGenericNetworkError(errorMessage, retryInfo, props);\n }\n}\n\nexport function throwR11sNetworkError(\n errorMessage: string,\n statusCode?: number,\n retryAfterMs?: number,\n): never {\n const networkError = createR11sNetworkError(\n errorMessage,\n statusCode,\n retryAfterMs);\n\n // eslint-disable-next-line @typescript-eslint/no-throw-literal\n throw networkError;\n}\n\n/**\n * Returns network error based on error object from R11s socket (IR11sSocketError)\n */\nexport function errorObjectFromSocketError(socketError: IR11sSocketError, handler: string): R11sError {\n // pre-0.58 error message prefix: R11sSocketError\n const message = `R11s socket error (${handler}): ${socketError.message}`;\n return createR11sNetworkError(\n message,\n socketError.code,\n socketError.retryAfterMs,\n );\n}\n"]}
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export declare const pkgName = "@fluidframework/routerlicious-driver";
8
- export declare const pkgVersion = "0.59.2000-61729";
8
+ export declare const pkgVersion = "0.59.2000-63294";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export const pkgName = "@fluidframework/routerlicious-driver";
8
- export const pkgVersion = "0.59.2000-61729";
8
+ export const pkgVersion = "0.59.2000-63294";
9
9
  //# sourceMappingURL=packageVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,sCAAsC,CAAC;AAC9D,MAAM,CAAC,MAAM,UAAU,GAAG,iBAAiB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/routerlicious-driver\";\nexport const pkgVersion = \"0.59.2000-61729\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,sCAAsC,CAAC;AAC9D,MAAM,CAAC,MAAM,UAAU,GAAG,iBAAiB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/routerlicious-driver\";\nexport const pkgVersion = \"0.59.2000-63294\";\n"]}
package/lib/policies.d.ts CHANGED
@@ -31,6 +31,11 @@ export interface IRouterliciousDriverPolicies {
31
31
  * Default: false
32
32
  */
33
33
  enableWholeSummaryUpload: boolean;
34
+ /**
35
+ * Enable service endpoint discovery when creating or joining a session.
36
+ * Default: false
37
+ */
38
+ enableDiscovery?: boolean;
34
39
  /**
35
40
  * Enable using RestLess which avoids CORS preflight requests.
36
41
  * Default: true
@@ -1 +1 @@
1
- {"version":3,"file":"policies.d.ts","sourceRoot":"","sources":["../src/policies.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,4BAA4B;IACzC;;;OAGG;IACH,cAAc,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,4BAA4B,EAAE,MAAM,CAAC;IACrC;;;OAGG;IACH,4BAA4B,EAAE,MAAM,CAAC;IACrC;;;;;;OAMG;IACH,8BAA8B,EAAE,MAAM,GAAG,SAAS,CAAC;IACnD;;;OAGG;IACH,wBAAwB,EAAE,OAAO,CAAC;IAClC;;;OAGG;IACH,cAAc,EAAE,OAAO,CAAC;CAC3B"}
1
+ {"version":3,"file":"policies.d.ts","sourceRoot":"","sources":["../src/policies.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,4BAA4B;IACzC;;;OAGG;IACH,cAAc,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,4BAA4B,EAAE,MAAM,CAAC;IACrC;;;OAGG;IACH,4BAA4B,EAAE,MAAM,CAAC;IACrC;;;;;;OAMG;IACH,8BAA8B,EAAE,MAAM,GAAG,SAAS,CAAC;IACnD;;;OAGG;IACH,wBAAwB,EAAE,OAAO,CAAC;IAClC;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,cAAc,EAAE,OAAO,CAAC;CAC3B"}
@@ -1 +1 @@
1
- {"version":3,"file":"policies.js","sourceRoot":"","sources":["../src/policies.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport interface IRouterliciousDriverPolicies {\n /**\n * Enable prefetching entire snapshot tree into memory before it is loaded by the runtime.\n * Default: true\n */\n enablePrefetch: boolean;\n /**\n * Rate limit concurrent storage requests.\n * Default: 100\n */\n maxConcurrentStorageRequests: number;\n /**\n * Rate limit concurrent orderer requests.\n * Default: 100\n */\n maxConcurrentOrdererRequests: number;\n /**\n * Give hosts the option to change blob aggregation behavior to suit their needs.\n * Larger number means fewer blob individual requests, but less blob-deduping.\n * Smaller number means more blob individual requests, but more blob-deduping.\n * Setting to `undefined` disables blob aggregration.\n * Default: undefined\n */\n aggregateBlobsSmallerThanBytes: number | undefined;\n /**\n * Enable uploading entire summary tree as a IWholeSummaryPayload to storage.\n * Default: false\n */\n enableWholeSummaryUpload: boolean;\n /**\n * Enable using RestLess which avoids CORS preflight requests.\n * Default: true\n */\n enableRestLess: boolean;\n}\n"]}
1
+ {"version":3,"file":"policies.js","sourceRoot":"","sources":["../src/policies.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport interface IRouterliciousDriverPolicies {\n /**\n * Enable prefetching entire snapshot tree into memory before it is loaded by the runtime.\n * Default: true\n */\n enablePrefetch: boolean;\n /**\n * Rate limit concurrent storage requests.\n * Default: 100\n */\n maxConcurrentStorageRequests: number;\n /**\n * Rate limit concurrent orderer requests.\n * Default: 100\n */\n maxConcurrentOrdererRequests: number;\n /**\n * Give hosts the option to change blob aggregation behavior to suit their needs.\n * Larger number means fewer blob individual requests, but less blob-deduping.\n * Smaller number means more blob individual requests, but more blob-deduping.\n * Setting to `undefined` disables blob aggregration.\n * Default: undefined\n */\n aggregateBlobsSmallerThanBytes: number | undefined;\n /**\n * Enable uploading entire summary tree as a IWholeSummaryPayload to storage.\n * Default: false\n */\n enableWholeSummaryUpload: boolean;\n /**\n * Enable service endpoint discovery when creating or joining a session.\n * Default: false\n */\n enableDiscovery?: boolean;\n /**\n * Enable using RestLess which avoids CORS preflight requests.\n * Default: true\n */\n enableRestLess: boolean;\n}\n"]}
package/lib/urlUtils.d.ts CHANGED
@@ -2,7 +2,9 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
+ import { IFluidResolvedUrl } from "@fluidframework/driver-definitions";
5
6
  import URLParse from "url-parse";
7
+ import { ISession } from "@fluidframework/server-services-client";
6
8
  export declare const parseFluidUrl: (fluidUrl: string) => URLParse;
7
9
  /**
8
10
  * Assume documentId is at end of url path.
@@ -11,4 +13,5 @@ export declare const parseFluidUrl: (fluidUrl: string) => URLParse;
11
13
  * TODO: Ideally we would be able to regenerate the resolvedUrl, rather than patching the current one.
12
14
  */
13
15
  export declare const replaceDocumentIdInPath: (urlPath: string, documentId: string) => string;
16
+ export declare const getDiscoveredFluidResolvedUrl: (resolvedUrl: IFluidResolvedUrl, session: ISession) => IFluidResolvedUrl;
14
17
  //# sourceMappingURL=urlUtils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"urlUtils.d.ts","sourceRoot":"","sources":["../src/urlUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,QAAQ,MAAM,WAAW,CAAC;AAEjC,eAAO,MAAM,aAAa,aAAc,MAAM,KAAG,QAEhD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,YAAa,MAAM,cAAc,MAAM,KAAG,MACZ,CAAC"}
1
+ {"version":3,"file":"urlUtils.d.ts","sourceRoot":"","sources":["../src/urlUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,QAAQ,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,wCAAwC,CAAC;AAElE,eAAO,MAAM,aAAa,aAAc,MAAM,KAAG,QAEhD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,YAAa,MAAM,cAAc,MAAM,KAAG,MACZ,CAAC;AAEnE,eAAO,MAAM,6BAA6B,gBAAiB,iBAAiB,WAAW,QAAQ,KAAG,iBA2BjG,CAAC"}
package/lib/urlUtils.js CHANGED
@@ -13,4 +13,30 @@ export const parseFluidUrl = (fluidUrl) => {
13
13
  * TODO: Ideally we would be able to regenerate the resolvedUrl, rather than patching the current one.
14
14
  */
15
15
  export const replaceDocumentIdInPath = (urlPath, documentId) => urlPath.split("/").slice(0, -1).concat([documentId]).join("/");
16
+ export const getDiscoveredFluidResolvedUrl = (resolvedUrl, session) => {
17
+ if (session) {
18
+ const discoveredOrdererUrl = new URLParse(session.ordererUrl);
19
+ const deltaStorageUrl = new URLParse(resolvedUrl.endpoints.deltaStorageUrl);
20
+ deltaStorageUrl.set("host", discoveredOrdererUrl.host);
21
+ const discoveredStorageUrl = new URLParse(session.historianUrl);
22
+ const storageUrl = new URLParse(resolvedUrl.endpoints.storageUrl);
23
+ storageUrl.set("host", discoveredStorageUrl.host);
24
+ const parsedUrl = parseFluidUrl(resolvedUrl.url);
25
+ const discoveredResolvedUrl = {
26
+ endpoints: {
27
+ deltaStorageUrl: deltaStorageUrl.toString(),
28
+ ordererUrl: session.ordererUrl,
29
+ storageUrl: storageUrl.toString(),
30
+ },
31
+ id: resolvedUrl.id,
32
+ tokens: resolvedUrl.tokens,
33
+ type: resolvedUrl.type,
34
+ url: new URLParse(`fluid://${discoveredOrdererUrl.host}${parsedUrl.pathname}`).toString(),
35
+ };
36
+ return discoveredResolvedUrl;
37
+ }
38
+ else {
39
+ return resolvedUrl;
40
+ }
41
+ };
16
42
  //# sourceMappingURL=urlUtils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"urlUtils.js","sourceRoot":"","sources":["../src/urlUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,QAAQ,MAAM,WAAW,CAAC;AAEjC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,QAAgB,EAAY,EAAE;IACxD,OAAO,IAAI,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AACxC,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,OAAe,EAAE,UAAkB,EAAU,EAAE,CACnF,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport URLParse from \"url-parse\";\n\nexport const parseFluidUrl = (fluidUrl: string): URLParse => {\n return new URLParse(fluidUrl, true);\n};\n\n/**\n * Assume documentId is at end of url path.\n * This is true for Routerlicious' and Tinylicious' documentUrl and deltaStorageUrl.\n * Routerlicious and Tinylicious do not use documentId in storageUrl nor ordererUrl.\n * TODO: Ideally we would be able to regenerate the resolvedUrl, rather than patching the current one.\n */\nexport const replaceDocumentIdInPath = (urlPath: string, documentId: string): string =>\n urlPath.split(\"/\").slice(0, -1).concat([documentId]).join(\"/\");\n"]}
1
+ {"version":3,"file":"urlUtils.js","sourceRoot":"","sources":["../src/urlUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,QAAQ,MAAM,WAAW,CAAC;AAGjC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,QAAgB,EAAY,EAAE;IACxD,OAAO,IAAI,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AACxC,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,OAAe,EAAE,UAAkB,EAAU,EAAE,CACnF,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEnE,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,WAA8B,EAAE,OAAiB,EAAqB,EAAE;IAClH,IAAI,OAAO,EAAE;QACT,MAAM,oBAAoB,GAAG,IAAI,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC9D,MAAM,eAAe,GAAG,IAAI,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QAC5E,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,IAAI,CAAC,CAAC;QAEvD,MAAM,oBAAoB,GAAG,IAAI,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAChE,MAAM,UAAU,GAAG,IAAI,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAClE,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,IAAI,CAAC,CAAC;QAElD,MAAM,SAAS,GAAG,aAAa,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACjD,MAAM,qBAAqB,GAAsB;YAC7C,SAAS,EAAE;gBACP,eAAe,EAAE,eAAe,CAAC,QAAQ,EAAE;gBAC3C,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,UAAU,EAAE,UAAU,CAAC,QAAQ,EAAE;aACpC;YACD,EAAE,EAAE,WAAW,CAAC,EAAE;YAClB,MAAM,EAAE,WAAW,CAAC,MAAM;YAC1B,IAAI,EAAE,WAAW,CAAC,IAAI;YACtB,GAAG,EAAE,IAAI,QAAQ,CAAC,WAAW,oBAAoB,CAAC,IAAI,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE;SAC5F,CAAC;QAEF,OAAO,qBAAqB,CAAC;KAChC;SAAM;QACH,OAAO,WAAW,CAAC;KACtB;AACL,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IFluidResolvedUrl } from \"@fluidframework/driver-definitions\";\nimport URLParse from \"url-parse\";\nimport { ISession } from \"@fluidframework/server-services-client\";\n\nexport const parseFluidUrl = (fluidUrl: string): URLParse => {\n return new URLParse(fluidUrl, true);\n};\n\n/**\n * Assume documentId is at end of url path.\n * This is true for Routerlicious' and Tinylicious' documentUrl and deltaStorageUrl.\n * Routerlicious and Tinylicious do not use documentId in storageUrl nor ordererUrl.\n * TODO: Ideally we would be able to regenerate the resolvedUrl, rather than patching the current one.\n */\nexport const replaceDocumentIdInPath = (urlPath: string, documentId: string): string =>\n urlPath.split(\"/\").slice(0, -1).concat([documentId]).join(\"/\");\n\nexport const getDiscoveredFluidResolvedUrl = (resolvedUrl: IFluidResolvedUrl, session: ISession): IFluidResolvedUrl => {\n if (session) {\n const discoveredOrdererUrl = new URLParse(session.ordererUrl);\n const deltaStorageUrl = new URLParse(resolvedUrl.endpoints.deltaStorageUrl);\n deltaStorageUrl.set(\"host\", discoveredOrdererUrl.host);\n\n const discoveredStorageUrl = new URLParse(session.historianUrl);\n const storageUrl = new URLParse(resolvedUrl.endpoints.storageUrl);\n storageUrl.set(\"host\", discoveredStorageUrl.host);\n\n const parsedUrl = parseFluidUrl(resolvedUrl.url);\n const discoveredResolvedUrl: IFluidResolvedUrl = {\n endpoints: {\n deltaStorageUrl: deltaStorageUrl.toString(),\n ordererUrl: session.ordererUrl,\n storageUrl: storageUrl.toString(),\n },\n id: resolvedUrl.id,\n tokens: resolvedUrl.tokens,\n type: resolvedUrl.type,\n url: new URLParse(`fluid://${discoveredOrdererUrl.host}${parsedUrl.pathname}`).toString(),\n };\n\n return discoveredResolvedUrl;\n } else {\n return resolvedUrl;\n }\n};\n"]}
@@ -8,17 +8,20 @@ import { ICreateBlobResponse, ISnapshotTree, ISummaryHandle, ISummaryTree, ITree
8
8
  import { GitManager } from "@fluidframework/server-services-client";
9
9
  import { ICache } from "./cache";
10
10
  import { ISnapshotTreeVersion } from "./definitions";
11
+ import { IRouterliciousDriverPolicies } from "./policies";
11
12
  export declare class WholeSummaryDocumentStorageService implements IDocumentStorageService {
12
13
  protected readonly id: string;
13
14
  protected readonly manager: GitManager;
14
15
  protected readonly logger: ITelemetryLogger;
15
16
  readonly policies: IDocumentStorageServicePolicies;
17
+ private readonly driverPolicies?;
16
18
  private readonly blobCache;
17
19
  private readonly snapshotTreeCache;
20
+ protected readonly noCacheGitManager?: GitManager | undefined;
18
21
  private readonly summaryUploadManager;
19
22
  private firstVersionsCall;
20
23
  get repositoryUrl(): string;
21
- constructor(id: string, manager: GitManager, logger: ITelemetryLogger, policies?: IDocumentStorageServicePolicies, blobCache?: ICache<ArrayBufferLike>, snapshotTreeCache?: ICache<ISnapshotTreeVersion>);
24
+ constructor(id: string, manager: GitManager, logger: ITelemetryLogger, policies?: IDocumentStorageServicePolicies, driverPolicies?: IRouterliciousDriverPolicies | undefined, blobCache?: ICache<ArrayBufferLike>, snapshotTreeCache?: ICache<ISnapshotTreeVersion>, noCacheGitManager?: GitManager | undefined);
22
25
  getVersions(versionId: string | null, count: number): Promise<IVersion[]>;
23
26
  getSnapshotTree(version?: IVersion): Promise<ISnapshotTree | null>;
24
27
  readBlob(blobId: string): Promise<ArrayBufferLike>;
@@ -1 +1 @@
1
- {"version":3,"file":"wholeSummaryDocumentStorageService.d.ts","sourceRoot":"","sources":["../src/wholeSummaryDocumentStorageService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAM3E,OAAO,EACH,uBAAuB,EACvB,eAAe,EACf,+BAA+B,EACjC,MAAM,oCAAoC,CAAC;AAC7C,OAAO,EACH,mBAAmB,EACnB,aAAa,EACb,cAAc,EACd,YAAY,EACZ,KAAK,EACL,QAAQ,EACX,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAEH,UAAU,EAGb,MAAM,wCAAwC,CAAC;AAEhD,OAAO,EAAE,MAAM,EAAiB,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAIrD,qBAAa,kCAAmC,YAAW,uBAAuB;IAS1E,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM;IAC7B,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,UAAU;IACtC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB;aAC3B,QAAQ,EAAE,+BAA+B;IACzD,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAbtC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAwB;IAC7D,OAAO,CAAC,iBAAiB,CAAiB;IAE1C,IAAW,aAAa,IAAI,MAAM,CAEjC;gBAGsB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,gBAAgB,EAC3B,QAAQ,GAAE,+BAAoC,EAC7C,SAAS,GAAE,MAAM,CAAC,eAAe,CAAuB,EACxD,iBAAiB,GAAE,MAAM,CAAC,oBAAoB,CAAuB;IAI7E,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAqCzE,eAAe,CAAC,OAAO,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAclE,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IA2BlD,wBAAwB,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IAW1F,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;IAI9D,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAItF,UAAU,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,mBAAmB,CAAC;YAqB9D,yBAAyB;YAiDzB,aAAa;CAO9B"}
1
+ {"version":3,"file":"wholeSummaryDocumentStorageService.d.ts","sourceRoot":"","sources":["../src/wholeSummaryDocumentStorageService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAM3E,OAAO,EACH,uBAAuB,EACvB,eAAe,EACf,+BAA+B,EAClC,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACH,mBAAmB,EACnB,aAAa,EACb,cAAc,EACd,YAAY,EACZ,KAAK,EACL,QAAQ,EACX,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAEH,UAAU,EAGb,MAAM,wCAAwC,CAAC;AAEhD,OAAO,EAAE,MAAM,EAAiB,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAI1D,qBAAa,kCAAmC,YAAW,uBAAuB;IAS1E,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM;IAC7B,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,UAAU;IACtC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB;aAC3B,QAAQ,EAAE,+BAA+B;IACzD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,SAAS,CAAC,QAAQ,CAAC,iBAAiB,CAAC;IAfzC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAwB;IAC7D,OAAO,CAAC,iBAAiB,CAAiB;IAE1C,IAAW,aAAa,IAAI,MAAM,CAEjC;gBAGsB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,gBAAgB,EAC3B,QAAQ,GAAE,+BAAoC,EAC7C,cAAc,CAAC,0CAA8B,EAC7C,SAAS,GAAE,MAAM,CAAC,eAAe,CAAuB,EACxD,iBAAiB,GAAE,MAAM,CAAC,oBAAoB,CAAuB,EACnE,iBAAiB,CAAC,wBAAY;IAIxC,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAuCzE,eAAe,CAAC,OAAO,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAclE,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IA2BlD,wBAAwB,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IAW1F,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;IAI9D,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAItF,UAAU,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,mBAAmB,CAAC;YAqB9D,yBAAyB;YAmDzB,aAAa;CAO9B"}
@@ -8,13 +8,15 @@ import { PerformanceEvent } from "@fluidframework/telemetry-utils";
8
8
  import { InMemoryCache } from "./cache";
9
9
  const latestSnapshotId = "latest";
10
10
  export class WholeSummaryDocumentStorageService {
11
- constructor(id, manager, logger, policies = {}, blobCache = new InMemoryCache(), snapshotTreeCache = new InMemoryCache()) {
11
+ constructor(id, manager, logger, policies = {}, driverPolicies, blobCache = new InMemoryCache(), snapshotTreeCache = new InMemoryCache(), noCacheGitManager) {
12
12
  this.id = id;
13
13
  this.manager = manager;
14
14
  this.logger = logger;
15
15
  this.policies = policies;
16
+ this.driverPolicies = driverPolicies;
16
17
  this.blobCache = blobCache;
17
18
  this.snapshotTreeCache = snapshotTreeCache;
19
+ this.noCacheGitManager = noCacheGitManager;
18
20
  this.firstVersionsCall = true;
19
21
  this.summaryUploadManager = new WholeSummaryUploadManager(manager);
20
22
  }
@@ -22,6 +24,7 @@ export class WholeSummaryDocumentStorageService {
22
24
  return "";
23
25
  }
24
26
  async getVersions(versionId, count) {
27
+ var _a;
25
28
  if (versionId !== this.id && versionId !== null) {
26
29
  // Blobs/Trees in this scenario will never have multiple versions, so return versionId as is
27
30
  return [{
@@ -33,7 +36,9 @@ export class WholeSummaryDocumentStorageService {
33
36
  // Fetch latest summary, cache it, and return its id.
34
37
  if (this.firstVersionsCall && count === 1) {
35
38
  this.firstVersionsCall = false;
36
- const { id: _id, snapshotTree } = await this.fetchAndCacheSnapshotTree(latestSnapshotId);
39
+ const { id: _id, snapshotTree } = !((_a = this.driverPolicies) === null || _a === void 0 ? void 0 : _a.enableDiscovery) ?
40
+ await this.fetchAndCacheSnapshotTree(latestSnapshotId, false) :
41
+ await this.fetchAndCacheSnapshotTree(latestSnapshotId, true);
37
42
  return [{
38
43
  id: _id,
39
44
  treeId: snapshotTree.id,
@@ -107,7 +112,7 @@ export class WholeSummaryDocumentStorageService {
107
112
  return response;
108
113
  });
109
114
  }
110
- async fetchAndCacheSnapshotTree(versionId) {
115
+ async fetchAndCacheSnapshotTree(versionId, disableCache) {
111
116
  const cachedSnapshotTreeVersion = await this.snapshotTreeCache.get(versionId);
112
117
  if (cachedSnapshotTreeVersion !== undefined) {
113
118
  return { id: cachedSnapshotTreeVersion.id, snapshotTree: cachedSnapshotTreeVersion.snapshotTree };
@@ -117,7 +122,9 @@ export class WholeSummaryDocumentStorageService {
117
122
  treeId: versionId,
118
123
  }, async (event) => {
119
124
  var _a;
120
- const response = await this.manager.getSummary(versionId);
125
+ const response = disableCache && this.noCacheGitManager !== undefined ?
126
+ await this.noCacheGitManager.getSummary(versionId) :
127
+ await this.manager.getSummary(versionId);
121
128
  event.end({
122
129
  size: (_a = response.trees[0]) === null || _a === void 0 ? void 0 : _a.entries.length,
123
130
  });
@@ -1 +1 @@
1
- {"version":3,"file":"wholeSummaryDocumentStorageService.js","sourceRoot":"","sources":["../src/wholeSummaryDocumentStorageService.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 type { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport {\n assert,\n stringToBuffer,\n Uint8ArrayToString,\n} from \"@fluidframework/common-utils\";\nimport {\n IDocumentStorageService,\n ISummaryContext,\n IDocumentStorageServicePolicies,\n } from \"@fluidframework/driver-definitions\";\nimport {\n ICreateBlobResponse,\n ISnapshotTree,\n ISummaryHandle,\n ISummaryTree,\n ITree,\n IVersion,\n} from \"@fluidframework/protocol-definitions\";\nimport {\n convertWholeFlatSummaryToSnapshotTreeAndBlobs,\n GitManager,\n ISummaryUploadManager,\n WholeSummaryUploadManager,\n} from \"@fluidframework/server-services-client\";\nimport { PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport { ICache, InMemoryCache } from \"./cache\";\nimport { ISnapshotTreeVersion } from \"./definitions\";\n\nconst latestSnapshotId: string = \"latest\";\n\nexport class WholeSummaryDocumentStorageService implements IDocumentStorageService {\n private readonly summaryUploadManager: ISummaryUploadManager;\n private firstVersionsCall: boolean = true;\n\n public get repositoryUrl(): string {\n return \"\";\n }\n\n constructor(\n protected readonly id: string,\n protected readonly manager: GitManager,\n protected readonly logger: ITelemetryLogger,\n public readonly policies: IDocumentStorageServicePolicies = {},\n private readonly blobCache: ICache<ArrayBufferLike> = new InMemoryCache(),\n private readonly snapshotTreeCache: ICache<ISnapshotTreeVersion> = new InMemoryCache()) {\n this.summaryUploadManager = new WholeSummaryUploadManager(manager);\n }\n\n public async getVersions(versionId: string | null, count: number): Promise<IVersion[]> {\n if (versionId !== this.id && versionId !== null) {\n // Blobs/Trees in this scenario will never have multiple versions, so return versionId as is\n return [{\n id: versionId,\n treeId: undefined!,\n }];\n }\n // If this is the first versions call for the document, we know we will want the latest summary.\n // Fetch latest summary, cache it, and return its id.\n if (this.firstVersionsCall && count === 1) {\n this.firstVersionsCall = false;\n const { id: _id, snapshotTree } = await this.fetchAndCacheSnapshotTree(latestSnapshotId);\n return [{\n id: _id,\n treeId: snapshotTree.id!,\n }];\n }\n\n // Otherwise, get the latest version of the document as normal.\n const id = versionId ? versionId : this.id;\n const commits = await PerformanceEvent.timedExecAsync(\n this.logger,\n {\n eventName: \"getVersions\",\n versionId: id,\n count,\n },\n async () => this.manager.getCommits(id, count),\n );\n return commits.map((commit) => ({\n date: commit.commit.author.date,\n id: commit.sha,\n treeId: commit.commit.tree.sha,\n }));\n }\n\n public async getSnapshotTree(version?: IVersion): Promise<ISnapshotTree | null> {\n let requestVersion = version;\n if (!requestVersion) {\n const versions = await this.getVersions(this.id, 1);\n if (versions.length === 0) {\n return null;\n }\n\n requestVersion = versions[0];\n }\n\n return (await this.fetchAndCacheSnapshotTree(requestVersion.id)).snapshotTree;\n }\n\n public async readBlob(blobId: string): Promise<ArrayBufferLike> {\n const cachedBlob = await this.blobCache.get(blobId);\n if (cachedBlob !== undefined) {\n return cachedBlob;\n }\n\n const blob = await PerformanceEvent.timedExecAsync(\n this.logger,\n {\n eventName: \"readBlob\",\n blobId,\n },\n async (event) => {\n const response = await this.manager.getBlob(blobId);\n event.end({\n size: response.size,\n });\n return response;\n },\n );\n const bufferValue = stringToBuffer(blob.content, blob.encoding);\n\n await this.blobCache.put(blob.sha, bufferValue);\n\n return bufferValue;\n }\n\n public async uploadSummaryWithContext(summary: ISummaryTree, context: ISummaryContext): Promise<string> {\n const summaryHandle = await PerformanceEvent.timedExecAsync(\n this.logger,\n {\n eventName: \"uploadSummaryWithContext\",\n },\n async () => this.summaryUploadManager.writeSummaryTree(summary, context.ackHandle ?? \"\", \"channel\"),\n );\n return summaryHandle;\n }\n\n public async downloadSummary(handle: ISummaryHandle): Promise<ISummaryTree> {\n throw new Error(\"NOT IMPLEMENTED!\");\n }\n\n public async write(tree: ITree, parents: string[], message: string, ref: string): Promise<IVersion> {\n throw new Error(\"NOT IMPLEMENTED!\");\n }\n\n public async createBlob(file: ArrayBufferLike): Promise<ICreateBlobResponse> {\n const uint8ArrayFile = new Uint8Array(file);\n return PerformanceEvent.timedExecAsync(\n this.logger,\n {\n eventName: \"createBlob\",\n size: uint8ArrayFile.length,\n },\n async (event) => {\n const response = await this.manager.createBlob(\n Uint8ArrayToString(\n uint8ArrayFile, \"base64\"),\n \"base64\").then((r) => ({ id: r.sha, url: r.url }));\n event.end({\n blobId: response.id,\n });\n return response;\n },\n );\n }\n\n private async fetchAndCacheSnapshotTree(versionId: string): Promise<ISnapshotTreeVersion> {\n const cachedSnapshotTreeVersion = await this.snapshotTreeCache.get(versionId);\n if (cachedSnapshotTreeVersion !== undefined) {\n return { id: cachedSnapshotTreeVersion.id, snapshotTree: cachedSnapshotTreeVersion.snapshotTree };\n }\n\n const wholeFlatSummary = await PerformanceEvent.timedExecAsync(\n this.logger,\n {\n eventName: \"getWholeFlatSummary\",\n treeId: versionId,\n },\n async (event) => {\n const response = await this.manager.getSummary(versionId);\n event.end({\n size: response.trees[0]?.entries.length,\n });\n return response;\n },\n );\n const normalizedWholeSummary = convertWholeFlatSummaryToSnapshotTreeAndBlobs(wholeFlatSummary);\n const wholeFlatSummaryId: string = wholeFlatSummary.id;\n const snapshotTreeId = normalizedWholeSummary.snapshotTree.id;\n assert(snapshotTreeId !== undefined, 0x275 /* \"Root tree should contain the id\" */);\n const snapshotTreeVersion = { id: wholeFlatSummaryId , snapshotTree: normalizedWholeSummary.snapshotTree };\n\n const cachePs: Promise<any>[] = [\n this.snapshotTreeCache.put(\n snapshotTreeId,\n snapshotTreeVersion,\n ),\n this.initBlobCache(normalizedWholeSummary.blobs),\n ];\n if (snapshotTreeId !== versionId) {\n // versionId could be \"latest\". When summarizer checks cache for \"latest\", we want it to be available.\n // TODO: For in-memory cache, <latest,snapshotTree> will be a shared pointer with <snapshotId,snapshotTree>,\n // However, for something like Redis, this will cache the same value twice. Alternatively, could we simply\n // cache with versionId?\n cachePs.push(this.snapshotTreeCache.put(\n versionId,\n snapshotTreeVersion,\n ));\n }\n\n await Promise.all(cachePs);\n\n return snapshotTreeVersion;\n }\n\n private async initBlobCache(blobs: Map<string, ArrayBuffer>): Promise<void> {\n const blobCachePutPs: Promise<void>[] = [];\n blobs.forEach((value, id) => {\n blobCachePutPs.push(this.blobCache.put(id, value));\n });\n await Promise.all(blobCachePutPs);\n }\n}\n"]}
1
+ {"version":3,"file":"wholeSummaryDocumentStorageService.js","sourceRoot":"","sources":["../src/wholeSummaryDocumentStorageService.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 type { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport {\n assert,\n stringToBuffer,\n Uint8ArrayToString,\n} from \"@fluidframework/common-utils\";\nimport {\n IDocumentStorageService,\n ISummaryContext,\n IDocumentStorageServicePolicies,\n} from \"@fluidframework/driver-definitions\";\nimport {\n ICreateBlobResponse,\n ISnapshotTree,\n ISummaryHandle,\n ISummaryTree,\n ITree,\n IVersion,\n} from \"@fluidframework/protocol-definitions\";\nimport {\n convertWholeFlatSummaryToSnapshotTreeAndBlobs,\n GitManager,\n ISummaryUploadManager,\n WholeSummaryUploadManager,\n} from \"@fluidframework/server-services-client\";\nimport { PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport { ICache, InMemoryCache } from \"./cache\";\nimport { ISnapshotTreeVersion } from \"./definitions\";\nimport { IRouterliciousDriverPolicies } from \"./policies\";\n\nconst latestSnapshotId: string = \"latest\";\n\nexport class WholeSummaryDocumentStorageService implements IDocumentStorageService {\n private readonly summaryUploadManager: ISummaryUploadManager;\n private firstVersionsCall: boolean = true;\n\n public get repositoryUrl(): string {\n return \"\";\n }\n\n constructor(\n protected readonly id: string,\n protected readonly manager: GitManager,\n protected readonly logger: ITelemetryLogger,\n public readonly policies: IDocumentStorageServicePolicies = {},\n private readonly driverPolicies?: IRouterliciousDriverPolicies,\n private readonly blobCache: ICache<ArrayBufferLike> = new InMemoryCache(),\n private readonly snapshotTreeCache: ICache<ISnapshotTreeVersion> = new InMemoryCache(),\n protected readonly noCacheGitManager?: GitManager) {\n this.summaryUploadManager = new WholeSummaryUploadManager(manager);\n }\n\n public async getVersions(versionId: string | null, count: number): Promise<IVersion[]> {\n if (versionId !== this.id && versionId !== null) {\n // Blobs/Trees in this scenario will never have multiple versions, so return versionId as is\n return [{\n id: versionId,\n treeId: undefined!,\n }];\n }\n // If this is the first versions call for the document, we know we will want the latest summary.\n // Fetch latest summary, cache it, and return its id.\n if (this.firstVersionsCall && count === 1) {\n this.firstVersionsCall = false;\n const { id: _id, snapshotTree } = !this.driverPolicies?.enableDiscovery ?\n await this.fetchAndCacheSnapshotTree(latestSnapshotId, false) :\n await this.fetchAndCacheSnapshotTree(latestSnapshotId, true);\n return [{\n id: _id,\n treeId: snapshotTree.id!,\n }];\n }\n\n // Otherwise, get the latest version of the document as normal.\n const id = versionId ? versionId : this.id;\n const commits = await PerformanceEvent.timedExecAsync(\n this.logger,\n {\n eventName: \"getVersions\",\n versionId: id,\n count,\n },\n async () => this.manager.getCommits(id, count),\n );\n return commits.map((commit) => ({\n date: commit.commit.author.date,\n id: commit.sha,\n treeId: commit.commit.tree.sha,\n }));\n }\n\n public async getSnapshotTree(version?: IVersion): Promise<ISnapshotTree | null> {\n let requestVersion = version;\n if (!requestVersion) {\n const versions = await this.getVersions(this.id, 1);\n if (versions.length === 0) {\n return null;\n }\n\n requestVersion = versions[0];\n }\n\n return (await this.fetchAndCacheSnapshotTree(requestVersion.id)).snapshotTree;\n }\n\n public async readBlob(blobId: string): Promise<ArrayBufferLike> {\n const cachedBlob = await this.blobCache.get(blobId);\n if (cachedBlob !== undefined) {\n return cachedBlob;\n }\n\n const blob = await PerformanceEvent.timedExecAsync(\n this.logger,\n {\n eventName: \"readBlob\",\n blobId,\n },\n async (event) => {\n const response = await this.manager.getBlob(blobId);\n event.end({\n size: response.size,\n });\n return response;\n },\n );\n const bufferValue = stringToBuffer(blob.content, blob.encoding);\n\n await this.blobCache.put(blob.sha, bufferValue);\n\n return bufferValue;\n }\n\n public async uploadSummaryWithContext(summary: ISummaryTree, context: ISummaryContext): Promise<string> {\n const summaryHandle = await PerformanceEvent.timedExecAsync(\n this.logger,\n {\n eventName: \"uploadSummaryWithContext\",\n },\n async () => this.summaryUploadManager.writeSummaryTree(summary, context.ackHandle ?? \"\", \"channel\"),\n );\n return summaryHandle;\n }\n\n public async downloadSummary(handle: ISummaryHandle): Promise<ISummaryTree> {\n throw new Error(\"NOT IMPLEMENTED!\");\n }\n\n public async write(tree: ITree, parents: string[], message: string, ref: string): Promise<IVersion> {\n throw new Error(\"NOT IMPLEMENTED!\");\n }\n\n public async createBlob(file: ArrayBufferLike): Promise<ICreateBlobResponse> {\n const uint8ArrayFile = new Uint8Array(file);\n return PerformanceEvent.timedExecAsync(\n this.logger,\n {\n eventName: \"createBlob\",\n size: uint8ArrayFile.length,\n },\n async (event) => {\n const response = await this.manager.createBlob(\n Uint8ArrayToString(\n uint8ArrayFile, \"base64\"),\n \"base64\").then((r) => ({ id: r.sha, url: r.url }));\n event.end({\n blobId: response.id,\n });\n return response;\n },\n );\n }\n\n private async fetchAndCacheSnapshotTree(versionId: string, disableCache?: boolean): Promise<ISnapshotTreeVersion> {\n const cachedSnapshotTreeVersion = await this.snapshotTreeCache.get(versionId);\n if (cachedSnapshotTreeVersion !== undefined) {\n return { id: cachedSnapshotTreeVersion.id, snapshotTree: cachedSnapshotTreeVersion.snapshotTree };\n }\n\n const wholeFlatSummary = await PerformanceEvent.timedExecAsync(\n this.logger,\n {\n eventName: \"getWholeFlatSummary\",\n treeId: versionId,\n },\n async (event) => {\n const response = disableCache && this.noCacheGitManager !== undefined ?\n await this.noCacheGitManager.getSummary(versionId) :\n await this.manager.getSummary(versionId);\n event.end({\n size: response.trees[0]?.entries.length,\n });\n return response;\n },\n );\n const normalizedWholeSummary = convertWholeFlatSummaryToSnapshotTreeAndBlobs(wholeFlatSummary);\n const wholeFlatSummaryId: string = wholeFlatSummary.id;\n const snapshotTreeId = normalizedWholeSummary.snapshotTree.id;\n assert(snapshotTreeId !== undefined, 0x275 /* \"Root tree should contain the id\" */);\n const snapshotTreeVersion = { id: wholeFlatSummaryId, snapshotTree: normalizedWholeSummary.snapshotTree };\n\n const cachePs: Promise<any>[] = [\n this.snapshotTreeCache.put(\n snapshotTreeId,\n snapshotTreeVersion,\n ),\n this.initBlobCache(normalizedWholeSummary.blobs),\n ];\n if (snapshotTreeId !== versionId) {\n // versionId could be \"latest\". When summarizer checks cache for \"latest\", we want it to be available.\n // TODO: For in-memory cache, <latest,snapshotTree> will be a shared pointer with <snapshotId,snapshotTree>,\n // However, for something like Redis, this will cache the same value twice. Alternatively, could we simply\n // cache with versionId?\n cachePs.push(this.snapshotTreeCache.put(\n versionId,\n snapshotTreeVersion,\n ));\n }\n\n await Promise.all(cachePs);\n\n return snapshotTreeVersion;\n }\n\n private async initBlobCache(blobs: Map<string, ArrayBuffer>): Promise<void> {\n const blobCachePutPs: Promise<void>[] = [];\n blobs.forEach((value, id) => {\n blobCachePutPs.push(this.blobCache.put(id, value));\n });\n await Promise.all(blobCachePutPs);\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/routerlicious-driver",
3
- "version": "0.59.2000-61729",
3
+ "version": "0.59.2000-63294",
4
4
  "description": "Socket.IO + Git implementation of Fluid service API",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -16,7 +16,7 @@
16
16
  "types": "dist/index.d.ts",
17
17
  "scripts": {
18
18
  "build": "npm run build:genver && concurrently npm:build:compile npm:lint && npm run build:docs",
19
- "build:commonjs": "npm run tsc && npm run build:test",
19
+ "build:commonjs": "npm run tsc && npm run typetests:gen && npm run build:test",
20
20
  "build:compile": "concurrently npm:build:commonjs npm:build:esnext",
21
21
  "build:docs": "api-extractor run --local --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/doc-models/* ../../../_api-extractor-temp/",
22
22
  "build:esnext": "tsc --project ./tsconfig.esnext.json",
@@ -36,7 +36,8 @@
36
36
  "test:mocha:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:mocha",
37
37
  "tsc": "tsc",
38
38
  "tsfmt": "tsfmt --verify",
39
- "tsfmt:fix": "tsfmt --replace"
39
+ "tsfmt:fix": "tsfmt --replace",
40
+ "typetests:gen": "fluid-type-validator -g -d ."
40
41
  },
41
42
  "nyc": {
42
43
  "all": true,
@@ -61,14 +62,14 @@
61
62
  "dependencies": {
62
63
  "@fluidframework/common-definitions": "^0.20.1",
63
64
  "@fluidframework/common-utils": "^0.32.1",
64
- "@fluidframework/driver-base": "0.59.2000-61729",
65
- "@fluidframework/driver-definitions": "^0.46.1000-0",
66
- "@fluidframework/driver-utils": "0.59.2000-61729",
67
- "@fluidframework/gitresources": "^0.1036.1000-0",
68
- "@fluidframework/protocol-base": "^0.1036.1000-0",
69
- "@fluidframework/protocol-definitions": "^0.1028.1000-0",
70
- "@fluidframework/server-services-client": "^0.1036.1000-0",
71
- "@fluidframework/telemetry-utils": "0.59.2000-61729",
65
+ "@fluidframework/driver-base": "0.59.2000-63294",
66
+ "@fluidframework/driver-definitions": "^0.46.1000",
67
+ "@fluidframework/driver-utils": "0.59.2000-63294",
68
+ "@fluidframework/gitresources": "^0.1036.1000",
69
+ "@fluidframework/protocol-base": "^0.1036.1000",
70
+ "@fluidframework/protocol-definitions": "^0.1028.1000",
71
+ "@fluidframework/server-services-client": "^0.1036.1000",
72
+ "@fluidframework/telemetry-utils": "0.59.2000-63294",
72
73
  "cross-fetch": "^3.1.5",
73
74
  "json-stringify-safe": "5.0.1",
74
75
  "socket.io-client": "^4.4.1",
@@ -77,10 +78,10 @@
77
78
  },
78
79
  "devDependencies": {
79
80
  "@fluidframework/build-common": "^0.23.0",
80
- "@fluidframework/eslint-config-fluid": "^0.28.1000-61189",
81
- "@fluidframework/mocha-test-setup": "0.59.2000-61729",
82
- "@fluidframework/routerlicious-driver-previous": "npm:@fluidframework/routerlicious-driver@^0.58.0",
83
- "@microsoft/api-extractor": "^7.16.1",
81
+ "@fluidframework/eslint-config-fluid": "^0.28.1000",
82
+ "@fluidframework/mocha-test-setup": "0.59.2000-63294",
83
+ "@fluidframework/routerlicious-driver-previous": "npm:@fluidframework/routerlicious-driver@0.59.1000",
84
+ "@microsoft/api-extractor": "^7.22.2",
84
85
  "@rushstack/eslint-config": "^2.5.1",
85
86
  "@types/mocha": "^8.2.2",
86
87
  "@types/nock": "^9.3.0",
@@ -96,8 +97,11 @@
96
97
  "eslint-plugin-editorconfig": "~3.2.0",
97
98
  "eslint-plugin-eslint-comments": "~3.2.0",
98
99
  "eslint-plugin-import": "~2.25.4",
99
- "eslint-plugin-no-null": "~1.0.2",
100
+ "eslint-plugin-jest": "~26.1.3",
101
+ "eslint-plugin-mocha": "~10.0.3",
102
+ "eslint-plugin-promise": "~6.0.0",
100
103
  "eslint-plugin-react": "~7.28.0",
104
+ "eslint-plugin-tsdoc": "~0.2.14",
101
105
  "eslint-plugin-unicorn": "~40.0.0",
102
106
  "mocha": "^8.4.0",
103
107
  "nock": "^10.0.1",
@@ -107,7 +111,7 @@
107
111
  "typescript-formatter": "7.1.0"
108
112
  },
109
113
  "typeValidation": {
110
- "version": "0.59.1000",
114
+ "version": "0.59.2000",
111
115
  "broken": {}
112
116
  }
113
117
  }
@@ -64,7 +64,7 @@ export class R11sDocumentDeltaConnection extends DocumentDeltaConnection
64
64
  */
65
65
  protected createErrorObject(handler: string, error?: any, canRetry = true): IAnyDriverError {
66
66
  // Note: we suspect the incoming error object is either:
67
- // - a socketError: add it to the OdspError object for driver to be able to parse it and reason over it.
67
+ // - a socketError: add it to the R11sError object for driver to be able to parse it and reason over it.
68
68
  // - anything else: let base class handle it
69
69
  if (canRetry && Number.isInteger(error?.code) && typeof error?.message === "string") {
70
70
  return errorObjectFromSocketError(error as IR11sSocketError, handler);
@@ -74,6 +74,12 @@ export class DocumentService implements api.IDocumentService {
74
74
  false,
75
75
  storageRestWrapper);
76
76
  const gitManager = new GitManager(historian);
77
+ const noCacheHistorian = new Historian(
78
+ this.gitUrl,
79
+ true,
80
+ true,
81
+ storageRestWrapper);
82
+ const noCacheGitManager = new GitManager(noCacheHistorian);
77
83
  const documentStorageServicePolicies: api.IDocumentStorageServicePolicies = {
78
84
  caching: this.driverPolicies.enablePrefetch
79
85
  ? api.LoaderCachingPolicy.Prefetch
@@ -88,7 +94,8 @@ export class DocumentService implements api.IDocumentService {
88
94
  documentStorageServicePolicies,
89
95
  this.driverPolicies,
90
96
  this.blobCache,
91
- this.snapshotTreeCache);
97
+ this.snapshotTreeCache,
98
+ noCacheGitManager);
92
99
  return this.documentStorageService;
93
100
  }
94
101
 
@@ -142,7 +149,7 @@ export class DocumentService implements api.IDocumentService {
142
149
  try {
143
150
  const connection = await connect();
144
151
  return connection;
145
- } catch (error) {
152
+ } catch (error: any) {
146
153
  if (error?.statusCode === 401) {
147
154
  // Fetch new token and retry once,
148
155
  // otherwise 401 will be bubbled up as non-retriable AuthorizationError.
@@ -18,12 +18,13 @@ import {
18
18
  RateLimiter,
19
19
  } from "@fluidframework/driver-utils";
20
20
  import { ChildLogger } from "@fluidframework/telemetry-utils";
21
+ import { ISession } from "@fluidframework/server-services-client";
21
22
  import { DocumentService } from "./documentService";
22
23
  import { IRouterliciousDriverPolicies } from "./policies";
23
24
  import { ITokenProvider } from "./tokens";
24
25
  import { RouterliciousOrdererRestWrapper } from "./restWrapper";
25
26
  import { convertSummaryToCreateNewSummary } from "./createNewUtils";
26
- import { parseFluidUrl, replaceDocumentIdInPath } from "./urlUtils";
27
+ import { parseFluidUrl, replaceDocumentIdInPath, getDiscoveredFluidResolvedUrl } from "./urlUtils";
27
28
  import { InMemoryCache } from "./cache";
28
29
  import { pkgVersion as driverVersion } from "./packageVersion";
29
30
  import { ISnapshotTreeVersion } from "./definitions";
@@ -33,6 +34,7 @@ const defaultRouterliciousDriverPolicies: IRouterliciousDriverPolicies = {
33
34
  maxConcurrentStorageRequests: 100,
34
35
  maxConcurrentOrdererRequests: 100,
35
36
  aggregateBlobsSmallerThanBytes: undefined,
37
+ enableDiscovery: false,
36
38
  enableWholeSummaryUpload: false,
37
39
  enableRestLess: true,
38
40
  };
@@ -66,7 +68,7 @@ export class RouterliciousDocumentServiceFactory implements IDocumentServiceFact
66
68
  ensureFluidResolvedUrl(resolvedUrl);
67
69
  assert(!!createNewSummary, 0x204 /* "create empty file not supported" */);
68
70
  assert(!!resolvedUrl.endpoints.ordererUrl, 0x0b2 /* "Missing orderer URL!" */);
69
- const parsedUrl = parseFluidUrl(resolvedUrl.url);
71
+ let parsedUrl = parseFluidUrl(resolvedUrl.url);
70
72
  if (!parsedUrl.pathname) {
71
73
  throw new Error("Parsed url should contain tenant and doc Id!!");
72
74
  }
@@ -92,15 +94,14 @@ export class RouterliciousDocumentServiceFactory implements IDocumentServiceFact
92
94
  resolvedUrl.endpoints.ordererUrl,
93
95
  );
94
96
 
95
- // the backend responds with the actual document ID associated with the new container.
96
-
97
97
  // @TODO: Remove returned "string" type when removing back-compat code
98
- const res = await ordererRestWrapper.post<{ id: string, token?: string } | string>(
98
+ const res = await ordererRestWrapper.post<{ id: string, token?: string, session?: ISession } | string>(
99
99
  `/documents/${tenantId}`,
100
100
  {
101
101
  summary: convertSummaryToCreateNewSummary(appSummary),
102
102
  sequenceNumber: documentAttributes.sequenceNumber,
103
103
  values: quorumValues,
104
+ enableDiscovery: this.driverPolicies.enableDiscovery,
104
105
  generateToken: this.tokenProvider.documentPostCreateCallback !== undefined,
105
106
  },
106
107
  );
@@ -111,13 +112,21 @@ export class RouterliciousDocumentServiceFactory implements IDocumentServiceFact
111
112
 
112
113
  let documentId: string;
113
114
  let token: string | undefined;
114
-
115
+ let session: ISession | undefined;
116
+ let fluidResolvedUrl: IResolvedUrl;
115
117
  if (typeof res === "string") {
116
118
  documentId = res;
117
119
  } else {
118
120
  documentId = res.id;
119
121
  token = res.token;
122
+ session = res.session;
120
123
  }
124
+ if (session && this.driverPolicies.enableDiscovery) {
125
+ fluidResolvedUrl = getDiscoveredFluidResolvedUrl(resolvedUrl, session);
126
+ } else {
127
+ fluidResolvedUrl = resolvedUrl;
128
+ }
129
+ parsedUrl = parseFluidUrl(fluidResolvedUrl.url);
121
130
 
122
131
  // @TODO: Remove token from the condition, checking the documentPostCreateCallback !== undefined
123
132
  // is sufficient to determine if the token will be undefined or not.
@@ -126,7 +135,7 @@ export class RouterliciousDocumentServiceFactory implements IDocumentServiceFact
126
135
  }
127
136
 
128
137
  parsedUrl.set("pathname", replaceDocumentIdInPath(parsedUrl.pathname, documentId));
129
- const deltaStorageUrl = resolvedUrl.endpoints.deltaStorageUrl;
138
+ const deltaStorageUrl = fluidResolvedUrl.endpoints.deltaStorageUrl;
130
139
  if (!deltaStorageUrl) {
131
140
  throw new Error(
132
141
  `All endpoints urls must be provided. [deltaStorageUrl:${deltaStorageUrl}]`);
@@ -136,16 +145,17 @@ export class RouterliciousDocumentServiceFactory implements IDocumentServiceFact
136
145
 
137
146
  return this.createDocumentService(
138
147
  {
139
- ...resolvedUrl,
148
+ ...fluidResolvedUrl,
140
149
  url: parsedUrl.toString(),
141
150
  id: documentId,
142
151
  endpoints: {
143
- ...resolvedUrl.endpoints,
152
+ ...fluidResolvedUrl.endpoints,
144
153
  deltaStorageUrl: parsedDeltaStorageUrl.toString(),
145
154
  },
146
155
  },
147
156
  logger,
148
157
  clientIsSummarizer,
158
+ true,
149
159
  );
150
160
  }
151
161
 
@@ -159,10 +169,40 @@ export class RouterliciousDocumentServiceFactory implements IDocumentServiceFact
159
169
  resolvedUrl: IResolvedUrl,
160
170
  logger?: ITelemetryBaseLogger,
161
171
  clientIsSummarizer?: boolean,
172
+ isCreateContainer?: boolean,
162
173
  ): Promise<IDocumentService> {
163
174
  ensureFluidResolvedUrl(resolvedUrl);
164
175
 
165
- const fluidResolvedUrl = resolvedUrl;
176
+ const parsedUrl = parseFluidUrl(resolvedUrl.url);
177
+ const [, tenantId, documentId] = parsedUrl.pathname.split("/");
178
+ if (!documentId || !tenantId) {
179
+ throw new Error(
180
+ `Couldn't parse documentId and/or tenantId. [documentId:${documentId}][tenantId:${tenantId}]`);
181
+ }
182
+ const logger2 = ChildLogger.create(logger, "RouterliciousDriver", { all: { driverVersion }});
183
+
184
+ let fluidResolvedUrl: IResolvedUrl;
185
+ if (!isCreateContainer && this.driverPolicies.enableDiscovery) {
186
+ const rateLimiter = new RateLimiter(this.driverPolicies.maxConcurrentOrdererRequests);
187
+ const ordererRestWrapper = await RouterliciousOrdererRestWrapper.load(
188
+ tenantId,
189
+ documentId,
190
+ this.tokenProvider,
191
+ logger2,
192
+ rateLimiter,
193
+ this.driverPolicies.enableRestLess,
194
+ resolvedUrl.endpoints.ordererUrl,
195
+ );
196
+
197
+ // the backend responds with the actual document session associated with the container.
198
+ const session: ISession = await ordererRestWrapper.get<ISession>(
199
+ `/documents/${tenantId}/session/${documentId}`,
200
+ );
201
+ fluidResolvedUrl = getDiscoveredFluidResolvedUrl(resolvedUrl, session);
202
+ } else {
203
+ fluidResolvedUrl = resolvedUrl;
204
+ }
205
+
166
206
  const storageUrl = fluidResolvedUrl.endpoints.storageUrl;
167
207
  const ordererUrl = fluidResolvedUrl.endpoints.ordererUrl;
168
208
  const deltaStorageUrl = fluidResolvedUrl.endpoints.deltaStorageUrl;
@@ -171,15 +211,6 @@ export class RouterliciousDocumentServiceFactory implements IDocumentServiceFact
171
211
  `All endpoints urls must be provided. [ordererUrl:${ordererUrl}][deltaStorageUrl:${deltaStorageUrl}]`);
172
212
  }
173
213
 
174
- const parsedUrl = parseFluidUrl(fluidResolvedUrl.url);
175
- const [, tenantId, documentId] = parsedUrl.pathname.split("/");
176
- if (!documentId || !tenantId) {
177
- throw new Error(
178
- `Couldn't parse documentId and/or tenantId. [documentId:${documentId}][tenantId:${tenantId}]`);
179
- }
180
-
181
- const logger2 = ChildLogger.create(logger, "RouterliciousDriver", { all: { driverVersion }});
182
-
183
214
  return new DocumentService(
184
215
  fluidResolvedUrl,
185
216
  ordererUrl,