@mcp-abap-adt/adt-clients 7.3.1 → 7.4.2

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 (85) hide show
  1. package/dist/clients/AdtClient.d.ts +32 -0
  2. package/dist/clients/AdtClient.d.ts.map +1 -1
  3. package/dist/clients/AdtClient.js +75 -30
  4. package/dist/core/accessControl/AdtAccessControl.d.ts +3 -1
  5. package/dist/core/accessControl/AdtAccessControl.d.ts.map +1 -1
  6. package/dist/core/accessControl/AdtAccessControl.js +11 -2
  7. package/dist/core/appendStructure/AdtAppendStructure.d.ts +3 -1
  8. package/dist/core/appendStructure/AdtAppendStructure.d.ts.map +1 -1
  9. package/dist/core/appendStructure/AdtAppendStructure.js +11 -2
  10. package/dist/core/authorizationField/AdtAuthorizationField.d.ts +3 -1
  11. package/dist/core/authorizationField/AdtAuthorizationField.d.ts.map +1 -1
  12. package/dist/core/authorizationField/AdtAuthorizationField.js +14 -3
  13. package/dist/core/behaviorDefinition/AdtBehaviorDefinition.d.ts +3 -1
  14. package/dist/core/behaviorDefinition/AdtBehaviorDefinition.d.ts.map +1 -1
  15. package/dist/core/behaviorDefinition/AdtBehaviorDefinition.js +11 -2
  16. package/dist/core/behaviorImplementation/AdtBehaviorImplementation.d.ts +2 -1
  17. package/dist/core/behaviorImplementation/AdtBehaviorImplementation.d.ts.map +1 -1
  18. package/dist/core/behaviorImplementation/AdtBehaviorImplementation.js +6 -3
  19. package/dist/core/class/AdtClass.d.ts +3 -1
  20. package/dist/core/class/AdtClass.d.ts.map +1 -1
  21. package/dist/core/class/AdtClass.js +16 -3
  22. package/dist/core/dataElement/AdtDataElement.d.ts +3 -1
  23. package/dist/core/dataElement/AdtDataElement.d.ts.map +1 -1
  24. package/dist/core/dataElement/AdtDataElement.js +9 -1
  25. package/dist/core/ddl/AdtDdl.d.ts +3 -1
  26. package/dist/core/ddl/AdtDdl.d.ts.map +1 -1
  27. package/dist/core/ddl/AdtDdl.js +11 -2
  28. package/dist/core/domain/AdtDomain.d.ts +3 -1
  29. package/dist/core/domain/AdtDomain.d.ts.map +1 -1
  30. package/dist/core/domain/AdtDomain.js +11 -1
  31. package/dist/core/enhancement/AdtEnhancement.d.ts +12 -1
  32. package/dist/core/enhancement/AdtEnhancement.d.ts.map +1 -1
  33. package/dist/core/enhancement/AdtEnhancement.js +35 -4
  34. package/dist/core/featureToggle/AdtFeatureToggle.d.ts +3 -1
  35. package/dist/core/featureToggle/AdtFeatureToggle.d.ts.map +1 -1
  36. package/dist/core/featureToggle/AdtFeatureToggle.js +14 -2
  37. package/dist/core/functionGroup/AdtFunctionGroup.d.ts +3 -1
  38. package/dist/core/functionGroup/AdtFunctionGroup.d.ts.map +1 -1
  39. package/dist/core/functionGroup/AdtFunctionGroup.js +9 -1
  40. package/dist/core/functionInclude/AdtFunctionInclude.d.ts +9 -1
  41. package/dist/core/functionInclude/AdtFunctionInclude.d.ts.map +1 -1
  42. package/dist/core/functionInclude/AdtFunctionInclude.js +33 -3
  43. package/dist/core/functionModule/AdtFunctionModule.d.ts +9 -1
  44. package/dist/core/functionModule/AdtFunctionModule.d.ts.map +1 -1
  45. package/dist/core/functionModule/AdtFunctionModule.js +27 -2
  46. package/dist/core/interface/AdtInterface.d.ts +3 -1
  47. package/dist/core/interface/AdtInterface.d.ts.map +1 -1
  48. package/dist/core/interface/AdtInterface.js +11 -2
  49. package/dist/core/messageClass/AdtMessageClass.d.ts +3 -1
  50. package/dist/core/messageClass/AdtMessageClass.d.ts.map +1 -1
  51. package/dist/core/messageClass/AdtMessageClass.js +11 -2
  52. package/dist/core/metadataExtension/AdtMetadataExtension.d.ts +3 -1
  53. package/dist/core/metadataExtension/AdtMetadataExtension.d.ts.map +1 -1
  54. package/dist/core/metadataExtension/AdtMetadataExtension.js +9 -1
  55. package/dist/core/package/AdtPackage.d.ts +3 -1
  56. package/dist/core/package/AdtPackage.d.ts.map +1 -1
  57. package/dist/core/package/AdtPackage.js +11 -2
  58. package/dist/core/program/AdtProgram.d.ts +3 -1
  59. package/dist/core/program/AdtProgram.d.ts.map +1 -1
  60. package/dist/core/program/AdtProgram.js +11 -2
  61. package/dist/core/scalarFunction/AdtScalarFunction.d.ts +3 -1
  62. package/dist/core/scalarFunction/AdtScalarFunction.d.ts.map +1 -1
  63. package/dist/core/scalarFunction/AdtScalarFunction.js +11 -2
  64. package/dist/core/scalarFunctionImplementation/AdtScalarFunctionImplementation.d.ts +3 -1
  65. package/dist/core/scalarFunctionImplementation/AdtScalarFunctionImplementation.d.ts.map +1 -1
  66. package/dist/core/scalarFunctionImplementation/AdtScalarFunctionImplementation.js +14 -2
  67. package/dist/core/serviceDefinition/AdtServiceDefinition.d.ts +6 -3
  68. package/dist/core/serviceDefinition/AdtServiceDefinition.d.ts.map +1 -1
  69. package/dist/core/serviceDefinition/AdtServiceDefinition.js +14 -4
  70. package/dist/core/shared/LockRegistry.d.ts +77 -0
  71. package/dist/core/shared/LockRegistry.d.ts.map +1 -0
  72. package/dist/core/shared/LockRegistry.js +91 -0
  73. package/dist/core/structure/AdtStructure.d.ts +3 -1
  74. package/dist/core/structure/AdtStructure.d.ts.map +1 -1
  75. package/dist/core/structure/AdtStructure.js +11 -2
  76. package/dist/core/table/AdtTable.d.ts +3 -1
  77. package/dist/core/table/AdtTable.d.ts.map +1 -1
  78. package/dist/core/table/AdtTable.js +11 -2
  79. package/dist/core/tabletype/AdtDdicTableType.d.ts +3 -1
  80. package/dist/core/tabletype/AdtDdicTableType.d.ts.map +1 -1
  81. package/dist/core/tabletype/AdtDdicTableType.js +9 -1
  82. package/dist/core/transformation/AdtTransformation.d.ts +3 -1
  83. package/dist/core/transformation/AdtTransformation.d.ts.map +1 -1
  84. package/dist/core/transformation/AdtTransformation.js +11 -2
  85. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"AdtScalarFunction.d.ts","sourceRoot":"","sources":["../../../src/core/scalarFunction/AdtScalarFunction.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAEV,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,OAAO,EACR,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAWpD,OAAO,KAAK,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAW3E,qBAAa,iBACX,YAAW,UAAU,CAAC,qBAAqB,EAAE,oBAAoB,CAAC;IAElE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,SAAgB,UAAU,EAAE,MAAM,CAAoB;gBAGpD,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB;IAO7B,QAAQ,CACZ,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,GACrC,OAAO,CAAC,oBAAoB,CAAC;IA6B1B,MAAM,CACV,MAAM,EAAE,qBAAqB,EAC7B,QAAQ,CAAC,EAAE,oBAAoB,GAC9B,OAAO,CAAC,oBAAoB,CAAC;IAwB1B,IAAI,CACR,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACtC,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,EAC/B,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;IAkBtC,YAAY,CAChB,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACtC,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,oBAAoB,CAAC;IAa1B,aAAa,CACjB,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACtC,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACtC,OAAO,CAAC,oBAAoB,CAAC;IAa1B,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACtC,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,oBAAoB,CAAC;IA6I1B,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,GACrC,OAAO,CAAC,oBAAoB,CAAC;IAmB1B,QAAQ,CACZ,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,GACrC,OAAO,CAAC,oBAAoB,CAAC;IAU1B,KAAK,CACT,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACtC,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,oBAAoB,CAAC;IAY1B,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAO7D,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACtC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,oBAAoB,CAAC;IAgBhC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC;IAIlD,gBAAgB,CAAC,UAAU,EAAE,MAAM;CAGpC"}
1
+ {"version":3,"file":"AdtScalarFunction.d.ts","sourceRoot":"","sources":["../../../src/core/scalarFunction/AdtScalarFunction.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAEV,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,OAAO,EACR,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,EAEL,KAAK,YAAY,EAElB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAWpD,OAAO,KAAK,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAW3E,qBAAa,iBACX,YAAW,UAAU,CAAC,qBAAqB,EAAE,oBAAoB,CAAC;IAElE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,SAAgB,UAAU,EAAE,MAAM,CAAoB;gBAGpD,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB,EACjC,YAAY,CAAC,EAAE,YAAY;IAavB,QAAQ,CACZ,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,GACrC,OAAO,CAAC,oBAAoB,CAAC;IA6B1B,MAAM,CACV,MAAM,EAAE,qBAAqB,EAC7B,QAAQ,CAAC,EAAE,oBAAoB,GAC9B,OAAO,CAAC,oBAAoB,CAAC;IAwB1B,IAAI,CACR,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACtC,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,EAC/B,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;IAkBtC,YAAY,CAChB,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACtC,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,oBAAoB,CAAC;IAa1B,aAAa,CACjB,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACtC,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACtC,OAAO,CAAC,oBAAoB,CAAC;IAa1B,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACtC,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,oBAAoB,CAAC;IAgJ1B,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,GACrC,OAAO,CAAC,oBAAoB,CAAC;IAmB1B,QAAQ,CACZ,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,GACrC,OAAO,CAAC,oBAAoB,CAAC;IAU1B,KAAK,CACT,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACtC,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,oBAAoB,CAAC;IAY1B,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAY7D,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACtC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,oBAAoB,CAAC;IAiBhC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC;IAIlD,gBAAgB,CAAC,UAAU,EAAE,MAAM;CAGpC"}
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AdtScalarFunction = void 0;
4
4
  const internalUtils_1 = require("../../utils/internalUtils");
5
+ const LockRegistry_1 = require("../shared/LockRegistry");
5
6
  const activation_1 = require("./activation");
6
7
  const check_1 = require("./check");
7
8
  const create_1 = require("./create");
@@ -17,11 +18,13 @@ class AdtScalarFunction {
17
18
  connection;
18
19
  logger;
19
20
  systemContext;
21
+ lockTracker;
20
22
  objectType = 'ScalarFunction';
21
- constructor(connection, logger, systemContext) {
23
+ constructor(connection, logger, systemContext, lockRegistry) {
22
24
  this.connection = connection;
23
25
  this.logger = logger;
24
26
  this.systemContext = systemContext ?? {};
27
+ this.lockTracker = (0, LockRegistry_1.createLockTracker)(lockRegistry, this.objectType, (name, lockHandle) => (0, unlock_1.unlockScalarFunction)(this.connection, name, lockHandle));
25
28
  }
26
29
  async validate(config) {
27
30
  const state = { errors: [] };
@@ -116,6 +119,7 @@ class AdtScalarFunction {
116
119
  try {
117
120
  this.connection.setSessionType('stateful');
118
121
  lockHandle = await (0, lock_1.lockScalarFunction)(this.connection, config.scalarFunctionName);
122
+ this.lockTracker.track(config.scalarFunctionName, lockHandle);
119
123
  const codeToCheck = options?.sourceCode || config.sourceCode;
120
124
  if (codeToCheck) {
121
125
  await (0, check_1.checkScalarFunction)(this.connection, config.scalarFunctionName, 'inactive', codeToCheck);
@@ -139,6 +143,7 @@ class AdtScalarFunction {
139
143
  finally {
140
144
  this.connection.setSessionType('stateless');
141
145
  }
146
+ this.lockTracker.untrack(config.scalarFunctionName);
142
147
  lockHandle = undefined;
143
148
  }
144
149
  await (0, check_1.checkScalarFunction)(this.connection, config.scalarFunctionName, 'inactive');
@@ -160,6 +165,7 @@ class AdtScalarFunction {
160
165
  try {
161
166
  this.connection.setSessionType('stateful');
162
167
  await (0, unlock_1.unlockScalarFunction)(this.connection, config.scalarFunctionName, lockHandle);
168
+ this.lockTracker.untrack(config.scalarFunctionName);
163
169
  }
164
170
  catch (unlockError) {
165
171
  this.logger?.warn?.('Failed to unlock during cleanup:', (0, internalUtils_1.safeErrorMessage)(unlockError));
@@ -222,7 +228,9 @@ class AdtScalarFunction {
222
228
  if (!config.scalarFunctionName)
223
229
  throw new Error('Scalar function name is required');
224
230
  this.connection.setSessionType('stateful');
225
- return (0, lock_1.lockScalarFunction)(this.connection, config.scalarFunctionName);
231
+ const lockHandle = await (0, lock_1.lockScalarFunction)(this.connection, config.scalarFunctionName);
232
+ this.lockTracker.track(config.scalarFunctionName, lockHandle);
233
+ return lockHandle;
226
234
  }
227
235
  async unlock(config, lockHandle) {
228
236
  if (!config.scalarFunctionName)
@@ -230,6 +238,7 @@ class AdtScalarFunction {
230
238
  this.connection.setSessionType('stateful');
231
239
  try {
232
240
  const unlockResult = await (0, unlock_1.unlockScalarFunction)(this.connection, config.scalarFunctionName, lockHandle);
241
+ this.lockTracker.untrack(config.scalarFunctionName);
233
242
  return { unlockResult, errors: [] };
234
243
  }
235
244
  finally {
@@ -4,14 +4,16 @@
4
4
  */
5
5
  import type { IAbapConnection, IAdtObject, IAdtOperationOptions, ILogger } from '@mcp-abap-adt/interfaces';
6
6
  import type { IAdtSystemContext } from '../../clients/AdtClient';
7
+ import { type LockRegistry } from '../shared/LockRegistry';
7
8
  import type { IReadOptions } from '../shared/types';
8
9
  import type { IScalarFunctionImplementationConfig, IScalarFunctionImplementationState } from './types';
9
10
  export declare class AdtScalarFunctionImplementation implements IAdtObject<IScalarFunctionImplementationConfig, IScalarFunctionImplementationState> {
10
11
  private readonly connection;
11
12
  private readonly logger?;
12
13
  private readonly systemContext;
14
+ private readonly lockTracker;
13
15
  readonly objectType: string;
14
- constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext);
16
+ constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext, lockRegistry?: LockRegistry);
15
17
  validate(config: Partial<IScalarFunctionImplementationConfig>): Promise<IScalarFunctionImplementationState>;
16
18
  create(config: IScalarFunctionImplementationConfig, _options?: IAdtOperationOptions): Promise<IScalarFunctionImplementationState>;
17
19
  read(config: Partial<IScalarFunctionImplementationConfig>, version?: 'active' | 'inactive', options?: IReadOptions): Promise<IScalarFunctionImplementationState | undefined>;
@@ -1 +1 @@
1
- {"version":3,"file":"AdtScalarFunctionImplementation.d.ts","sourceRoot":"","sources":["../../../src/core/scalarFunctionImplementation/AdtScalarFunctionImplementation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAEV,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,OAAO,EACR,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAWpD,OAAO,KAAK,EACV,mCAAmC,EACnC,kCAAkC,EACnC,MAAM,SAAS,CAAC;AAYjB,qBAAa,+BACX,YACE,UAAU,CACR,mCAAmC,EACnC,kCAAkC,CACnC;IAEH,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,SAAgB,UAAU,EAAE,MAAM,CAAkC;gBAGlE,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB;IAO7B,QAAQ,CACZ,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,GACnD,OAAO,CAAC,kCAAkC,CAAC;IA2BxC,MAAM,CACV,MAAM,EAAE,mCAAmC,EAC3C,QAAQ,CAAC,EAAE,oBAAoB,GAC9B,OAAO,CAAC,kCAAkC,CAAC;IA+BxC,IAAI,CACR,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,EACpD,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,EAC/B,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,kCAAkC,GAAG,SAAS,CAAC;IAkBpD,YAAY,CAChB,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,EACpD,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,kCAAkC,CAAC;IAaxC,aAAa,CACjB,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,EACpD,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACtC,OAAO,CAAC,kCAAkC,CAAC;IAa9C;;;;OAIG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,EACpD,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,kCAAkC,CAAC;IAiE9C;;;OAGG;IACG,cAAc,CAClB,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,EACpD,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,kCAAkC,CAAC;IAkExC,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,GACnD,OAAO,CAAC,kCAAkC,CAAC;IAsBxC,QAAQ,CACZ,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,GACnD,OAAO,CAAC,kCAAkC,CAAC;IAUxC,KAAK,CACT,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,EACpD,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,kCAAkC,CAAC;IAYxC,IAAI,CACR,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,GACnD,OAAO,CAAC,MAAM,CAAC;IAUZ,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,EACpD,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,kCAAkC,CAAC;IAgB9C,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC;IAIhE,gBAAgB,CAAC,UAAU,EAAE,MAAM;CAMpC"}
1
+ {"version":3,"file":"AdtScalarFunctionImplementation.d.ts","sourceRoot":"","sources":["../../../src/core/scalarFunctionImplementation/AdtScalarFunctionImplementation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAEV,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,OAAO,EACR,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,EAEL,KAAK,YAAY,EAElB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAWpD,OAAO,KAAK,EACV,mCAAmC,EACnC,kCAAkC,EACnC,MAAM,SAAS,CAAC;AAYjB,qBAAa,+BACX,YACE,UAAU,CACR,mCAAmC,EACnC,kCAAkC,CACnC;IAEH,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,SAAgB,UAAU,EAAE,MAAM,CAAkC;gBAGlE,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB,EACjC,YAAY,CAAC,EAAE,YAAY;IAavB,QAAQ,CACZ,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,GACnD,OAAO,CAAC,kCAAkC,CAAC;IA2BxC,MAAM,CACV,MAAM,EAAE,mCAAmC,EAC3C,QAAQ,CAAC,EAAE,oBAAoB,GAC9B,OAAO,CAAC,kCAAkC,CAAC;IA+BxC,IAAI,CACR,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,EACpD,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,EAC/B,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,kCAAkC,GAAG,SAAS,CAAC;IAkBpD,YAAY,CAChB,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,EACpD,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,kCAAkC,CAAC;IAaxC,aAAa,CACjB,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,EACpD,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACtC,OAAO,CAAC,kCAAkC,CAAC;IAa9C;;;;OAIG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,EACpD,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,kCAAkC,CAAC;IAoE9C;;;OAGG;IACG,cAAc,CAClB,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,EACpD,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,kCAAkC,CAAC;IAqExC,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,GACnD,OAAO,CAAC,kCAAkC,CAAC;IAsBxC,QAAQ,CACZ,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,GACnD,OAAO,CAAC,kCAAkC,CAAC;IAUxC,KAAK,CACT,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,EACpD,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,kCAAkC,CAAC;IAYxC,IAAI,CACR,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,GACnD,OAAO,CAAC,MAAM,CAAC;IAYZ,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,EACpD,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,kCAAkC,CAAC;IAiB9C,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC;IAIhE,gBAAgB,CAAC,UAAU,EAAE,MAAM;CAMpC"}
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AdtScalarFunctionImplementation = void 0;
4
4
  const internalUtils_1 = require("../../utils/internalUtils");
5
+ const LockRegistry_1 = require("../shared/LockRegistry");
5
6
  const activation_1 = require("./activation");
6
7
  const check_1 = require("./check");
7
8
  const create_1 = require("./create");
@@ -18,11 +19,13 @@ class AdtScalarFunctionImplementation {
18
19
  connection;
19
20
  logger;
20
21
  systemContext;
22
+ lockTracker;
21
23
  objectType = 'ScalarFunctionImplementation';
22
- constructor(connection, logger, systemContext) {
24
+ constructor(connection, logger, systemContext, lockRegistry) {
23
25
  this.connection = connection;
24
26
  this.logger = logger;
25
27
  this.systemContext = systemContext ?? {};
28
+ this.lockTracker = (0, LockRegistry_1.createLockTracker)(lockRegistry, this.objectType, (name, lockHandle) => (0, unlock_1.unlockScalarFunctionImplementation)(this.connection, name, lockHandle));
26
29
  }
27
30
  async validate(config) {
28
31
  const state = { errors: [] };
@@ -126,12 +129,14 @@ class AdtScalarFunctionImplementation {
126
129
  try {
127
130
  this.connection.setSessionType('stateful');
128
131
  lockHandle = await (0, lock_1.lockScalarFunctionImplementation)(this.connection, config.implementationName);
132
+ this.lockTracker.track(config.implementationName, lockHandle);
129
133
  const updateResult = await (0, update_1.updateScalarFunctionImplementation)(this.connection, {
130
134
  implementation_name: config.implementationName,
131
135
  source_code: sourceCode,
132
136
  transport_request: config.transportRequest,
133
137
  }, lockHandle);
134
138
  await (0, unlock_1.unlockScalarFunctionImplementation)(this.connection, config.implementationName, lockHandle);
139
+ this.lockTracker.untrack(config.implementationName);
135
140
  lockHandle = undefined;
136
141
  return { updateResult, errors: [] };
137
142
  }
@@ -139,6 +144,7 @@ class AdtScalarFunctionImplementation {
139
144
  if (lockHandle) {
140
145
  try {
141
146
  await (0, unlock_1.unlockScalarFunctionImplementation)(this.connection, config.implementationName, lockHandle);
147
+ this.lockTracker.untrack(config.implementationName);
142
148
  }
143
149
  catch (unlockError) {
144
150
  this.logger?.warn?.('Failed to unlock during cleanup:', (0, internalUtils_1.safeErrorMessage)(unlockError));
@@ -173,12 +179,14 @@ class AdtScalarFunctionImplementation {
173
179
  try {
174
180
  this.connection.setSessionType('stateful');
175
181
  lockHandle = await (0, lock_1.lockScalarFunctionImplementation)(this.connection, config.implementationName);
182
+ this.lockTracker.track(config.implementationName, lockHandle);
176
183
  const updateResult = await (0, updateMetadata_1.updateScalarFunctionImplementationMetadata)(this.connection, {
177
184
  implementation_name: config.implementationName,
178
185
  source_code: sourceCode,
179
186
  transport_request: config.transportRequest,
180
187
  }, lockHandle);
181
188
  await (0, unlock_1.unlockScalarFunctionImplementation)(this.connection, config.implementationName, lockHandle);
189
+ this.lockTracker.untrack(config.implementationName);
182
190
  lockHandle = undefined;
183
191
  return { updateResult, errors: [] };
184
192
  }
@@ -186,6 +194,7 @@ class AdtScalarFunctionImplementation {
186
194
  if (lockHandle) {
187
195
  try {
188
196
  await (0, unlock_1.unlockScalarFunctionImplementation)(this.connection, config.implementationName, lockHandle);
197
+ this.lockTracker.untrack(config.implementationName);
189
198
  }
190
199
  catch (unlockError) {
191
200
  this.logger?.warn?.('Failed to unlock during cleanup:', (0, internalUtils_1.safeErrorMessage)(unlockError));
@@ -234,7 +243,9 @@ class AdtScalarFunctionImplementation {
234
243
  if (!config.implementationName)
235
244
  throw new Error('Implementation name is required');
236
245
  this.connection.setSessionType('stateful');
237
- return (0, lock_1.lockScalarFunctionImplementation)(this.connection, config.implementationName);
246
+ const lockHandle = await (0, lock_1.lockScalarFunctionImplementation)(this.connection, config.implementationName);
247
+ this.lockTracker.track(config.implementationName, lockHandle);
248
+ return lockHandle;
238
249
  }
239
250
  async unlock(config, lockHandle) {
240
251
  if (!config.implementationName)
@@ -242,6 +253,7 @@ class AdtScalarFunctionImplementation {
242
253
  this.connection.setSessionType('stateful');
243
254
  try {
244
255
  const unlockResult = await (0, unlock_1.unlockScalarFunctionImplementation)(this.connection, config.implementationName, lockHandle);
256
+ this.lockTracker.untrack(config.implementationName);
245
257
  return { unlockResult, errors: [] };
246
258
  }
247
259
  finally {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * AdtServiceDefinition - High-level CRUD operations for Service Definition (DDLS) objects
2
+ * AdtServiceDefinition - High-level CRUD operations for Service Definition (SRVD/SRV) objects
3
3
  *
4
4
  * Implements IAdtObject interface with automatic operation chains,
5
5
  * error handling, and resource cleanup.
@@ -13,20 +13,23 @@
13
13
  * - activate uses same session/cookies (no stateful needed)
14
14
  *
15
15
  * Operation chains:
16
- * - Create: validate → create check lock check(inactive) update unlock → check → activate
16
+ * - Create: create (POST metadata only creates an empty source; the source
17
+ * code is written by a subsequent update(), mirroring what Eclipse ADT does)
17
18
  * - Update: lock → check(inactive) → update → unlock → check → activate
18
19
  * - Delete: check(deletion) → delete
19
20
  */
20
21
  import type { IAbapConnection, IAdtObject, IAdtOperationOptions, ILogger } from '@mcp-abap-adt/interfaces';
21
22
  import type { IAdtSystemContext } from '../../clients/AdtClient';
23
+ import { type LockRegistry } from '../shared/LockRegistry';
22
24
  import type { IReadOptions } from '../shared/types';
23
25
  import type { IServiceDefinitionConfig, IServiceDefinitionState } from './types';
24
26
  export declare class AdtServiceDefinition implements IAdtObject<IServiceDefinitionConfig, IServiceDefinitionState> {
25
27
  private readonly connection;
26
28
  private readonly logger?;
27
29
  private readonly systemContext;
30
+ private readonly lockTracker;
28
31
  readonly objectType: string;
29
- constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext);
32
+ constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext, lockRegistry?: LockRegistry);
30
33
  /**
31
34
  * Validate service definition configuration before creation
32
35
  */
@@ -1 +1 @@
1
- {"version":3,"file":"AdtServiceDefinition.d.ts","sourceRoot":"","sources":["../../../src/core/serviceDefinition/AdtServiceDefinition.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAEV,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,OAAO,EACR,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAWpD,OAAO,KAAK,EACV,wBAAwB,EACxB,uBAAuB,EACxB,MAAM,SAAS,CAAC;AASjB,qBAAa,oBACX,YAAW,UAAU,CAAC,wBAAwB,EAAE,uBAAuB,CAAC;IAExE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,SAAgB,UAAU,EAAE,MAAM,CAAuB;gBAGvD,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB;IAOnC;;OAEG;IACG,QAAQ,CACZ,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,GACxC,OAAO,CAAC,uBAAuB,CAAC;IA8BnC;;OAEG;IACG,MAAM,CACV,MAAM,EAAE,wBAAwB,EAChC,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,uBAAuB,CAAC;IAsCnC;;OAEG;IACG,IAAI,CACR,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,EACzC,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,EAC/B,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,uBAAuB,GAAG,SAAS,CAAC;IA2B/C;;OAEG;IACG,YAAY,CAChB,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,EACzC,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,uBAAuB,CAAC;IAkCnC;;OAEG;IACG,aAAa,CACjB,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,EACzC,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACtC,OAAO,CAAC,uBAAuB,CAAC;IAoCnC;;;;OAIG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,EACzC,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,uBAAuB,CAAC;IAmNnC;;OAEG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,GACxC,OAAO,CAAC,uBAAuB,CAAC;IAmCnC;;;OAGG;IACG,QAAQ,CACZ,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,GACxC,OAAO,CAAC,uBAAuB,CAAC;IAqBnC;;OAEG;IACG,KAAK,CACT,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,EACzC,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,uBAAuB,CAAC;IAkBnC;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAatE;;OAEG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,EACzC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,uBAAuB,CAAC;IAkBnC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC;IAIrD,gBAAgB,CAAC,UAAU,EAAE,MAAM;CAGpC"}
1
+ {"version":3,"file":"AdtServiceDefinition.d.ts","sourceRoot":"","sources":["../../../src/core/serviceDefinition/AdtServiceDefinition.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAEV,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,OAAO,EACR,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,EAEL,KAAK,YAAY,EAElB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAWpD,OAAO,KAAK,EACV,wBAAwB,EACxB,uBAAuB,EACxB,MAAM,SAAS,CAAC;AASjB,qBAAa,oBACX,YAAW,UAAU,CAAC,wBAAwB,EAAE,uBAAuB,CAAC;IAExE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,SAAgB,UAAU,EAAE,MAAM,CAAuB;gBAGvD,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB,EACjC,YAAY,CAAC,EAAE,YAAY;IAa7B;;OAEG;IACG,QAAQ,CACZ,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,GACxC,OAAO,CAAC,uBAAuB,CAAC;IA8BnC;;OAEG;IACG,MAAM,CACV,MAAM,EAAE,wBAAwB,EAChC,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,uBAAuB,CAAC;IAsCnC;;OAEG;IACG,IAAI,CACR,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,EACzC,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,EAC/B,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,uBAAuB,GAAG,SAAS,CAAC;IA2B/C;;OAEG;IACG,YAAY,CAChB,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,EACzC,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,uBAAuB,CAAC;IAkCnC;;OAEG;IACG,aAAa,CACjB,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,EACzC,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACtC,OAAO,CAAC,uBAAuB,CAAC;IAoCnC;;;;OAIG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,EACzC,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,uBAAuB,CAAC;IAuNnC;;OAEG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,GACxC,OAAO,CAAC,uBAAuB,CAAC;IAmCnC;;;OAGG;IACG,QAAQ,CACZ,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,GACxC,OAAO,CAAC,uBAAuB,CAAC;IAqBnC;;OAEG;IACG,KAAK,CACT,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,EACzC,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,uBAAuB,CAAC;IAkBnC;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IActE;;OAEG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,EACzC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,uBAAuB,CAAC;IAmBnC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC;IAIrD,gBAAgB,CAAC,UAAU,EAAE,MAAM;CAGpC"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /**
3
- * AdtServiceDefinition - High-level CRUD operations for Service Definition (DDLS) objects
3
+ * AdtServiceDefinition - High-level CRUD operations for Service Definition (SRVD/SRV) objects
4
4
  *
5
5
  * Implements IAdtObject interface with automatic operation chains,
6
6
  * error handling, and resource cleanup.
@@ -14,13 +14,15 @@
14
14
  * - activate uses same session/cookies (no stateful needed)
15
15
  *
16
16
  * Operation chains:
17
- * - Create: validate → create check lock check(inactive) update unlock → check → activate
17
+ * - Create: create (POST metadata only creates an empty source; the source
18
+ * code is written by a subsequent update(), mirroring what Eclipse ADT does)
18
19
  * - Update: lock → check(inactive) → update → unlock → check → activate
19
20
  * - Delete: check(deletion) → delete
20
21
  */
21
22
  Object.defineProperty(exports, "__esModule", { value: true });
22
23
  exports.AdtServiceDefinition = void 0;
23
24
  const internalUtils_1 = require("../../utils/internalUtils");
25
+ const LockRegistry_1 = require("../shared/LockRegistry");
24
26
  const activation_1 = require("./activation");
25
27
  const check_1 = require("./check");
26
28
  const create_1 = require("./create");
@@ -35,11 +37,13 @@ class AdtServiceDefinition {
35
37
  connection;
36
38
  logger;
37
39
  systemContext;
40
+ lockTracker;
38
41
  objectType = 'ServiceDefinition';
39
- constructor(connection, logger, systemContext) {
42
+ constructor(connection, logger, systemContext, lockRegistry) {
40
43
  this.connection = connection;
41
44
  this.logger = logger;
42
45
  this.systemContext = systemContext ?? {};
46
+ this.lockTracker = (0, LockRegistry_1.createLockTracker)(lockRegistry, this.objectType, (name, lockHandle) => (0, unlock_1.unlockServiceDefinition)(this.connection, name, lockHandle));
43
47
  }
44
48
  /**
45
49
  * Validate service definition configuration before creation
@@ -228,6 +232,7 @@ class AdtServiceDefinition {
228
232
  this.logger?.info?.('Step 1: Locking service definition');
229
233
  this.connection.setSessionType('stateful');
230
234
  lockHandle = await (0, lock_1.lockServiceDefinition)(this.connection, config.serviceDefinitionName);
235
+ this.lockTracker.track(config.serviceDefinitionName, lockHandle);
231
236
  this.logger?.info?.('Service definition locked, handle:', lockHandle);
232
237
  // 2. Check inactive with code for update (from options or config)
233
238
  const codeToCheck = options?.sourceCode || config.sourceCode;
@@ -246,9 +251,10 @@ class AdtServiceDefinition {
246
251
  }, lockHandle);
247
252
  this.logger?.info?.('Service definition updated');
248
253
  // 3.5. Read with long polling (wait for object to be ready after update)
254
+ // Poll the inactive version: the write above produced it; the active version may not exist yet.
249
255
  this.logger?.info?.('read (wait for object ready after update)');
250
256
  try {
251
- await this.read({ serviceDefinitionName: config.serviceDefinitionName }, 'active', { withLongPolling: true });
257
+ await this.read({ serviceDefinitionName: config.serviceDefinitionName }, 'inactive', { withLongPolling: true });
252
258
  this.logger?.info?.('object is ready after update');
253
259
  }
254
260
  catch (readError) {
@@ -262,6 +268,7 @@ class AdtServiceDefinition {
262
268
  this.connection.setSessionType('stateful');
263
269
  await (0, unlock_1.unlockServiceDefinition)(this.connection, config.serviceDefinitionName, lockHandle);
264
270
  this.connection.setSessionType('stateless');
271
+ this.lockTracker.untrack(config.serviceDefinitionName);
265
272
  lockHandle = undefined;
266
273
  this.logger?.info?.('Service definition unlocked');
267
274
  }
@@ -307,6 +314,7 @@ class AdtServiceDefinition {
307
314
  this.connection.setSessionType('stateful');
308
315
  await (0, unlock_1.unlockServiceDefinition)(this.connection, config.serviceDefinitionName, lockHandle);
309
316
  this.connection.setSessionType('stateless');
317
+ this.lockTracker.untrack(config.serviceDefinitionName);
310
318
  }
311
319
  catch (unlockError) {
312
320
  this.logger?.warn?.('Failed to unlock during cleanup:', (0, internalUtils_1.safeErrorMessage)(unlockError));
@@ -413,6 +421,7 @@ class AdtServiceDefinition {
413
421
  }
414
422
  this.connection.setSessionType('stateful');
415
423
  const lockHandle = await (0, lock_1.lockServiceDefinition)(this.connection, config.serviceDefinitionName);
424
+ this.lockTracker.track(config.serviceDefinitionName, lockHandle);
416
425
  return lockHandle;
417
426
  }
418
427
  /**
@@ -425,6 +434,7 @@ class AdtServiceDefinition {
425
434
  this.connection.setSessionType('stateful');
426
435
  const result = await (0, unlock_1.unlockServiceDefinition)(this.connection, config.serviceDefinitionName, lockHandle);
427
436
  this.connection.setSessionType('stateless');
437
+ this.lockTracker.untrack(config.serviceDefinitionName);
428
438
  return {
429
439
  unlockResult: result,
430
440
  errors: [],
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Session-scoped registry of held object locks.
3
+ *
4
+ * One registry per stateful session (owned by AdtClient). Handlers record a lock
5
+ * when they acquire it and remove it on a clean unlock. `unlockAll()` is the
6
+ * last-resort cleanup: it releases any lock still held (e.g. the consumer forgot
7
+ * to unlock, or a managed flow threw before its unlock), so a session is never
8
+ * abandoned with dangling enqueue locks.
9
+ *
10
+ * This is a safety net, NOT the primary defense. Preventing a timeout from
11
+ * interrupting the lock→unlock critical section is the caller's responsibility.
12
+ */
13
+ /**
14
+ * Releases a single held lock. Provided by the handler that acquired it.
15
+ *
16
+ * The thunk MUST NOT toggle the connection session type — `unlockAll()` keeps
17
+ * the session stateful for the whole batch and restores stateless once at the
18
+ * end (see {@link LockRegistry.unlockAll}).
19
+ */
20
+ export type UnlockThunk = () => Promise<unknown>;
21
+ /** A lock that `unlockAll()` failed to release, kept for reporting / retry. */
22
+ export interface LockFailure {
23
+ key: string;
24
+ error: unknown;
25
+ }
26
+ /** Minimal session control the registry needs to run an unlock batch. */
27
+ export interface ISessionController {
28
+ setSessionType(type: 'stateful' | 'stateless'): void;
29
+ }
30
+ export declare class LockRegistry {
31
+ private readonly session?;
32
+ private readonly locks;
33
+ /**
34
+ * @param session Controls the shared connection's session type. `unlockAll()`
35
+ * uses it to keep the session stateful for the whole batch — some
36
+ * connections (RFC) clear the stateful cookie when switched to stateless,
37
+ * which would invalidate the remaining lock handles mid-batch.
38
+ */
39
+ constructor(session?: ISessionController | undefined);
40
+ /** Record a held lock under a stable object key (e.g. `DOMA/ZFOO`). */
41
+ track(key: string, unlock: UnlockThunk): void;
42
+ /** Drop a lock after it has been released cleanly. */
43
+ untrack(key: string): void;
44
+ /** Keys of locks still held. */
45
+ get pending(): string[];
46
+ /**
47
+ * Release every lock still held. Successfully released locks are dropped;
48
+ * locks whose unlock throws are kept and returned as failures.
49
+ *
50
+ * The whole batch runs under a single stateful→stateless transition so that a
51
+ * per-unlock switch to stateless can't clear the session mid-batch and break
52
+ * the remaining lock handles.
53
+ */
54
+ unlockAll(): Promise<LockFailure[]>;
55
+ }
56
+ /**
57
+ * Per-handler view over a {@link LockRegistry}: records/removes locks under a
58
+ * stable, type-prefixed key. A no-op when no registry is present, so handlers
59
+ * work unchanged whether or not a registry was injected.
60
+ */
61
+ export interface LockTracker {
62
+ /** Record a held lock for `objectName`. */
63
+ track(objectName: string, lockHandle: string): void;
64
+ /** Drop the lock for `objectName` after a clean unlock. */
65
+ untrack(objectName: string): void;
66
+ }
67
+ /**
68
+ * Build a {@link LockTracker} for one object type.
69
+ *
70
+ * @param registry Session registry to record into (undefined → no-op tracker).
71
+ * @param objectType Stable type prefix for the key (e.g. `Domain`).
72
+ * @param unlock Raw release of a held lock, invoked by `unlockAll()` for
73
+ * abandoned locks. MUST NOT toggle the session type —
74
+ * `unlockAll()` manages the session for the whole batch.
75
+ */
76
+ export declare function createLockTracker(registry: LockRegistry | undefined, objectType: string, unlock: (objectName: string, lockHandle: string) => Promise<unknown>): LockTracker;
77
+ //# sourceMappingURL=LockRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LockRegistry.d.ts","sourceRoot":"","sources":["../../../src/core/shared/LockRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;AAEjD,+EAA+E;AAC/E,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,yEAAyE;AACzE,MAAM,WAAW,kBAAkB;IACjC,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,WAAW,GAAG,IAAI,CAAC;CACtD;AAED,qBAAa,YAAY;IASX,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IARrC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkC;IAExD;;;;;OAKG;gBAC0B,OAAO,CAAC,EAAE,kBAAkB,YAAA;IAEzD,uEAAuE;IACvE,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI;IAI7C,sDAAsD;IACtD,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAI1B,gCAAgC;IAChC,IAAI,OAAO,IAAI,MAAM,EAAE,CAEtB;IAED;;;;;;;OAOG;IACG,SAAS,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;CAmB1C;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,2CAA2C;IAC3C,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACpD,2DAA2D;IAC3D,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,YAAY,GAAG,SAAS,EAClC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GACnE,WAAW,CAWb"}
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ /**
3
+ * Session-scoped registry of held object locks.
4
+ *
5
+ * One registry per stateful session (owned by AdtClient). Handlers record a lock
6
+ * when they acquire it and remove it on a clean unlock. `unlockAll()` is the
7
+ * last-resort cleanup: it releases any lock still held (e.g. the consumer forgot
8
+ * to unlock, or a managed flow threw before its unlock), so a session is never
9
+ * abandoned with dangling enqueue locks.
10
+ *
11
+ * This is a safety net, NOT the primary defense. Preventing a timeout from
12
+ * interrupting the lock→unlock critical section is the caller's responsibility.
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.LockRegistry = void 0;
16
+ exports.createLockTracker = createLockTracker;
17
+ class LockRegistry {
18
+ session;
19
+ locks = new Map();
20
+ /**
21
+ * @param session Controls the shared connection's session type. `unlockAll()`
22
+ * uses it to keep the session stateful for the whole batch — some
23
+ * connections (RFC) clear the stateful cookie when switched to stateless,
24
+ * which would invalidate the remaining lock handles mid-batch.
25
+ */
26
+ constructor(session) {
27
+ this.session = session;
28
+ }
29
+ /** Record a held lock under a stable object key (e.g. `DOMA/ZFOO`). */
30
+ track(key, unlock) {
31
+ this.locks.set(key, unlock);
32
+ }
33
+ /** Drop a lock after it has been released cleanly. */
34
+ untrack(key) {
35
+ this.locks.delete(key);
36
+ }
37
+ /** Keys of locks still held. */
38
+ get pending() {
39
+ return [...this.locks.keys()];
40
+ }
41
+ /**
42
+ * Release every lock still held. Successfully released locks are dropped;
43
+ * locks whose unlock throws are kept and returned as failures.
44
+ *
45
+ * The whole batch runs under a single stateful→stateless transition so that a
46
+ * per-unlock switch to stateless can't clear the session mid-batch and break
47
+ * the remaining lock handles.
48
+ */
49
+ async unlockAll() {
50
+ const failures = [];
51
+ if (this.locks.size === 0)
52
+ return failures;
53
+ this.session?.setSessionType('stateful');
54
+ try {
55
+ for (const [key, unlock] of [...this.locks]) {
56
+ try {
57
+ await unlock();
58
+ this.locks.delete(key);
59
+ }
60
+ catch (error) {
61
+ failures.push({ key, error });
62
+ }
63
+ }
64
+ }
65
+ finally {
66
+ this.session?.setSessionType('stateless');
67
+ }
68
+ return failures;
69
+ }
70
+ }
71
+ exports.LockRegistry = LockRegistry;
72
+ /**
73
+ * Build a {@link LockTracker} for one object type.
74
+ *
75
+ * @param registry Session registry to record into (undefined → no-op tracker).
76
+ * @param objectType Stable type prefix for the key (e.g. `Domain`).
77
+ * @param unlock Raw release of a held lock, invoked by `unlockAll()` for
78
+ * abandoned locks. MUST NOT toggle the session type —
79
+ * `unlockAll()` manages the session for the whole batch.
80
+ */
81
+ function createLockTracker(registry, objectType, unlock) {
82
+ const keyOf = (objectName) => `${objectType}/${objectName.toUpperCase()}`;
83
+ return {
84
+ track(objectName, lockHandle) {
85
+ registry?.track(keyOf(objectName), () => unlock(objectName, lockHandle));
86
+ },
87
+ untrack(objectName) {
88
+ registry?.untrack(keyOf(objectName));
89
+ },
90
+ };
91
+ }
@@ -19,14 +19,16 @@
19
19
  */
20
20
  import type { IAbapConnection, IAdtObject, IAdtOperationOptions, ILogger } from '@mcp-abap-adt/interfaces';
21
21
  import type { IAdtSystemContext } from '../../clients/AdtClient';
22
+ import { type LockRegistry } from '../shared/LockRegistry';
22
23
  import type { IReadOptions } from '../shared/types';
23
24
  import type { IStructureConfig, IStructureState } from './types';
24
25
  export declare class AdtStructure implements IAdtObject<IStructureConfig, IStructureState> {
25
26
  private readonly connection;
26
27
  private readonly logger?;
27
28
  private readonly systemContext;
29
+ private readonly lockTracker;
28
30
  readonly objectType: string;
29
- constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext);
31
+ constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext, lockRegistry?: LockRegistry);
30
32
  /**
31
33
  * Validate structure configuration before creation
32
34
  */
@@ -1 +1 @@
1
- {"version":3,"file":"AdtStructure.d.ts","sourceRoot":"","sources":["../../../src/core/structure/AdtStructure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAEV,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,OAAO,EACR,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAWpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAMjE,qBAAa,YACX,YAAW,UAAU,CAAC,gBAAgB,EAAE,eAAe,CAAC;IAExD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,SAAgB,UAAU,EAAE,MAAM,CAAe;gBAG/C,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB;IAOnC;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC;IAyB3E;;;OAGG;IACG,MAAM,CACV,MAAM,EAAE,gBAAgB,EACxB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,eAAe,CAAC;IAuD3B;;OAEG;IACG,IAAI,CACR,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,EACjC,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,EAC/B,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IAyBvC;;OAEG;IACG,YAAY,CAChB,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,EACjC,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,eAAe,CAAC;IAgC3B;;OAEG;IACG,aAAa,CACjB,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,EACjC,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACtC,OAAO,CAAC,eAAe,CAAC;IAkC3B;;;;OAIG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,EACjC,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,eAAe,CAAC;IA8M3B;;OAEG;IACG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC;IAgCzE;;;OAGG;IACG,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC;IAoB3E;;OAEG;IACG,KAAK,CACT,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,EACjC,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,eAAe,CAAC;IAoB3B;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAa9D;;OAEG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,EACjC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,eAAe,CAAC;IAkB3B,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC;IAI7C,gBAAgB,CAAC,UAAU,EAAE,MAAM;CAGpC"}
1
+ {"version":3,"file":"AdtStructure.d.ts","sourceRoot":"","sources":["../../../src/core/structure/AdtStructure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAEV,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,OAAO,EACR,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,EAEL,KAAK,YAAY,EAElB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAWpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAMjE,qBAAa,YACX,YAAW,UAAU,CAAC,gBAAgB,EAAE,eAAe,CAAC;IAExD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,SAAgB,UAAU,EAAE,MAAM,CAAe;gBAG/C,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB,EACjC,YAAY,CAAC,EAAE,YAAY;IAY7B;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC;IAyB3E;;;OAGG;IACG,MAAM,CACV,MAAM,EAAE,gBAAgB,EACxB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,eAAe,CAAC;IAuD3B;;OAEG;IACG,IAAI,CACR,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,EACjC,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,EAC/B,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IAyBvC;;OAEG;IACG,YAAY,CAChB,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,EACjC,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,eAAe,CAAC;IAgC3B;;OAEG;IACG,aAAa,CACjB,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,EACjC,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACtC,OAAO,CAAC,eAAe,CAAC;IAkC3B;;;;OAIG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,EACjC,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,eAAe,CAAC;IAkN3B;;OAEG;IACG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC;IAgCzE;;;OAGG;IACG,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC;IAoB3E;;OAEG;IACG,KAAK,CACT,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,EACjC,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,eAAe,CAAC;IAoB3B;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAc9D;;OAEG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,EACjC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,eAAe,CAAC;IAmB3B,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC;IAI7C,gBAAgB,CAAC,UAAU,EAAE,MAAM;CAGpC"}
@@ -21,6 +21,7 @@
21
21
  Object.defineProperty(exports, "__esModule", { value: true });
22
22
  exports.AdtStructure = void 0;
23
23
  const internalUtils_1 = require("../../utils/internalUtils");
24
+ const LockRegistry_1 = require("../shared/LockRegistry");
24
25
  const activation_1 = require("./activation");
25
26
  const check_1 = require("./check");
26
27
  const create_1 = require("./create");
@@ -35,11 +36,13 @@ class AdtStructure {
35
36
  connection;
36
37
  logger;
37
38
  systemContext;
39
+ lockTracker;
38
40
  objectType = 'Structure';
39
- constructor(connection, logger, systemContext) {
41
+ constructor(connection, logger, systemContext, lockRegistry) {
40
42
  this.connection = connection;
41
43
  this.logger = logger;
42
44
  this.systemContext = systemContext ?? {};
45
+ this.lockTracker = (0, LockRegistry_1.createLockTracker)(lockRegistry, this.objectType, (name, lockHandle) => (0, unlock_1.unlockStructure)(this.connection, name, lockHandle));
43
46
  }
44
47
  /**
45
48
  * Validate structure configuration before creation
@@ -235,6 +238,7 @@ class AdtStructure {
235
238
  this.logger?.info?.('Step 1: Locking structure');
236
239
  this.connection.setSessionType('stateful');
237
240
  lockHandle = await (0, lock_1.lockStructure)(this.connection, config.structureName);
241
+ this.lockTracker.track(config.structureName, lockHandle);
238
242
  this.logger?.info?.('Structure locked, handle:', lockHandle);
239
243
  // 2. Check inactive with code for update (from options or config)
240
244
  const codeToCheck = options?.sourceCode || config.ddlCode;
@@ -252,10 +256,11 @@ class AdtStructure {
252
256
  transportRequest: config.transportRequest,
253
257
  }, lockHandle);
254
258
  this.logger?.info?.('Structure updated');
259
+ // Poll the inactive version: the write above produced it; the active version may not exist yet.
255
260
  // 3.5. Read with long polling to ensure object is ready after update
256
261
  this.logger?.info?.('read (wait for object ready after update)');
257
262
  try {
258
- await this.read({ structureName: config.structureName }, 'active', {
263
+ await this.read({ structureName: config.structureName }, 'inactive', {
259
264
  withLongPolling: true,
260
265
  });
261
266
  this.logger?.info?.('object is ready after update');
@@ -271,6 +276,7 @@ class AdtStructure {
271
276
  this.connection.setSessionType('stateful');
272
277
  await (0, unlock_1.unlockStructure)(this.connection, config.structureName, lockHandle);
273
278
  this.connection.setSessionType('stateless');
279
+ this.lockTracker.untrack(config.structureName);
274
280
  lockHandle = undefined;
275
281
  this.logger?.info?.('Structure unlocked');
276
282
  }
@@ -320,6 +326,7 @@ class AdtStructure {
320
326
  this.connection.setSessionType('stateful');
321
327
  await (0, unlock_1.unlockStructure)(this.connection, config.structureName, lockHandle);
322
328
  this.connection.setSessionType('stateless');
329
+ this.lockTracker.untrack(config.structureName);
323
330
  }
324
331
  catch (unlockError) {
325
332
  this.logger?.warn?.('Failed to unlock during cleanup:', (0, internalUtils_1.safeErrorMessage)(unlockError));
@@ -421,6 +428,7 @@ class AdtStructure {
421
428
  }
422
429
  this.connection.setSessionType('stateful');
423
430
  const lockHandle = await (0, lock_1.lockStructure)(this.connection, config.structureName);
431
+ this.lockTracker.track(config.structureName, lockHandle);
424
432
  return lockHandle;
425
433
  }
426
434
  /**
@@ -433,6 +441,7 @@ class AdtStructure {
433
441
  this.connection.setSessionType('stateful');
434
442
  const result = await (0, unlock_1.unlockStructure)(this.connection, config.structureName, lockHandle);
435
443
  this.connection.setSessionType('stateless');
444
+ this.lockTracker.untrack(config.structureName);
436
445
  return {
437
446
  unlockResult: result,
438
447
  errors: [],
@@ -19,14 +19,16 @@
19
19
  */
20
20
  import type { IAbapConnection, IAdtObject, IAdtOperationOptions, ILogger } from '@mcp-abap-adt/interfaces';
21
21
  import type { IAdtSystemContext } from '../../clients/AdtClient';
22
+ import { type LockRegistry } from '../shared/LockRegistry';
22
23
  import type { IReadOptions } from '../shared/types';
23
24
  import type { ITableConfig, ITableState } from './types';
24
25
  export declare class AdtTable implements IAdtObject<ITableConfig, ITableState> {
25
26
  private readonly connection;
26
27
  private readonly logger?;
27
28
  private readonly systemContext;
29
+ private readonly lockTracker;
28
30
  readonly objectType: string;
29
- constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext);
31
+ constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext, lockRegistry?: LockRegistry);
30
32
  /**
31
33
  * Validate table configuration before creation
32
34
  */
@@ -1 +1 @@
1
- {"version":3,"file":"AdtTable.d.ts","sourceRoot":"","sources":["../../../src/core/table/AdtTable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAEV,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,OAAO,EACR,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAOpD,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAMzD,qBAAa,QAAS,YAAW,UAAU,CAAC,YAAY,EAAE,WAAW,CAAC;IACpE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,SAAgB,UAAU,EAAE,MAAM,CAAW;gBAG3C,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB;IAOnC;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;IAanE;;OAEG;IACG,MAAM,CACV,MAAM,EAAE,YAAY,EACpB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,WAAW,CAAC;IAuDvB;;OAEG;IACG,IAAI,CACR,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,EAC7B,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,EAC/B,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,WAAW,CAAC;IAsBvB;;OAEG;IACG,YAAY,CAChB,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,EAC7B,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,WAAW,CAAC;IAgCvB;;OAEG;IACG,aAAa,CACjB,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,EAC7B,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACtC,OAAO,CAAC,WAAW,CAAC;IAkCvB;;;;OAIG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,EAC7B,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,WAAW,CAAC;IAwMvB;;OAEG;IACG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;IA6BjE;;;OAGG;IACG,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;IAcnE;;OAEG;IACG,KAAK,CACT,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,EAC7B,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,WAAW,CAAC;IAmBvB;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAa1D;;OAEG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,EAC7B,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,WAAW,CAAC;IAkBvB,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC;IAIzC,gBAAgB,CAAC,UAAU,EAAE,MAAM;CAGpC"}
1
+ {"version":3,"file":"AdtTable.d.ts","sourceRoot":"","sources":["../../../src/core/table/AdtTable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAEV,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,OAAO,EACR,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,EAEL,KAAK,YAAY,EAElB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAOpD,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAMzD,qBAAa,QAAS,YAAW,UAAU,CAAC,YAAY,EAAE,WAAW,CAAC;IACpE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,SAAgB,UAAU,EAAE,MAAM,CAAW;gBAG3C,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB,EACjC,YAAY,CAAC,EAAE,YAAY;IAY7B;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;IAanE;;OAEG;IACG,MAAM,CACV,MAAM,EAAE,YAAY,EACpB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,WAAW,CAAC;IAuDvB;;OAEG;IACG,IAAI,CACR,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,EAC7B,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,EAC/B,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,WAAW,CAAC;IAsBvB;;OAEG;IACG,YAAY,CAChB,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,EAC7B,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,WAAW,CAAC;IAgCvB;;OAEG;IACG,aAAa,CACjB,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,EAC7B,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACtC,OAAO,CAAC,WAAW,CAAC;IAkCvB;;;;OAIG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,EAC7B,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,WAAW,CAAC;IA4MvB;;OAEG;IACG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;IA6BjE;;;OAGG;IACG,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;IAcnE;;OAEG;IACG,KAAK,CACT,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,EAC7B,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,WAAW,CAAC;IAmBvB;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAc1D;;OAEG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,EAC7B,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,WAAW,CAAC;IAmBvB,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC;IAIzC,gBAAgB,CAAC,UAAU,EAAE,MAAM;CAGpC"}