@fluidframework/runtime-utils 2.53.1 → 2.61.0-355054

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 (137) hide show
  1. package/.eslintrc.cjs +1 -4
  2. package/.mocharc.cjs +1 -2
  3. package/CHANGELOG.md +4 -0
  4. package/api-report/{runtime-utils.legacy.alpha.api.md → runtime-utils.legacy.beta.api.md} +12 -12
  5. package/dist/compatibilityBase.d.ts +1 -3
  6. package/dist/compatibilityBase.d.ts.map +1 -1
  7. package/dist/compatibilityBase.js +3 -0
  8. package/dist/compatibilityBase.js.map +1 -1
  9. package/dist/dataStoreHandleContextUtils.d.ts +1 -1
  10. package/dist/dataStoreHandleContextUtils.d.ts.map +1 -1
  11. package/dist/dataStoreHandleContextUtils.js.map +1 -1
  12. package/dist/dataStoreHelpers.d.ts +18 -6
  13. package/dist/dataStoreHelpers.d.ts.map +1 -1
  14. package/dist/dataStoreHelpers.js +43 -15
  15. package/dist/dataStoreHelpers.js.map +1 -1
  16. package/dist/deltaManager.d.ts +1 -2
  17. package/dist/deltaManager.d.ts.map +1 -1
  18. package/dist/deltaManager.js +3 -2
  19. package/dist/deltaManager.js.map +1 -1
  20. package/dist/handles.d.ts +8 -12
  21. package/dist/handles.d.ts.map +1 -1
  22. package/dist/handles.js +14 -12
  23. package/dist/handles.js.map +1 -1
  24. package/dist/index.d.ts +6 -3
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js.map +1 -1
  27. package/dist/legacy.d.ts +4 -2
  28. package/dist/objectstoragepartition.d.ts +1 -1
  29. package/dist/objectstoragepartition.d.ts.map +1 -1
  30. package/dist/objectstoragepartition.js.map +1 -1
  31. package/dist/objectstorageutils.d.ts +9 -1
  32. package/dist/objectstorageutils.d.ts.map +1 -1
  33. package/dist/objectstorageutils.js +15 -6
  34. package/dist/objectstorageutils.js.map +1 -1
  35. package/dist/packageVersion.d.ts +1 -1
  36. package/dist/packageVersion.d.ts.map +1 -1
  37. package/dist/packageVersion.js +1 -1
  38. package/dist/packageVersion.js.map +1 -1
  39. package/dist/public.d.ts +2 -1
  40. package/dist/remoteFluidObjectHandle.d.ts +2 -2
  41. package/dist/remoteFluidObjectHandle.d.ts.map +1 -1
  42. package/dist/remoteFluidObjectHandle.js +1 -0
  43. package/dist/remoteFluidObjectHandle.js.map +1 -1
  44. package/dist/requestParser.d.ts +2 -3
  45. package/dist/requestParser.d.ts.map +1 -1
  46. package/dist/requestParser.js +9 -11
  47. package/dist/requestParser.js.map +1 -1
  48. package/dist/runtimeFactoryHelper.d.ts +3 -4
  49. package/dist/runtimeFactoryHelper.d.ts.map +1 -1
  50. package/dist/runtimeFactoryHelper.js +1 -2
  51. package/dist/runtimeFactoryHelper.js.map +1 -1
  52. package/dist/summaryUtils.d.ts +29 -20
  53. package/dist/summaryUtils.d.ts.map +1 -1
  54. package/dist/summaryUtils.js +49 -21
  55. package/dist/summaryUtils.js.map +1 -1
  56. package/dist/unpackUsedRoutes.d.ts.map +1 -1
  57. package/dist/unpackUsedRoutes.js +3 -3
  58. package/dist/unpackUsedRoutes.js.map +1 -1
  59. package/dist/utils.d.ts +1 -1
  60. package/dist/utils.d.ts.map +1 -1
  61. package/dist/utils.js.map +1 -1
  62. package/internal.d.ts +1 -1
  63. package/legacy.d.ts +1 -1
  64. package/lib/compatibilityBase.d.ts +1 -3
  65. package/lib/compatibilityBase.d.ts.map +1 -1
  66. package/lib/compatibilityBase.js +3 -0
  67. package/lib/compatibilityBase.js.map +1 -1
  68. package/lib/dataStoreHandleContextUtils.d.ts +1 -1
  69. package/lib/dataStoreHandleContextUtils.d.ts.map +1 -1
  70. package/lib/dataStoreHandleContextUtils.js.map +1 -1
  71. package/lib/dataStoreHelpers.d.ts +18 -6
  72. package/lib/dataStoreHelpers.d.ts.map +1 -1
  73. package/lib/dataStoreHelpers.js +43 -15
  74. package/lib/dataStoreHelpers.js.map +1 -1
  75. package/lib/deltaManager.d.ts +1 -2
  76. package/lib/deltaManager.d.ts.map +1 -1
  77. package/lib/deltaManager.js +3 -2
  78. package/lib/deltaManager.js.map +1 -1
  79. package/lib/handles.d.ts +8 -12
  80. package/lib/handles.d.ts.map +1 -1
  81. package/lib/handles.js +14 -12
  82. package/lib/handles.js.map +1 -1
  83. package/lib/index.d.ts +6 -3
  84. package/lib/index.d.ts.map +1 -1
  85. package/lib/index.js.map +1 -1
  86. package/lib/legacy.d.ts +4 -2
  87. package/lib/objectstoragepartition.d.ts +1 -1
  88. package/lib/objectstoragepartition.d.ts.map +1 -1
  89. package/lib/objectstoragepartition.js.map +1 -1
  90. package/lib/objectstorageutils.d.ts +9 -1
  91. package/lib/objectstorageutils.d.ts.map +1 -1
  92. package/lib/objectstorageutils.js +15 -6
  93. package/lib/objectstorageutils.js.map +1 -1
  94. package/lib/packageVersion.d.ts +1 -1
  95. package/lib/packageVersion.d.ts.map +1 -1
  96. package/lib/packageVersion.js +1 -1
  97. package/lib/packageVersion.js.map +1 -1
  98. package/lib/public.d.ts +2 -1
  99. package/lib/remoteFluidObjectHandle.d.ts +2 -2
  100. package/lib/remoteFluidObjectHandle.d.ts.map +1 -1
  101. package/lib/remoteFluidObjectHandle.js +1 -0
  102. package/lib/remoteFluidObjectHandle.js.map +1 -1
  103. package/lib/requestParser.d.ts +2 -3
  104. package/lib/requestParser.d.ts.map +1 -1
  105. package/lib/requestParser.js +9 -11
  106. package/lib/requestParser.js.map +1 -1
  107. package/lib/runtimeFactoryHelper.d.ts +3 -4
  108. package/lib/runtimeFactoryHelper.d.ts.map +1 -1
  109. package/lib/runtimeFactoryHelper.js +1 -2
  110. package/lib/runtimeFactoryHelper.js.map +1 -1
  111. package/lib/summaryUtils.d.ts +29 -20
  112. package/lib/summaryUtils.d.ts.map +1 -1
  113. package/lib/summaryUtils.js +51 -23
  114. package/lib/summaryUtils.js.map +1 -1
  115. package/lib/tsdoc-metadata.json +1 -1
  116. package/lib/unpackUsedRoutes.d.ts.map +1 -1
  117. package/lib/unpackUsedRoutes.js +3 -3
  118. package/lib/unpackUsedRoutes.js.map +1 -1
  119. package/lib/utils.d.ts +1 -1
  120. package/lib/utils.d.ts.map +1 -1
  121. package/lib/utils.js.map +1 -1
  122. package/package.json +22 -22
  123. package/src/compatibilityBase.ts +4 -3
  124. package/src/dataStoreHandleContextUtils.ts +1 -1
  125. package/src/dataStoreHelpers.ts +52 -20
  126. package/src/deltaManager.ts +3 -2
  127. package/src/handles.ts +14 -13
  128. package/src/index.ts +6 -4
  129. package/src/objectstoragepartition.ts +2 -2
  130. package/src/objectstorageutils.ts +17 -8
  131. package/src/packageVersion.ts +1 -1
  132. package/src/remoteFluidObjectHandle.ts +4 -3
  133. package/src/requestParser.ts +15 -15
  134. package/src/runtimeFactoryHelper.ts +4 -5
  135. package/src/summaryUtils.ts +70 -43
  136. package/src/unpackUsedRoutes.ts +7 -5
  137. package/src/utils.ts +2 -2
@@ -3,7 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { IRequest, IResponse } from "@fluidframework/core-interfaces";
6
+ import type { IRequest, IResponse } from "@fluidframework/core-interfaces";
7
7
  import { assert } from "@fluidframework/core-utils/internal";
8
8
  import { generateErrorWithStack } from "@fluidframework/telemetry-utils/internal";
9
9
 
@@ -12,53 +12,76 @@ interface IResponseException extends Error {
12
12
  message: string;
13
13
  code: number;
14
14
  stack?: string;
15
- underlyingResponseHeaders?: { [key: string]: any };
15
+ underlyingResponseHeaders?: Record<string, unknown>;
16
16
  }
17
17
 
18
18
  /**
19
+ * Type guard for determining if an error is an {@link IResponseException}.
19
20
  * @internal
20
21
  */
21
- export function exceptionToResponse(err: any): IResponse {
22
+ function isResponseException(err: unknown): err is IResponseException {
23
+ return (
24
+ err !== null &&
25
+ typeof err === "object" &&
26
+ "errorFromRequestFluidObject" in err &&
27
+ (err as { errorFromRequestFluidObject: unknown }).errorFromRequestFluidObject === true
28
+ );
29
+ }
30
+
31
+ /**
32
+ * Converts an error object into an {@link @fluidframework/core-interfaces#IResponse}.
33
+ * @internal
34
+ */
35
+ export function exceptionToResponse(error: unknown): IResponse {
22
36
  const status = 500;
23
- if (err !== null && typeof err === "object" && err.errorFromRequestFluidObject === true) {
24
- const responseErr: IResponseException = err;
37
+ if (isResponseException(error)) {
25
38
  return {
26
39
  mimeType: "text/plain",
27
- status: responseErr.code,
28
- value: responseErr.message,
40
+ status: error.code,
41
+ value: error.message,
29
42
  get stack() {
30
- return responseErr.stack;
43
+ return error.stack;
31
44
  },
32
- headers: responseErr.underlyingResponseHeaders,
45
+ headers: error.underlyingResponseHeaders,
33
46
  };
34
47
  }
35
48
 
36
- // Capture error objects, not stack itself, as stack retrieval is very expensive operation, so we delay it
37
- const errWithStack = generateErrorWithStack();
49
+ // Both error generation, and accessing the stack value are expensive operations, so we only create an error if necessary, and then defer accessing the stack value until it is needed.
50
+ const errWithStack =
51
+ typeof error === "object" && error !== null && "stack" in error
52
+ ? (error as { stack: string })
53
+ : generateErrorWithStack();
38
54
 
39
55
  return {
40
56
  mimeType: "text/plain",
41
57
  status,
42
- value: `${err}`,
58
+ value: `${error}`,
43
59
  get stack() {
44
- return (err?.stack as string | undefined) ?? errWithStack.stack;
60
+ return errWithStack.stack;
45
61
  },
46
62
  };
47
63
  }
48
64
 
49
65
  /**
66
+ * Converts an {@link @fluidframework/core-interfaces#IResponse} back into an Error object that can be thrown.
67
+ * @param response - The {@link @fluidframework/core-interfaces#IResponse} to convert.
68
+ * @param request - The original {@link @fluidframework/core-interfaces#IRequest}.
69
+ * @returns An Error object with additional properties from the response
50
70
  * @internal
51
71
  */
52
72
  export function responseToException(response: IResponse, request: IRequest): Error {
53
- const message = response.value;
54
- const errWithStack = generateErrorWithStack();
73
+ // As of 2025-08-20 the code seems to assume `response.value` is always a string.
74
+ // This type assertion just encodes that assumption as we move to stricter linting rules, but it might need to be revisited.
75
+ const message = response.value as string;
76
+ // Both error generation, and accessing the stack value are expensive operations, so we only create an error if necessary, and then defer accessing the stack value until it is needed.
77
+ const errWithStack = "stack" in response ? response : generateErrorWithStack();
55
78
  const responseErr: Error & IResponseException = {
56
79
  errorFromRequestFluidObject: true,
57
80
  message,
58
81
  name: "Error",
59
82
  code: response.status,
60
83
  get stack() {
61
- return response.stack ?? errWithStack.stack;
84
+ return errWithStack.stack;
62
85
  },
63
86
  underlyingResponseHeaders: response.headers,
64
87
  };
@@ -67,26 +90,35 @@ export function responseToException(response: IResponse, request: IRequest): Err
67
90
  }
68
91
 
69
92
  /**
93
+ * Creates a 404 "not found" response for the given request
94
+ * @param request - The request that resulted in the 404 response
95
+ * @returns An {@link @fluidframework/core-interfaces#IResponse} with 404 status code.
70
96
  * @legacy
71
- * @alpha
97
+ * @beta
72
98
  */
73
- export const create404Response = (request: IRequest) =>
99
+ export const create404Response = (request: IRequest): IResponse =>
74
100
  createResponseError(404, "not found", request);
75
101
 
76
102
  /**
103
+ * Creates an error response with the specified status code and message
104
+ * @param status - HTTP status code for the error (must not be 200)
105
+ * @param value - Error message or description
106
+ * @param request - The request that resulted in this error
107
+ * @param headers - Optional headers to include in the response
108
+ * @returns An {@link @fluidframework/core-interfaces#IResponse} representing the error
77
109
  * @internal
78
110
  */
79
111
  export function createResponseError(
80
112
  status: number,
81
113
  value: string,
82
114
  request: IRequest,
83
- headers?: { [key: string]: any },
115
+ headers?: Record<string, unknown>,
84
116
  ): IResponse {
85
117
  assert(status !== 200, 0x19b /* "Cannot not create response error on 200 status" */);
86
118
  // Omit query string which could contain personal data unfit for logging
87
119
  const urlNoQuery = request.url?.split("?")[0];
88
120
 
89
- // Capture error objects, not stack itself, as stack retrieval is very expensive operation, so we delay it
121
+ // Both error generation, and accessing the stack value are expensive operations, so we only create an error if necessary, and then defer accessing the stack value until it is needed.
90
122
  const errWithStack = generateErrorWithStack();
91
123
 
92
124
  return {
@@ -13,12 +13,12 @@ import type {
13
13
  /**
14
14
  * Casts the public API for delta manager into the internal one,
15
15
  * exposing access to APIs needed by the implementation of Fluid Framework but not its users.
16
- * @legacy
17
- * @alpha
16
+ * @legacy @beta
18
17
  */
19
18
  export function toDeltaManagerInternal(
20
19
  deltaManager: IDeltaManagerErased,
21
20
  ): IDeltaManager<ISequencedDocumentMessage, IDocumentMessage> {
21
+ // Type assertion is safe as IDeltaManagerErased is specifically designed to be a type-erased version of IDeltaManager
22
22
  return deltaManager as unknown as IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>;
23
23
  }
24
24
 
@@ -29,5 +29,6 @@ export function toDeltaManagerInternal(
29
29
  export function toDeltaManagerErased(
30
30
  deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,
31
31
  ): IDeltaManagerErased {
32
+ // Type assertion is safe as we're intentionally erasing the type information for public API safety
32
33
  return deltaManager as unknown as IDeltaManagerErased;
33
34
  }
package/src/handles.ts CHANGED
@@ -36,13 +36,15 @@ export interface ISerializedHandle {
36
36
  }
37
37
 
38
38
  /**
39
- * Is the input object a @see ISerializedHandle?
39
+ * Narrow a value to {@link ISerializedHandle} by checking its type property.
40
40
  * @internal
41
41
  */
42
- export const isSerializedHandle = (value: any): value is ISerializedHandle =>
43
- value?.type === "__fluid_handle__";
42
+ export const isSerializedHandle = (value: unknown): value is ISerializedHandle =>
43
+ // Type assertion is safe as we're only checking for the existence of the type property
44
+ (value as { type?: string } | undefined)?.type === "__fluid_handle__";
44
45
 
45
46
  /**
47
+ * Checks if a Fluid handle's internal payload is pending.
46
48
  * @internal
47
49
  */
48
50
  export const isFluidHandleInternalPayloadPending = (
@@ -55,8 +57,7 @@ export const isFluidHandleInternalPayloadPending = (
55
57
  * @privateRemarks
56
58
  * This should be true for locally-created BlobHandles currently. When IFluidHandlePayloadPending is merged
57
59
  * to IFluidHandle, this type guard will no longer be necessary.
58
- * @legacy
59
- * @alpha
60
+ * @legacy @beta
60
61
  */
61
62
  export const isFluidHandlePayloadPending = <T>(
62
63
  handle: IFluidHandle<T>,
@@ -66,8 +67,7 @@ export const isFluidHandlePayloadPending = <T>(
66
67
 
67
68
  /**
68
69
  * Check if the handle is an ILocalFluidHandle.
69
- * @legacy
70
- * @alpha
70
+ * @legacy @beta
71
71
  */
72
72
  export const isLocalFluidHandle = <T>(
73
73
  handle: IFluidHandle<T>,
@@ -122,6 +122,7 @@ export function isFluidHandle(value: unknown): value is IFluidHandle {
122
122
  // If enableBackwardsCompatibility, run check for FluidHandles predating use of fluidHandleSymbol.
123
123
  if (enableBackwardsCompatibility && IFluidHandle in value) {
124
124
  // Since this check can have false positives, make it a bit more robust by checking value[IFluidHandle][IFluidHandle]
125
+ // Type assertion is needed for backward compatibility with old FluidHandle format
125
126
  const inner = value[IFluidHandle] as IFluidHandle;
126
127
  if (typeof inner !== "object" || inner === null) {
127
128
  return false;
@@ -145,12 +146,12 @@ export function compareFluidHandles(a: IFluidHandle, b: IFluidHandle): boolean {
145
146
 
146
147
  /**
147
148
  * Downcast an IFluidHandle to an IFluidHandleInternal.
148
- * @legacy
149
- * @alpha
149
+ * @legacy @beta
150
150
  */
151
151
  export function toFluidHandleInternal<T>(handle: IFluidHandle<T>): IFluidHandleInternal<T> {
152
152
  if (!(fluidHandleSymbol in handle) || !(fluidHandleSymbol in handle[fluidHandleSymbol])) {
153
153
  if (enableBackwardsCompatibility && IFluidHandle in handle) {
154
+ // Type assertion needed for backward compatibility with old handle format
154
155
  return handle[IFluidHandle] as IFluidHandleInternal<T>;
155
156
  }
156
157
  throw new TypeError("Invalid IFluidHandle");
@@ -158,24 +159,24 @@ export function toFluidHandleInternal<T>(handle: IFluidHandle<T>): IFluidHandleI
158
159
 
159
160
  // This casts the IFluidHandleErased from the symbol instead of `handle` to ensure that if someone
160
161
  // implements their own IFluidHandle in terms of an existing handle, it won't break anything.
162
+ // Type assertion is safe as fluidHandleSymbol is guaranteed to contain an IFluidHandleInternal
161
163
  return handle[fluidHandleSymbol] as unknown as IFluidHandleInternal<T>;
162
164
  }
163
165
 
164
166
  /**
165
167
  * Type erase IFluidHandleInternal for use with {@link @fluidframework/core-interfaces#fluidHandleSymbol}.
166
- * @legacy
167
- * @alpha
168
+ * @legacy @beta
168
169
  */
169
170
  export function toFluidHandleErased<T>(
170
171
  handle: IFluidHandleInternal<T>,
171
172
  ): IFluidHandleErased<T> {
173
+ // Type assertion is safe as we're intentionally erasing internal type information
172
174
  return handle as unknown as IFluidHandleErased<T>;
173
175
  }
174
176
 
175
177
  /**
176
178
  * Base class which can be uses to assist implementing IFluidHandleInternal.
177
- * @legacy
178
- * @alpha
179
+ * @legacy @beta
179
180
  */
180
181
  export abstract class FluidHandleBase<T> implements IFluidHandleInternal<T> {
181
182
  public abstract absolutePath: string;
package/src/index.ts CHANGED
@@ -14,7 +14,6 @@ export {
14
14
  compareFluidHandles,
15
15
  encodeHandleForSerialization,
16
16
  FluidHandleBase,
17
- ISerializedHandle,
18
17
  isFluidHandle,
19
18
  isFluidHandleInternalPayloadPending,
20
19
  isFluidHandlePayloadPending,
@@ -23,6 +22,7 @@ export {
23
22
  toFluidHandleErased,
24
23
  toFluidHandleInternal,
25
24
  } from "./handles.js";
25
+ export type { ISerializedHandle } from "./handles.js";
26
26
  export { ObjectStoragePartition } from "./objectstoragepartition.js";
27
27
  export {
28
28
  getNormalizedObjectStoragePathParts,
@@ -49,24 +49,26 @@ export {
49
49
  } from "./summaryUtils.js";
50
50
  export { unpackChildNodesUsedRoutes } from "./unpackUsedRoutes.js";
51
51
  export {
52
- ReadAndParseBlob,
53
52
  RuntimeHeaders,
54
53
  seqFromTree,
55
54
  encodeCompactIdToString,
56
55
  } from "./utils.js";
56
+ export type { ReadAndParseBlob } from "./utils.js";
57
57
  export { isSnapshotFetchRequiredForLoadingGroupId } from "./snapshotUtils.js";
58
58
  export {
59
59
  toDeltaManagerErased,
60
60
  toDeltaManagerInternal,
61
61
  } from "./deltaManager.js";
62
62
  export {
63
- ConfigMap,
64
63
  configValueToMinVersionForCollab,
65
- ConfigValidationMap,
66
64
  defaultMinVersionForCollab,
67
65
  getValidationForRuntimeOptions,
68
66
  getConfigsForMinVersionForCollab,
69
67
  isValidMinVersionForCollab,
68
+ } from "./compatibilityBase.js";
69
+ export type {
70
+ ConfigMap,
71
+ ConfigValidationMap,
70
72
  MinimumMinorSemanticVersion,
71
73
  SemanticVersion,
72
74
  } from "./compatibilityBase.js";
@@ -4,14 +4,14 @@
4
4
  */
5
5
 
6
6
  import { assert } from "@fluidframework/core-utils/internal";
7
- import { IChannelStorageService } from "@fluidframework/datastore-definitions/internal";
7
+ import type { IChannelStorageService } from "@fluidframework/datastore-definitions/internal";
8
8
 
9
9
  /**
10
10
  * Returns a new IChannelStorageService that resolves the given `path` as root.
11
11
  * @internal
12
12
  */
13
13
  export class ObjectStoragePartition implements IChannelStorageService {
14
- constructor(
14
+ public constructor(
15
15
  private readonly storage: IChannelStorageService,
16
16
  private readonly path: string,
17
17
  ) {
@@ -3,18 +3,22 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { ITree } from "@fluidframework/driver-definitions/internal";
6
+ import type { ITree } from "@fluidframework/driver-definitions/internal";
7
+ import { TreeEntry } from "@fluidframework/driver-definitions/internal";
7
8
 
8
9
  /**
10
+ * Normalizes a storage path by removing leading and trailing slashes and splitting into parts
11
+ * @param path - The storage path to normalize (e.g. "/foo/bar/")
12
+ * @returns Array of path segments (e.g. ["foo", "bar"])
9
13
  * @internal
10
14
  */
11
- export function getNormalizedObjectStoragePathParts(path: string) {
15
+ export function getNormalizedObjectStoragePathParts(path: string): string[] {
12
16
  let normalizePath = path;
13
17
  if (normalizePath.startsWith("/")) {
14
- normalizePath = normalizePath.substr(1);
18
+ normalizePath = normalizePath.slice(1);
15
19
  }
16
20
  if (normalizePath.endsWith("/")) {
17
- normalizePath = normalizePath.substr(0, normalizePath.length - 1);
21
+ normalizePath = normalizePath.slice(0, -1);
18
22
  }
19
23
  if (normalizePath.length > 0) {
20
24
  return normalizePath.split("/");
@@ -23,6 +27,11 @@ export function getNormalizedObjectStoragePathParts(path: string) {
23
27
  }
24
28
 
25
29
  /**
30
+ * Lists all blobs at the specified path in the given tree
31
+ * @param inputTree - The tree to search within
32
+ * @param path - The path to search at (e.g. "foo/bar")
33
+ * @returns Promise that resolves to an array of blob names at that path
34
+ * @throws Error if the path does not exist in the tree
26
35
  * @internal
27
36
  */
28
37
  export async function listBlobsAtTreePath(
@@ -34,16 +43,16 @@ export async function listBlobsAtTreePath(
34
43
  while (tree?.entries !== undefined && pathParts.length > 0) {
35
44
  const part = pathParts.shift();
36
45
  const treeEntry = tree.entries.find((value) => {
37
- return value.type === "Tree" && value.path === part ? true : false;
46
+ return value.type === TreeEntry.Tree && value.path === part ? true : false;
38
47
  });
39
48
 
40
49
  // this check is largely superfluous due to the same check being done
41
50
  // immediately above. the type system, however, is not aware of this.
42
51
  // so we must redundantly determine that the entry's type is "Tree"
43
- tree = treeEntry?.type === "Tree" ? treeEntry.value : undefined;
52
+ tree = treeEntry?.type === TreeEntry.Tree ? treeEntry.value : undefined;
44
53
  }
45
- if (tree?.entries === undefined || pathParts.length !== 0) {
54
+ if (tree?.entries === undefined || pathParts.length > 0) {
46
55
  throw new Error("path does not exist");
47
56
  }
48
- return tree.entries.filter((e) => e.type === "Blob").map((e) => e.path);
57
+ return tree.entries.filter((e) => e.type === TreeEntry.Blob).map((e) => e.path);
49
58
  }
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/runtime-utils";
9
- export const pkgVersion = "2.53.1";
9
+ export const pkgVersion = "2.61.0-355054";
@@ -3,8 +3,8 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { FluidObject, IRequest } from "@fluidframework/core-interfaces";
7
- import { IFluidHandleContext } from "@fluidframework/core-interfaces/internal";
6
+ import type { FluidObject, IRequest } from "@fluidframework/core-interfaces";
7
+ import type { IFluidHandleContext } from "@fluidframework/core-interfaces/internal";
8
8
  import { assert } from "@fluidframework/core-utils/internal";
9
9
 
10
10
  import { responseToException } from "./dataStoreHelpers.js";
@@ -30,7 +30,7 @@ export class RemoteFluidObjectHandle extends FluidHandleBase<FluidObject> {
30
30
  * @param routeContext - The root IFluidHandleContext that has a route to this handle.
31
31
  * @param payloadPending - Whether the handle may have a pending payload that is not yet available.
32
32
  */
33
- constructor(
33
+ public constructor(
34
34
  public readonly absolutePath: string,
35
35
  public readonly routeContext: IFluidHandleContext,
36
36
  public readonly payloadPending: boolean,
@@ -54,6 +54,7 @@ export class RemoteFluidObjectHandle extends FluidHandleBase<FluidObject> {
54
54
  };
55
55
  this.objectP = this.routeContext.resolveHandle(request).then<FluidObject>((response) => {
56
56
  if (response.mimeType === "fluid/object") {
57
+ // Responses with mimeType == "fluid/object" are produced by Fluid, and thus they can reasonably be expected to always be a FluidObject
57
58
  const fluidObject: FluidObject = response.value as FluidObject;
58
59
  return fluidObject;
59
60
  }
@@ -3,12 +3,11 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { IRequest, IRequestHeader } from "@fluidframework/core-interfaces";
6
+ import type { IRequest, IRequestHeader } from "@fluidframework/core-interfaces";
7
7
 
8
8
  /**
9
9
  * The Request Parser takes an IRequest provides parsing and sub request creation
10
- * @legacy
11
- * @alpha
10
+ * @legacy @beta
12
11
  */
13
12
  export class RequestParser implements IRequest {
14
13
  /**
@@ -17,21 +16,22 @@ export class RequestParser implements IRequest {
17
16
  */
18
17
  public static getPathParts(url: string): readonly string[] {
19
18
  const queryStartIndex = url.indexOf("?");
20
- return url
21
- .substring(0, queryStartIndex < 0 ? url.length : queryStartIndex)
22
- .split("/")
23
- .reduce<string[]>((pv, cv) => {
24
- if (cv !== undefined && cv.length > 0) {
25
- pv.push(decodeURIComponent(cv));
26
- }
27
- return pv;
28
- }, []);
19
+ const pathParts: string[] = [];
20
+ const urlPath = url.slice(0, queryStartIndex < 0 ? url.length : queryStartIndex);
21
+
22
+ for (const part of urlPath.split("/")) {
23
+ if (part !== undefined && part.length > 0) {
24
+ pathParts.push(decodeURIComponent(part));
25
+ }
26
+ }
27
+
28
+ return pathParts;
29
29
  }
30
30
 
31
31
  private requestPathParts: readonly string[] | undefined;
32
32
  public readonly query: string;
33
33
 
34
- public static create(request: Readonly<IRequest>) {
34
+ public static create(request: Readonly<IRequest>): RequestParser {
35
35
  // Perf optimizations.
36
36
  if (request instanceof RequestParser) {
37
37
  return request;
@@ -41,7 +41,7 @@ export class RequestParser implements IRequest {
41
41
 
42
42
  protected constructor(private readonly request: Readonly<IRequest>) {
43
43
  const queryStartIndex = this.request.url.indexOf("?");
44
- this.query = queryStartIndex >= 0 ? this.request.url.substring(queryStartIndex) : "";
44
+ this.query = queryStartIndex >= 0 ? this.request.url.slice(queryStartIndex) : "";
45
45
  if (request.headers !== undefined) {
46
46
  this.headers = request.headers;
47
47
  }
@@ -67,7 +67,7 @@ export class RequestParser implements IRequest {
67
67
  * Returns true if it's a terminating path, i.e. no more elements after `elements` entries and empty query.
68
68
  * @param elements - number of elements in path
69
69
  */
70
- public isLeaf(elements: number) {
70
+ public isLeaf(elements: number): boolean {
71
71
  return this.query === "" && this.pathParts.length === elements;
72
72
  }
73
73
 
@@ -3,19 +3,18 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import {
6
+ import type {
7
7
  IContainerContext,
8
8
  IRuntime,
9
9
  IRuntimeFactory,
10
10
  } from "@fluidframework/container-definitions/internal";
11
- import { IContainerRuntime } from "@fluidframework/container-runtime-definitions/internal";
11
+ import type { IContainerRuntime } from "@fluidframework/container-runtime-definitions/internal";
12
12
 
13
13
  /**
14
- * @legacy
15
- * @alpha
14
+ * @legacy @beta
16
15
  */
17
16
  export abstract class RuntimeFactoryHelper<T = IContainerRuntime> implements IRuntimeFactory {
18
- public get IRuntimeFactory() {
17
+ public get IRuntimeFactory(): this {
19
18
  return this;
20
19
  }
21
20