@fluidframework/runtime-utils 0.52.0 → 0.54.0-47413
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/bench/src/index.ts +1 -1
- package/dist/dataStoreHelpers.d.ts +0 -1
- package/dist/dataStoreHelpers.d.ts.map +1 -1
- package/dist/dataStoreHelpers.js +18 -31
- package/dist/dataStoreHelpers.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/remoteObjectHandle.d.ts +0 -4
- package/dist/remoteObjectHandle.d.ts.map +1 -1
- package/dist/remoteObjectHandle.js +0 -6
- package/dist/remoteObjectHandle.js.map +1 -1
- package/dist/serializer.d.ts +2 -1
- package/dist/serializer.d.ts.map +1 -1
- package/dist/serializer.js +7 -2
- package/dist/serializer.js.map +1 -1
- package/dist/summarizerNode/summarizerNodeWithGc.d.ts +1 -13
- package/dist/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/dist/summarizerNode/summarizerNodeWithGc.js +3 -73
- package/dist/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/lib/dataStoreHelpers.d.ts +0 -1
- package/lib/dataStoreHelpers.d.ts.map +1 -1
- package/lib/dataStoreHelpers.js +17 -29
- package/lib/dataStoreHelpers.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/remoteObjectHandle.d.ts +0 -4
- package/lib/remoteObjectHandle.d.ts.map +1 -1
- package/lib/remoteObjectHandle.js +0 -6
- package/lib/remoteObjectHandle.js.map +1 -1
- package/lib/serializer.d.ts +2 -1
- package/lib/serializer.d.ts.map +1 -1
- package/lib/serializer.js +7 -2
- package/lib/serializer.js.map +1 -1
- package/lib/summarizerNode/summarizerNodeWithGc.d.ts +1 -13
- package/lib/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/lib/summarizerNode/summarizerNodeWithGc.js +4 -74
- package/lib/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/package.json +10 -9
- package/src/dataStoreHelpers.ts +24 -29
- package/src/packageVersion.ts +1 -1
- package/src/remoteObjectHandle.ts +0 -7
- package/src/serializer.ts +8 -2
- package/src/summarizerNode/summarizerNodeWithGc.ts +3 -92
package/bench/src/index.ts
CHANGED
|
@@ -9,7 +9,7 @@ import { FluidSerializer } from "../..";
|
|
|
9
9
|
import { makeJson, MockHandleContext } from "../../src/test/utils";
|
|
10
10
|
import { consume, runSuites } from "./util";
|
|
11
11
|
|
|
12
|
-
const serializer = new FluidSerializer(new MockHandleContext());
|
|
12
|
+
const serializer = new FluidSerializer(new MockHandleContext(), (handle: IFluidHandle) => {});
|
|
13
13
|
|
|
14
14
|
// Mock Fluid handle
|
|
15
15
|
const handle: IFluidHandle = {
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { FluidObject, IFluidObject, IFluidRouter, IRequest, IResponse } from "@fluidframework/core-interfaces";
|
|
6
6
|
import { IFluidDataStoreFactory, IFluidDataStoreRegistry, IProvideFluidDataStoreRegistry } from "@fluidframework/runtime-definitions";
|
|
7
|
-
export declare function getStack(): string | undefined;
|
|
8
7
|
export declare function exceptionToResponse(err: any): IResponse;
|
|
9
8
|
export declare function responseToException(response: IResponse, request: IRequest): Error;
|
|
10
9
|
export declare function requestFluidObject<T = IFluidObject & FluidObject>(router: IFluidRouter, url: string | IRequest): Promise<T>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataStoreHelpers.d.ts","sourceRoot":"","sources":["../src/dataStoreHelpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACH,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,SAAS,EACZ,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACH,sBAAsB,EACtB,uBAAuB,EACvB,8BAA8B,EACjC,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"dataStoreHelpers.d.ts","sourceRoot":"","sources":["../src/dataStoreHelpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACH,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,SAAS,EACZ,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACH,sBAAsB,EACtB,uBAAuB,EACvB,8BAA8B,EACjC,MAAM,qCAAqC,CAAC;AAU7C,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,GAAG,GAAG,SAAS,CAsBvD;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,GAAG,KAAK,CAYjF;AAED,wBAAsB,kBAAkB,CAAC,CAAC,GAAG,YAAY,GAAG,WAAW,EACnE,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,CAU5D;AAED,eAAO,MAAM,iBAAiB,YAAa,QAAQ,cAAmD,CAAC;AAEvG,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,GAAG,SAAS,CAc/F;AAED,oBAAY,OAAO,GAAG,sBAAsB,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAAC;AAGvF,wBAAgB,sBAAsB,CAClC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAChC,sBAAsB,GAAG,uBAAuB,CAStD"}
|
package/dist/dataStoreHelpers.js
CHANGED
|
@@ -4,23 +4,10 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.createDataStoreFactory = exports.createResponseError = exports.create404Response = exports.requestFluidObject = exports.responseToException = exports.exceptionToResponse =
|
|
7
|
+
exports.createDataStoreFactory = exports.createResponseError = exports.create404Response = exports.requestFluidObject = exports.responseToException = exports.exceptionToResponse = void 0;
|
|
8
8
|
const common_utils_1 = require("@fluidframework/common-utils");
|
|
9
|
-
|
|
10
|
-
const err = new Error();
|
|
11
|
-
if (err.stack !== undefined) {
|
|
12
|
-
return err.stack;
|
|
13
|
-
}
|
|
14
|
-
try {
|
|
15
|
-
throw err;
|
|
16
|
-
}
|
|
17
|
-
catch (err2) {
|
|
18
|
-
return err2.stack;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
exports.getStack = getStack;
|
|
9
|
+
const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
|
|
22
10
|
function exceptionToResponse(err) {
|
|
23
|
-
var _a;
|
|
24
11
|
const status = 500;
|
|
25
12
|
// eslint-disable-next-line no-null/no-null
|
|
26
13
|
if (err !== null && typeof err === "object" && err.errorFromRequestFluidObject === true) {
|
|
@@ -29,32 +16,30 @@ function exceptionToResponse(err) {
|
|
|
29
16
|
mimeType: "text/plain",
|
|
30
17
|
status: responseErr.code,
|
|
31
18
|
value: responseErr.message,
|
|
32
|
-
stack
|
|
19
|
+
get stack() { return responseErr.stack; },
|
|
33
20
|
};
|
|
34
21
|
}
|
|
22
|
+
// Capture error objects, not stack itself, as stack retrieval is very expensive operation, so we delay it
|
|
23
|
+
const errWithStack = telemetry_utils_1.generateErrorWithStack();
|
|
35
24
|
return {
|
|
36
25
|
mimeType: "text/plain",
|
|
37
26
|
status,
|
|
38
27
|
value: `${err}`,
|
|
39
|
-
stack:
|
|
28
|
+
get stack() { var _a; return (_a = (err === null || err === void 0 ? void 0 : err.stack)) !== null && _a !== void 0 ? _a : errWithStack.stack; },
|
|
40
29
|
};
|
|
41
30
|
}
|
|
42
31
|
exports.exceptionToResponse = exceptionToResponse;
|
|
43
32
|
function responseToException(response, request) {
|
|
44
33
|
const message = response.value;
|
|
45
|
-
const
|
|
46
|
-
const responseErr =
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
catch (err2) { }
|
|
56
|
-
}
|
|
57
|
-
return err;
|
|
34
|
+
const errWithStack = telemetry_utils_1.generateErrorWithStack();
|
|
35
|
+
const responseErr = {
|
|
36
|
+
errorFromRequestFluidObject: true,
|
|
37
|
+
message,
|
|
38
|
+
name: "Error",
|
|
39
|
+
code: response.status,
|
|
40
|
+
get stack() { var _a; return (_a = response.stack) !== null && _a !== void 0 ? _a : errWithStack.stack; },
|
|
41
|
+
};
|
|
42
|
+
return responseErr;
|
|
58
43
|
}
|
|
59
44
|
exports.responseToException = responseToException;
|
|
60
45
|
async function requestFluidObject(router, url) {
|
|
@@ -74,11 +59,13 @@ function createResponseError(status, value, request) {
|
|
|
74
59
|
common_utils_1.assert(status !== 200, 0x19b /* "Cannot not create response error on 200 status" */);
|
|
75
60
|
// Omit query string which could contain personal data (aka "PII")
|
|
76
61
|
const urlNoQuery = (_a = request.url) === null || _a === void 0 ? void 0 : _a.split("?")[0];
|
|
62
|
+
// Capture error objects, not stack itself, as stack retrieval is very expensive operation, so we delay it
|
|
63
|
+
const errWithStack = telemetry_utils_1.generateErrorWithStack();
|
|
77
64
|
return {
|
|
78
65
|
mimeType: "text/plain",
|
|
79
66
|
status,
|
|
80
67
|
value: urlNoQuery === undefined ? value : `${value}: ${urlNoQuery}`,
|
|
81
|
-
stack
|
|
68
|
+
get stack() { return errWithStack.stack; },
|
|
82
69
|
};
|
|
83
70
|
}
|
|
84
71
|
exports.createResponseError = createResponseError;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataStoreHelpers.js","sourceRoot":"","sources":["../src/dataStoreHelpers.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAAsD;
|
|
1
|
+
{"version":3,"file":"dataStoreHelpers.js","sourceRoot":"","sources":["../src/dataStoreHelpers.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAAsD;AAatD,qEAAyE;AASzE,SAAgB,mBAAmB,CAAC,GAAQ;IACxC,MAAM,MAAM,GAAG,GAAG,CAAC;IACnB,2CAA2C;IAC3C,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,2BAA2B,KAAK,IAAI,EAAE;QACrF,MAAM,WAAW,GAAuB,GAAG,CAAC;QAC5C,OAAO;YACH,QAAQ,EAAE,YAAY;YACtB,MAAM,EAAE,WAAW,CAAC,IAAI;YACxB,KAAK,EAAE,WAAW,CAAC,OAAO;YAC1B,IAAI,KAAK,KAAK,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;SAC5C,CAAC;KACL;IAED,0GAA0G;IAC1G,MAAM,YAAY,GAAG,wCAAsB,EAAE,CAAC;IAE9C,OAAO;QACH,QAAQ,EAAE,YAAY;QACtB,MAAM;QACN,KAAK,EAAE,GAAG,GAAG,EAAE;QACf,IAAI,KAAK,aAAK,aAAQ,CAAC,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,KAAK,CAAwB,mCAAI,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;KACrF,CAAC;AACN,CAAC;AAtBD,kDAsBC;AAED,SAAgB,mBAAmB,CAAC,QAAmB,EAAE,OAAiB;IACtE,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC;IAC/B,MAAM,YAAY,GAAG,wCAAsB,EAAE,CAAC;IAC9C,MAAM,WAAW,GAA+B;QAC5C,2BAA2B,EAAE,IAAI;QACjC,OAAO;QACP,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,QAAQ,CAAC,MAAM;QACrB,IAAI,KAAK,aAAK,aAAO,QAAQ,CAAC,KAAK,mCAAI,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;KAC/D,CAAC;IAEF,OAAO,WAAW,CAAC;AACvB,CAAC;AAZD,kDAYC;AAEM,KAAK,UAAU,kBAAkB,CACpC,MAAoB,EAAE,GAAsB;IAC5C,MAAM,OAAO,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;IACxD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAE/C,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,QAAQ,KAAK,cAAc,EAAE;QACjE,MAAM,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;KAChD;IAED,qBAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,uDAAuD,CAAC,CAAC;IACtF,OAAO,QAAQ,CAAC,KAAU,CAAC;AAC/B,CAAC;AAXD,gDAWC;AAEM,MAAM,iBAAiB,GAAG,CAAC,OAAiB,EAAE,EAAE,CAAC,mBAAmB,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;AAA1F,QAAA,iBAAiB,qBAAyE;AAEvG,SAAgB,mBAAmB,CAAC,MAAc,EAAE,KAAa,EAAE,OAAiB;;IAChF,qBAAM,CAAC,MAAM,KAAK,GAAG,EAAE,KAAK,CAAC,sDAAsD,CAAC,CAAC;IACrF,kEAAkE;IAClE,MAAM,UAAU,SAAG,OAAO,CAAC,GAAG,0CAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAE9C,0GAA0G;IAC1G,MAAM,YAAY,GAAG,wCAAsB,EAAE,CAAC;IAE9C,OAAO;QACH,QAAQ,EAAE,YAAY;QACtB,MAAM;QACN,KAAK,EAAE,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,UAAU,EAAE;QACnE,IAAI,KAAK,KAAK,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;KAC7C,CAAC;AACN,CAAC;AAdD,kDAcC;AAID,+DAA+D;AAC/D,SAAgB,sBAAsB,CAClC,IAAY,EACZ,OAAmC;IAGnC,OAAO;QACH,IAAI;QACJ,IAAI,sBAAsB,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;QAC7C,IAAI,uBAAuB,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;QAC9C,oBAAoB,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,MAAM,OAAO,CAAC,CAAC,oBAAoB,CAAC,OAAO,EAAE,QAAQ,CAAC;QAC1G,GAAG,EAAE,KAAK,EAAE,IAAY,EAAE,EAAE,wBAAC,CAAC,MAAM,OAAO,CAAC,CAAC,uBAAuB,0CAAE,GAAG,CAAC,IAAI,IAAC;KAClF,CAAC;AACN,CAAC;AAZD,wDAYC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport {\n FluidObject,\n IFluidObject,\n IFluidRouter,\n IRequest,\n IResponse,\n} from \"@fluidframework/core-interfaces\";\nimport {\n IFluidDataStoreFactory,\n IFluidDataStoreRegistry,\n IProvideFluidDataStoreRegistry,\n} from \"@fluidframework/runtime-definitions\";\nimport { generateErrorWithStack } from \"@fluidframework/telemetry-utils\";\n\ninterface IResponseException extends Error {\n errorFromRequestFluidObject: true;\n message: string;\n code: number;\n stack?: string;\n}\n\nexport function exceptionToResponse(err: any): IResponse {\n const status = 500;\n // eslint-disable-next-line no-null/no-null\n if (err !== null && typeof err === \"object\" && err.errorFromRequestFluidObject === true) {\n const responseErr: IResponseException = err;\n return {\n mimeType: \"text/plain\",\n status: responseErr.code,\n value: responseErr.message,\n get stack() { return responseErr.stack; },\n };\n }\n\n // Capture error objects, not stack itself, as stack retrieval is very expensive operation, so we delay it\n const errWithStack = generateErrorWithStack();\n\n return {\n mimeType: \"text/plain\",\n status,\n value: `${err}`,\n get stack() { return ((err?.stack) as (string|undefined)) ?? errWithStack.stack; },\n };\n}\n\nexport function responseToException(response: IResponse, request: IRequest): Error {\n const message = response.value;\n const errWithStack = generateErrorWithStack();\n const responseErr: Error & IResponseException = {\n errorFromRequestFluidObject: true,\n message,\n name: \"Error\",\n code: response.status,\n get stack() { return response.stack ?? errWithStack.stack; },\n };\n\n return responseErr;\n}\n\nexport async function requestFluidObject<T = IFluidObject & FluidObject>(\n router: IFluidRouter, url: string | IRequest): Promise<T> {\n const request = typeof url === \"string\" ? { url } : url;\n const response = await router.request(request);\n\n if (response.status !== 200 || response.mimeType !== \"fluid/object\") {\n throw responseToException(response, request);\n }\n\n assert(response.value, 0x19a /* \"Invalid response value for Fluid object request\" */);\n return response.value as T;\n}\n\nexport const create404Response = (request: IRequest) => createResponseError(404, \"not found\", request);\n\nexport function createResponseError(status: number, value: string, request: IRequest): IResponse {\n assert(status !== 200, 0x19b /* \"Cannot not create response error on 200 status\" */);\n // Omit query string which could contain personal data (aka \"PII\")\n const urlNoQuery = request.url?.split(\"?\")[0];\n\n // Capture error objects, not stack itself, as stack retrieval is very expensive operation, so we delay it\n const errWithStack = generateErrorWithStack();\n\n return {\n mimeType: \"text/plain\",\n status,\n value: urlNoQuery === undefined ? value : `${value}: ${urlNoQuery}`,\n get stack() { return errWithStack.stack; },\n };\n}\n\nexport type Factory = IFluidDataStoreFactory & Partial<IProvideFluidDataStoreRegistry>;\n\n// eslint-disable-next-line prefer-arrow/prefer-arrow-functions\nexport function createDataStoreFactory(\n type: string,\n factory: Factory | Promise<Factory>,\n ): IFluidDataStoreFactory & IFluidDataStoreRegistry\n{\n return {\n type,\n get IFluidDataStoreFactory() { return this; },\n get IFluidDataStoreRegistry() { return this; },\n instantiateDataStore: async (context, existing) => (await factory).instantiateDataStore(context, existing),\n get: async (name: string) => (await factory).IFluidDataStoreRegistry?.get(name),\n };\n}\n"]}
|
package/dist/packageVersion.d.ts
CHANGED
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
|
|
6
6
|
*/
|
|
7
7
|
export declare const pkgName = "@fluidframework/runtime-utils";
|
|
8
|
-
export declare const pkgVersion = "0.
|
|
8
|
+
export declare const pkgVersion = "0.54.0-47413";
|
|
9
9
|
//# sourceMappingURL=packageVersion.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,kCAAkC,CAAC;AACvD,eAAO,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,kCAAkC,CAAC;AACvD,eAAO,MAAM,UAAU,iBAAiB,CAAC"}
|
package/dist/packageVersion.js
CHANGED
|
@@ -8,5 +8,5 @@
|
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.pkgVersion = exports.pkgName = void 0;
|
|
10
10
|
exports.pkgName = "@fluidframework/runtime-utils";
|
|
11
|
-
exports.pkgVersion = "0.
|
|
11
|
+
exports.pkgVersion = "0.54.0-47413";
|
|
12
12
|
//# sourceMappingURL=packageVersion.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,+BAA+B,CAAC;AAC1C,QAAA,UAAU,GAAG,
|
|
1
|
+
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,+BAA+B,CAAC;AAC1C,QAAA,UAAU,GAAG,cAAc,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/runtime-utils\";\nexport const pkgVersion = \"0.54.0-47413\";\n"]}
|
|
@@ -24,10 +24,6 @@ export declare class RemoteFluidObjectHandle implements IFluidHandle {
|
|
|
24
24
|
* @param routeContext - The root IFluidHandleContext that has a route to this handle.
|
|
25
25
|
*/
|
|
26
26
|
constructor(absolutePath: string, routeContext: IFluidHandleContext);
|
|
27
|
-
/**
|
|
28
|
-
* @deprecated - This returns the absolute path.
|
|
29
|
-
*/
|
|
30
|
-
get path(): string;
|
|
31
27
|
get(): Promise<any>;
|
|
32
28
|
attachGraph(): void;
|
|
33
29
|
bind(handle: IFluidHandle): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remoteObjectHandle.d.ts","sourceRoot":"","sources":["../src/remoteObjectHandle.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACH,YAAY,EACZ,mBAAmB,EACnB,QAAQ,EACR,SAAS,EAGZ,MAAM,iCAAiC,CAAC;AAGzC;;;;;;GAMG;AACH,qBAAa,uBAAwB,YAAW,YAAY;aAcpC,YAAY,EAAE,MAAM;aACpB,YAAY,EAAE,mBAAmB;IAdrD,IAAW,YAAY,SAAmB;IAC1C,IAAW,mBAAmB,SAAmB;IACjD,IAAW,YAAY,SAAmB;IAE1C,SAAgB,UAAU,QAAQ;IAClC,OAAO,CAAC,OAAO,CAAmC;IAElD;;;;OAIG;gBAEiB,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,mBAAmB;
|
|
1
|
+
{"version":3,"file":"remoteObjectHandle.d.ts","sourceRoot":"","sources":["../src/remoteObjectHandle.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACH,YAAY,EACZ,mBAAmB,EACnB,QAAQ,EACR,SAAS,EAGZ,MAAM,iCAAiC,CAAC;AAGzC;;;;;;GAMG;AACH,qBAAa,uBAAwB,YAAW,YAAY;aAcpC,YAAY,EAAE,MAAM;aACpB,YAAY,EAAE,mBAAmB;IAdrD,IAAW,YAAY,SAAmB;IAC1C,IAAW,mBAAmB,SAAmB;IACjD,IAAW,YAAY,SAAmB;IAE1C,SAAgB,UAAU,QAAQ;IAClC,OAAO,CAAC,OAAO,CAAmC;IAElD;;;;OAIG;gBAEiB,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,mBAAmB;IAKxC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IAezB,WAAW,IAAI,IAAI;IAInB,IAAI,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAI1B,OAAO,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC;CAY9D"}
|
|
@@ -29,12 +29,6 @@ class RemoteFluidObjectHandle {
|
|
|
29
29
|
get IFluidRouter() { return this; }
|
|
30
30
|
get IFluidHandleContext() { return this; }
|
|
31
31
|
get IFluidHandle() { return this; }
|
|
32
|
-
/**
|
|
33
|
-
* @deprecated - This returns the absolute path.
|
|
34
|
-
*/
|
|
35
|
-
get path() {
|
|
36
|
-
return this.absolutePath;
|
|
37
|
-
}
|
|
38
32
|
async get() {
|
|
39
33
|
if (this.objectP === undefined) {
|
|
40
34
|
const request = { url: this.absolutePath };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remoteObjectHandle.js","sourceRoot":"","sources":["../src/remoteObjectHandle.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAAsD;AAStD,yDAAiG;AAEjG;;;;;;GAMG;AACH,MAAa,uBAAuB;IAQhC;;;;OAIG;IACH,YACoB,YAAoB,EACpB,YAAiC;QADjC,iBAAY,GAAZ,YAAY,CAAQ;QACpB,iBAAY,GAAZ,YAAY,CAAqB;QAVrC,eAAU,GAAG,IAAI,CAAC;QAY9B,qBAAM,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,iDAAiD,CAAC,CAAC;IAClG,CAAC;IAjBD,IAAW,YAAY,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;IAC1C,IAAW,mBAAmB,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;IACjD,IAAW,YAAY,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"remoteObjectHandle.js","sourceRoot":"","sources":["../src/remoteObjectHandle.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAAsD;AAStD,yDAAiG;AAEjG;;;;;;GAMG;AACH,MAAa,uBAAuB;IAQhC;;;;OAIG;IACH,YACoB,YAAoB,EACpB,YAAiC;QADjC,iBAAY,GAAZ,YAAY,CAAQ;QACpB,iBAAY,GAAZ,YAAY,CAAqB;QAVrC,eAAU,GAAG,IAAI,CAAC;QAY9B,qBAAM,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,iDAAiD,CAAC,CAAC;IAClG,CAAC;IAjBD,IAAW,YAAY,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;IAC1C,IAAW,mBAAmB,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;IACjD,IAAW,YAAY,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;IAiBnC,KAAK,CAAC,GAAG;QACZ,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE;YAC5B,MAAM,OAAO,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC;YAC3C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,OAAO,CAAC;iBAClD,IAAI,CAAc,CAAC,QAAQ,EAAE,EAAE;gBAC5B,IAAI,QAAQ,CAAC,QAAQ,KAAK,cAAc,EAAE;oBACtC,MAAM,WAAW,GAAgB,QAAQ,CAAC,KAAK,CAAC;oBAChD,OAAO,WAAW,CAAC;iBACtB;gBACD,MAAM,sCAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACjD,CAAC,CAAC,CAAC;SACV;QACD,OAAO,IAAI,CAAC,OAAO,CAAC;IACxB,CAAC;IAEM,WAAW;QACd,OAAO;IACX,CAAC;IAEM,IAAI,CAAC,MAAoB;QAC5B,MAAM,CAAC,WAAW,EAAE,CAAC;IACzB,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,OAAiB;QAClC,IAAI;YACA,MAAM,MAAM,GAA8B,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;YAC3D,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC;YAEnC,OAAO,MAAM,KAAK,SAAS;gBACvB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;gBACzB,CAAC,CAAC,oCAAiB,CAAC,OAAO,CAAC,CAAC;SACpC;QAAC,OAAO,KAAK,EAAE;YACZ,OAAO,sCAAmB,CAAC,KAAK,CAAC,CAAC;SACrC;IACL,CAAC;CACJ;AAvDD,0DAuDC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport {\n IFluidHandle,\n IFluidHandleContext,\n IRequest,\n IResponse,\n FluidObject,\n IFluidRouter,\n} from \"@fluidframework/core-interfaces\";\nimport { create404Response, exceptionToResponse, responseToException } from \"./dataStoreHelpers\";\n\n/**\n * This handle is used to dynamically load a Fluid object on a remote client and is created on parsing a serialized\n * FluidObjectHandle.\n * This class is used to generate an IFluidHandle when de-serializing any all handles (including handles to DDSs, custom\n * objects) that are stored in SharedObjects. The Data Store or SharedObject corresponding to the IFluidHandle can be\n * retrieved by calling `get` on it.\n */\nexport class RemoteFluidObjectHandle implements IFluidHandle {\n public get IFluidRouter() { return this; }\n public get IFluidHandleContext() { return this; }\n public get IFluidHandle() { return this; }\n\n public readonly isAttached = true;\n private objectP: Promise<FluidObject> | undefined;\n\n /**\n * Creates a new RemoteFluidObjectHandle when parsing an IFluidHandle.\n * @param absolutePath - The absolute path to the handle from the container runtime.\n * @param routeContext - The root IFluidHandleContext that has a route to this handle.\n */\n constructor(\n public readonly absolutePath: string,\n public readonly routeContext: IFluidHandleContext,\n ) {\n assert(absolutePath.startsWith(\"/\"), 0x19d /* \"Handles should always have absolute paths\" */);\n }\n\n public async get(): Promise<any> {\n if (this.objectP === undefined) {\n const request = { url: this.absolutePath };\n this.objectP = this.routeContext.resolveHandle(request)\n .then<FluidObject>((response) => {\n if (response.mimeType === \"fluid/object\") {\n const fluidObject: FluidObject = response.value;\n return fluidObject;\n }\n throw responseToException(response, request);\n });\n }\n return this.objectP;\n }\n\n public attachGraph(): void {\n return;\n }\n\n public bind(handle: IFluidHandle): void {\n handle.attachGraph();\n }\n\n public async request(request: IRequest): Promise<IResponse> {\n try {\n const object: FluidObject<IFluidRouter> = await this.get();\n const router = object.IFluidRouter;\n\n return router !== undefined\n ? router.request(request)\n : create404Response(request);\n } catch (error) {\n return exceptionToResponse(error);\n }\n }\n}\n"]}
|
package/dist/serializer.d.ts
CHANGED
|
@@ -8,8 +8,9 @@ import { IFluidHandle, IFluidHandleContext, IFluidSerializer } from "@fluidframe
|
|
|
8
8
|
*/
|
|
9
9
|
export declare class FluidSerializer implements IFluidSerializer {
|
|
10
10
|
private readonly context;
|
|
11
|
+
private readonly handleParsedCb;
|
|
11
12
|
private readonly root;
|
|
12
|
-
constructor(context: IFluidHandleContext);
|
|
13
|
+
constructor(context: IFluidHandleContext, handleParsedCb: (handle: IFluidHandle) => void);
|
|
13
14
|
get IFluidSerializer(): this;
|
|
14
15
|
/**
|
|
15
16
|
* Given a mostly-jsonable object tree that may have handle objects embedded within, will return a
|
package/dist/serializer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EACH,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EACnB,MAAM,iCAAiC,CAAC;AAKzC;;GAEG;AACH,qBAAa,eAAgB,YAAW,gBAAgB;
|
|
1
|
+
{"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EACH,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EACnB,MAAM,iCAAiC,CAAC;AAKzC;;GAEG;AACH,qBAAa,eAAgB,YAAW,gBAAgB;IAIhD,OAAO,CAAC,QAAQ,CAAC,OAAO;IAExB,OAAO,CAAC,QAAQ,CAAC,cAAc;IALnC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAsB;gBAGtB,OAAO,EAAE,mBAAmB,EAE5B,cAAc,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI;IAQnE,IAAW,gBAAgB,SAAmB;IAE9C;;;;;;;;OAQG;IACK,cAAc,CAClB,KAAK,EAAE,GAAG,EACV,IAAI,EAAE,YAAY;IAUtB;;;;;;;;OAQG;IACK,MAAM,CAAC,KAAK,EAAE,GAAG;IASlB,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,YAAY;IAKxC,KAAK,CAAC,KAAK,EAAE,MAAM;IAM1B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAQ1B;IAIF,OAAO,CAAC,QAAQ,CAAC,WAAW,CAe1B;IAKF,OAAO,CAAC,kBAAkB;IAgD1B,SAAS,CAAC,eAAe,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,YAAY;;;;CAOrE"}
|
package/dist/serializer.js
CHANGED
|
@@ -12,8 +12,11 @@ const utils_1 = require("./utils");
|
|
|
12
12
|
* Data Store serializer implementation
|
|
13
13
|
*/
|
|
14
14
|
class FluidSerializer {
|
|
15
|
-
constructor(context
|
|
15
|
+
constructor(context,
|
|
16
|
+
// To be called whenever a handle is parsed by this serializer.
|
|
17
|
+
handleParsedCb) {
|
|
16
18
|
this.context = context;
|
|
19
|
+
this.handleParsedCb = handleParsedCb;
|
|
17
20
|
// If the given 'value' is an IFluidHandle, returns the encoded IFluidHandle.
|
|
18
21
|
// Otherwise returns the original 'value'. Used by 'replaceHandles()' and 'stringify()'.
|
|
19
22
|
this.encodeValue = (value, bind) => {
|
|
@@ -34,7 +37,9 @@ class FluidSerializer {
|
|
|
34
37
|
const absolutePath = value.url.startsWith("/")
|
|
35
38
|
? value.url
|
|
36
39
|
: dataStoreHandleContextUtils_1.generateHandleContextPath(value.url, this.context);
|
|
37
|
-
|
|
40
|
+
const parsedHandle = new remoteObjectHandle_1.RemoteFluidObjectHandle(absolutePath, this.root);
|
|
41
|
+
this.handleParsedCb(parsedHandle);
|
|
42
|
+
return parsedHandle;
|
|
38
43
|
}
|
|
39
44
|
else {
|
|
40
45
|
return value;
|
package/dist/serializer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serializer.js","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAUH,6DAA+D;AAC/D,+EAA0E;AAC1E,mCAA6C;AAE7C;;GAEG;AACH,MAAa,eAAe;IAGxB,YAAoC,OAA4B;QAA5B,YAAO,GAAP,OAAO,CAAqB;QAyDhE,6EAA6E;QAC7E,yFAAyF;QACxE,gBAAW,GAAG,CAAC,KAAU,EAAE,IAAkB,EAAE,EAAE;YAC9D,wCAAwC;YACxC,MAAM,MAAM,GAAG,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,YAAY,CAAC;YAEnC,yDAAyD;YACzD,OAAO,MAAM,KAAK,SAAS;gBACvB,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC;gBACpC,CAAC,CAAC,KAAK,CAAC;QAChB,CAAC,CAAC;QAEF,qFAAqF;QACrF,6EAA6E;QAC5D,gBAAW,GAAG,CAAC,KAAU,EAAE,EAAE;YAC1C,0EAA0E;YAC1E,IAAI,0BAAkB,CAAC,KAAK,CAAC,EAAE;gBAC3B,kGAAkG;gBAClG,4FAA4F;gBAC5F,MAAM,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;oBAC1C,CAAC,CAAC,KAAK,CAAC,GAAG;oBACX,CAAC,CAAC,uDAAyB,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;gBAEzD,OAAO,IAAI,4CAAuB,CAAC,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;aAC/D;iBAAM;gBACH,OAAO,KAAK,CAAC;aAChB;QACL,CAAC,CAAC;QAnFE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC;QACzB,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE;YACzC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC;SACtC;IACL,CAAC;IAED,IAAW,gBAAgB,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;IAE9C;;;;;;;;OAQG;IACK,cAAc,CAClB,KAAU,EACV,IAAkB;QAElB,kFAAkF;QAClF,+CAA+C;QAC/C,yEAAyE;QACzE,OAAO,CAAC,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;YACvC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC;YACxD,CAAC,CAAC,KAAK,CAAC;IAChB,CAAC;IAED;;;;;;;;OAQG;IACK,MAAM,CAAC,KAAU;QACrB,kFAAkF;QAClF,+CAA+C;QAC/C,yEAAyE;QACzE,OAAO,CAAC,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;YACvC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC;YAClD,CAAC,CAAC,KAAK,CAAC;IAChB,CAAC;IAEM,SAAS,CAAC,KAAU,EAAE,IAAkB;QAC3C,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;IAChF,CAAC;IAED,kGAAkG;IAC3F,KAAK,CAAC,KAAa;QACtB,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;IACtE,CAAC;IA+BD,mFAAmF;IACnF,0FAA0F;IAC1F,gCAAgC;IACxB,kBAAkB,CACtB,KAAU,EACV,QAA2C,EAC3C,OAAa;QAEb,+EAA+E;QAC/E,4CAA4C;QAE5C,yGAAyG;QACzG,wBAAwB;QACxB,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAE/C,qGAAqG;QACrG,8BAA8B;QAC9B,IAAI,aAAa,KAAK,KAAK,EAAE;YACzB,OAAO,aAAa,CAAC;SACxB;QAED,8EAA8E;QAC9E,wDAAwD;QACxD,IAAI,KAAyB,CAAC;QAC9B,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;YAClC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;YACzB,yEAAyE;YACzE,IAAI,CAAC,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;gBACtC,8FAA8F;gBAC9F,+FAA+F;gBAC/F,8DAA8D;gBAC9D,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;gBAEnE,kGAAkG;gBAClG,+FAA+F;gBAC/F,wDAAwD;gBACxD,IAAI,QAAQ,KAAK,KAAK,EAAE;oBACpB,qFAAqF;oBACrF,KAAK,GAAG,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;wBAClC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;wBACZ,CAAC,mBAAM,KAAK,CAAE,CAAC,CAAC;oBAEpB,+EAA+E;oBAC/E,oEAAoE;oBACpE,KAAM,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;iBAC1B;aACJ;SACJ;QACD,OAAO,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,KAAK,CAAC;IAC1B,CAAC;IAES,eAAe,CAAC,MAAoB,EAAE,IAAkB;QAC9D,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClB,OAAO;YACH,IAAI,EAAE,kBAAkB;YACxB,GAAG,EAAE,MAAM,CAAC,YAAY;SAC3B,CAAC;IACN,CAAC;CACJ;AAnJD,0CAmJC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n// RATIONALE: Many methods consume and return 'any' by necessity.\n/* eslint-disable @typescript-eslint/no-unsafe-return */\n\nimport {\n IFluidHandle,\n IFluidHandleContext,\n IFluidSerializer,\n} from \"@fluidframework/core-interfaces\";\nimport { RemoteFluidObjectHandle } from \"./remoteObjectHandle\";\nimport { generateHandleContextPath } from \"./dataStoreHandleContextUtils\";\nimport { isSerializedHandle } from \"./utils\";\n\n/**\n * Data Store serializer implementation\n */\nexport class FluidSerializer implements IFluidSerializer {\n private readonly root: IFluidHandleContext;\n\n public constructor(private readonly context: IFluidHandleContext) {\n this.root = this.context;\n while (this.root.routeContext !== undefined) {\n this.root = this.root.routeContext;\n }\n }\n\n public get IFluidSerializer() { return this; }\n\n /**\n * Given a mostly-jsonable object tree that may have handle objects embedded within, will return a\n * fully-jsonable object tree where any embedded IFluidHandles have been replaced with a serializable form.\n *\n * The original `input` object is not mutated. This method will shallowly clones all objects in the path from\n * the root to any replaced handles. (If no handles are found, returns the original object.)\n *\n * Any unbound handles encountered are bound to the provided IFluidHandle.\n */\n public replaceHandles(\n input: any,\n bind: IFluidHandle,\n ) {\n // If the given 'input' cannot contain handles, return it immediately. Otherwise,\n // return the result of 'recursivelyReplace()'.\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n return !!input && typeof input === \"object\"\n ? this.recursivelyReplace(input, this.encodeValue, bind)\n : input;\n }\n\n /**\n * Given a fully-jsonable object tree that may have encoded handle objects embedded within, will return an\n * equivalent object tree where any encoded IFluidHandles have been replaced with thier decoded form.\n *\n * The original `input` object is not mutated. This method will shallowly clones all objects in the path from\n * the root to any replaced handles. (If no handles are found, returns the original object.)\n *\n * The decoded handles are implicitly bound to the handle context of this serializer.\n */\n public decode(input: any) {\n // If the given 'input' cannot contain handles, return it immediately. Otherwise,\n // return the result of 'recursivelyReplace()'.\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n return !!input && typeof input === \"object\"\n ? this.recursivelyReplace(input, this.decodeValue)\n : input;\n }\n\n public stringify(input: any, bind: IFluidHandle) {\n return JSON.stringify(input, (key, value) => this.encodeValue(value, bind));\n }\n\n // Parses the serialized data - context must match the context with which the JSON was stringified\n public parse(input: string) {\n return JSON.parse(input, (key, value) => this.decodeValue(value));\n }\n\n // If the given 'value' is an IFluidHandle, returns the encoded IFluidHandle.\n // Otherwise returns the original 'value'. Used by 'replaceHandles()' and 'stringify()'.\n private readonly encodeValue = (value: any, bind: IFluidHandle) => {\n // Detect if 'value' is an IFluidHandle.\n const handle = value?.IFluidHandle;\n\n // If 'value' is an IFluidHandle return its encoded form.\n return handle !== undefined\n ? this.serializeHandle(handle, bind)\n : value;\n };\n\n // If the given 'value' is an encoded IFluidHandle, returns the decoded IFluidHandle.\n // Otherwise returns the original 'value'. Used by 'decode()' and 'parse()'.\n private readonly decodeValue = (value: any) => {\n // If 'value' is a serialized IFluidHandle return the deserialized result.\n if (isSerializedHandle(value)) {\n // Old documents may have handles with relative path in their summaries. Convert these to absolute\n // paths. This will ensure that future summaries will have absolute paths for these handles.\n const absolutePath = value.url.startsWith(\"/\")\n ? value.url\n : generateHandleContextPath(value.url, this.context);\n\n return new RemoteFluidObjectHandle(absolutePath, this.root);\n } else {\n return value;\n }\n };\n\n // Invoked for non-null objects to recursively replace references to IFluidHandles.\n // Clones as-needed to avoid mutating the `input` object. If no IFluidHandes are present,\n // returns the original `input`.\n private recursivelyReplace(\n input: any,\n replacer: (input: any, context: any) => any,\n context?: any,\n ) {\n // Note: Caller is responsible for ensuring that `input` is defined / non-null.\n // (Required for Object.keys() below.)\n\n // Execute the `replace` on the current input. Note that Caller is responsible for ensuring that `input`\n // is a non-null object.\n const maybeReplaced = replacer(input, context);\n\n // If the replacer made a substitution there is no need to decscend further. IFluidHandles are always\n // leaves in the object graph.\n if (maybeReplaced !== input) {\n return maybeReplaced;\n }\n\n // Otherwise descend into the object graph looking for IFluidHandle instances.\n // eslint-disable-next-line @typescript-eslint/ban-types\n let clone: object | undefined;\n for (const key of Object.keys(input)) {\n const value = input[key];\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n if (!!value && typeof value === \"object\") {\n // Note: Except for IFluidHandle, `input` must not contain circular references (as object must\n // be JSON serializable.) Therefore, guarding against infinite recursion here would only\n // lead to a later error when attempting to stringify().\n const replaced = this.recursivelyReplace(value, replacer, context);\n\n // If the `replaced` object is different than the original `value` then the subgraph contained one\n // or more handles. If this happens, we need to return a clone of the `input` object where the\n // current property is replaced by the `replaced` value.\n if (replaced !== value) {\n // Lazily create a shallow clone of the `input` object if we haven't done so already.\n clone = clone ?? (Array.isArray(input)\n ? [...input]\n : { ...input });\n\n // Overwrite the current property `key` in the clone with the `replaced` value.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n clone![key] = replaced;\n }\n }\n }\n return clone ?? input;\n }\n\n protected serializeHandle(handle: IFluidHandle, bind: IFluidHandle) {\n bind.bind(handle);\n return {\n type: \"__fluid_handle__\",\n url: handle.absolutePath,\n };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"serializer.js","sourceRoot":"","sources":["../src/serializer.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\n// RATIONALE: Many methods consume and return 'any' by necessity.\n/* eslint-disable @typescript-eslint/no-unsafe-return */\n\nimport {\n IFluidHandle,\n IFluidHandleContext,\n IFluidSerializer,\n} from \"@fluidframework/core-interfaces\";\nimport { RemoteFluidObjectHandle } from \"./remoteObjectHandle\";\nimport { generateHandleContextPath } from \"./dataStoreHandleContextUtils\";\nimport { isSerializedHandle } from \"./utils\";\n\n/**\n * Data Store serializer implementation\n */\nexport class FluidSerializer implements IFluidSerializer {\n private readonly root: IFluidHandleContext;\n\n public constructor(\n private readonly context: IFluidHandleContext,\n // To be called whenever a handle is parsed by this serializer.\n private readonly handleParsedCb: (handle: IFluidHandle) => void,\n ) {\n this.root = this.context;\n while (this.root.routeContext !== undefined) {\n this.root = this.root.routeContext;\n }\n }\n\n public get IFluidSerializer() { return this; }\n\n /**\n * Given a mostly-jsonable object tree that may have handle objects embedded within, will return a\n * fully-jsonable object tree where any embedded IFluidHandles have been replaced with a serializable form.\n *\n * The original `input` object is not mutated. This method will shallowly clones all objects in the path from\n * the root to any replaced handles. (If no handles are found, returns the original object.)\n *\n * Any unbound handles encountered are bound to the provided IFluidHandle.\n */\n public replaceHandles(\n input: any,\n bind: IFluidHandle,\n ) {\n // If the given 'input' cannot contain handles, return it immediately. Otherwise,\n // return the result of 'recursivelyReplace()'.\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n return !!input && typeof input === \"object\"\n ? this.recursivelyReplace(input, this.encodeValue, bind)\n : input;\n }\n\n /**\n * Given a fully-jsonable object tree that may have encoded handle objects embedded within, will return an\n * equivalent object tree where any encoded IFluidHandles have been replaced with thier decoded form.\n *\n * The original `input` object is not mutated. This method will shallowly clones all objects in the path from\n * the root to any replaced handles. (If no handles are found, returns the original object.)\n *\n * The decoded handles are implicitly bound to the handle context of this serializer.\n */\n public decode(input: any) {\n // If the given 'input' cannot contain handles, return it immediately. Otherwise,\n // return the result of 'recursivelyReplace()'.\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n return !!input && typeof input === \"object\"\n ? this.recursivelyReplace(input, this.decodeValue)\n : input;\n }\n\n public stringify(input: any, bind: IFluidHandle) {\n return JSON.stringify(input, (key, value) => this.encodeValue(value, bind));\n }\n\n // Parses the serialized data - context must match the context with which the JSON was stringified\n public parse(input: string) {\n return JSON.parse(input, (key, value) => this.decodeValue(value));\n }\n\n // If the given 'value' is an IFluidHandle, returns the encoded IFluidHandle.\n // Otherwise returns the original 'value'. Used by 'replaceHandles()' and 'stringify()'.\n private readonly encodeValue = (value: any, bind: IFluidHandle) => {\n // Detect if 'value' is an IFluidHandle.\n const handle = value?.IFluidHandle;\n\n // If 'value' is an IFluidHandle return its encoded form.\n return handle !== undefined\n ? this.serializeHandle(handle, bind)\n : value;\n };\n\n // If the given 'value' is an encoded IFluidHandle, returns the decoded IFluidHandle.\n // Otherwise returns the original 'value'. Used by 'decode()' and 'parse()'.\n private readonly decodeValue = (value: any) => {\n // If 'value' is a serialized IFluidHandle return the deserialized result.\n if (isSerializedHandle(value)) {\n // Old documents may have handles with relative path in their summaries. Convert these to absolute\n // paths. This will ensure that future summaries will have absolute paths for these handles.\n const absolutePath = value.url.startsWith(\"/\")\n ? value.url\n : generateHandleContextPath(value.url, this.context);\n\n const parsedHandle = new RemoteFluidObjectHandle(absolutePath, this.root);\n this.handleParsedCb(parsedHandle);\n return parsedHandle;\n } else {\n return value;\n }\n };\n\n // Invoked for non-null objects to recursively replace references to IFluidHandles.\n // Clones as-needed to avoid mutating the `input` object. If no IFluidHandes are present,\n // returns the original `input`.\n private recursivelyReplace(\n input: any,\n replacer: (input: any, context: any) => any,\n context?: any,\n ) {\n // Note: Caller is responsible for ensuring that `input` is defined / non-null.\n // (Required for Object.keys() below.)\n\n // Execute the `replace` on the current input. Note that Caller is responsible for ensuring that `input`\n // is a non-null object.\n const maybeReplaced = replacer(input, context);\n\n // If the replacer made a substitution there is no need to decscend further. IFluidHandles are always\n // leaves in the object graph.\n if (maybeReplaced !== input) {\n return maybeReplaced;\n }\n\n // Otherwise descend into the object graph looking for IFluidHandle instances.\n // eslint-disable-next-line @typescript-eslint/ban-types\n let clone: object | undefined;\n for (const key of Object.keys(input)) {\n const value = input[key];\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n if (!!value && typeof value === \"object\") {\n // Note: Except for IFluidHandle, `input` must not contain circular references (as object must\n // be JSON serializable.) Therefore, guarding against infinite recursion here would only\n // lead to a later error when attempting to stringify().\n const replaced = this.recursivelyReplace(value, replacer, context);\n\n // If the `replaced` object is different than the original `value` then the subgraph contained one\n // or more handles. If this happens, we need to return a clone of the `input` object where the\n // current property is replaced by the `replaced` value.\n if (replaced !== value) {\n // Lazily create a shallow clone of the `input` object if we haven't done so already.\n clone = clone ?? (Array.isArray(input)\n ? [...input]\n : { ...input });\n\n // Overwrite the current property `key` in the clone with the `replaced` value.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n clone![key] = replaced;\n }\n }\n }\n return clone ?? input;\n }\n\n protected serializeHandle(handle: IFluidHandle, bind: IFluidHandle) {\n bind.bind(handle);\n return {\n type: \"__fluid_handle__\",\n url: handle.absolutePath,\n };\n }\n}\n"]}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
import { ITelemetryLogger } from "@fluidframework/common-definitions";
|
|
6
|
-
import {
|
|
6
|
+
import { ISnapshotTree } from "@fluidframework/protocol-definitions";
|
|
7
7
|
import { CreateChildSummarizerNodeParam, IGarbageCollectionData, IGarbageCollectionSummaryDetails, ISummarizeInternalResult, ISummarizeResult, ISummarizerNodeConfigWithGC, ISummarizerNodeWithGC } from "@fluidframework/runtime-definitions";
|
|
8
8
|
import { ReadAndParseBlob } from "../utils";
|
|
9
9
|
import { SummarizerNode } from "./summarizerNode";
|
|
@@ -28,11 +28,7 @@ export declare class SummarizerNodeWithGC extends SummarizerNode implements IRoo
|
|
|
28
28
|
private gcData;
|
|
29
29
|
private usedRoutes;
|
|
30
30
|
private unreferencedTimestampMs;
|
|
31
|
-
private readonly maxUnreferencedDurationMs;
|
|
32
|
-
private readonly unreferencedTimer;
|
|
33
|
-
private inactive;
|
|
34
31
|
private readonly gcDisabled;
|
|
35
|
-
private useAfterFreeErrorLogged;
|
|
36
32
|
/**
|
|
37
33
|
* Do not call constructor directly.
|
|
38
34
|
* Use createRootSummarizerNodeWithGC to create root node, or createChild to create child nodes.
|
|
@@ -102,14 +98,6 @@ export declare class SummarizerNodeWithGC extends SummarizerNode implements IRoo
|
|
|
102
98
|
getChild(id: string): ISummarizerNodeWithGC | undefined;
|
|
103
99
|
isReferenced(): boolean;
|
|
104
100
|
updateUsedRoutes(usedRoutes: string[], gcTimestamp?: number): void;
|
|
105
|
-
recordChange(op: ISequencedDocumentMessage): void;
|
|
106
|
-
/**
|
|
107
|
-
* Logs an error event if the node is inactive. This is used to identify cases where an inactive object is used.
|
|
108
|
-
* @param eventName - The name of the event to log.
|
|
109
|
-
* @param currentTimestampMs - The current time stamp. Used to report how long the object has been inactive.
|
|
110
|
-
* @returns true if we logged an error, false otherwise.
|
|
111
|
-
*/
|
|
112
|
-
private logErrorIfInactive;
|
|
113
101
|
/**
|
|
114
102
|
* Override the hasChanged method. If this node data or its used state changed, the node is considered changed.
|
|
115
103
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summarizerNodeWithGc.d.ts","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNodeWithGc.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAGtE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"summarizerNodeWithGc.d.ts","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNodeWithGc.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,7 +10,6 @@ const garbage_collector_1 = require("@fluidframework/garbage-collector");
|
|
|
10
10
|
const runtime_definitions_1 = require("@fluidframework/runtime-definitions");
|
|
11
11
|
const summarizerNode_1 = require("./summarizerNode");
|
|
12
12
|
const summarizerNodeUtils_1 = require("./summarizerNodeUtils");
|
|
13
|
-
const defaultMaxUnreferencedDurationMs = 7 * 24 * 60 * 60 * 1000; // 7 days
|
|
14
13
|
// Extend SummaryNode to add used routes tracking to it.
|
|
15
14
|
class SummaryNodeWithGC extends summarizerNodeUtils_1.SummaryNode {
|
|
16
15
|
constructor(serializedUsedRoutes, summary) {
|
|
@@ -35,7 +34,6 @@ class SummarizerNodeWithGC extends summarizerNode_1.SummarizerNode {
|
|
|
35
34
|
constructor(logger, summarizeFn, config, changeSequenceNumber,
|
|
36
35
|
/** Undefined means created without summary */
|
|
37
36
|
latestSummary, initialSummary, wipSummaryLogger, getGCDataFn, getInitialGCSummaryDetailsFn) {
|
|
38
|
-
var _a;
|
|
39
37
|
super(logger, async (fullTree) => summarizeFn(fullTree, true /* trackState */), config, changeSequenceNumber, latestSummary, initialSummary, wipSummaryLogger);
|
|
40
38
|
this.summarizeFn = summarizeFn;
|
|
41
39
|
this.getGCDataFn = getGCDataFn;
|
|
@@ -43,20 +41,11 @@ class SummarizerNodeWithGC extends summarizerNode_1.SummarizerNode {
|
|
|
43
41
|
// that this node is not marked as collected when running GC has been disabled. Once, the option to disable GC is
|
|
44
42
|
// removed (from runGC flag in IContainerRuntimeOptions), this should be changed to be have no routes by default.
|
|
45
43
|
this.usedRoutes = [""];
|
|
46
|
-
// Tracks whether this node is inactive after being unreferenced for maxUnreferencedDurationMs.
|
|
47
|
-
this.inactive = false;
|
|
48
|
-
// Keeps track of whether we logged an use-after-free error. This is temporary since the error is too noisy.
|
|
49
|
-
// To be removed once this item is completed - https://github.com/microsoft/FluidFramework/issues/7895.
|
|
50
|
-
this.useAfterFreeErrorLogged = false;
|
|
51
44
|
this.gcDisabled = config.gcDisabled === true;
|
|
52
|
-
this.maxUnreferencedDurationMs = (_a = config.maxUnreferencedDurationMs) !== null && _a !== void 0 ? _a : defaultMaxUnreferencedDurationMs;
|
|
53
45
|
this.gcDetailsInInitialSummaryP = new common_utils_1.LazyPromise(async () => {
|
|
54
46
|
const gcSummaryDetails = await (getInitialGCSummaryDetailsFn === null || getInitialGCSummaryDetailsFn === void 0 ? void 0 : getInitialGCSummaryDetailsFn());
|
|
55
47
|
return gcSummaryDetails !== null && gcSummaryDetails !== void 0 ? gcSummaryDetails : { usedRoutes: [] };
|
|
56
48
|
});
|
|
57
|
-
this.unreferencedTimer = new common_utils_1.Timer(this.maxUnreferencedDurationMs, () => {
|
|
58
|
-
this.inactive = true;
|
|
59
|
-
});
|
|
60
49
|
}
|
|
61
50
|
// Returns the GC details that may be added to this node's summary.
|
|
62
51
|
getGCSummaryDetails() {
|
|
@@ -203,12 +192,12 @@ class SummarizerNodeWithGC extends summarizerNode_1.SummarizerNode {
|
|
|
203
192
|
* Attach information if it is created from an attach op.
|
|
204
193
|
*/
|
|
205
194
|
createParam, config = {}, getGCDataFn, getInitialGCSummaryDetailsFn) {
|
|
206
|
-
var _a
|
|
195
|
+
var _a;
|
|
207
196
|
common_utils_1.assert(!this.children.has(id), 0x1b6 /* "Create SummarizerNode child already exists" */);
|
|
208
197
|
const createDetails = this.getCreateDetailsForChild(id, createParam);
|
|
209
198
|
const child = new SummarizerNodeWithGC(this.defaultLogger, summarizeInternalFn, Object.assign(Object.assign({}, config), {
|
|
210
199
|
// Propagate our gcDisabled state to the child if its not explicity specified in child's config.
|
|
211
|
-
gcDisabled: (_a = config.gcDisabled) !== null && _a !== void 0 ? _a : this.gcDisabled
|
|
200
|
+
gcDisabled: (_a = config.gcDisabled) !== null && _a !== void 0 ? _a : this.gcDisabled }), createDetails.changeSequenceNumber, createDetails.latestSummary, createDetails.initialSummary, this.wipSummaryLogger, getGCDataFn, getInitialGCSummaryDetailsFn);
|
|
212
201
|
// There may be additional state that has to be updated in this child. For example, if a summary is being
|
|
213
202
|
// tracked, the child's summary tracking state needs to be updated too.
|
|
214
203
|
this.maybeUpdateChildState(child);
|
|
@@ -240,72 +229,13 @@ class SummarizerNodeWithGC extends summarizerNode_1.SummarizerNode {
|
|
|
240
229
|
this.wipSerializedUsedRoutes = JSON.stringify(this.usedRoutes);
|
|
241
230
|
}
|
|
242
231
|
if (this.isReferenced()) {
|
|
243
|
-
// If this node has been unreferenced for longer than maxUnreferencedDurationMs and is being referenced,
|
|
244
|
-
// log an error as this may mean the maxUnreferencedDurationMs is not long enough.
|
|
245
|
-
this.logErrorIfInactive("inactiveObjectRevived", gcTimestamp);
|
|
246
|
-
// Clear unreferenced / inactive state, if any.
|
|
247
|
-
this.inactive = false;
|
|
248
232
|
this.unreferencedTimestampMs = undefined;
|
|
249
|
-
this.unreferencedTimer.clear();
|
|
250
|
-
return;
|
|
251
|
-
}
|
|
252
|
-
// This node is unreferenced. We need to check if this node is inative or if we need to start the unreferenced
|
|
253
|
-
// timer which would mark the node as inactive.
|
|
254
|
-
// If there is no timestamp when GC was run, we don't have enough information to determine whether this content
|
|
255
|
-
// should become inactive.
|
|
256
|
-
if (gcTimestamp === undefined) {
|
|
257
233
|
return;
|
|
258
234
|
}
|
|
259
|
-
// If
|
|
260
|
-
// and start the unreferenced timer.
|
|
261
|
-
// Note that it's possible this node has been unreferenced before but the unreferencedTimestampMs was not added.
|
|
262
|
-
// For example, older versions where this concept did not exist or if gcTimestamp wasn't available. In such
|
|
263
|
-
// cases, we track them as if the content just became unreferenced.
|
|
235
|
+
// If this node just became unreferenced, update its unreferencedTimestampMs.
|
|
264
236
|
if (this.unreferencedTimestampMs === undefined) {
|
|
265
237
|
this.unreferencedTimestampMs = gcTimestamp;
|
|
266
|
-
this.unreferencedTimer.start();
|
|
267
|
-
return;
|
|
268
|
-
}
|
|
269
|
-
// If we are here, this node was unreferenced earlier.
|
|
270
|
-
// If it is already inactive or has an unreferenced timer running, there is no more work to be done.
|
|
271
|
-
if (this.inactive || this.unreferencedTimer.hasTimer) {
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
|
-
// If it has been unreferenced longer than maxUnreferencedDurationMs, mark it as inactive. Otherwise, start the
|
|
275
|
-
// unreferenced timer for the duration left for it to reach maxUnreferencedDurationMs.
|
|
276
|
-
const currentUnreferencedDurationMs = gcTimestamp - this.unreferencedTimestampMs;
|
|
277
|
-
if (currentUnreferencedDurationMs >= this.maxUnreferencedDurationMs) {
|
|
278
|
-
this.inactive = true;
|
|
279
|
-
}
|
|
280
|
-
else {
|
|
281
|
-
this.unreferencedTimer.start(this.maxUnreferencedDurationMs - currentUnreferencedDurationMs);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
recordChange(op) {
|
|
285
|
-
// If the node is changed after it is inactive, log an error as this may mean use-after-delete.
|
|
286
|
-
// Currently, we only log this error once per node per session as it's too noisy.
|
|
287
|
-
if (!this.useAfterFreeErrorLogged && this.logErrorIfInactive("inactiveObjectChanged")) {
|
|
288
|
-
this.useAfterFreeErrorLogged = true;
|
|
289
|
-
}
|
|
290
|
-
super.recordChange(op);
|
|
291
|
-
}
|
|
292
|
-
/**
|
|
293
|
-
* Logs an error event if the node is inactive. This is used to identify cases where an inactive object is used.
|
|
294
|
-
* @param eventName - The name of the event to log.
|
|
295
|
-
* @param currentTimestampMs - The current time stamp. Used to report how long the object has been inactive.
|
|
296
|
-
* @returns true if we logged an error, false otherwise.
|
|
297
|
-
*/
|
|
298
|
-
logErrorIfInactive(eventName, currentTimestampMs) {
|
|
299
|
-
if (this.inactive) {
|
|
300
|
-
common_utils_1.assert(this.unreferencedTimestampMs !== undefined, 0x271 /* "Node should not become inactive without setting unreferencedTimestampMs first" */);
|
|
301
|
-
this.defaultLogger.sendErrorEvent({
|
|
302
|
-
eventName,
|
|
303
|
-
unreferencedDuratonMs: (currentTimestampMs !== null && currentTimestampMs !== void 0 ? currentTimestampMs : Date.now()) - this.unreferencedTimestampMs,
|
|
304
|
-
maxUnreferencedDurationMs: this.maxUnreferencedDurationMs,
|
|
305
|
-
});
|
|
306
|
-
return true;
|
|
307
238
|
}
|
|
308
|
-
return false;
|
|
309
239
|
}
|
|
310
240
|
/**
|
|
311
241
|
* Override the hasChanged method. If this node data or its used state changed, the node is considered changed.
|