@fluidframework/container-runtime 2.1.0-276326 → 2.1.0-281041
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.
- package/README.md +74 -21
- package/api-extractor/api-extractor.current.json +5 -0
- package/api-extractor/api-extractor.legacy.json +1 -1
- package/api-extractor.json +1 -1
- package/api-report/container-runtime.legacy.public.api.md +9 -0
- package/container-runtime.test-files.tar +0 -0
- package/dist/{blobManager.d.ts → blobManager/blobManager.d.ts} +19 -29
- package/dist/blobManager/blobManager.d.ts.map +1 -0
- package/dist/{blobManager.js → blobManager/blobManager.js} +42 -83
- package/dist/blobManager/blobManager.js.map +1 -0
- package/dist/blobManager/blobManagerSnapSum.d.ts +30 -0
- package/dist/blobManager/blobManagerSnapSum.d.ts.map +1 -0
- package/dist/blobManager/blobManagerSnapSum.js +82 -0
- package/dist/blobManager/blobManagerSnapSum.js.map +1 -0
- package/dist/blobManager/index.d.ts +7 -0
- package/dist/blobManager/index.d.ts.map +1 -0
- package/dist/blobManager/index.js +16 -0
- package/dist/blobManager/index.js.map +1 -0
- package/dist/channelCollection.d.ts +1 -1
- package/dist/channelCollection.d.ts.map +1 -1
- package/dist/channelCollection.js +40 -8
- package/dist/channelCollection.js.map +1 -1
- package/dist/containerRuntime.d.ts +15 -10
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +199 -162
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStoreContext.d.ts +5 -0
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +16 -5
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts +1 -1
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +16 -10
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +4 -2
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcHelpers.d.ts.map +1 -1
- package/dist/gc/gcHelpers.js +12 -0
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts +3 -2
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js +6 -6
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/legacy.d.ts +1 -1
- package/dist/metadata.d.ts +7 -1
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.js +6 -0
- package/dist/metadata.js.map +1 -1
- package/dist/opLifecycle/batchManager.d.ts +8 -1
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js +37 -16
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/definitions.d.ts +1 -1
- package/dist/opLifecycle/definitions.d.ts.map +1 -1
- package/dist/opLifecycle/definitions.js.map +1 -1
- package/dist/opLifecycle/index.d.ts +1 -1
- package/dist/opLifecycle/index.d.ts.map +1 -1
- package/dist/opLifecycle/index.js +2 -1
- package/dist/opLifecycle/index.js.map +1 -1
- package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opCompressor.js +12 -8
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js +14 -11
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +11 -6
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +22 -6
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +43 -21
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.d.ts +22 -6
- package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js +59 -9
- package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/pendingStateManager.d.ts +39 -13
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +98 -33
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/public.d.ts +1 -1
- package/dist/scheduleManager.js +4 -0
- package/dist/scheduleManager.js.map +1 -1
- package/dist/summary/index.d.ts +1 -1
- package/dist/summary/index.d.ts.map +1 -1
- package/dist/summary/index.js +1 -2
- package/dist/summary/index.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.js +2 -0
- package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts +0 -1
- package/dist/summary/summaryFormat.d.ts.map +1 -1
- package/dist/summary/summaryFormat.js +7 -4
- package/dist/summary/summaryFormat.js.map +1 -1
- package/internal.d.ts +1 -1
- package/legacy.d.ts +1 -1
- package/lib/{blobManager.d.ts → blobManager/blobManager.d.ts} +19 -29
- package/lib/blobManager/blobManager.d.ts.map +1 -0
- package/lib/{blobManager.js → blobManager/blobManager.js} +40 -83
- package/lib/blobManager/blobManager.js.map +1 -0
- package/lib/blobManager/blobManagerSnapSum.d.ts +30 -0
- package/lib/blobManager/blobManagerSnapSum.d.ts.map +1 -0
- package/lib/blobManager/blobManagerSnapSum.js +75 -0
- package/lib/blobManager/blobManagerSnapSum.js.map +1 -0
- package/lib/blobManager/index.d.ts +7 -0
- package/lib/blobManager/index.d.ts.map +1 -0
- package/lib/blobManager/index.js +7 -0
- package/lib/blobManager/index.js.map +1 -0
- package/lib/channelCollection.d.ts +1 -1
- package/lib/channelCollection.d.ts.map +1 -1
- package/lib/channelCollection.js +40 -8
- package/lib/channelCollection.js.map +1 -1
- package/lib/containerRuntime.d.ts +15 -10
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +149 -112
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStoreContext.d.ts +5 -0
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +17 -6
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts +1 -1
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +16 -10
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +4 -2
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcHelpers.d.ts.map +1 -1
- package/lib/gc/gcHelpers.js +12 -0
- package/lib/gc/gcHelpers.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts +3 -2
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +6 -6
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/legacy.d.ts +1 -1
- package/lib/metadata.d.ts +7 -1
- package/lib/metadata.d.ts.map +1 -1
- package/lib/metadata.js +4 -1
- package/lib/metadata.js.map +1 -1
- package/lib/opLifecycle/batchManager.d.ts +8 -1
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js +35 -15
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/definitions.d.ts +1 -1
- package/lib/opLifecycle/definitions.d.ts.map +1 -1
- package/lib/opLifecycle/definitions.js.map +1 -1
- package/lib/opLifecycle/index.d.ts +1 -1
- package/lib/opLifecycle/index.d.ts.map +1 -1
- package/lib/opLifecycle/index.js +1 -1
- package/lib/opLifecycle/index.js.map +1 -1
- package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opCompressor.js +12 -8
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js +14 -11
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +11 -6
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +22 -6
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +44 -22
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.d.ts +22 -6
- package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js +57 -7
- package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/pendingStateManager.d.ts +39 -13
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +99 -34
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/public.d.ts +1 -1
- package/lib/scheduleManager.js +4 -0
- package/lib/scheduleManager.js.map +1 -1
- package/lib/summary/index.d.ts +1 -1
- package/lib/summary/index.d.ts.map +1 -1
- package/lib/summary/index.js +1 -1
- package/lib/summary/index.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.js +2 -0
- package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/lib/summary/summaryFormat.d.ts +0 -1
- package/lib/summary/summaryFormat.d.ts.map +1 -1
- package/lib/summary/summaryFormat.js +5 -2
- package/lib/summary/summaryFormat.js.map +1 -1
- package/package.json +49 -34
- package/src/{blobManager.ts → blobManager/blobManager.ts} +57 -123
- package/src/blobManager/blobManagerSnapSum.ts +133 -0
- package/src/blobManager/index.ts +19 -0
- package/src/channelCollection.ts +48 -11
- package/src/containerRuntime.ts +213 -158
- package/src/dataStoreContext.ts +30 -6
- package/src/gc/garbageCollection.ts +17 -12
- package/src/gc/gcDefinitions.ts +7 -2
- package/src/gc/gcHelpers.ts +18 -6
- package/src/gc/gcTelemetry.ts +20 -8
- package/src/index.ts +1 -1
- package/src/metadata.ts +11 -1
- package/src/opLifecycle/README.md +0 -8
- package/src/opLifecycle/batchManager.ts +46 -16
- package/src/opLifecycle/definitions.ts +1 -1
- package/src/opLifecycle/index.ts +8 -1
- package/src/opLifecycle/opCompressor.ts +12 -8
- package/src/opLifecycle/opGroupingManager.ts +14 -11
- package/src/opLifecycle/opSplitter.ts +10 -6
- package/src/opLifecycle/outbox.ts +64 -26
- package/src/opLifecycle/remoteMessageProcessor.ts +84 -11
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +177 -60
- package/src/scheduleManager.ts +6 -2
- package/src/summary/README.md +81 -0
- package/src/summary/index.ts +0 -1
- package/src/summary/summarizerNode/summarizerNodeUtils.ts +3 -1
- package/src/summary/summaryFormat.ts +4 -2
- package/src/summary/summaryFormats.md +69 -8
- package/tsconfig.json +0 -1
- package/dist/blobManager.d.ts.map +0 -1
- package/dist/blobManager.js.map +0 -1
- package/lib/blobManager.d.ts.map +0 -1
- package/lib/blobManager.js.map +0 -1
- package/src/summary/images/appTree.png +0 -0
- package/src/summary/images/protocolAndAppTree.png +0 -0
- package/src/summary/images/summaryTree.png +0 -0
package/README.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# @fluidframework/container-runtime
|
|
2
2
|
|
|
3
|
+
<!-- AUTO-GENERATED-CONTENT:START (LIBRARY_PACKAGE_README_HEADER) -->
|
|
4
|
+
|
|
5
|
+
<!-- prettier-ignore-start -->
|
|
6
|
+
<!-- NOTE: This section is automatically generated using @fluid-tools/markdown-magic. Do not update these generated contents directly. -->
|
|
7
|
+
|
|
8
|
+
## Using Fluid Framework libraries
|
|
9
|
+
|
|
10
|
+
When taking a dependency on a Fluid Framework library's public APIs, we recommend using a `^` (caret) version range, such as `^1.3.4`.
|
|
11
|
+
While Fluid Framework libraries may use different ranges with interdependencies between other Fluid Framework libraries,
|
|
12
|
+
library consumers should always prefer `^`.
|
|
13
|
+
|
|
14
|
+
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
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
To get started, install the package by running the following command:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm i @fluidframework/container-runtime
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Importing from this package
|
|
25
|
+
|
|
26
|
+
This package leverages [package.json exports](https://nodejs.org/api/packages.html#exports) to separate its APIs by support level.
|
|
27
|
+
For more information on the related support guarantees, see [API Support Levels](https://fluidframework.com/docs/build/releases-and-apitags/#api-support-levels).
|
|
28
|
+
|
|
29
|
+
To access the `public` ([SemVer](https://semver.org/)) APIs, import via `@fluidframework/container-runtime` like normal.
|
|
30
|
+
|
|
31
|
+
To access the `legacy` APIs, import via `@fluidframework/container-runtime/legacy`.
|
|
32
|
+
|
|
33
|
+
<!-- prettier-ignore-end -->
|
|
34
|
+
|
|
35
|
+
<!-- AUTO-GENERATED-CONTENT:END -->
|
|
36
|
+
|
|
3
37
|
## Data Virtualization For DataStores (Work in Progress)
|
|
4
38
|
|
|
5
39
|
It's a capability to exclude some content from initial snapshot (used when loading container) and thus improve boot
|
|
@@ -45,37 +79,58 @@ fetch snapshot for that group of datastores rather than one network call for eac
|
|
|
45
79
|
can get fairly big in size content wise and which are not required to be loaded on boot, can be put under a non-default
|
|
46
80
|
groupId.
|
|
47
81
|
|
|
48
|
-
<!-- AUTO-GENERATED-CONTENT:START (
|
|
82
|
+
<!-- AUTO-GENERATED-CONTENT:START (LIBRARY_PACKAGE_README_FOOTER) -->
|
|
49
83
|
|
|
50
84
|
<!-- prettier-ignore-start -->
|
|
51
85
|
<!-- NOTE: This section is automatically generated using @fluid-tools/markdown-magic. Do not update these generated contents directly. -->
|
|
52
86
|
|
|
53
|
-
##
|
|
87
|
+
## API Documentation
|
|
54
88
|
|
|
55
|
-
|
|
56
|
-
While Fluid Framework libraries may use different ranges with interdependencies between other Fluid Framework libraries,
|
|
57
|
-
library consumers should always prefer `^`.
|
|
89
|
+
API documentation for **@fluidframework/container-runtime** is available at <https://fluidframework.com/docs/apis/container-runtime>.
|
|
58
90
|
|
|
59
|
-
##
|
|
91
|
+
## Minimum Client Requirements
|
|
60
92
|
|
|
61
|
-
|
|
93
|
+
These are the platform requirements for the current version of Fluid Framework Client Packages.
|
|
94
|
+
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.
|
|
95
|
+
For Long Term Support (LTS) versions this can require supporting these platforms for several years.
|
|
62
96
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
97
|
+
It is likely that other configurations will work, but they are not supported: if they stop working, we do not consider that a bug.
|
|
98
|
+
If you would benefit from support for something not listed here, file an issue and the product team will evaluate your request.
|
|
99
|
+
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.
|
|
66
100
|
|
|
67
|
-
|
|
101
|
+
### Supported Runtimes
|
|
68
102
|
|
|
69
|
-
|
|
70
|
-
|
|
103
|
+
- NodeJs ^20.10.0 except that we will drop support for it [when NodeJs 20 loses its upstream support on 2026-04-30](https://github.com/nodejs/release#release-schedule), and will support a newer LTS version of NodeJS (22) at least 1 year before 20 is end-of-life. This same policy applies to NodeJS 22 when it is end of life (2027-04-30).
|
|
104
|
+
- 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).
|
|
71
105
|
|
|
72
|
-
|
|
106
|
+
### Supported Tools
|
|
73
107
|
|
|
74
|
-
|
|
108
|
+
- TypeScript 5.4:
|
|
109
|
+
- All [`strict`](https://www.typescriptlang.org/tsconfig) options are supported.
|
|
110
|
+
- [`strictNullChecks`](https://www.typescriptlang.org/tsconfig) is required.
|
|
111
|
+
- [Configuration options deprecated in 5.0](https://github.com/microsoft/TypeScript/issues/51909) are not supported.
|
|
112
|
+
- `exactOptionalPropertyTypes` is currently not fully supported.
|
|
113
|
+
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.
|
|
114
|
+
- [webpack](https://webpack.js.org/) 5
|
|
115
|
+
- We are not intending to be prescriptive about what bundler to use.
|
|
116
|
+
Other bundlers which can handle ES Modules should work, but webpack is the only one we actively test.
|
|
75
117
|
|
|
76
|
-
|
|
118
|
+
### Module Resolution
|
|
77
119
|
|
|
78
|
-
|
|
120
|
+
[`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).
|
|
121
|
+
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.
|
|
122
|
+
|
|
123
|
+
### Module Formats
|
|
124
|
+
|
|
125
|
+
- ES Modules:
|
|
126
|
+
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.
|
|
127
|
+
- CommonJs:
|
|
128
|
+
Consuming our client packages as CommonJs is supported only in NodeJS and only for the cases listed below.
|
|
129
|
+
This is done to accommodate some workflows without good ES Module support.
|
|
130
|
+
If you have a workflow you would like included in this list, file an issue.
|
|
131
|
+
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.
|
|
132
|
+
|
|
133
|
+
- 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))
|
|
79
134
|
|
|
80
135
|
## Contribution Guidelines
|
|
81
136
|
|
|
@@ -97,11 +152,9 @@ Use of Microsoft trademarks or logos in modified versions of this project must n
|
|
|
97
152
|
|
|
98
153
|
## Help
|
|
99
154
|
|
|
100
|
-
Not finding what you're looking for in this README? Check out
|
|
101
|
-
Wiki](https://github.com/microsoft/FluidFramework/wiki) or [fluidframework.com](https://fluidframework.com/docs/).
|
|
155
|
+
Not finding what you're looking for in this README? Check out [fluidframework.com](https://fluidframework.com/docs/).
|
|
102
156
|
|
|
103
|
-
Still not finding what you're looking for? Please [file an
|
|
104
|
-
issue](https://github.com/microsoft/FluidFramework/wiki/Submitting-Bugs-and-Feature-Requests).
|
|
157
|
+
Still not finding what you're looking for? Please [file an issue](https://github.com/microsoft/FluidFramework/wiki/Submitting-Bugs-and-Feature-Requests).
|
|
105
158
|
|
|
106
159
|
Thank you!
|
|
107
160
|
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
|
|
3
|
+
"extends": "<projectFolder>/../../../common/build/build-common/api-extractor-report.esm.current.json",
|
|
4
|
+
"mainEntryPointFilePath": "<projectFolder>/lib/public.d.ts"
|
|
5
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
|
|
3
|
-
"extends": "<projectFolder>/../../../common/build/build-common/api-extractor-
|
|
3
|
+
"extends": "<projectFolder>/../../../common/build/build-common/api-extractor-report.esm.legacy.json"
|
|
4
4
|
}
|
package/api-extractor.json
CHANGED
|
@@ -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-
|
|
3
|
+
"extends": "../../../common/build/build-common/api-extractor-model.esm.json"
|
|
4
4
|
}
|
|
Binary file
|
|
@@ -6,9 +6,10 @@ import { TypedEventEmitter } from "@fluid-internal/client-utils";
|
|
|
6
6
|
import { ICriticalContainerError } from "@fluidframework/container-definitions";
|
|
7
7
|
import { IContainerRuntime, IContainerRuntimeEvents } from "@fluidframework/container-runtime-definitions/internal";
|
|
8
8
|
import { IFluidHandleContext, type IFluidHandleInternal } from "@fluidframework/core-interfaces/internal";
|
|
9
|
-
import { IDocumentStorageService,
|
|
9
|
+
import { IDocumentStorageService, ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
|
|
10
10
|
import { IGarbageCollectionData, ISummaryTreeWithStats, ITelemetryContext } from "@fluidframework/runtime-definitions/internal";
|
|
11
11
|
import { FluidHandleBase } from "@fluidframework/runtime-utils/internal";
|
|
12
|
+
import { type IBlobManagerLoadInfo } from "./blobManagerSnapSum.js";
|
|
12
13
|
/**
|
|
13
14
|
* This class represents blob (long string)
|
|
14
15
|
* This object is used only when creating (writing) new blob and serialization purposes.
|
|
@@ -28,15 +29,6 @@ export declare class BlobHandle extends FluidHandleBase<ArrayBufferLike> {
|
|
|
28
29
|
attachGraph(): void;
|
|
29
30
|
bind(handle: IFluidHandleInternal): void;
|
|
30
31
|
}
|
|
31
|
-
/**
|
|
32
|
-
* Information from a snapshot needed to load BlobManager
|
|
33
|
-
* @legacy
|
|
34
|
-
* @alpha
|
|
35
|
-
*/
|
|
36
|
-
export interface IBlobManagerLoadInfo {
|
|
37
|
-
ids?: string[];
|
|
38
|
-
redirectTable?: [string, string][];
|
|
39
|
-
}
|
|
40
32
|
export type IBlobManagerRuntime = Pick<IContainerRuntime, "attachState" | "connected" | "baseLogger" | "clientDetails"> & TypedEventEmitter<IContainerRuntimeEvents>;
|
|
41
33
|
export interface IPendingBlobs {
|
|
42
34
|
[id: string]: {
|
|
@@ -50,9 +42,8 @@ export interface IPendingBlobs {
|
|
|
50
42
|
export interface IBlobManagerEvents {
|
|
51
43
|
(event: "noPendingBlobs", listener: () => void): any;
|
|
52
44
|
}
|
|
45
|
+
export declare const blobManagerBasePath: "_blobs";
|
|
53
46
|
export declare class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
54
|
-
static readonly basePath = "_blobs";
|
|
55
|
-
private static readonly redirectTableBlobName;
|
|
56
47
|
private readonly mc;
|
|
57
48
|
/**
|
|
58
49
|
* Map of local IDs to storage IDs. Contains identity entries (id → id) for storage IDs. All requested IDs should
|
|
@@ -109,11 +100,6 @@ export declare class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
109
100
|
* Upload blobs added while offline. This must be completed before connecting and resubmitting ops.
|
|
110
101
|
*/
|
|
111
102
|
trackPendingStashedUploads(): Promise<void>;
|
|
112
|
-
/**
|
|
113
|
-
* Set of actual storage IDs (i.e., IDs that can be requested from storage). This will be empty if the container is
|
|
114
|
-
* detached or there are no (non-pending) attachment blobs in the document
|
|
115
|
-
*/
|
|
116
|
-
private get storageIds();
|
|
117
103
|
getBlob(blobId: string): Promise<ArrayBufferLike>;
|
|
118
104
|
private getBlobHandle;
|
|
119
105
|
private createBlobDetached;
|
|
@@ -134,17 +120,6 @@ export declare class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
134
120
|
*/
|
|
135
121
|
reSubmit(metadata: Record<string, unknown> | undefined): void;
|
|
136
122
|
processBlobAttachOp(message: ISequencedDocumentMessage, local: boolean): void;
|
|
137
|
-
/**
|
|
138
|
-
* Reads blobs needed to load BlobManager from storage.
|
|
139
|
-
* @param blobsTree - Tree containing IDs of previously attached blobs. We
|
|
140
|
-
* look for the IDs in the blob entries of the tree since the both the r11s
|
|
141
|
-
* and SPO drivers replace the attachment types returned in snapshot() with blobs.
|
|
142
|
-
*/
|
|
143
|
-
static load(blobsTree: ISnapshotTree | undefined, tryFetchBlob: (id: string) => Promise<[string, string][]>): Promise<IBlobManagerLoadInfo>;
|
|
144
|
-
/**
|
|
145
|
-
* Load a set of previously attached blob IDs and redirect table from a previous snapshot.
|
|
146
|
-
*/
|
|
147
|
-
private load;
|
|
148
123
|
summarize(telemetryContext?: ITelemetryContext): ISummaryTreeWithStats;
|
|
149
124
|
/**
|
|
150
125
|
* Generates data used for garbage collection. Each blob uploaded represents a node in the GC graph as it can be
|
|
@@ -162,7 +137,7 @@ export declare class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
162
137
|
deleteSweepReadyNodes(sweepReadyBlobRoutes: readonly string[]): readonly string[];
|
|
163
138
|
/**
|
|
164
139
|
* Delete blobs with the given routes from the redirect table.
|
|
165
|
-
* The routes are GC nodes paths of format -`/<
|
|
140
|
+
* The routes are GC nodes paths of format -`/<blobManagerBasePath>/<blobId>`. The blob ids are all local ids.
|
|
166
141
|
* Deleting the blobs involves 2 steps:
|
|
167
142
|
* 1. The redirect table entry for the local ids are deleted.
|
|
168
143
|
* 2. If the storage ids corresponding to the deleted local ids are not in-use anymore, the redirect table entries
|
|
@@ -178,6 +153,21 @@ export declare class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
178
153
|
*/
|
|
179
154
|
private verifyBlobNotDeleted;
|
|
180
155
|
setRedirectTable(table: Map<string, string>): void;
|
|
156
|
+
/**
|
|
157
|
+
* Part of container serialization when imminent closure is enabled (Currently when calling closeAndGetPendingLocalState).
|
|
158
|
+
* This asynchronous function resolves all pending createBlob calls and waits for each blob
|
|
159
|
+
* to be attached. It will also send BlobAttach ops for each pending blob that hasn't sent it
|
|
160
|
+
* yet so that serialized container can resubmit them when rehydrated.
|
|
161
|
+
*
|
|
162
|
+
* @param stopBlobAttachingSignal - Optional signal to abort the blob attaching process.
|
|
163
|
+
* @returns - A promise that resolves with the details of the attached blobs,
|
|
164
|
+
* or undefined if no blobs were processed.
|
|
165
|
+
*/
|
|
181
166
|
attachAndGetPendingBlobs(stopBlobAttachingSignal?: AbortSignal): Promise<IPendingBlobs | undefined>;
|
|
182
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* Returns whether a given path is for attachment blobs that are in the format - "/blobManagerBasePath/...".
|
|
170
|
+
*/
|
|
171
|
+
export declare const isBlobPath: (path: string) => path is `/_blobs/${string}`;
|
|
172
|
+
export declare const areBlobPathParts: (pathParts: string[]) => pathParts is ["", "_blobs", string];
|
|
183
173
|
//# sourceMappingURL=blobManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blobManager.d.ts","sourceRoot":"","sources":["../../src/blobManager/blobManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.BlobManager = exports.BlobHandle = void 0;
|
|
7
|
+
exports.areBlobPathParts = exports.isBlobPath = exports.BlobManager = exports.blobManagerBasePath = exports.BlobHandle = void 0;
|
|
8
8
|
const client_utils_1 = require("@fluid-internal/client-utils");
|
|
9
9
|
const container_definitions_1 = require("@fluidframework/container-definitions");
|
|
10
10
|
const internal_1 = require("@fluidframework/core-utils/internal");
|
|
@@ -12,6 +12,7 @@ const internal_2 = require("@fluidframework/driver-utils/internal");
|
|
|
12
12
|
const internal_3 = require("@fluidframework/runtime-utils/internal");
|
|
13
13
|
const internal_4 = require("@fluidframework/telemetry-utils/internal");
|
|
14
14
|
const uuid_1 = require("uuid");
|
|
15
|
+
const blobManagerSnapSum_js_1 = require("./blobManagerSnapSum.js");
|
|
15
16
|
/**
|
|
16
17
|
* This class represents blob (long string)
|
|
17
18
|
* This object is used only when creating (writing) new blob and serialization purposes.
|
|
@@ -49,6 +50,7 @@ const stashedPendingBlobOverrides = {
|
|
|
49
50
|
minTTLInSeconds: undefined,
|
|
50
51
|
uploadTime: undefined,
|
|
51
52
|
};
|
|
53
|
+
exports.blobManagerBasePath = "_blobs";
|
|
52
54
|
class BlobManager extends client_utils_1.TypedEventEmitter {
|
|
53
55
|
constructor(props) {
|
|
54
56
|
super();
|
|
@@ -74,7 +76,7 @@ class BlobManager extends client_utils_1.TypedEventEmitter {
|
|
|
74
76
|
logger: this.runtime.baseLogger,
|
|
75
77
|
namespace: "BlobManager",
|
|
76
78
|
});
|
|
77
|
-
this.redirectTable =
|
|
79
|
+
this.redirectTable = (0, blobManagerSnapSum_js_1.toRedirectTable)(snapshot, this.mc.logger, this.runtime.attachState);
|
|
78
80
|
// Begin uploading stashed blobs from previous container instance
|
|
79
81
|
Object.entries(stashedBlobs ?? {}).forEach(([localId, entry]) => {
|
|
80
82
|
const { acked, storageId, minTTLInSeconds, uploadTime } = entry;
|
|
@@ -165,20 +167,6 @@ class BlobManager extends client_utils_1.TypedEventEmitter {
|
|
|
165
167
|
count: pendingUploads.length,
|
|
166
168
|
}, async () => Promise.all(pendingUploads), { start: true, end: true });
|
|
167
169
|
}
|
|
168
|
-
/**
|
|
169
|
-
* Set of actual storage IDs (i.e., IDs that can be requested from storage). This will be empty if the container is
|
|
170
|
-
* detached or there are no (non-pending) attachment blobs in the document
|
|
171
|
-
*/
|
|
172
|
-
get storageIds() {
|
|
173
|
-
const ids = new Set(this.redirectTable.values());
|
|
174
|
-
// If we are detached, we will not have storage IDs, only undefined
|
|
175
|
-
const undefinedValueInTable = ids.delete(undefined);
|
|
176
|
-
// For a detached container, entries are inserted into the redirect table with an undefined storage ID.
|
|
177
|
-
// For an attached container, entries are inserted w/storage ID after the BlobAttach op round-trips.
|
|
178
|
-
(0, internal_1.assert)(!undefinedValueInTable ||
|
|
179
|
-
(this.runtime.attachState === container_definitions_1.AttachState.Detached && ids.size === 0), 0x382 /* 'redirectTable' must contain only undefined while detached / defined values while attached */);
|
|
180
|
-
return ids;
|
|
181
|
-
}
|
|
182
170
|
async getBlob(blobId) {
|
|
183
171
|
// Verify that the blob is not deleted, i.e., it has not been garbage collected. If it is, this will throw
|
|
184
172
|
// an error, failing the call.
|
|
@@ -210,14 +198,16 @@ class BlobManager extends client_utils_1.TypedEventEmitter {
|
|
|
210
198
|
getBlobHandle(id) {
|
|
211
199
|
(0, internal_1.assert)(this.redirectTable.has(id) || this.pendingBlobs.has(id), 0x384 /* requesting handle for unknown blob */);
|
|
212
200
|
const pending = this.pendingBlobs.get(id);
|
|
201
|
+
// Create a callback function for once the blob has been attached
|
|
213
202
|
const callback = pending
|
|
214
203
|
? () => {
|
|
215
204
|
pending.attached = true;
|
|
205
|
+
// Notify listeners (e.g. serialization process) that blob has been attached
|
|
216
206
|
this.emit("blobAttached", pending);
|
|
217
207
|
this.deletePendingBlobMaybe(id);
|
|
218
208
|
}
|
|
219
209
|
: undefined;
|
|
220
|
-
return new BlobHandle(
|
|
210
|
+
return new BlobHandle(getGCNodePathFromBlobId(id), this.routeContext, async () => this.getBlob(id), callback);
|
|
221
211
|
}
|
|
222
212
|
async createBlobDetached(blob) {
|
|
223
213
|
// Blobs created while the container is detached are stored in IDetachedBlobStorage.
|
|
@@ -325,7 +315,8 @@ class BlobManager extends client_utils_1.TypedEventEmitter {
|
|
|
325
315
|
if (!entry.opsent) {
|
|
326
316
|
this.sendBlobAttachOp(localId, response.id);
|
|
327
317
|
}
|
|
328
|
-
|
|
318
|
+
const storageIds = (0, blobManagerSnapSum_js_1.getStorageIds)(this.redirectTable, this.runtime.attachState);
|
|
319
|
+
if (storageIds.has(response.id)) {
|
|
329
320
|
// The blob is de-duped. Set up a local ID to storage ID mapping and return the blob. Since this is
|
|
330
321
|
// an existing blob, we don't have to wait for the op to be ack'd since this step has already
|
|
331
322
|
// happened before and so, the server won't delete it.
|
|
@@ -403,60 +394,8 @@ class BlobManager extends client_utils_1.TypedEventEmitter {
|
|
|
403
394
|
}
|
|
404
395
|
}
|
|
405
396
|
}
|
|
406
|
-
/**
|
|
407
|
-
* Reads blobs needed to load BlobManager from storage.
|
|
408
|
-
* @param blobsTree - Tree containing IDs of previously attached blobs. We
|
|
409
|
-
* look for the IDs in the blob entries of the tree since the both the r11s
|
|
410
|
-
* and SPO drivers replace the attachment types returned in snapshot() with blobs.
|
|
411
|
-
*/
|
|
412
|
-
static async load(blobsTree, tryFetchBlob) {
|
|
413
|
-
if (!blobsTree) {
|
|
414
|
-
return {};
|
|
415
|
-
}
|
|
416
|
-
let redirectTable;
|
|
417
|
-
const tableId = blobsTree.blobs[this.redirectTableBlobName];
|
|
418
|
-
if (tableId) {
|
|
419
|
-
redirectTable = await tryFetchBlob(tableId);
|
|
420
|
-
}
|
|
421
|
-
const ids = Object.entries(blobsTree.blobs)
|
|
422
|
-
.filter(([k, _]) => k !== this.redirectTableBlobName)
|
|
423
|
-
.map(([_, v]) => v);
|
|
424
|
-
return { ids, redirectTable };
|
|
425
|
-
}
|
|
426
|
-
/**
|
|
427
|
-
* Load a set of previously attached blob IDs and redirect table from a previous snapshot.
|
|
428
|
-
*/
|
|
429
|
-
load(snapshot) {
|
|
430
|
-
this.mc.logger.sendTelemetryEvent({
|
|
431
|
-
eventName: "AttachmentBlobsLoaded",
|
|
432
|
-
count: snapshot.ids?.length ?? 0,
|
|
433
|
-
redirectTable: snapshot.redirectTable?.length,
|
|
434
|
-
});
|
|
435
|
-
const table = new Map(snapshot.redirectTable);
|
|
436
|
-
if (snapshot.ids) {
|
|
437
|
-
const detached = this.runtime.attachState === container_definitions_1.AttachState.Detached;
|
|
438
|
-
// If we are detached, we don't have storage IDs yet, so set to undefined
|
|
439
|
-
// Otherwise, set identity (id -> id) entries
|
|
440
|
-
snapshot.ids.forEach((entry) => table.set(entry, detached ? undefined : entry));
|
|
441
|
-
}
|
|
442
|
-
return table;
|
|
443
|
-
}
|
|
444
397
|
summarize(telemetryContext) {
|
|
445
|
-
|
|
446
|
-
const blobIds = this.storageIds.size > 0
|
|
447
|
-
? Array.from(this.storageIds)
|
|
448
|
-
: Array.from(this.redirectTable.keys());
|
|
449
|
-
const builder = new internal_3.SummaryTreeBuilder();
|
|
450
|
-
blobIds.forEach((blobId) => {
|
|
451
|
-
builder.addAttachment(blobId);
|
|
452
|
-
});
|
|
453
|
-
// Any non-identity entries in the table need to be saved in the summary
|
|
454
|
-
if (this.redirectTable.size > blobIds.length) {
|
|
455
|
-
builder.addBlob(BlobManager.redirectTableBlobName,
|
|
456
|
-
// filter out identity entries
|
|
457
|
-
JSON.stringify(Array.from(this.redirectTable.entries()).filter(([localId, storageId]) => localId !== storageId)));
|
|
458
|
-
}
|
|
459
|
-
return builder.getSummaryTree();
|
|
398
|
+
return (0, blobManagerSnapSum_js_1.summarizeBlobManagerState)(this.redirectTable, this.runtime.attachState);
|
|
460
399
|
}
|
|
461
400
|
/**
|
|
462
401
|
* Generates data used for garbage collection. Each blob uploaded represents a node in the GC graph as it can be
|
|
@@ -490,7 +429,7 @@ class BlobManager extends client_utils_1.TypedEventEmitter {
|
|
|
490
429
|
}
|
|
491
430
|
/**
|
|
492
431
|
* Delete blobs with the given routes from the redirect table.
|
|
493
|
-
* The routes are GC nodes paths of format -`/<
|
|
432
|
+
* The routes are GC nodes paths of format -`/<blobManagerBasePath>/<blobId>`. The blob ids are all local ids.
|
|
494
433
|
* Deleting the blobs involves 2 steps:
|
|
495
434
|
* 1. The redirect table entry for the local ids are deleted.
|
|
496
435
|
* 2. If the storage ids corresponding to the deleted local ids are not in-use anymore, the redirect table entries
|
|
@@ -554,7 +493,7 @@ class BlobManager extends client_utils_1.TypedEventEmitter {
|
|
|
554
493
|
// Only log deleted events. Tombstone events are logged by garbage collector.
|
|
555
494
|
this.mc.logger.sendErrorEvent({
|
|
556
495
|
eventName: "GC_Deleted_Blob_Requested",
|
|
557
|
-
pkg:
|
|
496
|
+
pkg: exports.blobManagerBasePath,
|
|
558
497
|
}, error);
|
|
559
498
|
throw error;
|
|
560
499
|
}
|
|
@@ -568,6 +507,16 @@ class BlobManager extends client_utils_1.TypedEventEmitter {
|
|
|
568
507
|
this.setRedirection(storageId, storageId);
|
|
569
508
|
}
|
|
570
509
|
}
|
|
510
|
+
/**
|
|
511
|
+
* Part of container serialization when imminent closure is enabled (Currently when calling closeAndGetPendingLocalState).
|
|
512
|
+
* This asynchronous function resolves all pending createBlob calls and waits for each blob
|
|
513
|
+
* to be attached. It will also send BlobAttach ops for each pending blob that hasn't sent it
|
|
514
|
+
* yet so that serialized container can resubmit them when rehydrated.
|
|
515
|
+
*
|
|
516
|
+
* @param stopBlobAttachingSignal - Optional signal to abort the blob attaching process.
|
|
517
|
+
* @returns - A promise that resolves with the details of the attached blobs,
|
|
518
|
+
* or undefined if no blobs were processed.
|
|
519
|
+
*/
|
|
571
520
|
async attachAndGetPendingBlobs(stopBlobAttachingSignal) {
|
|
572
521
|
return internal_4.PerformanceEvent.timedExecAsync(this.mc.logger, { eventName: "GetPendingBlobs" }, async () => {
|
|
573
522
|
if (this.pendingBlobs.size === 0) {
|
|
@@ -575,12 +524,17 @@ class BlobManager extends client_utils_1.TypedEventEmitter {
|
|
|
575
524
|
}
|
|
576
525
|
const blobs = {};
|
|
577
526
|
const localBlobs = new Set();
|
|
527
|
+
// This while is used to stash blobs created while attaching and getting blobs
|
|
578
528
|
while (localBlobs.size < this.pendingBlobs.size) {
|
|
579
529
|
const attachBlobsP = [];
|
|
580
530
|
for (const [id, entry] of this.pendingBlobs) {
|
|
581
531
|
if (!localBlobs.has(entry)) {
|
|
582
532
|
localBlobs.add(entry);
|
|
533
|
+
// Resolving the blob handle to let hosts continue with their operations (it will resolve
|
|
534
|
+
// original createBlob call) and let them attach the blob. This is a lie we told since the upload
|
|
535
|
+
// hasn't finished yet, but it's fine since we will retry on rehydration.
|
|
583
536
|
entry.handleP.resolve(this.getBlobHandle(id));
|
|
537
|
+
// Array of promises that will resolve when blobs get attached.
|
|
584
538
|
attachBlobsP.push(new Promise((resolve, reject) => {
|
|
585
539
|
stopBlobAttachingSignal?.addEventListener("abort", () => {
|
|
586
540
|
this.stopAttaching = true;
|
|
@@ -601,6 +555,8 @@ class BlobManager extends client_utils_1.TypedEventEmitter {
|
|
|
601
555
|
}));
|
|
602
556
|
}
|
|
603
557
|
}
|
|
558
|
+
// Wait for all blobs to be attached. This is important, otherwise serialized container
|
|
559
|
+
// could send the blobAttach op without any op that references the blob, making it useless.
|
|
604
560
|
await Promise.allSettled(attachBlobsP).catch(() => { });
|
|
605
561
|
}
|
|
606
562
|
for (const [id, entry] of this.pendingBlobs) {
|
|
@@ -628,22 +584,25 @@ class BlobManager extends client_utils_1.TypedEventEmitter {
|
|
|
628
584
|
}
|
|
629
585
|
}
|
|
630
586
|
exports.BlobManager = BlobManager;
|
|
631
|
-
BlobManager.basePath = "_blobs";
|
|
632
|
-
BlobManager.redirectTableBlobName = ".redirectTable";
|
|
633
587
|
/**
|
|
634
|
-
* For a blobId, returns its path in GC's graph. The node path is of the format `/<
|
|
588
|
+
* For a blobId, returns its path in GC's graph. The node path is of the format `/<blobManagerBasePath>/<blobId>`.
|
|
635
589
|
* This path must match the path of the blob handle returned by the createBlob API because blobs are marked
|
|
636
590
|
* referenced by storing these handles in a referenced DDS.
|
|
637
591
|
*/
|
|
638
|
-
|
|
639
|
-
return `/${BlobManager.basePath}/${blobId}`;
|
|
640
|
-
}
|
|
592
|
+
const getGCNodePathFromBlobId = (blobId) => `/${exports.blobManagerBasePath}/${blobId}`;
|
|
641
593
|
/**
|
|
642
|
-
* For a given GC node path, return the blobId. The node path is of the format `/<
|
|
594
|
+
* For a given GC node path, return the blobId. The node path is of the format `/<basePath>/<blobId>`.
|
|
643
595
|
*/
|
|
644
|
-
|
|
596
|
+
const getBlobIdFromGCNodePath = (nodePath) => {
|
|
645
597
|
const pathParts = nodePath.split("/");
|
|
646
|
-
(0, internal_1.assert)(
|
|
598
|
+
(0, internal_1.assert)((0, exports.areBlobPathParts)(pathParts), 0x5bd /* Invalid blob node path */);
|
|
647
599
|
return pathParts[2];
|
|
648
|
-
}
|
|
600
|
+
};
|
|
601
|
+
/**
|
|
602
|
+
* Returns whether a given path is for attachment blobs that are in the format - "/blobManagerBasePath/...".
|
|
603
|
+
*/
|
|
604
|
+
const isBlobPath = (path) => (0, exports.areBlobPathParts)(path.split("/"));
|
|
605
|
+
exports.isBlobPath = isBlobPath;
|
|
606
|
+
const areBlobPathParts = (pathParts) => pathParts.length === 3 && pathParts[1] === exports.blobManagerBasePath;
|
|
607
|
+
exports.areBlobPathParts = areBlobPathParts;
|
|
649
608
|
//# sourceMappingURL=blobManager.js.map
|