@fluid-experimental/dds-interceptions 2.0.0-dev-rc.2.0.0.245554

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 (83) hide show
  1. package/.eslintrc.cjs +14 -0
  2. package/.mocharc.cjs +12 -0
  3. package/CHANGELOG.md +93 -0
  4. package/LICENSE +21 -0
  5. package/README.md +95 -0
  6. package/api-extractor-cjs.json +8 -0
  7. package/api-extractor-lint.json +4 -0
  8. package/api-extractor.json +4 -0
  9. package/api-report/dds-interceptions.api.md +24 -0
  10. package/dist/dds-interceptions-alpha.d.ts +13 -0
  11. package/dist/dds-interceptions-beta.d.ts +19 -0
  12. package/dist/dds-interceptions-public.d.ts +19 -0
  13. package/dist/dds-interceptions-untrimmed.d.ts +67 -0
  14. package/dist/index.d.ts +7 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +13 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/map/index.d.ts +7 -0
  19. package/dist/map/index.d.ts.map +1 -0
  20. package/dist/map/index.js +12 -0
  21. package/dist/map/index.js.map +1 -0
  22. package/dist/map/sharedDirectoryWithInterception.d.ts +29 -0
  23. package/dist/map/sharedDirectoryWithInterception.d.ts.map +1 -0
  24. package/dist/map/sharedDirectoryWithInterception.js +117 -0
  25. package/dist/map/sharedDirectoryWithInterception.js.map +1 -0
  26. package/dist/map/sharedMapWithInterception.d.ts +23 -0
  27. package/dist/map/sharedMapWithInterception.d.ts.map +1 -0
  28. package/dist/map/sharedMapWithInterception.js +49 -0
  29. package/dist/map/sharedMapWithInterception.js.map +1 -0
  30. package/dist/package.json +3 -0
  31. package/dist/sequence/index.d.ts +6 -0
  32. package/dist/sequence/index.d.ts.map +1 -0
  33. package/dist/sequence/index.js +10 -0
  34. package/dist/sequence/index.js.map +1 -0
  35. package/dist/sequence/sharedStringWithInterception.d.ts +27 -0
  36. package/dist/sequence/sharedStringWithInterception.d.ts.map +1 -0
  37. package/dist/sequence/sharedStringWithInterception.js +207 -0
  38. package/dist/sequence/sharedStringWithInterception.js.map +1 -0
  39. package/dist/tsdoc-metadata.json +11 -0
  40. package/lib/dds-interceptions-alpha.d.ts +13 -0
  41. package/lib/dds-interceptions-beta.d.ts +19 -0
  42. package/lib/dds-interceptions-public.d.ts +19 -0
  43. package/lib/dds-interceptions-untrimmed.d.ts +67 -0
  44. package/lib/index.d.ts +7 -0
  45. package/lib/index.d.ts.map +1 -0
  46. package/lib/index.js +7 -0
  47. package/lib/index.js.map +1 -0
  48. package/lib/map/index.d.ts +7 -0
  49. package/lib/map/index.d.ts.map +1 -0
  50. package/lib/map/index.js +7 -0
  51. package/lib/map/index.js.map +1 -0
  52. package/lib/map/sharedDirectoryWithInterception.d.ts +29 -0
  53. package/lib/map/sharedDirectoryWithInterception.d.ts.map +1 -0
  54. package/lib/map/sharedDirectoryWithInterception.js +113 -0
  55. package/lib/map/sharedDirectoryWithInterception.js.map +1 -0
  56. package/lib/map/sharedMapWithInterception.d.ts +23 -0
  57. package/lib/map/sharedMapWithInterception.d.ts.map +1 -0
  58. package/lib/map/sharedMapWithInterception.js +45 -0
  59. package/lib/map/sharedMapWithInterception.js.map +1 -0
  60. package/lib/sequence/index.d.ts +6 -0
  61. package/lib/sequence/index.d.ts.map +1 -0
  62. package/lib/sequence/index.js +6 -0
  63. package/lib/sequence/index.js.map +1 -0
  64. package/lib/sequence/sharedStringWithInterception.d.ts +27 -0
  65. package/lib/sequence/sharedStringWithInterception.d.ts.map +1 -0
  66. package/lib/sequence/sharedStringWithInterception.js +203 -0
  67. package/lib/sequence/sharedStringWithInterception.js.map +1 -0
  68. package/lib/test/sharedDirectoryWithInterception.spec.js +282 -0
  69. package/lib/test/sharedDirectoryWithInterception.spec.js.map +1 -0
  70. package/lib/test/sharedMapWithInterception.spec.js +105 -0
  71. package/lib/test/sharedMapWithInterception.spec.js.map +1 -0
  72. package/lib/test/sharedStringWithInterception.spec.js +147 -0
  73. package/lib/test/sharedStringWithInterception.spec.js.map +1 -0
  74. package/package.json +151 -0
  75. package/prettier.config.cjs +8 -0
  76. package/src/index.ts +7 -0
  77. package/src/map/index.ts +7 -0
  78. package/src/map/sharedDirectoryWithInterception.ts +172 -0
  79. package/src/map/sharedMapWithInterception.ts +58 -0
  80. package/src/sequence/index.ts +6 -0
  81. package/src/sequence/sharedStringWithInterception.ts +288 -0
  82. package/tsconfig.cjs.json +7 -0
  83. package/tsconfig.json +9 -0
@@ -0,0 +1,113 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { assert } from "@fluidframework/core-utils";
6
+ /**
7
+ * - Create a new object from the passed subDirectory.
8
+ *
9
+ * - Modify the set method to call the setInterceptionCallback before calling set on the underlying object.
10
+ *
11
+ * - The setInterceptionCallback and the call to the underlying object are wrapped around an orderSequentially
12
+ * call to batch any operations that might happen in the callback.
13
+ *
14
+ * - Modify the sub directory methods to create / return a wrapper object that in turn intercepts the set method and
15
+ * calls the setInterceptionCallback.
16
+ *
17
+ * - When a sub directory is created from this directory, this base directory object is passed to it which is passed
18
+ * into the interception callback.
19
+ *
20
+ * @param baseDirectory - The base directory in the directory structure that is passed to the interception callback
21
+ * @param subDirectory - The underlying object that is to be intercepted
22
+ * @param context - The IFluidDataStoreContext that will be used to call orderSequentially
23
+ * @param setInterceptionCallback - The interception callback to be called
24
+ *
25
+ * @returns A new sub directory that intercepts the set method and calls the setInterceptionCallback.
26
+ */
27
+ function createSubDirectoryWithInterception(baseDirectory, subDirectory, context, setInterceptionCallback) {
28
+ const subDirectoryWithInterception = Object.create(subDirectory);
29
+ // executingCallback keeps track of whether set is called recursively from the setInterceptionCallback.
30
+ let executingCallback = false;
31
+ subDirectoryWithInterception.set = (key, value) => {
32
+ let directory;
33
+ // Set should not be called on the wrapped object from the interception callback as this will lead to
34
+ // infinite recursion.
35
+ assert(executingCallback === false, 0x0bf /* "set called recursively from the interception callback" */);
36
+ context.containerRuntime.orderSequentially(() => {
37
+ directory = subDirectory.set(key, value);
38
+ executingCallback = true;
39
+ try {
40
+ setInterceptionCallback(baseDirectory, subDirectory, key, value);
41
+ }
42
+ finally {
43
+ executingCallback = false;
44
+ }
45
+ });
46
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
47
+ return directory;
48
+ };
49
+ subDirectoryWithInterception.createSubDirectory = (subdirName) => {
50
+ const subSubDirectory = subDirectory.createSubDirectory(subdirName);
51
+ return createSubDirectoryWithInterception(baseDirectory, subSubDirectory, context, setInterceptionCallback);
52
+ };
53
+ subDirectoryWithInterception.getSubDirectory = (subdirName) => {
54
+ const subSubDirectory = subDirectory.getSubDirectory(subdirName);
55
+ return subSubDirectory === undefined
56
+ ? subSubDirectory
57
+ : createSubDirectoryWithInterception(baseDirectory, subSubDirectory, context, setInterceptionCallback);
58
+ };
59
+ subDirectoryWithInterception.subdirectories = () => {
60
+ const localDirectoriesIterator = subDirectory.subdirectories();
61
+ const iterator = {
62
+ next() {
63
+ const nextVal = localDirectoriesIterator.next();
64
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
65
+ if (nextVal.done) {
66
+ return { value: undefined, done: true };
67
+ }
68
+ else {
69
+ // Wrap the stored subdirectory in the interception wrapper.
70
+ const subDir = createSubDirectoryWithInterception(baseDirectory, nextVal.value[1], context, setInterceptionCallback);
71
+ return { value: [nextVal.value[0], subDir], done: false };
72
+ }
73
+ },
74
+ [Symbol.iterator]() {
75
+ return this;
76
+ },
77
+ };
78
+ return iterator;
79
+ };
80
+ subDirectoryWithInterception.getWorkingDirectory = (relativePath) => {
81
+ const subSubDirectory = subDirectory.getWorkingDirectory(relativePath);
82
+ return subSubDirectory === undefined
83
+ ? subSubDirectory
84
+ : createSubDirectoryWithInterception(baseDirectory, subSubDirectory, context, setInterceptionCallback);
85
+ };
86
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
87
+ return subDirectoryWithInterception;
88
+ }
89
+ /**
90
+ * - Create a new object from the passed IDirectory object.
91
+ *
92
+ * - Modify the set method to call the setInterceptionCallback before calling set on the underlying object.
93
+ *
94
+ * - The setInterceptionCallback and the call to the underlying object are wrapped around an orderSequentially
95
+ * call to batch any operations that might happen in the callback.
96
+ *
97
+ * - Modify the sub directory methods to create / return a wrapper object that in turn intercepts the set method and
98
+ * calls the setInterceptionCallback.
99
+ *
100
+ * - When a sub directory is created from this directory, this directory object is passed to it which is passed into
101
+ * the interception callback.
102
+ *
103
+ * @param baseDirectory - The underlying object that is to be intercepted
104
+ * @param context - The IFluidDataStoreContext that will be used to call orderSequentially
105
+ * @param setInterceptionCallback - The interception callback to be called
106
+ *
107
+ * @returns A new IDirectory object that intercepts the set method and calls the setInterceptionCallback.
108
+ * @internal
109
+ */
110
+ export function createDirectoryWithInterception(baseDirectory, context, setInterceptionCallback) {
111
+ return createSubDirectoryWithInterception(baseDirectory, baseDirectory, context, setInterceptionCallback);
112
+ }
113
+ //# sourceMappingURL=sharedDirectoryWithInterception.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sharedDirectoryWithInterception.js","sourceRoot":"","sources":["../../src/map/sharedDirectoryWithInterception.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils\";\nimport { IDirectory } from \"@fluidframework/map\";\nimport { IFluidDataStoreContext } from \"@fluidframework/runtime-definitions\";\n\n/**\n * - Create a new object from the passed subDirectory.\n *\n * - Modify the set method to call the setInterceptionCallback before calling set on the underlying object.\n *\n * - The setInterceptionCallback and the call to the underlying object are wrapped around an orderSequentially\n * call to batch any operations that might happen in the callback.\n *\n * - Modify the sub directory methods to create / return a wrapper object that in turn intercepts the set method and\n * calls the setInterceptionCallback.\n *\n * - When a sub directory is created from this directory, this base directory object is passed to it which is passed\n * into the interception callback.\n *\n * @param baseDirectory - The base directory in the directory structure that is passed to the interception callback\n * @param subDirectory - The underlying object that is to be intercepted\n * @param context - The IFluidDataStoreContext that will be used to call orderSequentially\n * @param setInterceptionCallback - The interception callback to be called\n *\n * @returns A new sub directory that intercepts the set method and calls the setInterceptionCallback.\n */\nfunction createSubDirectoryWithInterception<T extends IDirectory>(\n\tbaseDirectory: T,\n\tsubDirectory: T,\n\tcontext: IFluidDataStoreContext,\n\tsetInterceptionCallback: (\n\t\tbaseDirectory: IDirectory,\n\t\tsubDirectory: IDirectory,\n\t\tkey: string,\n\t\tvalue: any,\n\t) => void,\n): T {\n\tconst subDirectoryWithInterception = Object.create(subDirectory);\n\n\t// executingCallback keeps track of whether set is called recursively from the setInterceptionCallback.\n\tlet executingCallback: boolean = false;\n\n\tsubDirectoryWithInterception.set = (key: string, value: any) => {\n\t\tlet directory;\n\t\t// Set should not be called on the wrapped object from the interception callback as this will lead to\n\t\t// infinite recursion.\n\t\tassert(\n\t\t\texecutingCallback === false,\n\t\t\t0x0bf /* \"set called recursively from the interception callback\" */,\n\t\t);\n\n\t\tcontext.containerRuntime.orderSequentially(() => {\n\t\t\tdirectory = subDirectory.set(key, value);\n\t\t\texecutingCallback = true;\n\t\t\ttry {\n\t\t\t\tsetInterceptionCallback(baseDirectory, subDirectory, key, value);\n\t\t\t} finally {\n\t\t\t\texecutingCallback = false;\n\t\t\t}\n\t\t});\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\treturn directory;\n\t};\n\n\tsubDirectoryWithInterception.createSubDirectory = (subdirName: string): IDirectory => {\n\t\tconst subSubDirectory = subDirectory.createSubDirectory(subdirName);\n\t\treturn createSubDirectoryWithInterception(\n\t\t\tbaseDirectory,\n\t\t\tsubSubDirectory,\n\t\t\tcontext,\n\t\t\tsetInterceptionCallback,\n\t\t);\n\t};\n\n\tsubDirectoryWithInterception.getSubDirectory = (subdirName: string): IDirectory | undefined => {\n\t\tconst subSubDirectory = subDirectory.getSubDirectory(subdirName);\n\t\treturn subSubDirectory === undefined\n\t\t\t? subSubDirectory\n\t\t\t: createSubDirectoryWithInterception(\n\t\t\t\t\tbaseDirectory,\n\t\t\t\t\tsubSubDirectory,\n\t\t\t\t\tcontext,\n\t\t\t\t\tsetInterceptionCallback,\n\t\t\t );\n\t};\n\n\tsubDirectoryWithInterception.subdirectories = (): IterableIterator<[string, IDirectory]> => {\n\t\tconst localDirectoriesIterator = subDirectory.subdirectories();\n\t\tconst iterator = {\n\t\t\tnext(): IteratorResult<[string, IDirectory]> {\n\t\t\t\tconst nextVal = localDirectoriesIterator.next();\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n\t\t\t\tif (nextVal.done) {\n\t\t\t\t\treturn { value: undefined, done: true };\n\t\t\t\t} else {\n\t\t\t\t\t// Wrap the stored subdirectory in the interception wrapper.\n\t\t\t\t\tconst subDir = createSubDirectoryWithInterception(\n\t\t\t\t\t\tbaseDirectory,\n\t\t\t\t\t\tnextVal.value[1],\n\t\t\t\t\t\tcontext,\n\t\t\t\t\t\tsetInterceptionCallback,\n\t\t\t\t\t);\n\t\t\t\t\treturn { value: [nextVal.value[0], subDir], done: false };\n\t\t\t\t}\n\t\t\t},\n\t\t\t[Symbol.iterator]() {\n\t\t\t\treturn this;\n\t\t\t},\n\t\t};\n\t\treturn iterator;\n\t};\n\n\tsubDirectoryWithInterception.getWorkingDirectory = (\n\t\trelativePath: string,\n\t): IDirectory | undefined => {\n\t\tconst subSubDirectory = subDirectory.getWorkingDirectory(relativePath);\n\t\treturn subSubDirectory === undefined\n\t\t\t? subSubDirectory\n\t\t\t: createSubDirectoryWithInterception(\n\t\t\t\t\tbaseDirectory,\n\t\t\t\t\tsubSubDirectory,\n\t\t\t\t\tcontext,\n\t\t\t\t\tsetInterceptionCallback,\n\t\t\t );\n\t};\n\n\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\treturn subDirectoryWithInterception;\n}\n\n/**\n * - Create a new object from the passed IDirectory object.\n *\n * - Modify the set method to call the setInterceptionCallback before calling set on the underlying object.\n *\n * - The setInterceptionCallback and the call to the underlying object are wrapped around an orderSequentially\n * call to batch any operations that might happen in the callback.\n *\n * - Modify the sub directory methods to create / return a wrapper object that in turn intercepts the set method and\n * calls the setInterceptionCallback.\n *\n * - When a sub directory is created from this directory, this directory object is passed to it which is passed into\n * the interception callback.\n *\n * @param baseDirectory - The underlying object that is to be intercepted\n * @param context - The IFluidDataStoreContext that will be used to call orderSequentially\n * @param setInterceptionCallback - The interception callback to be called\n *\n * @returns A new IDirectory object that intercepts the set method and calls the setInterceptionCallback.\n * @internal\n */\nexport function createDirectoryWithInterception<T extends IDirectory>(\n\tbaseDirectory: T,\n\tcontext: IFluidDataStoreContext,\n\tsetInterceptionCallback: (\n\t\tbaseDirectory: IDirectory,\n\t\tsubDirectory: IDirectory,\n\t\tkey: string,\n\t\tvalue: any,\n\t) => void,\n): T {\n\treturn createSubDirectoryWithInterception(\n\t\tbaseDirectory,\n\t\tbaseDirectory,\n\t\tcontext,\n\t\tsetInterceptionCallback,\n\t);\n}\n"]}
@@ -0,0 +1,23 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { ISharedMap } from "@fluidframework/map";
6
+ import { IFluidDataStoreContext } from "@fluidframework/runtime-definitions";
7
+ /**
8
+ * - Create a new object from the passed SharedMap.
9
+ *
10
+ * - Modify the set method to call the setInterceptionCallback before calling set on the underlying SharedMap.
11
+ *
12
+ * - The setInterceptionCallback and the call to the underlying SharedMap are wrapped around an
13
+ * orderSequentially call to batch any operations that might happen in the callback.
14
+ *
15
+ * @param sharedMap - The underlying SharedMap
16
+ * @param context - The IFluidDataStoreContext that will be used to call orderSequentially
17
+ * @param setInterceptionCallback - The interception callback to be called
18
+ *
19
+ * @returns A new SharedMap that intercepts the set method and calls the setInterceptionCallback.
20
+ * @internal
21
+ */
22
+ export declare function createSharedMapWithInterception(sharedMap: ISharedMap, context: IFluidDataStoreContext, setInterceptionCallback: (sharedMap: ISharedMap, key: string, value: any) => void): ISharedMap;
23
+ //# sourceMappingURL=sharedMapWithInterception.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sharedMapWithInterception.d.ts","sourceRoot":"","sources":["../../src/map/sharedMapWithInterception.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAE7E;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,+BAA+B,CAC9C,SAAS,EAAE,UAAU,EACrB,OAAO,EAAE,sBAAsB,EAC/B,uBAAuB,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,GAC/E,UAAU,CA6BZ"}
@@ -0,0 +1,45 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { assert } from "@fluidframework/core-utils";
6
+ /**
7
+ * - Create a new object from the passed SharedMap.
8
+ *
9
+ * - Modify the set method to call the setInterceptionCallback before calling set on the underlying SharedMap.
10
+ *
11
+ * - The setInterceptionCallback and the call to the underlying SharedMap are wrapped around an
12
+ * orderSequentially call to batch any operations that might happen in the callback.
13
+ *
14
+ * @param sharedMap - The underlying SharedMap
15
+ * @param context - The IFluidDataStoreContext that will be used to call orderSequentially
16
+ * @param setInterceptionCallback - The interception callback to be called
17
+ *
18
+ * @returns A new SharedMap that intercepts the set method and calls the setInterceptionCallback.
19
+ * @internal
20
+ */
21
+ export function createSharedMapWithInterception(sharedMap, context, setInterceptionCallback) {
22
+ const sharedMapWithInterception = Object.create(sharedMap);
23
+ // executingCallback keeps track of whether set is called recursively from the setInterceptionCallback.
24
+ let executingCallback = false;
25
+ sharedMapWithInterception.set = (key, value) => {
26
+ let map;
27
+ // Set should not be called on the wrapped object from the interception callback as this will lead to
28
+ // infinite recursion.
29
+ assert(executingCallback === false, 0x0c0 /* "set called recursively from the interception callback" */);
30
+ context.containerRuntime.orderSequentially(() => {
31
+ map = sharedMap.set(key, value);
32
+ executingCallback = true;
33
+ try {
34
+ setInterceptionCallback(sharedMap, key, value);
35
+ }
36
+ finally {
37
+ executingCallback = false;
38
+ }
39
+ });
40
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
41
+ return map;
42
+ };
43
+ return sharedMapWithInterception;
44
+ }
45
+ //# sourceMappingURL=sharedMapWithInterception.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sharedMapWithInterception.js","sourceRoot":"","sources":["../../src/map/sharedMapWithInterception.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAIpD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,+BAA+B,CAC9C,SAAqB,EACrB,OAA+B,EAC/B,uBAAiF;IAEjF,MAAM,yBAAyB,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAE3D,uGAAuG;IACvG,IAAI,iBAAiB,GAAY,KAAK,CAAC;IAEvC,yBAAyB,CAAC,GAAG,GAAG,CAAC,GAAW,EAAE,KAAU,EAAE,EAAE;QAC3D,IAAI,GAAG,CAAC;QACR,qGAAqG;QACrG,sBAAsB;QACtB,MAAM,CACL,iBAAiB,KAAK,KAAK,EAC3B,KAAK,CAAC,6DAA6D,CACnE,CAAC;QAEF,OAAO,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,GAAG,EAAE;YAC/C,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAChC,iBAAiB,GAAG,IAAI,CAAC;YACzB,IAAI;gBACH,uBAAuB,CAAC,SAAS,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;aAC/C;oBAAS;gBACT,iBAAiB,GAAG,KAAK,CAAC;aAC1B;QACF,CAAC,CAAC,CAAC;QACH,+DAA+D;QAC/D,OAAO,GAAG,CAAC;IACZ,CAAC,CAAC;IAEF,OAAO,yBAAuC,CAAC;AAChD,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils\";\nimport { ISharedMap } from \"@fluidframework/map\";\nimport { IFluidDataStoreContext } from \"@fluidframework/runtime-definitions\";\n\n/**\n * - Create a new object from the passed SharedMap.\n *\n * - Modify the set method to call the setInterceptionCallback before calling set on the underlying SharedMap.\n *\n * - The setInterceptionCallback and the call to the underlying SharedMap are wrapped around an\n * orderSequentially call to batch any operations that might happen in the callback.\n *\n * @param sharedMap - The underlying SharedMap\n * @param context - The IFluidDataStoreContext that will be used to call orderSequentially\n * @param setInterceptionCallback - The interception callback to be called\n *\n * @returns A new SharedMap that intercepts the set method and calls the setInterceptionCallback.\n * @internal\n */\nexport function createSharedMapWithInterception(\n\tsharedMap: ISharedMap,\n\tcontext: IFluidDataStoreContext,\n\tsetInterceptionCallback: (sharedMap: ISharedMap, key: string, value: any) => void,\n): ISharedMap {\n\tconst sharedMapWithInterception = Object.create(sharedMap);\n\n\t// executingCallback keeps track of whether set is called recursively from the setInterceptionCallback.\n\tlet executingCallback: boolean = false;\n\n\tsharedMapWithInterception.set = (key: string, value: any) => {\n\t\tlet map;\n\t\t// Set should not be called on the wrapped object from the interception callback as this will lead to\n\t\t// infinite recursion.\n\t\tassert(\n\t\t\texecutingCallback === false,\n\t\t\t0x0c0 /* \"set called recursively from the interception callback\" */,\n\t\t);\n\n\t\tcontext.containerRuntime.orderSequentially(() => {\n\t\t\tmap = sharedMap.set(key, value);\n\t\t\texecutingCallback = true;\n\t\t\ttry {\n\t\t\t\tsetInterceptionCallback(sharedMap, key, value);\n\t\t\t} finally {\n\t\t\t\texecutingCallback = false;\n\t\t\t}\n\t\t});\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\treturn map;\n\t};\n\n\treturn sharedMapWithInterception as ISharedMap;\n}\n"]}
@@ -0,0 +1,6 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ export { createSharedStringWithInterception } from "./sharedStringWithInterception.js";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sequence/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,kCAAkC,EAAE,MAAM,mCAAmC,CAAC"}
@@ -0,0 +1,6 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ export { createSharedStringWithInterception } from "./sharedStringWithInterception.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sequence/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,kCAAkC,EAAE,MAAM,mCAAmC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport { createSharedStringWithInterception } from \"./sharedStringWithInterception.js\";\n"]}
@@ -0,0 +1,27 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import * as MergeTree from "@fluidframework/merge-tree";
6
+ import { SharedString } from "@fluidframework/sequence";
7
+ import { IFluidDataStoreContext } from "@fluidframework/runtime-definitions";
8
+ /**
9
+ * - Create a new object from the passed SharedString.
10
+ *
11
+ * - Modify the methods that insert / remove / annotate the properties of the SharedString to call
12
+ * the propertyInterceptionCallback to get new properties.
13
+ *
14
+ * - Use these new properties to call the underlying SharedString.
15
+ *
16
+ * - The propertyInterceptionCallback and the call to the underlying SharedString are wrapped around an
17
+ * orderSequentially call to batch any operations that might happen in the callback.
18
+ *
19
+ * @param sharedString - The underlying SharedString
20
+ * @param context - The IFluidDataStoreContext that will be used to call orderSequentially
21
+ * @param propertyInterceptionCallback - The interception callback to be called
22
+ *
23
+ * @returns A new SharedString that intercepts the methods modifying the SharedString properties.
24
+ * @internal
25
+ */
26
+ export declare function createSharedStringWithInterception(sharedString: SharedString, context: IFluidDataStoreContext, propertyInterceptionCallback: (props?: MergeTree.PropertySet) => MergeTree.PropertySet): SharedString;
27
+ //# sourceMappingURL=sharedStringWithInterception.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sharedStringWithInterception.d.ts","sourceRoot":"","sources":["../../src/sequence/sharedStringWithInterception.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,SAAS,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAE7E;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kCAAkC,CACjD,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,sBAAsB,EAC/B,4BAA4B,EAAE,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,WAAW,KAAK,SAAS,CAAC,WAAW,GACpF,YAAY,CA+Pd"}
@@ -0,0 +1,203 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { assert } from "@fluidframework/core-utils";
6
+ /**
7
+ * - Create a new object from the passed SharedString.
8
+ *
9
+ * - Modify the methods that insert / remove / annotate the properties of the SharedString to call
10
+ * the propertyInterceptionCallback to get new properties.
11
+ *
12
+ * - Use these new properties to call the underlying SharedString.
13
+ *
14
+ * - The propertyInterceptionCallback and the call to the underlying SharedString are wrapped around an
15
+ * orderSequentially call to batch any operations that might happen in the callback.
16
+ *
17
+ * @param sharedString - The underlying SharedString
18
+ * @param context - The IFluidDataStoreContext that will be used to call orderSequentially
19
+ * @param propertyInterceptionCallback - The interception callback to be called
20
+ *
21
+ * @returns A new SharedString that intercepts the methods modifying the SharedString properties.
22
+ * @internal
23
+ */
24
+ export function createSharedStringWithInterception(sharedString, context, propertyInterceptionCallback) {
25
+ const sharedStringWithInterception = Object.create(sharedString);
26
+ // executingCallback keeps track of whether a method on this wrapper object is called recursively
27
+ // from the propertyInterceptionCallback.
28
+ let executingCallback = false;
29
+ /**
30
+ * Inserts a marker at a relative position.
31
+ *
32
+ * @param relativePos1 - The relative position to insert the marker at
33
+ * @param refType - The reference type of the marker
34
+ * @param props - The properties of the marker
35
+ */
36
+ sharedStringWithInterception.insertMarkerRelative = (relativePos1, refType, props) => {
37
+ // Wrapper methods should not be called from the interception callback as this will lead to
38
+ // infinite recursion.
39
+ assert(executingCallback === false, 0x0c1 /* "Interception wrapper methods called recursively from the interception callback" */);
40
+ context.containerRuntime.orderSequentially(() => {
41
+ executingCallback = true;
42
+ try {
43
+ sharedString.insertMarkerRelative(relativePos1, refType, propertyInterceptionCallback(props));
44
+ }
45
+ finally {
46
+ executingCallback = false;
47
+ }
48
+ });
49
+ };
50
+ /**
51
+ * Inserts a marker at the position.
52
+ *
53
+ * @param pos - The position to insert the marker at
54
+ * @param refType - The reference type of the marker
55
+ * @param props - The properties of the marker
56
+ */
57
+ sharedStringWithInterception.insertMarker = (pos, refType, props) => {
58
+ let insertOp;
59
+ // Wrapper methods should not be called from the interception callback as this will lead to
60
+ // infinite recursion.
61
+ assert(executingCallback === false, 0x0c2 /* "Interception wrapper methods called recursively from the interception callback" */);
62
+ context.containerRuntime.orderSequentially(() => {
63
+ executingCallback = true;
64
+ try {
65
+ insertOp = sharedString.insertMarker(pos, refType, propertyInterceptionCallback(props));
66
+ }
67
+ finally {
68
+ executingCallback = false;
69
+ }
70
+ });
71
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
72
+ return insertOp;
73
+ };
74
+ /**
75
+ * Inserts the text at a relative position.
76
+ *
77
+ * @param relativePos1 - The relative position to insert the text at
78
+ * @param text - The text to insert
79
+ * @param props - The properties of text
80
+ */
81
+ sharedStringWithInterception.insertTextRelative = (relativePos1, text, props) => {
82
+ // Wrapper methods should not be called from the interception callback as this will lead to
83
+ // infinite recursion.
84
+ assert(executingCallback === false, 0x0c3 /* "Interception wrapper methods called recursively from the interception callback" */);
85
+ context.containerRuntime.orderSequentially(() => {
86
+ executingCallback = true;
87
+ try {
88
+ sharedString.insertTextRelative(relativePos1, text, propertyInterceptionCallback(props));
89
+ }
90
+ finally {
91
+ executingCallback = false;
92
+ }
93
+ });
94
+ };
95
+ /**
96
+ * Inserts the text at the position.
97
+ *
98
+ * @param pos - The position to insert the text at
99
+ * @param text - The text to insert
100
+ * @param props - The properties of text
101
+ */
102
+ sharedStringWithInterception.insertText = (pos, text, props) => {
103
+ // Wrapper methods should not be called from the interception callback as this will lead to
104
+ // infinite recursion.
105
+ assert(executingCallback === false, 0x0c4 /* "Interception wrapper methods called recursively from the interception callback" */);
106
+ context.containerRuntime.orderSequentially(() => {
107
+ executingCallback = true;
108
+ try {
109
+ sharedString.insertText(pos, text, propertyInterceptionCallback(props));
110
+ }
111
+ finally {
112
+ executingCallback = false;
113
+ }
114
+ });
115
+ };
116
+ /**
117
+ * Replaces a range with the provided text.
118
+ *
119
+ * @param start - The inclusive start of the range to replace
120
+ * @param end - The exclusive end of the range to replace
121
+ * @param text - The text to replace the range with
122
+ * @param props - Optional. The properties of the replacement text
123
+ */
124
+ sharedStringWithInterception.replaceText = (start, end, text, props) => {
125
+ // Wrapper methods should not be called from the interception callback as this will lead to
126
+ // infinite recursion.
127
+ assert(executingCallback === false, 0x0c5 /* "Interception wrapper methods called recursively from the interception callback" */);
128
+ context.containerRuntime.orderSequentially(() => {
129
+ executingCallback = true;
130
+ try {
131
+ sharedString.replaceText(start, end, text, propertyInterceptionCallback(props));
132
+ }
133
+ finally {
134
+ executingCallback = false;
135
+ }
136
+ });
137
+ };
138
+ /**
139
+ * Annotates the marker with the provided properties.
140
+ *
141
+ * @param marker - The marker to annotate
142
+ * @param props - The properties to annotate the marker with
143
+ */
144
+ sharedStringWithInterception.annotateMarker = (marker, props) => {
145
+ // Wrapper methods should not be called from the interception callback as this will lead to
146
+ // infinite recursion.
147
+ assert(executingCallback === false, 0x0c7 /* "Interception wrapper methods called recursively from the interception callback" */);
148
+ context.containerRuntime.orderSequentially(() => {
149
+ executingCallback = true;
150
+ try {
151
+ sharedString.annotateMarker(marker, propertyInterceptionCallback(props));
152
+ }
153
+ finally {
154
+ executingCallback = false;
155
+ }
156
+ });
157
+ };
158
+ /**
159
+ * Annotates the range with the provided properties.
160
+ *
161
+ * @param start - The inclusive start position of the range to annotate
162
+ * @param end - The exclusive end position of the range to annotate
163
+ * @param props - The properties to annotate the range with
164
+ *
165
+ */
166
+ sharedStringWithInterception.annotateRange = (start, end, props) => {
167
+ // Wrapper methods should not be called from the interception callback as this will lead to
168
+ // infinite recursion.
169
+ assert(executingCallback === false, 0x0c8 /* "Interception wrapper methods called recursively from the interception callback" */);
170
+ context.containerRuntime.orderSequentially(() => {
171
+ executingCallback = true;
172
+ try {
173
+ sharedString.annotateRange(start, end, propertyInterceptionCallback(props));
174
+ }
175
+ finally {
176
+ executingCallback = false;
177
+ }
178
+ });
179
+ };
180
+ /**
181
+ * Inserts the segment at the given position
182
+ *
183
+ * @param pos - The position to insert the segment at
184
+ * @param segment - The segment to insert
185
+ */
186
+ sharedStringWithInterception.insertAtReferencePosition = (pos, segment) => {
187
+ // Wrapper methods should not be called from the interception callback as this will lead to
188
+ // infinite recursion.
189
+ assert(executingCallback === false, 0x0c9 /* "Interception wrapper methods called recursively from the interception callback" */);
190
+ context.containerRuntime.orderSequentially(() => {
191
+ executingCallback = true;
192
+ try {
193
+ segment.properties = propertyInterceptionCallback(segment.properties);
194
+ sharedString.insertAtReferencePosition(pos, segment);
195
+ }
196
+ finally {
197
+ executingCallback = false;
198
+ }
199
+ });
200
+ };
201
+ return sharedStringWithInterception;
202
+ }
203
+ //# sourceMappingURL=sharedStringWithInterception.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sharedStringWithInterception.js","sourceRoot":"","sources":["../../src/sequence/sharedStringWithInterception.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils\";\nimport * as MergeTree from \"@fluidframework/merge-tree\";\nimport { SharedString } from \"@fluidframework/sequence\";\nimport { IFluidDataStoreContext } from \"@fluidframework/runtime-definitions\";\n\n/**\n * - Create a new object from the passed SharedString.\n *\n * - Modify the methods that insert / remove / annotate the properties of the SharedString to call\n * the propertyInterceptionCallback to get new properties.\n *\n * - Use these new properties to call the underlying SharedString.\n *\n * - The propertyInterceptionCallback and the call to the underlying SharedString are wrapped around an\n * orderSequentially call to batch any operations that might happen in the callback.\n *\n * @param sharedString - The underlying SharedString\n * @param context - The IFluidDataStoreContext that will be used to call orderSequentially\n * @param propertyInterceptionCallback - The interception callback to be called\n *\n * @returns A new SharedString that intercepts the methods modifying the SharedString properties.\n * @internal\n */\nexport function createSharedStringWithInterception(\n\tsharedString: SharedString,\n\tcontext: IFluidDataStoreContext,\n\tpropertyInterceptionCallback: (props?: MergeTree.PropertySet) => MergeTree.PropertySet,\n): SharedString {\n\tconst sharedStringWithInterception = Object.create(sharedString);\n\n\t// executingCallback keeps track of whether a method on this wrapper object is called recursively\n\t// from the propertyInterceptionCallback.\n\tlet executingCallback: boolean = false;\n\n\t/**\n\t * Inserts a marker at a relative position.\n\t *\n\t * @param relativePos1 - The relative position to insert the marker at\n\t * @param refType - The reference type of the marker\n\t * @param props - The properties of the marker\n\t */\n\tsharedStringWithInterception.insertMarkerRelative = (\n\t\trelativePos1: MergeTree.IRelativePosition,\n\t\trefType: MergeTree.ReferenceType,\n\t\tprops?: MergeTree.PropertySet,\n\t) => {\n\t\t// Wrapper methods should not be called from the interception callback as this will lead to\n\t\t// infinite recursion.\n\t\tassert(\n\t\t\texecutingCallback === false,\n\t\t\t0x0c1 /* \"Interception wrapper methods called recursively from the interception callback\" */,\n\t\t);\n\n\t\tcontext.containerRuntime.orderSequentially(() => {\n\t\t\texecutingCallback = true;\n\t\t\ttry {\n\t\t\t\tsharedString.insertMarkerRelative(\n\t\t\t\t\trelativePos1,\n\t\t\t\t\trefType,\n\t\t\t\t\tpropertyInterceptionCallback(props),\n\t\t\t\t);\n\t\t\t} finally {\n\t\t\t\texecutingCallback = false;\n\t\t\t}\n\t\t});\n\t};\n\n\t/**\n\t * Inserts a marker at the position.\n\t *\n\t * @param pos - The position to insert the marker at\n\t * @param refType - The reference type of the marker\n\t * @param props - The properties of the marker\n\t */\n\tsharedStringWithInterception.insertMarker = (\n\t\tpos: number,\n\t\trefType: MergeTree.ReferenceType,\n\t\tprops?: MergeTree.PropertySet,\n\t) => {\n\t\tlet insertOp;\n\t\t// Wrapper methods should not be called from the interception callback as this will lead to\n\t\t// infinite recursion.\n\t\tassert(\n\t\t\texecutingCallback === false,\n\t\t\t0x0c2 /* \"Interception wrapper methods called recursively from the interception callback\" */,\n\t\t);\n\n\t\tcontext.containerRuntime.orderSequentially(() => {\n\t\t\texecutingCallback = true;\n\t\t\ttry {\n\t\t\t\tinsertOp = sharedString.insertMarker(\n\t\t\t\t\tpos,\n\t\t\t\t\trefType,\n\t\t\t\t\tpropertyInterceptionCallback(props),\n\t\t\t\t);\n\t\t\t} finally {\n\t\t\t\texecutingCallback = false;\n\t\t\t}\n\t\t});\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\treturn insertOp;\n\t};\n\n\t/**\n\t * Inserts the text at a relative position.\n\t *\n\t * @param relativePos1 - The relative position to insert the text at\n\t * @param text - The text to insert\n\t * @param props - The properties of text\n\t */\n\tsharedStringWithInterception.insertTextRelative = (\n\t\trelativePos1: MergeTree.IRelativePosition,\n\t\ttext: string,\n\t\tprops?: MergeTree.PropertySet,\n\t) => {\n\t\t// Wrapper methods should not be called from the interception callback as this will lead to\n\t\t// infinite recursion.\n\t\tassert(\n\t\t\texecutingCallback === false,\n\t\t\t0x0c3 /* \"Interception wrapper methods called recursively from the interception callback\" */,\n\t\t);\n\n\t\tcontext.containerRuntime.orderSequentially(() => {\n\t\t\texecutingCallback = true;\n\t\t\ttry {\n\t\t\t\tsharedString.insertTextRelative(\n\t\t\t\t\trelativePos1,\n\t\t\t\t\ttext,\n\t\t\t\t\tpropertyInterceptionCallback(props),\n\t\t\t\t);\n\t\t\t} finally {\n\t\t\t\texecutingCallback = false;\n\t\t\t}\n\t\t});\n\t};\n\n\t/**\n\t * Inserts the text at the position.\n\t *\n\t * @param pos - The position to insert the text at\n\t * @param text - The text to insert\n\t * @param props - The properties of text\n\t */\n\tsharedStringWithInterception.insertText = (\n\t\tpos: number,\n\t\ttext: string,\n\t\tprops?: MergeTree.PropertySet,\n\t) => {\n\t\t// Wrapper methods should not be called from the interception callback as this will lead to\n\t\t// infinite recursion.\n\t\tassert(\n\t\t\texecutingCallback === false,\n\t\t\t0x0c4 /* \"Interception wrapper methods called recursively from the interception callback\" */,\n\t\t);\n\n\t\tcontext.containerRuntime.orderSequentially(() => {\n\t\t\texecutingCallback = true;\n\t\t\ttry {\n\t\t\t\tsharedString.insertText(pos, text, propertyInterceptionCallback(props));\n\t\t\t} finally {\n\t\t\t\texecutingCallback = false;\n\t\t\t}\n\t\t});\n\t};\n\n\t/**\n\t * Replaces a range with the provided text.\n\t *\n\t * @param start - The inclusive start of the range to replace\n\t * @param end - The exclusive end of the range to replace\n\t * @param text - The text to replace the range with\n\t * @param props - Optional. The properties of the replacement text\n\t */\n\tsharedStringWithInterception.replaceText = (\n\t\tstart: number,\n\t\tend: number,\n\t\ttext: string,\n\t\tprops?: MergeTree.PropertySet,\n\t) => {\n\t\t// Wrapper methods should not be called from the interception callback as this will lead to\n\t\t// infinite recursion.\n\t\tassert(\n\t\t\texecutingCallback === false,\n\t\t\t0x0c5 /* \"Interception wrapper methods called recursively from the interception callback\" */,\n\t\t);\n\n\t\tcontext.containerRuntime.orderSequentially(() => {\n\t\t\texecutingCallback = true;\n\t\t\ttry {\n\t\t\t\tsharedString.replaceText(start, end, text, propertyInterceptionCallback(props));\n\t\t\t} finally {\n\t\t\t\texecutingCallback = false;\n\t\t\t}\n\t\t});\n\t};\n\n\t/**\n\t * Annotates the marker with the provided properties.\n\t *\n\t * @param marker - The marker to annotate\n\t * @param props - The properties to annotate the marker with\n\t */\n\tsharedStringWithInterception.annotateMarker = (\n\t\tmarker: MergeTree.Marker,\n\t\tprops: MergeTree.PropertySet,\n\t) => {\n\t\t// Wrapper methods should not be called from the interception callback as this will lead to\n\t\t// infinite recursion.\n\t\tassert(\n\t\t\texecutingCallback === false,\n\t\t\t0x0c7 /* \"Interception wrapper methods called recursively from the interception callback\" */,\n\t\t);\n\n\t\tcontext.containerRuntime.orderSequentially(() => {\n\t\t\texecutingCallback = true;\n\t\t\ttry {\n\t\t\t\tsharedString.annotateMarker(marker, propertyInterceptionCallback(props));\n\t\t\t} finally {\n\t\t\t\texecutingCallback = false;\n\t\t\t}\n\t\t});\n\t};\n\n\t/**\n\t * Annotates the range with the provided properties.\n\t *\n\t * @param start - The inclusive start position of the range to annotate\n\t * @param end - The exclusive end position of the range to annotate\n\t * @param props - The properties to annotate the range with\n\t *\n\t */\n\tsharedStringWithInterception.annotateRange = (\n\t\tstart: number,\n\t\tend: number,\n\t\tprops: MergeTree.PropertySet,\n\t) => {\n\t\t// Wrapper methods should not be called from the interception callback as this will lead to\n\t\t// infinite recursion.\n\t\tassert(\n\t\t\texecutingCallback === false,\n\t\t\t0x0c8 /* \"Interception wrapper methods called recursively from the interception callback\" */,\n\t\t);\n\n\t\tcontext.containerRuntime.orderSequentially(() => {\n\t\t\texecutingCallback = true;\n\t\t\ttry {\n\t\t\t\tsharedString.annotateRange(start, end, propertyInterceptionCallback(props));\n\t\t\t} finally {\n\t\t\t\texecutingCallback = false;\n\t\t\t}\n\t\t});\n\t};\n\n\t/**\n\t * Inserts the segment at the given position\n\t *\n\t * @param pos - The position to insert the segment at\n\t * @param segment - The segment to insert\n\t */\n\tsharedStringWithInterception.insertAtReferencePosition = (\n\t\tpos: MergeTree.ReferencePosition,\n\t\tsegment: MergeTree.TextSegment,\n\t) => {\n\t\t// Wrapper methods should not be called from the interception callback as this will lead to\n\t\t// infinite recursion.\n\t\tassert(\n\t\t\texecutingCallback === false,\n\t\t\t0x0c9 /* \"Interception wrapper methods called recursively from the interception callback\" */,\n\t\t);\n\n\t\tcontext.containerRuntime.orderSequentially(() => {\n\t\t\texecutingCallback = true;\n\t\t\ttry {\n\t\t\t\tsegment.properties = propertyInterceptionCallback(segment.properties);\n\t\t\t\tsharedString.insertAtReferencePosition(pos, segment);\n\t\t\t} finally {\n\t\t\t\texecutingCallback = false;\n\t\t\t}\n\t\t});\n\t};\n\n\treturn sharedStringWithInterception as SharedString;\n}\n"]}