@fluidframework/local-driver 2.118.1 → 3.0.1

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 (86) hide show
  1. package/CHANGELOG.md +40 -4
  2. package/README.md +54 -51
  3. package/{api-extractor.json → api-extractor/api-extractor-model.json} +1 -1
  4. package/api-report/local-driver.legacy.beta.api.md +1 -0
  5. package/dist/auth.js +2 -3
  6. package/dist/auth.js.map +1 -1
  7. package/dist/ephemeralService.js +15 -12
  8. package/dist/ephemeralService.js.map +1 -1
  9. package/dist/index.d.ts +1 -1
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +2 -1
  12. package/dist/index.js.map +1 -1
  13. package/dist/localCreateDocument.js +1 -2
  14. package/dist/localCreateDocument.js.map +1 -1
  15. package/dist/localDeltaStorageService.js +3 -0
  16. package/dist/localDeltaStorageService.js.map +1 -1
  17. package/dist/localDocumentDeltaConnection.d.ts.map +1 -1
  18. package/dist/localDocumentService.d.ts.map +1 -1
  19. package/dist/localDocumentService.js +11 -2
  20. package/dist/localDocumentService.js.map +1 -1
  21. package/dist/localDocumentServiceFactory.d.ts +9 -0
  22. package/dist/localDocumentServiceFactory.d.ts.map +1 -1
  23. package/dist/localDocumentServiceFactory.js +22 -10
  24. package/dist/localDocumentServiceFactory.js.map +1 -1
  25. package/dist/localDocumentStorageService.d.ts.map +1 -1
  26. package/dist/localDocumentStorageService.js +15 -5
  27. package/dist/localDocumentStorageService.js.map +1 -1
  28. package/dist/localLayerCompatState.d.ts +8 -1
  29. package/dist/localLayerCompatState.d.ts.map +1 -1
  30. package/dist/localLayerCompatState.js +20 -1
  31. package/dist/localLayerCompatState.js.map +1 -1
  32. package/dist/localResolver.js +5 -6
  33. package/dist/localResolver.js.map +1 -1
  34. package/dist/localSessionStorageDb.js +3 -7
  35. package/dist/localSessionStorageDb.js.map +1 -1
  36. package/dist/packageVersion.d.ts +1 -1
  37. package/dist/packageVersion.d.ts.map +1 -1
  38. package/dist/packageVersion.js +1 -1
  39. package/dist/packageVersion.js.map +1 -1
  40. package/lib/alpha.d.ts +1 -1
  41. package/lib/ephemeralService.js +11 -8
  42. package/lib/ephemeralService.js.map +1 -1
  43. package/lib/index.d.ts +1 -1
  44. package/lib/index.d.ts.map +1 -1
  45. package/lib/index.js +1 -1
  46. package/lib/index.js.map +1 -1
  47. package/lib/legacy.d.ts +1 -1
  48. package/lib/localDeltaStorageService.js +3 -0
  49. package/lib/localDeltaStorageService.js.map +1 -1
  50. package/lib/localDocumentDeltaConnection.d.ts.map +1 -1
  51. package/lib/localDocumentService.d.ts.map +1 -1
  52. package/lib/localDocumentService.js +9 -0
  53. package/lib/localDocumentService.js.map +1 -1
  54. package/lib/localDocumentServiceFactory.d.ts +9 -0
  55. package/lib/localDocumentServiceFactory.d.ts.map +1 -1
  56. package/lib/localDocumentServiceFactory.js +23 -11
  57. package/lib/localDocumentServiceFactory.js.map +1 -1
  58. package/lib/localDocumentStorageService.d.ts.map +1 -1
  59. package/lib/localDocumentStorageService.js +16 -6
  60. package/lib/localDocumentStorageService.js.map +1 -1
  61. package/lib/localLayerCompatState.d.ts +8 -1
  62. package/lib/localLayerCompatState.d.ts.map +1 -1
  63. package/lib/localLayerCompatState.js +20 -1
  64. package/lib/localLayerCompatState.js.map +1 -1
  65. package/lib/localResolver.js +3 -4
  66. package/lib/localResolver.js.map +1 -1
  67. package/lib/localSessionStorageDb.js +3 -7
  68. package/lib/localSessionStorageDb.js.map +1 -1
  69. package/lib/packageVersion.d.ts +1 -1
  70. package/lib/packageVersion.d.ts.map +1 -1
  71. package/lib/packageVersion.js +1 -1
  72. package/lib/packageVersion.js.map +1 -1
  73. package/lib/public.d.ts +1 -1
  74. package/package.json +42 -58
  75. package/src/ephemeralService.ts +1 -1
  76. package/src/index.ts +4 -1
  77. package/src/localDocumentServiceFactory.ts +15 -1
  78. package/src/localDocumentStorageService.ts +9 -3
  79. package/src/localLayerCompatState.ts +29 -1
  80. package/src/packageVersion.ts +1 -1
  81. package/tsconfig.json +1 -1
  82. package/alpha.d.ts +0 -11
  83. package/internal.d.ts +0 -11
  84. package/legacy.d.ts +0 -11
  85. /package/api-extractor/{api-extractor.current.json → api-extractor-report.current.json} +0 -0
  86. /package/api-extractor/{api-extractor.legacy.json → api-extractor-report.legacy.json} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,12 +1,48 @@
1
1
  # @fluidframework/local-driver
2
2
 
3
- ## 2.118.0
3
+ ## 3.0.0
4
4
 
5
- Dependency updates only.
5
+ ### Minor Changes
6
6
 
7
- ## 2.117.0
7
+ - Removal of direct CommonJS support ([#28124](https://github.com/microsoft/FluidFramework/pull/28124)) [0f84e3b8878](https://github.com/microsoft/FluidFramework/commit/0f84e3b8878a5e75b2253976d98fd963bbd9db88)
8
8
 
9
- Dependency updates only.
9
+ Direct `require()` import is no longer directly supported.
10
+ Package is transpiled as ECMAScript Module.
11
+
12
+ See [Removal of direct CommonJS support in v3.0](https://github.com/microsoft/FluidFramework/issues/27444) for more information.
13
+
14
+ - New ILayerCompatSupportRequirements property on LocalDocumentServiceFactory and OdspDocumentServiceFactoryCore ([#27516](https://github.com/microsoft/FluidFramework/pull/27516)) [f8bcc56859f](https://github.com/microsoft/FluidFramework/commit/f8bcc56859fc51957d45453bcf59ce154a2e0c18)
15
+
16
+ A new optional property, `ILayerCompatSupportRequirements`, has been added to [`LocalDocumentServiceFactory`](https://fluidframework.com/docs/api/local-driver/localdocumentservicefactory-class) and [`OdspDocumentServiceFactoryCore`](https://fluidframework.com/docs/api/odsp-driver/odspdocumentservicefactorycore-class).
17
+
18
+ The Driver layer uses this property to publish the requirements that the Loader layer must meet to be compatible with it. Because the Driver has no reference to the Loader, it cannot validate the Loader directly; instead the Loader reads these requirements and validates itself against them on the Driver's behalf. This enables the Loader / Driver compatibility check to run in both directions.
19
+
20
+ - Require modern TypeScript module resolution ([#27970](https://github.com/microsoft/FluidFramework/pull/27970)) [325e2016ca9](https://github.com/microsoft/FluidFramework/commit/325e2016ca9978d4a1f7552c97ba34feac9df41f)
21
+
22
+ Fluid Framework Client packages no longer include type declaration compatibility entrypoints for TypeScript's legacy Node10 resolution mode (`"moduleResolution": "node"` or `"node10"`).
23
+ Applications upgrading to Fluid Framework 3.0 must use one of the following supported configurations:
24
+ - `"module": "Node16"` with `"moduleResolution": "Node16"`
25
+ - `"module": "NodeNext"` with `"moduleResolution": "NodeNext"`
26
+ - `"module": "ESNext"` with `"moduleResolution": "Bundler"`
27
+
28
+ Existing public package entrypoints exposed through `package.json` exports, including `/alpha`, `/beta`, and `/legacy`, remain available under supported module resolution modes.
29
+
30
+ See [Removal of Node10 resolutions in v3.0](https://github.com/microsoft/FluidFramework/issues/27457) for more information.
31
+
32
+ - Client packages now target ES2022 ([#27846](https://github.com/microsoft/FluidFramework/pull/27846)) [91c78541bdd](https://github.com/microsoft/FluidFramework/commit/91c78541bddcbca5d6c5f357b023eeaee617d885)
33
+
34
+ The TypeScript compilation `target` and `lib` for the Fluid Framework client packages have been raised from ES2021/ES2020 to **ES2022**.
35
+ The published JavaScript now uses ES2022 language features (with correspondingly less down-leveling), so consuming these packages requires a runtime that supports ES2022.
36
+ All actively supported Node.js versions and evergreen browsers already meet this requirement.
37
+
38
+ Note that Fluid Framework has not officially supported targets older than ES2022 since before 2.0: this is documented in [ClientRequirements.md](https://github.com/microsoft/FluidFramework/blob/main/ClientRequirements.md) as well as the README for every client package.
39
+
40
+ It is possible this change could impact users of less up to date JavaScript runtimes.
41
+ Impacted users can use a tool like [babel](https://babeljs.io/) to transpile out unsupported language features.
42
+
43
+ - Build with TypeScript 6 ([#28052](https://github.com/microsoft/FluidFramework/pull/28052)) [7ab015c49de](https://github.com/microsoft/FluidFramework/commit/7ab015c49deec84833cdfe1fb5e1606b901f6e81)
44
+
45
+ FluidFramework Client SDK is now built using TypeScript 6. Consumers should build with TypeScript v6 or v7 or compatible tooling.
10
46
 
11
47
  ## 2.116.0
12
48
 
package/README.md CHANGED
@@ -9,15 +9,15 @@ TODO: document this package
9
9
 
10
10
  ## Using Fluid Framework libraries
11
11
 
12
- When taking a dependency on a Fluid Framework library's public APIs, we recommend using a `^` (caret) version range, such as `^1.3.4`.
13
- While Fluid Framework libraries may use different ranges with interdependencies between other Fluid Framework libraries,
14
- library consumers should always prefer `^`.
12
+ For a dependency on a Fluid Framework library's public APIs, we recommend a `^` (caret) version range.
13
+ For example, use `^1.3.4`.
15
14
 
16
- If using any of Fluid Framework's unstable APIs (for example, its `beta` APIs), we recommend using a more constrained version range, such as `~`.
15
+ For a dependency on an unstable API, such as a `beta` API, we recommend a more restrictive version range.
16
+ For example, use a `~` version range.
17
17
 
18
18
  ## Installation
19
19
 
20
- To get started, install the package by running the following command:
20
+ Run this command to install the package:
21
21
 
22
22
  ```bash
23
23
  npm i @fluidframework/local-driver
@@ -25,18 +25,18 @@ npm i @fluidframework/local-driver
25
25
 
26
26
  ## Importing from this package
27
27
 
28
- This package leverages [package.json exports](https://nodejs.org/api/packages.html#exports) to separate its APIs by support level.
29
- For more information on the related support guarantees, see [API Support Levels](https://fluidframework.com/docs/build/releases-and-apitags/#api-support-levels).
28
+ This package uses [package.json exports](https://nodejs.org/api/packages.html#exports) to separate APIs by support level.
29
+ For information about the support guarantees, read [API Support Levels](https://fluidframework.com/docs/build/releases-and-apitags/#api-support-levels).
30
30
 
31
- To access the `public` ([SemVer](https://semver.org/)) APIs, import via `@fluidframework/local-driver` like normal.
31
+ Import the `public` APIs from `@fluidframework/local-driver`.
32
32
 
33
- To access the `alpha` APIs, import via `@fluidframework/local-driver/alpha`.
33
+ Import the `alpha` APIs from `@fluidframework/local-driver/alpha`.
34
34
 
35
- To access the `legacy` APIs, import via `@fluidframework/local-driver/legacy`.
35
+ Import the `legacy` APIs from `@fluidframework/local-driver/legacy`.
36
36
 
37
37
  ## API Documentation
38
38
 
39
- API documentation for **@fluidframework/local-driver** is available at <https://fluidframework.com/docs/apis/local-driver>.
39
+ Read the **@fluidframework/local-driver** API documentation at <https://fluidframework.com/docs/apis/local-driver>.
40
40
 
41
41
  <!-- prettier-ignore-end -->
42
42
 
@@ -49,62 +49,69 @@ API documentation for **@fluidframework/local-driver** is available at <https://
49
49
 
50
50
  ## Minimum Client Requirements
51
51
 
52
- These are the platform requirements for the current version of Fluid Framework Client Packages.
53
- These requirements err on the side of being too strict since within a major version they can be relaxed over time, but not made stricter.
54
- For Long Term Support (LTS) versions this can require supporting these platforms for several years.
52
+ Fluid Framework client libraries support the platforms in this document.
53
+ These requirements are intentionally restrictive.
54
+ Within a major version series, we can relax these requirements, but we cannot make them stricter.
55
+ For a Long Term Support (LTS) version, we might need to support these platforms for several years.
55
56
 
56
- It is likely that other configurations will work, but they are not supported: if they stop working, we do not consider that a bug.
57
- If you would benefit from support for something not listed here, file an issue and the product team will evaluate your request.
58
- When making such a request please include if the configuration already works (and thus the request is just that it becomes officially supported), or if changes are required to get it working.
57
+ Other configurations can work, but Fluid Framework does not support them.
58
+ If an unsupported configuration stops working, we do not classify this as a bug.
59
+ To request support for a configuration that is not listed, file an issue.
60
+ The product team will evaluate your request.
61
+ In the issue, specify the current status of the configuration:
62
+
63
+ - The configuration works but needs official support.
64
+ - The configuration does not work and requires changes.
59
65
 
60
66
  ### Supported Runtimes
61
67
 
62
- - NodeJs ^22.22.2 except that we will drop support for it [when NodeJs 22 loses its upstream support on 2027-04-30](https://github.com/nodejs/release#release-schedule), and will support a newer LTS version of NodeJS at least 1 year before 22 is end-of-life.
63
- - Running Fluid in a Node.js environment with the `--no-experimental-fetch` flag is not supported.
64
- - Modern browsers supporting the es2022 standard library: in response to asks we can add explicit support for using babel to polyfill to target specific standards or runtimes (meaning we can avoid/remove use of things that don't polyfill robustly, but otherwise target modern standards).
68
+ - Fluid Framework supports Node.js versions 22 and 24 while they receive [upstream support](https://nodejs.org/en/about/previous-releases).
69
+ - Fluid Framework will stop support for version 22 [when upstream support ends on 2027-04-30](https://github.com/nodejs/release#release-schedule).
70
+ - Fluid Framework does not support Node.js with the `--no-experimental-fetch` flag.
71
+ - Fluid Framework supports modern browsers that support the ES2022 standard library.
65
72
 
66
73
  ### Supported Tools
67
74
 
68
- - TypeScript 5.4:
69
- - All [`strict`](https://www.typescriptlang.org/tsconfig) options are supported.
70
- - [`strictNullChecks`](https://www.typescriptlang.org/tsconfig) is required.
71
- - [Configuration options deprecated in 5.0](https://github.com/microsoft/TypeScript/issues/51909) are not supported.
72
- - `exactOptionalPropertyTypes` is currently not fully supported.
73
- If used, narrowing members of Fluid Framework types types using `in`, `Reflect.has`, `Object.hasOwn` or `Object.prototype.hasOwnProperty` should be avoided as they may incorrectly exclude `undefined` from the possible values in some cases.
75
+ - [TypeScript 6.0](https://typescriptdocs.com/release-notes/TypeScript%206.0):
76
+ - Fluid Framework supports all [`strict`](https://www.typescriptlang.org/tsconfig) options.
77
+ - Set the build targets (`lib`, `target`) to `ES2022` or later.
78
+ - Enable [`strictNullChecks`](https://www.typescriptlang.org/tsconfig).
79
+ - Fluid Framework does not support [configuration options deprecated in TypeScript 6.0](https://typescriptdocs.com/release-notes/TypeScript%206.0#breaking-changes-and-deprecations-in-typescript-6-0).
80
+ - Fluid Framework does not fully support `exactOptionalPropertyTypes`.
81
+ If you enable this option, do not use `in`, `Reflect.has`, `Object.hasOwn`, or `Object.prototype.hasOwnProperty` to narrow members of Fluid Framework types.
82
+ These methods can incorrectly exclude `undefined` from the possible values.
74
83
  - [webpack](https://webpack.js.org/) 5
75
- - We are not intending to be prescriptive about what bundler to use.
76
- Other bundlers which can handle ES Modules should work, but webpack is the only one we actively test.
84
+ - We do not require a specific bundler.
85
+ Other bundlers that handle ES Modules can work, but we actively test only webpack.
77
86
 
78
87
  ### Module Resolution
79
88
 
80
- [`Node16`, `NodeNext`, or `Bundler`](https://www.typescriptlang.org/tsconfig#moduleResolution) resolution should be used with TypeScript compilerOptions to follow the [Node.js v12+ ESM Resolution and Loading algorithm](https://nodejs.github.io/nodejs.dev/en/api/v20/esm/#resolution-and-loading-algorithm).
81
- Node10 resolution is not supported as it does not support Fluid Framework's API structuring pattern that is used to distinguish stable APIs from those that are in development.
89
+ In TypeScript `compilerOptions`, use [`Node16`, `Node20`, `NodeNext`, or `Bundler`](https://www.typescriptlang.org/tsconfig#moduleResolution) module resolution.
90
+ These settings follow the [Node.js v12+ ESM Resolution and Loading algorithm](https://nodejs.github.io/nodejs.dev/en/api/v20/esm/#resolution-and-loading-algorithm).
91
+
92
+ Do not use `Node10` module resolution.
82
93
 
83
94
  ### Module Formats
84
95
 
85
96
  - ES Modules:
86
- ES Modules are the preferred way to consume our client packages (including in NodeJs) and consuming our client packages from ES Modules is fully supported.
87
- - CommonJs:
88
- Consuming our client packages as CommonJs is supported only in NodeJS and only for the cases listed below.
89
- This is done to accommodate some workflows without good ES Module support.
90
- If you have a workflow you would like included in this list, file an issue.
91
- Once this list of workflows motivating CommonJS support is empty, we may drop support for CommonJS one year after notice of the change is posted here.
92
-
93
- - Testing with Jest (which lacks [stable ESM support](https://jestjs.io/docs/ecmascript-modules) due to [unstable APIs in NodeJs](https://github.com/nodejs/node/issues/37648))
97
+ Use ES Modules to consume Fluid Framework client packages, including in Node.js.
98
+ - CommonJS:
99
+ Fluid Framework does not officially support CommonJS in version 3.0 or later.
94
100
 
95
101
  ## Contribution Guidelines
96
102
 
97
- There are many ways to [contribute](https://github.com/microsoft/FluidFramework/blob/main/CONTRIBUTING.md) to Fluid.
103
+ You can [contribute](https://github.com/microsoft/FluidFramework/blob/main/CONTRIBUTING.md) to Fluid Framework in these ways:
98
104
 
99
- - Participate in Q&A in our [GitHub Discussions](https://github.com/microsoft/FluidFramework/discussions).
100
- - [Submit bugs](https://github.com/microsoft/FluidFramework/issues) and help us verify fixes as they are checked in.
101
- - Review the [source code changes](https://github.com/microsoft/FluidFramework/pulls).
105
+ - Answer questions in [GitHub Discussions](https://github.com/microsoft/FluidFramework/discussions).
106
+ - [Submit bug reports](https://github.com/microsoft/FluidFramework/issues) and help verify fixes.
107
+ - Review [source code changes](https://github.com/microsoft/FluidFramework/pulls).
102
108
  - [Contribute bug fixes](https://github.com/microsoft/FluidFramework/blob/main/CONTRIBUTING.md).
103
109
 
104
- Detailed instructions for working in the repo can be found in the [Wiki](https://github.com/microsoft/FluidFramework/blob/main/docs/content/Home.md).
110
+ For detailed instructions, read the [repo documentation](https://github.com/microsoft/FluidFramework/blob/main/docs/content/Home.md).
105
111
 
106
- This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
107
- For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
112
+ This project follows the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
113
+ For more information, read the [Code of Conduct frequently asked questions](https://opensource.microsoft.com/codeofconduct/faq/).
114
+ For questions or comments, contact [opencode@microsoft.com](mailto:opencode@microsoft.com).
108
115
 
109
116
  This project may contain Microsoft trademarks or logos for Microsoft projects, products, or services.
110
117
  Use of these trademarks or logos must follow Microsoft’s [Trademark & Brand Guidelines](https://www.microsoft.com/trademarks).
@@ -112,13 +119,9 @@ Use of Microsoft trademarks or logos in modified versions of this project must n
112
119
 
113
120
  ## Help
114
121
 
115
- Not finding what you're looking for in this README?
116
- Check out [fluidframework.com](https://fluidframework.com/docs/).
117
-
118
- Still not finding what you're looking for?
119
- Please [file an issue](https://github.com/microsoft/FluidFramework/blob/main/docs/content/Contributing/Submitting-Bugs-and-Feature-Requests.md).
122
+ Read the [Fluid Framework documentation](https://fluidframework.com/docs/) for information about Fluid Framework concepts and APIs.
120
123
 
121
- Thank you!
124
+ To request information that the documentation does not contain, [create an issue](https://github.com/microsoft/FluidFramework/blob/main/docs/content/Contributing/Submitting-Bugs-and-Feature-Requests.md).
122
125
 
123
126
  ## Trademark
124
127
 
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
3
- "extends": "../../../common/build/build-common/api-extractor-model.esm.json"
3
+ "extends": "<projectFolder>/../../../common/build/build-common/api-extractor-model.esm.json"
4
4
  }
@@ -15,6 +15,7 @@ export class LocalDocumentServiceFactory implements IDocumentServiceFactory {
15
15
  createDocumentService(resolvedUrl: IResolvedUrl, logger?: ITelemetryBaseLogger, clientIsSummarizer?: boolean): Promise<IDocumentService>;
16
16
  disconnectClient(clientId: string, disconnectReason: string): void;
17
17
  readonly ILayerCompatDetails?: unknown;
18
+ readonly ILayerCompatSupportRequirements?: unknown;
18
19
  nackClient(clientId: string, code?: number, type?: NackErrorType, message?: any): void;
19
20
  }
20
21
 
package/dist/auth.js CHANGED
@@ -4,7 +4,8 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.generateUser = exports.generateToken = void 0;
7
+ exports.generateToken = generateToken;
8
+ exports.generateUser = generateUser;
8
9
  const jsrsasign_1 = require("jsrsasign");
9
10
  const uuid_1 = require("uuid");
10
11
  /**
@@ -31,7 +32,6 @@ function generateToken(tenantId, documentId, key, scopes, user, lifetime = 60 *
31
32
  const utf8Key = { utf8: key };
32
33
  return jsrsasign_1.KJUR.jws.JWS.sign(null, JSON.stringify({ alg: "HS256", typ: "JWT" }), claims, utf8Key);
33
34
  }
34
- exports.generateToken = generateToken;
35
35
  function generateUser() {
36
36
  const userId = (0, uuid_1.v4)();
37
37
  const match = /^([\da-f]{8})-([\da-f]{4})/.exec(userId);
@@ -42,5 +42,4 @@ function generateUser() {
42
42
  };
43
43
  return randomUser;
44
44
  }
45
- exports.generateUser = generateUser;
46
45
  //# sourceMappingURL=auth.js.map
package/dist/auth.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAIH,yCAA8C;AAC9C,+BAAkC;AAElC;;;GAGG;AACH,SAAgB,aAAa,CAC5B,QAAgB,EAChB,UAAkB,EAClB,GAAW,EACX,MAAmB,EACnB,IAAY,EACZ,WAAmB,EAAE,GAAG,EAAE,EAC1B,MAAc,KAAK;IAEnB,2HAA2H;IAC3H,IAAI,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC;IAC7C,IAAI,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,SAAS,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QACvD,SAAS,GAAG,YAAY,EAAE,CAAC;IAC5B,CAAC;IAED,0BAA0B;IAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAE1C,MAAM,MAAM,GAAiB;QAC5B,UAAU;QACV,MAAM;QACN,QAAQ;QACR,IAAI,EAAE,SAAS;QACf,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG,GAAG,QAAQ;QACnB,GAAG;KACH,CAAC;IAEF,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IAC9B,OAAO,gBAAS,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAC5B,IAAI,EACJ,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAC5C,MAAM,EACN,OAAO,CACP,CAAC;AACH,CAAC;AAnCD,sCAmCC;AAED,SAAgB,YAAY;IAC3B,MAAM,MAAM,GAAG,IAAA,SAAI,GAAE,CAAC;IACtB,MAAM,KAAK,GAAG,4BAA4B,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,uEAAuE;IAE5H,MAAM,UAAU,GAAG;QAClB,EAAE,EAAE,MAAM;QACV,IAAI,EAAE,QAAQ;KACd,CAAC;IAEF,OAAO,UAAU,CAAC;AACnB,CAAC;AAXD,oCAWC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IUser } from \"@fluidframework/driver-definitions\";\nimport type { ITokenClaims, ScopeType } from \"@fluidframework/driver-definitions/internal\";\nimport { KJUR as jsrsasign } from \"jsrsasign\";\nimport { v4 as uuid } from \"uuid\";\n\n/**\n * Generates a JWT token to authorize against. We do not use the implementation in\n * services-client since it cannot run in the browser without polyfills.\n */\nexport function generateToken(\n\ttenantId: string,\n\tdocumentId: string,\n\tkey: string,\n\tscopes: ScopeType[],\n\tuser?: IUser,\n\tlifetime: number = 60 * 60,\n\tver: string = \"1.0\",\n): string {\n\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ?? could change behavior for falsy values\n\tlet userClaim = user ? user : generateUser();\n\tif (userClaim.id === \"\" || userClaim.id === undefined) {\n\t\tuserClaim = generateUser();\n\t}\n\n\t// Current time in seconds\n\tconst now = Math.round(Date.now() / 1000);\n\n\tconst claims: ITokenClaims = {\n\t\tdocumentId,\n\t\tscopes,\n\t\ttenantId,\n\t\tuser: userClaim,\n\t\tiat: now,\n\t\texp: now + lifetime,\n\t\tver,\n\t};\n\n\tconst utf8Key = { utf8: key };\n\treturn jsrsasign.jws.JWS.sign(\n\t\tnull,\n\t\tJSON.stringify({ alg: \"HS256\", typ: \"JWT\" }),\n\t\tclaims,\n\t\tutf8Key,\n\t);\n}\n\nexport function generateUser(): IUser {\n\tconst userId = uuid();\n\tconst match = /^([\\da-f]{8})-([\\da-f]{4})/.exec(userId);\n\tconst userName = match === null ? userId : match[0]; // Just use the first two segments of the (fake) userId as a fake name.\n\n\tconst randomUser = {\n\t\tid: userId,\n\t\tname: userName,\n\t};\n\n\treturn randomUser;\n}\n"]}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAWH,sCAmCC;AAED,oCAWC;AAvDD,yCAA8C;AAC9C,+BAAkC;AAElC;;;GAGG;AACH,SAAgB,aAAa,CAC5B,QAAgB,EAChB,UAAkB,EAClB,GAAW,EACX,MAAmB,EACnB,IAAY,EACZ,WAAmB,EAAE,GAAG,EAAE,EAC1B,MAAc,KAAK;IAEnB,2HAA2H;IAC3H,IAAI,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC;IAC7C,IAAI,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,SAAS,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QACvD,SAAS,GAAG,YAAY,EAAE,CAAC;IAC5B,CAAC;IAED,0BAA0B;IAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAE1C,MAAM,MAAM,GAAiB;QAC5B,UAAU;QACV,MAAM;QACN,QAAQ;QACR,IAAI,EAAE,SAAS;QACf,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG,GAAG,QAAQ;QACnB,GAAG;KACH,CAAC;IAEF,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IAC9B,OAAO,gBAAS,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAC5B,IAAI,EACJ,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAC5C,MAAM,EACN,OAAO,CACP,CAAC;AACH,CAAC;AAED,SAAgB,YAAY;IAC3B,MAAM,MAAM,GAAG,IAAA,SAAI,GAAE,CAAC;IACtB,MAAM,KAAK,GAAG,4BAA4B,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,uEAAuE;IAE5H,MAAM,UAAU,GAAG;QAClB,EAAE,EAAE,MAAM;QACV,IAAI,EAAE,QAAQ;KACd,CAAC;IAEF,OAAO,UAAU,CAAC;AACnB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IUser } from \"@fluidframework/driver-definitions\";\nimport type { ITokenClaims, ScopeType } from \"@fluidframework/driver-definitions/internal\";\nimport { KJUR as jsrsasign } from \"jsrsasign\";\nimport { v4 as uuid } from \"uuid\";\n\n/**\n * Generates a JWT token to authorize against. We do not use the implementation in\n * services-client since it cannot run in the browser without polyfills.\n */\nexport function generateToken(\n\ttenantId: string,\n\tdocumentId: string,\n\tkey: string,\n\tscopes: ScopeType[],\n\tuser?: IUser,\n\tlifetime: number = 60 * 60,\n\tver: string = \"1.0\",\n): string {\n\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ?? could change behavior for falsy values\n\tlet userClaim = user ? user : generateUser();\n\tif (userClaim.id === \"\" || userClaim.id === undefined) {\n\t\tuserClaim = generateUser();\n\t}\n\n\t// Current time in seconds\n\tconst now = Math.round(Date.now() / 1000);\n\n\tconst claims: ITokenClaims = {\n\t\tdocumentId,\n\t\tscopes,\n\t\ttenantId,\n\t\tuser: userClaim,\n\t\tiat: now,\n\t\texp: now + lifetime,\n\t\tver,\n\t};\n\n\tconst utf8Key = { utf8: key };\n\treturn jsrsasign.jws.JWS.sign(\n\t\tnull,\n\t\tJSON.stringify({ alg: \"HS256\", typ: \"JWT\" }),\n\t\tclaims,\n\t\tutf8Key,\n\t);\n}\n\nexport function generateUser(): IUser {\n\tconst userId = uuid();\n\tconst match = /^([\\da-f]{8})-([\\da-f]{4})/.exec(userId);\n\tconst userName = match === null ? userId : match[0]; // Just use the first two segments of the (fake) userId as a fake name.\n\n\tconst randomUser = {\n\t\tid: userId,\n\t\tname: userName,\n\t};\n\n\treturn randomUser;\n}\n"]}
@@ -4,7 +4,10 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.EphemeralServiceContainer = exports.getDefaultEphemeralService = exports.cleanupEphemeralService = exports.startEphemeralService = void 0;
7
+ exports.EphemeralServiceContainer = void 0;
8
+ exports.startEphemeralService = startEphemeralService;
9
+ exports.cleanupEphemeralService = cleanupEphemeralService;
10
+ exports.getDefaultEphemeralService = getDefaultEphemeralService;
8
11
  const internal_1 = require("@fluidframework/container-definitions/internal");
9
12
  const internal_2 = require("@fluidframework/container-loader/internal");
10
13
  const internal_3 = require("@fluidframework/container-runtime/internal");
@@ -38,7 +41,6 @@ function startEphemeralService(isDefault = true) {
38
41
  }
39
42
  return service;
40
43
  }
41
- exports.startEphemeralService = startEphemeralService;
42
44
  /**
43
45
  * Cleans up the service passed in {@link startEphemeralService}, or the {@link getDefaultEphemeralService|default} if none is passed.
44
46
  * @remarks
@@ -57,7 +59,6 @@ async function cleanupEphemeralService(service) {
57
59
  defaultEphemeralService = undefined;
58
60
  }
59
61
  }
60
- exports.cleanupEphemeralService = cleanupEphemeralService;
61
62
  /**
62
63
  * Get the default {@link EphemeralService} if one has been {@link startEphemeralService|started}.
63
64
  * @throws If no default service is running.
@@ -69,7 +70,6 @@ function getDefaultEphemeralService() {
69
70
  }
70
71
  throw new internal_8.UsageError("No default EphemeralService is running");
71
72
  }
72
- exports.getDefaultEphemeralService = getDefaultEphemeralService;
73
73
  /**
74
74
  * The {@link defaultEphemeralService} if one has been {@link startEphemeralService|started}.
75
75
  */
@@ -81,15 +81,15 @@ let defaultEphemeralService;
81
81
  * Narrow an {@link EphemeralService} to it with `EphemeralServiceImplementation.narrow`.
82
82
  */
83
83
  class EphemeralServiceImplementation extends internal_4.ErasedTypeImplementation {
84
+ // A single server is shared by all containers connected to this service so they can communicate with each other.
85
+ server = server_local_server_1.LocalDeltaConnectionServer.create(
86
+ // new LocalSessionStorageDbFactory(),
87
+ );
88
+ documentServiceFactory = new localDocumentServiceFactory_js_1.LocalDocumentServiceFactory(this.server);
89
+ containers = new Set();
90
+ closed = false;
84
91
  constructor() {
85
92
  super();
86
- // A single server is shared by all containers connected to this service so they can communicate with each other.
87
- this.server = server_local_server_1.LocalDeltaConnectionServer.create(
88
- // new LocalSessionStorageDbFactory(),
89
- );
90
- this.documentServiceFactory = new localDocumentServiceFactory_js_1.LocalDocumentServiceFactory(this.server);
91
- this.containers = new Set();
92
- this.closed = false;
93
93
  this.defaultClient = this.newClient();
94
94
  }
95
95
  newClient(options) {
@@ -99,6 +99,7 @@ class EphemeralServiceImplementation extends internal_4.ErasedTypeImplementation
99
99
  };
100
100
  return new EphemeralServiceClientImplementation(finalOptions);
101
101
  }
102
+ defaultClient;
102
103
  async close() {
103
104
  if (this.closed) {
104
105
  return;
@@ -206,6 +207,7 @@ class EphemeralServiceImplementation extends internal_4.ErasedTypeImplementation
206
207
  }
207
208
  }
208
209
  class EphemeralServiceClientImplementation extends internal_7.ServiceClientImplementation {
210
+ service;
209
211
  constructor(options) {
210
212
  super(options, EphemeralServiceContainer);
211
213
  this.service = options.service;
@@ -217,7 +219,7 @@ const containerRuntimeLoader = async (parameters) => {
217
219
  registry: parameters.registry,
218
220
  provideEntryPoint: parameters.provideEntryPoint,
219
221
  existing: parameters.existing,
220
- minVersionForCollab: parameters.minVersionForCollab,
222
+ oldestSupportedClient: parameters.minVersionForCollab,
221
223
  runtimeOptions: { enableRuntimeIdCompressor: "on" },
222
224
  });
223
225
  if (!parameters.existing) {
@@ -252,6 +254,7 @@ let documentIdCounter = 0;
252
254
  * @internal
253
255
  */
254
256
  class EphemeralServiceContainer extends internal_7.ServiceContainerBase {
257
+ service;
255
258
  static async createDetached(registry, options, root) {
256
259
  EphemeralServiceImplementation.narrow(options.service);
257
260
  const container = await (0, internal_2.createDetachedContainer)({
@@ -1 +1 @@
1
- {"version":3,"file":"ephemeralService.js","sourceRoot":"","sources":["../src/ephemeralService.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 {\n\tConnectionState,\n\ttype IContainer,\n} from \"@fluidframework/container-definitions/internal\";\nimport {\n\tcreateDetachedContainer,\n\tloadExistingContainer,\n} from \"@fluidframework/container-loader/internal\";\nimport { ContainerRuntime } from \"@fluidframework/container-runtime/internal\";\nimport type { IRequest } from \"@fluidframework/core-interfaces\";\nimport {\n\tErasedTypeImplementation,\n\ttype ErasedBaseType,\n} from \"@fluidframework/core-interfaces/internal\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport {\n\tfeatureVersion,\n\ttype DataStoreKind,\n\ttype DataStoreRegistry,\n\ttype FluidContainerAttached,\n\ttype FluidContainerWithService,\n\ttype OldestSupportedServiceClientVersion,\n\ttype Registry,\n\ttype ServiceClient,\n\ttype ServiceOptions,\n} from \"@fluidframework/driver-definitions/internal\";\nimport {\n\ttype ContainerRuntimeLoader,\n\ttype ContainerRuntimeLoaderParams,\n\tmakeCodeLoader,\n\trootDataStoreId,\n\tServiceClientImplementation,\n\tServiceContainerBase,\n} from \"@fluidframework/runtime-utils/internal\";\nimport {\n\tLocalDeltaConnectionServer,\n\ttype ILocalDeltaConnectionServer,\n} from \"@fluidframework/server-local-server\";\nimport { UsageError } from \"@fluidframework/driver-utils/internal\";\n\nimport { LocalDocumentServiceFactory } from \"./localDocumentServiceFactory.js\";\nimport { createLocalResolverCreateNewRequest, LocalResolver } from \"./localResolver.js\";\nimport { pkgVersion } from \"./packageVersion.js\";\n\n/**\n * Starts and returns a new {@link EphemeralService}.\n * @param isDefault - Whether this service should saved as the default service for {@link cleanupEphemeralService} to cleanup.\n * Defaults to true.\n * @remarks\n * The returned service owns an in-memory server and holds the documents created through clients connected to it.\n * {@link cleanupEphemeralService} can be used to ensure the service is properly cleaned up (a no-op if stopped/closed already).\n *\n * As a service, it may start timers which may require an explicit `close` to fully free.\n * @alpha\n */\nexport function startEphemeralService(isDefault = true): EphemeralService {\n\tif (isDefault && defaultEphemeralService) {\n\t\tthrow new UsageError(\"A default EphemeralService is already running\");\n\t}\n\n\tconst service = new EphemeralServiceImplementation();\n\tif (isDefault) {\n\t\tdefaultEphemeralService = service;\n\t}\n\treturn service;\n}\n\n/**\n * Cleans up the service passed in {@link startEphemeralService}, or the {@link getDefaultEphemeralService|default} if none is passed.\n * @remarks\n * This closes the service, and all its containers.\n * This is a good way to ensure the service and its containers leave no lingering timers\n * which could leak memory, trigger asynchronous work or prevent a clean process exit.\n * @alpha\n */\nexport async function cleanupEphemeralService(service?: EphemeralService): Promise<void> {\n\tconst toCleanup = service ?? defaultEphemeralService;\n\tif (toCleanup) {\n\t\t// TODO: we may want to make closing of containers a separate operation which is done here.\n\t\tawait toCleanup.close();\n\t}\n\tif (toCleanup === defaultEphemeralService) {\n\t\tdefaultEphemeralService = undefined;\n\t}\n}\n\n/**\n * Get the default {@link EphemeralService} if one has been {@link startEphemeralService|started}.\n * @throws If no default service is running.\n * @alpha\n */\nexport function getDefaultEphemeralService(): EphemeralService {\n\tif (defaultEphemeralService) {\n\t\treturn defaultEphemeralService;\n\t}\n\tthrow new UsageError(\"No default EphemeralService is running\");\n}\n\n/**\n * Internal Options for creating an {@link EphemeralServiceClient}, extending {@link @fluidframework/driver-definitions#ServiceOptions}\n * with the {@link EphemeralService} the client should connect to.\n * @input\n * @internal\n */\nexport interface EphemeralServiceOptions extends ServiceOptions {\n\t/**\n\t * {@inheritdoc @fluidframework/driver-definitions#ServiceOptions.oldestSupportedClient}\n\t */\n\treadonly oldestSupportedClient: OldestSupportedServiceClientVersion;\n\t/**\n\t * The service instance to connect to.\n\t */\n\treadonly service: EphemeralService;\n}\n\n/**\n * An in-memory Fluid service that can produce connected {@link EphemeralServiceClient}s.\n * @remarks\n * All documents created through clients connected to a given `EphemeralService` are held in-memory by that service.\n * Closing the service (via {@link EphemeralService.close} or {@link cleanupEphemeralService}) closes the connections\n * to any remaining open containers, and cleans up the service's timers.\n *\n * Create one with {@link startEphemeralService}.\n *\n * Most {@link @fluidframework/driver-definitions#ServiceClient} implementations would take in a URL and credentials to connect to a service,\n * but that is not needed for the ephemeral in-memory service.\n * Instead this object representing the actual service instance is provided.\n * @privateRemarks\n * This is separated out from the actual {@link @fluidframework/driver-definitions#ServiceClient} object so that it's possible to create multiple service clients\n * connected to the same service.\n * Doing so is rarely necessary, but would be needed to test multiple clients collaborating on the same\n * document with different `oldestSupportedClient` values.\n * This also exposes a place to put APIs for preloading and exporting document contents in the future.\n *\n * This is an erased type: its only implementation is the module-private {@link EphemeralServiceImplementation}, which holds\n * the mutable server and container state so it does not appear on this public type.\n *\n * TODO: formalize this lifecycle with an interface which documents these stages.\n * Lifecycle:\n * The intended lifecycle of an {@link EphemeralService} follows roughly the same pattern as containers:\n *\n * 1. Open: accepts connections from {@link EphemeralServiceClient}s, which can create and load containers.\n * Might have timers and event registrations which can trigger asynchronous work, and retain the object in memory.\n *\n * 2. Closing: asynchronous transition from open to closed. New use should behave as it closed, but may be cleaning up or saving resources asynchronously.\n * Timers and event registrations may still be active, but should be cleaned up by the time the transition to closed completes.\n *\n * 3. Closed: no longer accepts connections from {@link EphemeralServiceClient}s, and all containers connected to it are closed.\n * Should have no subscriptions to events or timers which could retain it in memory or trigger asynchronous work.\n * The object can still be used in a limited capacity (typically just to inspect its status (e.g. `isClosed`), and to view (but not edit) the final state of any containers which were connected to it before it closed.)\n *\n * Events or errors can cause an open to closing transition. Any nonfunctional state, including error states, should be considered as closed (or closing which will transition to closed),\n * and meet the requirements of closed with regards to timers and events.\n *\n * @alpha @sealed\n */\nexport interface EphemeralService extends ErasedBaseType<readonly [\"EphemeralService\"]> {\n\t/**\n\t * Close this service, which closes all containers connected to it and releases its resources.\n\t * @remarks\n\t * All documents held by this service are discarded, and any timers it (or its containers) were keeping alive\n\t * are cleaned up.\n\t * The returned promise resolves once all asynchronous cleanup (including shutting down the in-memory server)\n\t * has completed.\n\t * Closing is idempotent: calling it again after the service is closed resolves without doing anything.\n\t */\n\tclose(): Promise<void>;\n\n\t/**\n\t * Drives all containers connected to this service toward convergence, processing pending operations and\n\t * waiting for all dirty containers to save.\n\t *\n\t * @param timeoutMilliseconds - The maximum time to wait for containers to quiesce, in milliseconds. Defaults to 30_000.\n\t *\n\t * @privateRemarks\n\t * This is a best-effort implementation simplified from `LoaderContainerTracker.ensureSynchronized`.\n\t * Currently it does not perform receiver-side sequence-number quiescence or wait for join/leave (audience) ops.\n\t * See `LoaderContainerTracker.ensureSynchronized` for the fuller version this is based on.\n\t * For the currently exposed API surface, this should be sufficient,\n\t * but users down casting to internal types might run into some limitations.\n\t */\n\tsynchronize(timeoutMilliseconds?: number): Promise<void>;\n\n\t/**\n\t * Creates and returns a {@link EphemeralServiceClient} for an in-memory, ephemeral Fluid service.\n\t *\n\t * @param options - Options for the client. `oldestSupportedClient` may be omitted because all\n\t * clients are in the same process, so it defaults to the current version. `service` may be omitted to allocate a new\n\t * {@link EphemeralService} dedicated to this client, or provided to connect the client to an existing service instance.\n\t *\n\t * @remarks\n\t * The service is ephemeral and in-memory: all documents are held by the {@link EphemeralService} the client is\n\t * connected to, and live for as long as that service is open — independent of whether any container for them is open.\n\t * A document created and attached (obtaining an `id`) can be loaded by `id` for as long as its service remains open,\n\t * even after every container for it has been closed.\n\t * Closing the service (via {@link EphemeralService.close} or {@link cleanupEphemeralService}) discards all of its\n\t * documents and releases its resources; afterwards those `id`s can no longer be loaded.\n\t *\n\t * When no `service` is provided, a new one is allocated for this client (accessible via {@link EphemeralServiceClient.service}).\n\t * Provide the same {@link EphemeralService} to multiple clients (via `options.service`) to have them collaborate on the\n\t * same documents, and control that service's lifetime explicitly.\n\t *\n\t * Since a service holds timers while open, tests should close the services they use (e.g. via\n\t * {@link cleanupEphemeralService} in an `afterEach`) to avoid lingering timers that can hang test runners.\n\t *\n\t * @privateRemarks\n\t * TODO: We should provide a way to extract (for potential serialization as test data) and load documents into a service.\n\t * This is needed to use this API surface for testing reference documents.\n\t * Ideally we would provide a service agnostic way to do the export, but likely only support loading them into the local service.\n\t * This can be done via an API on FluidContainer (or a free function taking one) to do the export, then adding a\n\t * service specific API (on {@link EphemeralService}) to load from the export format and return the ID of the loaded document.\n\t */\n\tnewClient(options: ServiceOptions): EphemeralServiceClient;\n\n\t/**\n\t * A client connected to this service using the default options.\n\t */\n\treadonly defaultClient: EphemeralServiceClient;\n}\n\n/**\n * The {@link defaultEphemeralService} if one has been {@link startEphemeralService|started}.\n */\nlet defaultEphemeralService: EphemeralServiceImplementation | undefined;\n\n/**\n * The concrete implementation of {@link EphemeralService}.\n * @remarks\n * Kept module-private so its mutable state and internal helpers are not part of the public API.\n * Narrow an {@link EphemeralService} to it with `EphemeralServiceImplementation.narrow`.\n */\nclass EphemeralServiceImplementation\n\textends ErasedTypeImplementation<EphemeralService>\n\timplements EphemeralService\n{\n\t// A single server is shared by all containers connected to this service so they can communicate with each other.\n\tprivate readonly server: ILocalDeltaConnectionServer =\n\t\tLocalDeltaConnectionServer.create(\n\t\t\t// new LocalSessionStorageDbFactory(),\n\t\t);\n\tprivate readonly documentServiceFactory = new LocalDocumentServiceFactory(this.server);\n\tprivate readonly containers = new Set<EphemeralServiceContainer<unknown>>();\n\tprivate closed = false;\n\n\tpublic constructor() {\n\t\tsuper();\n\t\tthis.defaultClient = this.newClient();\n\t}\n\tpublic newClient(options?: Partial<ServiceOptions>): EphemeralServiceClient {\n\t\tconst finalOptions: EphemeralServiceOptions = {\n\t\t\toldestSupportedClient: options?.oldestSupportedClient ?? featureVersion(pkgVersion),\n\t\t\tservice: this,\n\t\t};\n\t\treturn new EphemeralServiceClientImplementation(finalOptions);\n\t}\n\tpublic readonly defaultClient: EphemeralServiceClient;\n\n\tpublic async close(): Promise<void> {\n\t\tif (this.closed) {\n\t\t\treturn;\n\t\t}\n\t\tthis.closed = true;\n\n\t\t// Close every open container via the same public close() path a user would use.\n\t\t// We might want to remove this.\n\t\tconst toClose = [...this.containers];\n\t\tthis.containers.clear();\n\t\tfor (const c of toClose) {\n\t\t\tc.close();\n\t\t}\n\n\t\t// Shut down the in-memory server. Its timers (e.g. the Deli read-client idle `setInterval`) belong to the\n\t\t// server rather than any container, so closing containers alone would leave them running.\n\t\tawait this.server.close();\n\t}\n\n\tpublic async synchronize(timeoutMilliseconds = 30_000): Promise<void> {\n\t\t// Timeout to allow for better errors in the case of hangs.\n\t\tlet timedOut = false;\n\t\tlet deadlineTimer: ReturnType<typeof setTimeout> | undefined;\n\t\tconst deadline = new Promise<true>((resolve) => {\n\t\t\tdeadlineTimer = setTimeout(() => {\n\t\t\t\ttimedOut = true;\n\t\t\t\tresolve(true);\n\t\t\t}, timeoutMilliseconds);\n\t\t});\n\n\t\ttry {\n\t\t\t// Require two consecutive quiescent passes (no dirty containers and no pending server work),\n\t\t\t// each separated by a macrotask turn, to give late side effects a chance to surface.\n\t\t\tlet clean = 0;\n\t\t\twhile (clean < 2) {\n\t\t\t\tif (timedOut) {\n\t\t\t\t\tthrow new UsageError(\n\t\t\t\t\t\t`EphemeralService.synchronize timed out after ${timeoutMilliseconds}ms waiting for local containers to quiesce.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// Yield a macrotask turn *first*, so the local server's scheduled broadcast send and each\n\t\t\t\t// container's inbound op processing can run before we sample their state below. Sampling\n\t\t\t\t// hasPendingWork() in a tight `while (await ...)` loop instead would starve that scheduled\n\t\t\t\t// send (it is a macrotask, while the await resolves on the microtask queue) and could hang.\n\t\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\t\tsetTimeout(resolve, 0);\n\t\t\t\t});\n\n\t\t\t\t// Prune any containers that have closed since the last pass.\n\t\t\t\tfor (const container of [...this.containers]) {\n\t\t\t\t\tif (container.container.closed) {\n\t\t\t\t\t\tthis.containers.delete(container);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst containersToApply = [...this.containers].map((container) => container.container);\n\n\t\t\t\t// Ignore readonly/disconnected dirty containers: they can't send ops, so nothing can be done about them being dirty here.\n\t\t\t\t// Neither state is reachable through the ephemeral service API today, but the checks are cheap and keep this robust to future changes.\n\t\t\t\tconst dirtyContainers = containersToApply.filter((c) => {\n\t\t\t\t\tconst { deltaManager, isDirty, connectionState } = c;\n\t\t\t\t\treturn (\n\t\t\t\t\t\tconnectionState !== ConnectionState.Disconnected &&\n\t\t\t\t\t\tdeltaManager.readOnlyInfo.readonly !== true &&\n\t\t\t\t\t\tisDirty\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t\tif (dirtyContainers.length > 0) {\n\t\t\t\t\t// Bound this wait by the shared deadline: a container that never saves (and never\n\t\t\t\t\t// closes) must not block past the overall timeout, since the top-of-loop check can't\n\t\t\t\t\t// run while we are awaiting here.\n\t\t\t\t\tawait Promise.race([\n\t\t\t\t\t\tPromise.all(\n\t\t\t\t\t\t\tdirtyContainers.map(async (c) =>\n\t\t\t\t\t\t\t\tPromise.race([\n\t\t\t\t\t\t\t\t\tnew Promise((resolve) => c.once(\"saved\", resolve)),\n\t\t\t\t\t\t\t\t\tnew Promise((resolve) => c.once(\"closed\", resolve)),\n\t\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t\tdeadline,\n\t\t\t\t\t]);\n\n\t\t\t\t\tclean = 0;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Sample pending server work once per pass (the macrotask yield above gave the broadcaster's\n\t\t\t\t// scheduled send a chance to run first).\n\t\t\t\tif (await Promise.race([this.server.hasPendingWork(), deadline])) {\n\t\t\t\t\tclean = 0;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tclean++;\n\t\t\t}\n\t\t} finally {\n\t\t\tclearTimeout(deadlineTimer);\n\t\t}\n\t}\n\n\t/**\n\t * The document service factory for this service.\n\t * @remarks Internal helper for {@link EphemeralServiceContainer}; not part of the public {@link EphemeralService} API.\n\t */\n\tpublic getDocumentServiceFactory(): LocalDocumentServiceFactory {\n\t\tassert(\n\t\t\t!this.closed,\n\t\t\t0xd11 /* Cannot create or load containers on a closed EphemeralService */,\n\t\t);\n\t\treturn this.documentServiceFactory;\n\t}\n\n\t/**\n\t * Registers a newly created container as connected to this service.\n\t * @remarks Internal helper for {@link EphemeralServiceContainer}; not part of the public {@link EphemeralService} API.\n\t */\n\tpublic addContainer(container: EphemeralServiceContainer<unknown>): void {\n\t\tthis.containers.add(container);\n\t}\n\n\t/**\n\t * Removes a now-closed container from this service.\n\t * @remarks Internal helper for {@link EphemeralServiceContainer}; not part of the public {@link EphemeralService} API.\n\t */\n\tpublic removeContainer(container: EphemeralServiceContainer<unknown>): void {\n\t\tthis.containers.delete(container);\n\t}\n}\n\n/**\n * A {@link @fluidframework/driver-definitions#ServiceClient} connected to a specific {@link EphemeralService}.\n * @alpha @sealed\n */\nexport interface EphemeralServiceClient extends ServiceClient {\n\t/**\n\t * The service instance this client is connected to.\n\t */\n\treadonly service: EphemeralService;\n}\n\nclass EphemeralServiceClientImplementation\n\textends ServiceClientImplementation<EphemeralServiceOptions>\n\timplements EphemeralServiceClient\n{\n\tpublic readonly service: EphemeralService;\n\n\tpublic constructor(options: EphemeralServiceOptions) {\n\t\tsuper(options, EphemeralServiceContainer);\n\t\tthis.service = options.service;\n\t}\n}\n\nconst containerRuntimeLoader: ContainerRuntimeLoader = async (\n\tparameters: ContainerRuntimeLoaderParams,\n) => {\n\tconst { runtime } = await ContainerRuntime.loadRuntime2({\n\t\tcontext: parameters.context,\n\t\tregistry: parameters.registry,\n\t\tprovideEntryPoint: parameters.provideEntryPoint,\n\t\texisting: parameters.existing,\n\t\tminVersionForCollab: parameters.minVersionForCollab,\n\t\truntimeOptions: { enableRuntimeIdCompressor: \"on\" },\n\t});\n\tif (!parameters.existing) {\n\t\tassert(\n\t\t\tparameters.newContainerRootType !== undefined,\n\t\t\t0xd12 /* Root data store kind must be provided for new containers */,\n\t\t);\n\t\tconst dataStore = await runtime.createDataStore(parameters.newContainerRootType);\n\t\tconst aliasResult = await dataStore.trySetAlias(rootDataStoreId);\n\t\tassert(\n\t\t\taliasResult === \"Success\",\n\t\t\t0xd13 /* Should be able to set alias on new data store */,\n\t\t);\n\t}\n\treturn runtime;\n};\n\nconst urlResolver = new LocalResolver();\n/**\n * Create a request to open an existing document.\n *\n * @param documentId - the existing document to open.\n * @privateRemarks\n * Like createLocalResolverCreateNewRequest, but without the option to create a new document.\n * TODO: At some point we should avoid specifying the URL in so many places, but the current APIs don't accommodate it yet.\n */\nconst createLoadExistingRequest = (documentId: string): IRequest => {\n\treturn { url: `http://localhost:3000/${documentId}` };\n};\n\nlet documentIdCounter = 0;\n\n/**\n * A Fluid container backed by an ephemeral (in-memory) local service, implementing\n * {@link @fluidframework/driver-definitions#FluidContainerWithService}.\n *\n * @remarks\n * Data is stored in-memory by the {@link EphemeralService} the container's client is connected to (see\n * {@link EphemeralServiceContainer.service}), enabling side-by-side collaboration testing without a real server.\n *\n * @internal\n */\nexport class EphemeralServiceContainer<TData>\n\textends ServiceContainerBase<TData, EphemeralServiceOptions>\n\timplements FluidContainerWithService<TData>\n{\n\tpublic readonly service: EphemeralService;\n\n\tpublic static async createDetached<T>(\n\t\tregistry: DataStoreRegistry<T>,\n\t\toptions: EphemeralServiceOptions,\n\t\troot: DataStoreKind<T>,\n\t): Promise<EphemeralServiceContainer<T>> {\n\t\tEphemeralServiceImplementation.narrow(options.service);\n\t\tconst container: IContainer = await createDetachedContainer({\n\t\t\tcodeDetails: { package: \"1.0\" },\n\t\t\turlResolver,\n\t\t\tdocumentServiceFactory: options.service.getDocumentServiceFactory(),\n\t\t\tcodeLoader: makeCodeLoader(\n\t\t\t\tregistry,\n\t\t\t\toptions.oldestSupportedClient,\n\t\t\t\tcontainerRuntimeLoader,\n\t\t\t\troot,\n\t\t\t),\n\t\t});\n\n\t\treturn new EphemeralServiceContainer<T>(\n\t\t\tregistry,\n\t\t\toptions,\n\t\t\tcontainer,\n\t\t\t(await container.getEntryPoint()) as T,\n\t\t\tundefined,\n\t\t);\n\t}\n\n\tpublic static async load<T>(\n\t\tregistry: DataStoreRegistry<T>,\n\t\toptions: EphemeralServiceOptions,\n\t\tid: string,\n\t): Promise<EphemeralServiceContainer<T> & FluidContainerAttached<T>> {\n\t\tEphemeralServiceImplementation.narrow(options.service);\n\t\tconst containerInner = await loadExistingContainer({\n\t\t\trequest: createLoadExistingRequest(id),\n\t\t\turlResolver,\n\t\t\tdocumentServiceFactory: options.service.getDocumentServiceFactory(),\n\t\t\tcodeLoader: makeCodeLoader(\n\t\t\t\tregistry,\n\t\t\t\toptions.oldestSupportedClient,\n\t\t\t\tcontainerRuntimeLoader,\n\t\t\t),\n\t\t});\n\n\t\tconst container = new EphemeralServiceContainer<T>(\n\t\t\tregistry,\n\t\t\toptions,\n\t\t\tcontainerInner,\n\t\t\t(await containerInner.getEntryPoint()) as T,\n\t\t\tid,\n\t\t);\n\t\tassert(\n\t\t\tcontainer.id !== undefined,\n\t\t\t0xd14 /* id should be defined when loading a container */,\n\t\t);\n\t\treturn container as typeof container & { id: string };\n\t}\n\n\tprivate constructor(\n\t\tregistry: Registry<Promise<DataStoreKind<TData>>>,\n\t\toptions: EphemeralServiceOptions,\n\t\tcontainer: IContainer,\n\t\tdata: TData,\n\t\tid: string | undefined,\n\t) {\n\t\tsuper(registry, options, container, data, id);\n\t\tthis.service = options.service;\n\t\tEphemeralServiceImplementation.narrow(this.service);\n\t\tthis.service.addContainer(this);\n\t}\n\n\tpublic override close(): void {\n\t\tsuper.close();\n\t\t// Remove this now-closed container from its service's set of open containers.\n\t\tEphemeralServiceImplementation.narrow(this.service);\n\t\tthis.service.removeContainer(this);\n\t}\n\n\tprotected createAttachRequest(): IRequest {\n\t\tconst documentId = (documentIdCounter++).toString();\n\t\treturn createLocalResolverCreateNewRequest(documentId);\n\t}\n}\n"]}
1
+ {"version":3,"file":"ephemeralService.js","sourceRoot":"","sources":["../src/ephemeralService.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 {\n\tConnectionState,\n\ttype IContainer,\n} from \"@fluidframework/container-definitions/internal\";\nimport {\n\tcreateDetachedContainer,\n\tloadExistingContainer,\n} from \"@fluidframework/container-loader/internal\";\nimport { ContainerRuntime } from \"@fluidframework/container-runtime/internal\";\nimport type { IRequest } from \"@fluidframework/core-interfaces\";\nimport {\n\tErasedTypeImplementation,\n\ttype ErasedBaseType,\n} from \"@fluidframework/core-interfaces/internal\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport {\n\tfeatureVersion,\n\ttype DataStoreKind,\n\ttype DataStoreRegistry,\n\ttype FluidContainerAttached,\n\ttype FluidContainerWithService,\n\ttype OldestSupportedServiceClientVersion,\n\ttype Registry,\n\ttype ServiceClient,\n\ttype ServiceOptions,\n} from \"@fluidframework/driver-definitions/internal\";\nimport {\n\ttype ContainerRuntimeLoader,\n\ttype ContainerRuntimeLoaderParams,\n\tmakeCodeLoader,\n\trootDataStoreId,\n\tServiceClientImplementation,\n\tServiceContainerBase,\n} from \"@fluidframework/runtime-utils/internal\";\nimport {\n\tLocalDeltaConnectionServer,\n\ttype ILocalDeltaConnectionServer,\n} from \"@fluidframework/server-local-server\";\nimport { UsageError } from \"@fluidframework/driver-utils/internal\";\n\nimport { LocalDocumentServiceFactory } from \"./localDocumentServiceFactory.js\";\nimport { createLocalResolverCreateNewRequest, LocalResolver } from \"./localResolver.js\";\nimport { pkgVersion } from \"./packageVersion.js\";\n\n/**\n * Starts and returns a new {@link EphemeralService}.\n * @param isDefault - Whether this service should saved as the default service for {@link cleanupEphemeralService} to cleanup.\n * Defaults to true.\n * @remarks\n * The returned service owns an in-memory server and holds the documents created through clients connected to it.\n * {@link cleanupEphemeralService} can be used to ensure the service is properly cleaned up (a no-op if stopped/closed already).\n *\n * As a service, it may start timers which may require an explicit `close` to fully free.\n * @alpha\n */\nexport function startEphemeralService(isDefault = true): EphemeralService {\n\tif (isDefault && defaultEphemeralService) {\n\t\tthrow new UsageError(\"A default EphemeralService is already running\");\n\t}\n\n\tconst service = new EphemeralServiceImplementation();\n\tif (isDefault) {\n\t\tdefaultEphemeralService = service;\n\t}\n\treturn service;\n}\n\n/**\n * Cleans up the service passed in {@link startEphemeralService}, or the {@link getDefaultEphemeralService|default} if none is passed.\n * @remarks\n * This closes the service, and all its containers.\n * This is a good way to ensure the service and its containers leave no lingering timers\n * which could leak memory, trigger asynchronous work or prevent a clean process exit.\n * @alpha\n */\nexport async function cleanupEphemeralService(service?: EphemeralService): Promise<void> {\n\tconst toCleanup = service ?? defaultEphemeralService;\n\tif (toCleanup) {\n\t\t// TODO: we may want to make closing of containers a separate operation which is done here.\n\t\tawait toCleanup.close();\n\t}\n\tif (toCleanup === defaultEphemeralService) {\n\t\tdefaultEphemeralService = undefined;\n\t}\n}\n\n/**\n * Get the default {@link EphemeralService} if one has been {@link startEphemeralService|started}.\n * @throws If no default service is running.\n * @alpha\n */\nexport function getDefaultEphemeralService(): EphemeralService {\n\tif (defaultEphemeralService) {\n\t\treturn defaultEphemeralService;\n\t}\n\tthrow new UsageError(\"No default EphemeralService is running\");\n}\n\n/**\n * Internal Options for creating an {@link EphemeralServiceClient}, extending {@link @fluidframework/driver-definitions#ServiceOptions}\n * with the {@link EphemeralService} the client should connect to.\n * @input\n * @internal\n */\nexport interface EphemeralServiceOptions extends ServiceOptions {\n\t/**\n\t * {@inheritdoc @fluidframework/driver-definitions#ServiceOptions.oldestSupportedClient}\n\t */\n\treadonly oldestSupportedClient: OldestSupportedServiceClientVersion;\n\t/**\n\t * The service instance to connect to.\n\t */\n\treadonly service: EphemeralService;\n}\n\n/**\n * An in-memory Fluid service that can produce connected {@link EphemeralServiceClient}s.\n * @remarks\n * All documents created through clients connected to a given `EphemeralService` are held in-memory by that service.\n * Closing the service (via {@link EphemeralService.close} or {@link cleanupEphemeralService}) closes the connections\n * to any remaining open containers, and cleans up the service's timers.\n *\n * Create one with {@link startEphemeralService}.\n *\n * Most {@link @fluidframework/driver-definitions#ServiceClient} implementations would take in a URL and credentials to connect to a service,\n * but that is not needed for the ephemeral in-memory service.\n * Instead this object representing the actual service instance is provided.\n * @privateRemarks\n * This is separated out from the actual {@link @fluidframework/driver-definitions#ServiceClient} object so that it's possible to create multiple service clients\n * connected to the same service.\n * Doing so is rarely necessary, but would be needed to test multiple clients collaborating on the same\n * document with different `oldestSupportedClient` values.\n * This also exposes a place to put APIs for preloading and exporting document contents in the future.\n *\n * This is an erased type: its only implementation is the module-private {@link EphemeralServiceImplementation}, which holds\n * the mutable server and container state so it does not appear on this public type.\n *\n * TODO: formalize this lifecycle with an interface which documents these stages.\n * Lifecycle:\n * The intended lifecycle of an {@link EphemeralService} follows roughly the same pattern as containers:\n *\n * 1. Open: accepts connections from {@link EphemeralServiceClient}s, which can create and load containers.\n * Might have timers and event registrations which can trigger asynchronous work, and retain the object in memory.\n *\n * 2. Closing: asynchronous transition from open to closed. New use should behave as it closed, but may be cleaning up or saving resources asynchronously.\n * Timers and event registrations may still be active, but should be cleaned up by the time the transition to closed completes.\n *\n * 3. Closed: no longer accepts connections from {@link EphemeralServiceClient}s, and all containers connected to it are closed.\n * Should have no subscriptions to events or timers which could retain it in memory or trigger asynchronous work.\n * The object can still be used in a limited capacity (typically just to inspect its status (e.g. `isClosed`), and to view (but not edit) the final state of any containers which were connected to it before it closed.)\n *\n * Events or errors can cause an open to closing transition. Any nonfunctional state, including error states, should be considered as closed (or closing which will transition to closed),\n * and meet the requirements of closed with regards to timers and events.\n *\n * @alpha @sealed\n */\nexport interface EphemeralService extends ErasedBaseType<readonly [\"EphemeralService\"]> {\n\t/**\n\t * Close this service, which closes all containers connected to it and releases its resources.\n\t * @remarks\n\t * All documents held by this service are discarded, and any timers it (or its containers) were keeping alive\n\t * are cleaned up.\n\t * The returned promise resolves once all asynchronous cleanup (including shutting down the in-memory server)\n\t * has completed.\n\t * Closing is idempotent: calling it again after the service is closed resolves without doing anything.\n\t */\n\tclose(): Promise<void>;\n\n\t/**\n\t * Drives all containers connected to this service toward convergence, processing pending operations and\n\t * waiting for all dirty containers to save.\n\t *\n\t * @param timeoutMilliseconds - The maximum time to wait for containers to quiesce, in milliseconds. Defaults to 30_000.\n\t *\n\t * @privateRemarks\n\t * This is a best-effort implementation simplified from `LoaderContainerTracker.ensureSynchronized`.\n\t * Currently it does not perform receiver-side sequence-number quiescence or wait for join/leave (audience) ops.\n\t * See `LoaderContainerTracker.ensureSynchronized` for the fuller version this is based on.\n\t * For the currently exposed API surface, this should be sufficient,\n\t * but users down casting to internal types might run into some limitations.\n\t */\n\tsynchronize(timeoutMilliseconds?: number): Promise<void>;\n\n\t/**\n\t * Creates and returns a {@link EphemeralServiceClient} for an in-memory, ephemeral Fluid service.\n\t *\n\t * @param options - Options for the client. `oldestSupportedClient` may be omitted because all\n\t * clients are in the same process, so it defaults to the current version. `service` may be omitted to allocate a new\n\t * {@link EphemeralService} dedicated to this client, or provided to connect the client to an existing service instance.\n\t *\n\t * @remarks\n\t * The service is ephemeral and in-memory: all documents are held by the {@link EphemeralService} the client is\n\t * connected to, and live for as long as that service is open — independent of whether any container for them is open.\n\t * A document created and attached (obtaining an `id`) can be loaded by `id` for as long as its service remains open,\n\t * even after every container for it has been closed.\n\t * Closing the service (via {@link EphemeralService.close} or {@link cleanupEphemeralService}) discards all of its\n\t * documents and releases its resources; afterwards those `id`s can no longer be loaded.\n\t *\n\t * When no `service` is provided, a new one is allocated for this client (accessible via {@link EphemeralServiceClient.service}).\n\t * Provide the same {@link EphemeralService} to multiple clients (via `options.service`) to have them collaborate on the\n\t * same documents, and control that service's lifetime explicitly.\n\t *\n\t * Since a service holds timers while open, tests should close the services they use (e.g. via\n\t * {@link cleanupEphemeralService} in an `afterEach`) to avoid lingering timers that can hang test runners.\n\t *\n\t * @privateRemarks\n\t * TODO: We should provide a way to extract (for potential serialization as test data) and load documents into a service.\n\t * This is needed to use this API surface for testing reference documents.\n\t * Ideally we would provide a service agnostic way to do the export, but likely only support loading them into the local service.\n\t * This can be done via an API on FluidContainer (or a free function taking one) to do the export, then adding a\n\t * service specific API (on {@link EphemeralService}) to load from the export format and return the ID of the loaded document.\n\t */\n\tnewClient(options: ServiceOptions): EphemeralServiceClient;\n\n\t/**\n\t * A client connected to this service using the default options.\n\t */\n\treadonly defaultClient: EphemeralServiceClient;\n}\n\n/**\n * The {@link defaultEphemeralService} if one has been {@link startEphemeralService|started}.\n */\nlet defaultEphemeralService: EphemeralServiceImplementation | undefined;\n\n/**\n * The concrete implementation of {@link EphemeralService}.\n * @remarks\n * Kept module-private so its mutable state and internal helpers are not part of the public API.\n * Narrow an {@link EphemeralService} to it with `EphemeralServiceImplementation.narrow`.\n */\nclass EphemeralServiceImplementation\n\textends ErasedTypeImplementation<EphemeralService>\n\timplements EphemeralService\n{\n\t// A single server is shared by all containers connected to this service so they can communicate with each other.\n\tprivate readonly server: ILocalDeltaConnectionServer =\n\t\tLocalDeltaConnectionServer.create(\n\t\t\t// new LocalSessionStorageDbFactory(),\n\t\t);\n\tprivate readonly documentServiceFactory = new LocalDocumentServiceFactory(this.server);\n\tprivate readonly containers = new Set<EphemeralServiceContainer<unknown>>();\n\tprivate closed = false;\n\n\tpublic constructor() {\n\t\tsuper();\n\t\tthis.defaultClient = this.newClient();\n\t}\n\tpublic newClient(options?: Partial<ServiceOptions>): EphemeralServiceClient {\n\t\tconst finalOptions: EphemeralServiceOptions = {\n\t\t\toldestSupportedClient: options?.oldestSupportedClient ?? featureVersion(pkgVersion),\n\t\t\tservice: this,\n\t\t};\n\t\treturn new EphemeralServiceClientImplementation(finalOptions);\n\t}\n\tpublic readonly defaultClient: EphemeralServiceClient;\n\n\tpublic async close(): Promise<void> {\n\t\tif (this.closed) {\n\t\t\treturn;\n\t\t}\n\t\tthis.closed = true;\n\n\t\t// Close every open container via the same public close() path a user would use.\n\t\t// We might want to remove this.\n\t\tconst toClose = [...this.containers];\n\t\tthis.containers.clear();\n\t\tfor (const c of toClose) {\n\t\t\tc.close();\n\t\t}\n\n\t\t// Shut down the in-memory server. Its timers (e.g. the Deli read-client idle `setInterval`) belong to the\n\t\t// server rather than any container, so closing containers alone would leave them running.\n\t\tawait this.server.close();\n\t}\n\n\tpublic async synchronize(timeoutMilliseconds = 30_000): Promise<void> {\n\t\t// Timeout to allow for better errors in the case of hangs.\n\t\tlet timedOut = false;\n\t\tlet deadlineTimer: ReturnType<typeof setTimeout> | undefined;\n\t\tconst deadline = new Promise<true>((resolve) => {\n\t\t\tdeadlineTimer = setTimeout(() => {\n\t\t\t\ttimedOut = true;\n\t\t\t\tresolve(true);\n\t\t\t}, timeoutMilliseconds);\n\t\t});\n\n\t\ttry {\n\t\t\t// Require two consecutive quiescent passes (no dirty containers and no pending server work),\n\t\t\t// each separated by a macrotask turn, to give late side effects a chance to surface.\n\t\t\tlet clean = 0;\n\t\t\twhile (clean < 2) {\n\t\t\t\tif (timedOut) {\n\t\t\t\t\tthrow new UsageError(\n\t\t\t\t\t\t`EphemeralService.synchronize timed out after ${timeoutMilliseconds}ms waiting for local containers to quiesce.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// Yield a macrotask turn *first*, so the local server's scheduled broadcast send and each\n\t\t\t\t// container's inbound op processing can run before we sample their state below. Sampling\n\t\t\t\t// hasPendingWork() in a tight `while (await ...)` loop instead would starve that scheduled\n\t\t\t\t// send (it is a macrotask, while the await resolves on the microtask queue) and could hang.\n\t\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\t\tsetTimeout(resolve, 0);\n\t\t\t\t});\n\n\t\t\t\t// Prune any containers that have closed since the last pass.\n\t\t\t\tfor (const container of [...this.containers]) {\n\t\t\t\t\tif (container.container.closed) {\n\t\t\t\t\t\tthis.containers.delete(container);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst containersToApply = [...this.containers].map((container) => container.container);\n\n\t\t\t\t// Ignore readonly/disconnected dirty containers: they can't send ops, so nothing can be done about them being dirty here.\n\t\t\t\t// Neither state is reachable through the ephemeral service API today, but the checks are cheap and keep this robust to future changes.\n\t\t\t\tconst dirtyContainers = containersToApply.filter((c) => {\n\t\t\t\t\tconst { deltaManager, isDirty, connectionState } = c;\n\t\t\t\t\treturn (\n\t\t\t\t\t\tconnectionState !== ConnectionState.Disconnected &&\n\t\t\t\t\t\tdeltaManager.readOnlyInfo.readonly !== true &&\n\t\t\t\t\t\tisDirty\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t\tif (dirtyContainers.length > 0) {\n\t\t\t\t\t// Bound this wait by the shared deadline: a container that never saves (and never\n\t\t\t\t\t// closes) must not block past the overall timeout, since the top-of-loop check can't\n\t\t\t\t\t// run while we are awaiting here.\n\t\t\t\t\tawait Promise.race([\n\t\t\t\t\t\tPromise.all(\n\t\t\t\t\t\t\tdirtyContainers.map(async (c) =>\n\t\t\t\t\t\t\t\tPromise.race([\n\t\t\t\t\t\t\t\t\tnew Promise((resolve) => c.once(\"saved\", resolve)),\n\t\t\t\t\t\t\t\t\tnew Promise((resolve) => c.once(\"closed\", resolve)),\n\t\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t\tdeadline,\n\t\t\t\t\t]);\n\n\t\t\t\t\tclean = 0;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Sample pending server work once per pass (the macrotask yield above gave the broadcaster's\n\t\t\t\t// scheduled send a chance to run first).\n\t\t\t\tif (await Promise.race([this.server.hasPendingWork(), deadline])) {\n\t\t\t\t\tclean = 0;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tclean++;\n\t\t\t}\n\t\t} finally {\n\t\t\tclearTimeout(deadlineTimer);\n\t\t}\n\t}\n\n\t/**\n\t * The document service factory for this service.\n\t * @remarks Internal helper for {@link EphemeralServiceContainer}; not part of the public {@link EphemeralService} API.\n\t */\n\tpublic getDocumentServiceFactory(): LocalDocumentServiceFactory {\n\t\tassert(\n\t\t\t!this.closed,\n\t\t\t0xd11 /* Cannot create or load containers on a closed EphemeralService */,\n\t\t);\n\t\treturn this.documentServiceFactory;\n\t}\n\n\t/**\n\t * Registers a newly created container as connected to this service.\n\t * @remarks Internal helper for {@link EphemeralServiceContainer}; not part of the public {@link EphemeralService} API.\n\t */\n\tpublic addContainer(container: EphemeralServiceContainer<unknown>): void {\n\t\tthis.containers.add(container);\n\t}\n\n\t/**\n\t * Removes a now-closed container from this service.\n\t * @remarks Internal helper for {@link EphemeralServiceContainer}; not part of the public {@link EphemeralService} API.\n\t */\n\tpublic removeContainer(container: EphemeralServiceContainer<unknown>): void {\n\t\tthis.containers.delete(container);\n\t}\n}\n\n/**\n * A {@link @fluidframework/driver-definitions#ServiceClient} connected to a specific {@link EphemeralService}.\n * @alpha @sealed\n */\nexport interface EphemeralServiceClient extends ServiceClient {\n\t/**\n\t * The service instance this client is connected to.\n\t */\n\treadonly service: EphemeralService;\n}\n\nclass EphemeralServiceClientImplementation\n\textends ServiceClientImplementation<EphemeralServiceOptions>\n\timplements EphemeralServiceClient\n{\n\tpublic readonly service: EphemeralService;\n\n\tpublic constructor(options: EphemeralServiceOptions) {\n\t\tsuper(options, EphemeralServiceContainer);\n\t\tthis.service = options.service;\n\t}\n}\n\nconst containerRuntimeLoader: ContainerRuntimeLoader = async (\n\tparameters: ContainerRuntimeLoaderParams,\n) => {\n\tconst { runtime } = await ContainerRuntime.loadRuntime2({\n\t\tcontext: parameters.context,\n\t\tregistry: parameters.registry,\n\t\tprovideEntryPoint: parameters.provideEntryPoint,\n\t\texisting: parameters.existing,\n\t\toldestSupportedClient: parameters.minVersionForCollab,\n\t\truntimeOptions: { enableRuntimeIdCompressor: \"on\" },\n\t});\n\tif (!parameters.existing) {\n\t\tassert(\n\t\t\tparameters.newContainerRootType !== undefined,\n\t\t\t0xd12 /* Root data store kind must be provided for new containers */,\n\t\t);\n\t\tconst dataStore = await runtime.createDataStore(parameters.newContainerRootType);\n\t\tconst aliasResult = await dataStore.trySetAlias(rootDataStoreId);\n\t\tassert(\n\t\t\taliasResult === \"Success\",\n\t\t\t0xd13 /* Should be able to set alias on new data store */,\n\t\t);\n\t}\n\treturn runtime;\n};\n\nconst urlResolver = new LocalResolver();\n/**\n * Create a request to open an existing document.\n *\n * @param documentId - the existing document to open.\n * @privateRemarks\n * Like createLocalResolverCreateNewRequest, but without the option to create a new document.\n * TODO: At some point we should avoid specifying the URL in so many places, but the current APIs don't accommodate it yet.\n */\nconst createLoadExistingRequest = (documentId: string): IRequest => {\n\treturn { url: `http://localhost:3000/${documentId}` };\n};\n\nlet documentIdCounter = 0;\n\n/**\n * A Fluid container backed by an ephemeral (in-memory) local service, implementing\n * {@link @fluidframework/driver-definitions#FluidContainerWithService}.\n *\n * @remarks\n * Data is stored in-memory by the {@link EphemeralService} the container's client is connected to (see\n * {@link EphemeralServiceContainer.service}), enabling side-by-side collaboration testing without a real server.\n *\n * @internal\n */\nexport class EphemeralServiceContainer<TData>\n\textends ServiceContainerBase<TData, EphemeralServiceOptions>\n\timplements FluidContainerWithService<TData>\n{\n\tpublic readonly service: EphemeralService;\n\n\tpublic static async createDetached<T>(\n\t\tregistry: DataStoreRegistry<T>,\n\t\toptions: EphemeralServiceOptions,\n\t\troot: DataStoreKind<T>,\n\t): Promise<EphemeralServiceContainer<T>> {\n\t\tEphemeralServiceImplementation.narrow(options.service);\n\t\tconst container: IContainer = await createDetachedContainer({\n\t\t\tcodeDetails: { package: \"1.0\" },\n\t\t\turlResolver,\n\t\t\tdocumentServiceFactory: options.service.getDocumentServiceFactory(),\n\t\t\tcodeLoader: makeCodeLoader(\n\t\t\t\tregistry,\n\t\t\t\toptions.oldestSupportedClient,\n\t\t\t\tcontainerRuntimeLoader,\n\t\t\t\troot,\n\t\t\t),\n\t\t});\n\n\t\treturn new EphemeralServiceContainer<T>(\n\t\t\tregistry,\n\t\t\toptions,\n\t\t\tcontainer,\n\t\t\t(await container.getEntryPoint()) as T,\n\t\t\tundefined,\n\t\t);\n\t}\n\n\tpublic static async load<T>(\n\t\tregistry: DataStoreRegistry<T>,\n\t\toptions: EphemeralServiceOptions,\n\t\tid: string,\n\t): Promise<EphemeralServiceContainer<T> & FluidContainerAttached<T>> {\n\t\tEphemeralServiceImplementation.narrow(options.service);\n\t\tconst containerInner = await loadExistingContainer({\n\t\t\trequest: createLoadExistingRequest(id),\n\t\t\turlResolver,\n\t\t\tdocumentServiceFactory: options.service.getDocumentServiceFactory(),\n\t\t\tcodeLoader: makeCodeLoader(\n\t\t\t\tregistry,\n\t\t\t\toptions.oldestSupportedClient,\n\t\t\t\tcontainerRuntimeLoader,\n\t\t\t),\n\t\t});\n\n\t\tconst container = new EphemeralServiceContainer<T>(\n\t\t\tregistry,\n\t\t\toptions,\n\t\t\tcontainerInner,\n\t\t\t(await containerInner.getEntryPoint()) as T,\n\t\t\tid,\n\t\t);\n\t\tassert(\n\t\t\tcontainer.id !== undefined,\n\t\t\t0xd14 /* id should be defined when loading a container */,\n\t\t);\n\t\treturn container as typeof container & { id: string };\n\t}\n\n\tprivate constructor(\n\t\tregistry: Registry<Promise<DataStoreKind<TData>>>,\n\t\toptions: EphemeralServiceOptions,\n\t\tcontainer: IContainer,\n\t\tdata: TData,\n\t\tid: string | undefined,\n\t) {\n\t\tsuper(registry, options, container, data, id);\n\t\tthis.service = options.service;\n\t\tEphemeralServiceImplementation.narrow(this.service);\n\t\tthis.service.addContainer(this);\n\t}\n\n\tpublic override close(): void {\n\t\tsuper.close();\n\t\t// Remove this now-closed container from its service's set of open containers.\n\t\tEphemeralServiceImplementation.narrow(this.service);\n\t\tthis.service.removeContainer(this);\n\t}\n\n\tprotected createAttachRequest(): IRequest {\n\t\tconst documentId = (documentIdCounter++).toString();\n\t\treturn createLocalResolverCreateNewRequest(documentId);\n\t}\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -8,7 +8,7 @@ export { createLocalDocumentService, LocalDocumentService } from "./localDocumen
8
8
  export { LocalDocumentServiceFactory } from "./localDocumentServiceFactory.js";
9
9
  export { LocalDocumentStorageService } from "./localDocumentStorageService.js";
10
10
  export { createLocalResolverCreateNewRequest, LocalResolver } from "./localResolver.js";
11
- export { localDriverCompatDetailsForLoader } from "./localLayerCompatState.js";
11
+ export { localDriverCompatDetailsForLoader, localDriverCompatRequirementsForLoader, } from "./localLayerCompatState.js";
12
12
  export { LocalSessionStorageDbFactory } from "./localSessionStorageDb.js";
13
13
  export type { EphemeralService, EphemeralServiceClient, EphemeralServiceOptions, } from "./ephemeralService.js";
14
14
  export { startEphemeralService, cleanupEphemeralService, getDefaultEphemeralService, } from "./ephemeralService.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AACjF,OAAO,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAC7F,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EAAE,mCAAmC,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxF,OAAO,EAAE,iCAAiC,EAAE,MAAM,4BAA4B,CAAC;AAC/E,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAC1E,YAAY,EACX,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,GACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACN,qBAAqB,EACrB,uBAAuB,EACvB,0BAA0B,GAC1B,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AACjF,OAAO,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAC7F,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EAAE,mCAAmC,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxF,OAAO,EACN,iCAAiC,EACjC,sCAAsC,GACtC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAC1E,YAAY,EACX,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,GACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACN,qBAAqB,EACrB,uBAAuB,EACvB,0BAA0B,GAC1B,MAAM,uBAAuB,CAAC"}
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.getDefaultEphemeralService = exports.cleanupEphemeralService = exports.startEphemeralService = exports.LocalSessionStorageDbFactory = exports.localDriverCompatDetailsForLoader = exports.LocalResolver = exports.createLocalResolverCreateNewRequest = exports.LocalDocumentStorageService = exports.LocalDocumentServiceFactory = exports.LocalDocumentService = exports.createLocalDocumentService = exports.LocalDocumentDeltaConnection = exports.LocalDeltaStorageService = void 0;
7
+ exports.getDefaultEphemeralService = exports.cleanupEphemeralService = exports.startEphemeralService = exports.LocalSessionStorageDbFactory = exports.localDriverCompatRequirementsForLoader = exports.localDriverCompatDetailsForLoader = exports.LocalResolver = exports.createLocalResolverCreateNewRequest = exports.LocalDocumentStorageService = exports.LocalDocumentServiceFactory = exports.LocalDocumentService = exports.createLocalDocumentService = exports.LocalDocumentDeltaConnection = exports.LocalDeltaStorageService = void 0;
8
8
  var localDeltaStorageService_js_1 = require("./localDeltaStorageService.js");
9
9
  Object.defineProperty(exports, "LocalDeltaStorageService", { enumerable: true, get: function () { return localDeltaStorageService_js_1.LocalDeltaStorageService; } });
10
10
  var localDocumentDeltaConnection_js_1 = require("./localDocumentDeltaConnection.js");
@@ -21,6 +21,7 @@ Object.defineProperty(exports, "createLocalResolverCreateNewRequest", { enumerab
21
21
  Object.defineProperty(exports, "LocalResolver", { enumerable: true, get: function () { return localResolver_js_1.LocalResolver; } });
22
22
  var localLayerCompatState_js_1 = require("./localLayerCompatState.js");
23
23
  Object.defineProperty(exports, "localDriverCompatDetailsForLoader", { enumerable: true, get: function () { return localLayerCompatState_js_1.localDriverCompatDetailsForLoader; } });
24
+ Object.defineProperty(exports, "localDriverCompatRequirementsForLoader", { enumerable: true, get: function () { return localLayerCompatState_js_1.localDriverCompatRequirementsForLoader; } });
24
25
  var localSessionStorageDb_js_1 = require("./localSessionStorageDb.js");
25
26
  Object.defineProperty(exports, "LocalSessionStorageDbFactory", { enumerable: true, get: function () { return localSessionStorageDb_js_1.LocalSessionStorageDbFactory; } });
26
27
  var ephemeralService_js_1 = require("./ephemeralService.js");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,6EAAyE;AAAhE,uIAAA,wBAAwB,OAAA;AACjC,qFAAiF;AAAxE,+IAAA,4BAA4B,OAAA;AACrC,qEAA6F;AAApF,qIAAA,0BAA0B,OAAA;AAAE,+HAAA,oBAAoB,OAAA;AACzD,mFAA+E;AAAtE,6IAAA,2BAA2B,OAAA;AACpC,mFAA+E;AAAtE,6IAAA,2BAA2B,OAAA;AACpC,uDAAwF;AAA/E,uIAAA,mCAAmC,OAAA;AAAE,iHAAA,aAAa,OAAA;AAC3D,uEAA+E;AAAtE,6IAAA,iCAAiC,OAAA;AAC1C,uEAA0E;AAAjE,wIAAA,4BAA4B,OAAA;AAMrC,6DAI+B;AAH9B,4HAAA,qBAAqB,OAAA;AACrB,8HAAA,uBAAuB,OAAA;AACvB,iIAAA,0BAA0B,OAAA","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport { LocalDeltaStorageService } from \"./localDeltaStorageService.js\";\nexport { LocalDocumentDeltaConnection } from \"./localDocumentDeltaConnection.js\";\nexport { createLocalDocumentService, LocalDocumentService } from \"./localDocumentService.js\";\nexport { LocalDocumentServiceFactory } from \"./localDocumentServiceFactory.js\";\nexport { LocalDocumentStorageService } from \"./localDocumentStorageService.js\";\nexport { createLocalResolverCreateNewRequest, LocalResolver } from \"./localResolver.js\";\nexport { localDriverCompatDetailsForLoader } from \"./localLayerCompatState.js\";\nexport { LocalSessionStorageDbFactory } from \"./localSessionStorageDb.js\";\nexport type {\n\tEphemeralService,\n\tEphemeralServiceClient,\n\tEphemeralServiceOptions,\n} from \"./ephemeralService.js\";\nexport {\n\tstartEphemeralService,\n\tcleanupEphemeralService,\n\tgetDefaultEphemeralService,\n} from \"./ephemeralService.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,6EAAyE;AAAhE,uIAAA,wBAAwB,OAAA;AACjC,qFAAiF;AAAxE,+IAAA,4BAA4B,OAAA;AACrC,qEAA6F;AAApF,qIAAA,0BAA0B,OAAA;AAAE,+HAAA,oBAAoB,OAAA;AACzD,mFAA+E;AAAtE,6IAAA,2BAA2B,OAAA;AACpC,mFAA+E;AAAtE,6IAAA,2BAA2B,OAAA;AACpC,uDAAwF;AAA/E,uIAAA,mCAAmC,OAAA;AAAE,iHAAA,aAAa,OAAA;AAC3D,uEAGoC;AAFnC,6IAAA,iCAAiC,OAAA;AACjC,kJAAA,sCAAsC,OAAA;AAEvC,uEAA0E;AAAjE,wIAAA,4BAA4B,OAAA;AAMrC,6DAI+B;AAH9B,4HAAA,qBAAqB,OAAA;AACrB,8HAAA,uBAAuB,OAAA;AACvB,iIAAA,0BAA0B,OAAA","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport { LocalDeltaStorageService } from \"./localDeltaStorageService.js\";\nexport { LocalDocumentDeltaConnection } from \"./localDocumentDeltaConnection.js\";\nexport { createLocalDocumentService, LocalDocumentService } from \"./localDocumentService.js\";\nexport { LocalDocumentServiceFactory } from \"./localDocumentServiceFactory.js\";\nexport { LocalDocumentStorageService } from \"./localDocumentStorageService.js\";\nexport { createLocalResolverCreateNewRequest, LocalResolver } from \"./localResolver.js\";\nexport {\n\tlocalDriverCompatDetailsForLoader,\n\tlocalDriverCompatRequirementsForLoader,\n} from \"./localLayerCompatState.js\";\nexport { LocalSessionStorageDbFactory } from \"./localSessionStorageDb.js\";\nexport type {\n\tEphemeralService,\n\tEphemeralServiceClient,\n\tEphemeralServiceOptions,\n} from \"./ephemeralService.js\";\nexport {\n\tstartEphemeralService,\n\tcleanupEphemeralService,\n\tgetDefaultEphemeralService,\n} from \"./ephemeralService.js\";\n"]}
@@ -4,7 +4,7 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.createDocument = void 0;
7
+ exports.createDocument = createDocument;
8
8
  const internal_1 = require("@fluidframework/driver-utils/internal");
9
9
  const server_services_client_1 = require("@fluidframework/server-services-client");
10
10
  async function createDocument(localDeltaConnectionServer, resolvedUrl, summary) {
@@ -28,5 +28,4 @@ async function createDocument(localDeltaConnectionServer, resolvedUrl, summary)
28
28
  const sequenceNumber = documentAttributes.sequenceNumber;
29
29
  await documentStorage.createDocument(tenantId, id, appSummary, sequenceNumber, server_services_client_1.defaultHash, resolvedUrl.endpoints.ordererUrl ?? "", resolvedUrl.endpoints.storageUrl ?? "", resolvedUrl.endpoints.deltaStorageUrl ?? "", quorumValues, false /* enableDiscovery */, false /* isEphemeralContainer */);
30
30
  }
31
- exports.createDocument = createDocument;
32
31
  //# sourceMappingURL=localCreateDocument.js.map