@decaf-ts/transactional-decorators 0.1.3 → 0.1.4

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 (52) hide show
  1. package/LICENSE.md +3 -2
  2. package/README.md +242 -17
  3. package/dist/transactional-decorators.cjs +2 -643
  4. package/dist/transactional-decorators.cjs.map +1 -0
  5. package/dist/transactional-decorators.js +2 -0
  6. package/dist/transactional-decorators.js.map +1 -0
  7. package/lib/Transaction.cjs +1 -1
  8. package/lib/Transaction.js.map +1 -0
  9. package/lib/constants.cjs +1 -1
  10. package/lib/constants.js.map +1 -0
  11. package/lib/decorators.cjs +1 -1
  12. package/lib/decorators.js.map +1 -0
  13. package/lib/esm/Transaction.js +1 -1
  14. package/lib/esm/Transaction.js.map +1 -0
  15. package/lib/esm/constants.js +1 -1
  16. package/lib/esm/constants.js.map +1 -0
  17. package/lib/esm/decorators.js +1 -1
  18. package/lib/esm/decorators.js.map +1 -0
  19. package/lib/esm/index.js +1 -1
  20. package/lib/esm/index.js.map +1 -0
  21. package/lib/esm/interfaces/TransactionLock.js +1 -1
  22. package/lib/esm/interfaces/TransactionLock.js.map +1 -0
  23. package/lib/esm/interfaces/index.js +1 -1
  24. package/lib/esm/interfaces/index.js.map +1 -0
  25. package/lib/esm/locks/Lock.js +1 -1
  26. package/lib/esm/locks/Lock.js.map +1 -0
  27. package/lib/esm/locks/SyncronousLock.js +1 -1
  28. package/lib/esm/locks/SyncronousLock.js.map +1 -0
  29. package/lib/esm/locks/index.js +1 -1
  30. package/lib/esm/locks/index.js.map +1 -0
  31. package/lib/esm/types.js +1 -1
  32. package/lib/esm/types.js.map +1 -0
  33. package/lib/esm/utils.js +1 -1
  34. package/lib/esm/utils.js.map +1 -0
  35. package/lib/index.cjs +1 -1
  36. package/lib/index.js.map +1 -0
  37. package/lib/interfaces/TransactionLock.cjs +1 -1
  38. package/lib/interfaces/TransactionLock.js.map +1 -0
  39. package/lib/interfaces/index.cjs +1 -1
  40. package/lib/interfaces/index.js.map +1 -0
  41. package/lib/locks/Lock.cjs +1 -1
  42. package/lib/locks/Lock.js.map +1 -0
  43. package/lib/locks/SyncronousLock.cjs +1 -1
  44. package/lib/locks/SyncronousLock.js.map +1 -0
  45. package/lib/locks/index.cjs +1 -1
  46. package/lib/locks/index.js.map +1 -0
  47. package/lib/types.cjs +1 -1
  48. package/lib/types.js.map +1 -0
  49. package/lib/utils.cjs +1 -1
  50. package/lib/utils.js.map +1 -0
  51. package/package.json +23 -24
  52. package/dist/transactional-decorators.esm.cjs +0 -632
@@ -1,643 +1,2 @@
1
- (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@decaf-ts/reflection'), require('@decaf-ts/db-decorators')) :
3
- typeof define === 'function' && define.amd ? define(['exports', '@decaf-ts/reflection', '@decaf-ts/db-decorators'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["transactional-decorators"] = {}, global.reflection, global.dbDecorators));
5
- })(this, (function (exports, reflection, dbDecorators) { 'use strict';
6
-
7
- /**
8
- * @description Base lock implementation for concurrency control
9
- * @summary Provides a basic lock mechanism for controlling access to shared resources, with support for queuing and executing functions when the lock is available
10
- * @class Lock
11
- * @example
12
- * // Using the Lock class to execute a function with exclusive access
13
- * const lock = new Lock();
14
- * const result = await lock.execute(async () => {
15
- * // This code will run with exclusive access
16
- * return await performCriticalOperation();
17
- * });
18
- */
19
- class Lock {
20
- constructor() {
21
- this.queue = [];
22
- this.locked = false;
23
- }
24
- /**
25
- * @description Executes a function with exclusive lock access
26
- * @summary Acquires the lock, executes the provided function, and releases the lock afterward, ensuring proper cleanup even if the function throws an error
27
- * @param {Function} func - The function to execute when the lock is acquired
28
- * @return {Promise<any>} A promise that resolves with the result of the executed function
29
- */
30
- async execute(func) {
31
- await this.acquire();
32
- let result;
33
- try {
34
- result = await Promise.resolve(func());
35
- }
36
- catch (e) {
37
- this.release();
38
- throw e;
39
- }
40
- this.release();
41
- return result;
42
- }
43
- /**
44
- * @summary waits to acquire the lock
45
- * @param {string} [issuer]
46
- */
47
- async acquire() {
48
- // eslint-disable-next-line @typescript-eslint/no-this-alias
49
- const self = this;
50
- if (self.locked) {
51
- return new Promise((resolve) => self.queue.push(resolve));
52
- }
53
- else {
54
- self.locked = true;
55
- return Promise.resolve();
56
- }
57
- }
58
- /**
59
- * @summary releases the lock
60
- */
61
- release() {
62
- // eslint-disable-next-line @typescript-eslint/no-this-alias
63
- const self = this;
64
- const next = self.queue.shift();
65
- if (next) {
66
- if (typeof globalThis.window === "undefined")
67
- globalThis.process.nextTick(next); // if you are on node
68
- else
69
- setTimeout(next, 0); // if you are in the browser
70
- }
71
- else {
72
- self.locked = false;
73
- }
74
- }
75
- }
76
-
77
- /**
78
- * @summary Simple Synchronous Lock implementation
79
- * @description for transaction management
80
- * adapted from {@link https://www.talkinghightech.com/en/creating-a-js-lock-for-a-resource/}
81
- *
82
- * @param {number} [counter] the number of simultaneous transactions allowed. defaults to 1
83
- * @param {Function} [onBegin] to be called at the start of the transaction
84
- * @param {Function} [onEnd] to be called at the conclusion of the transaction
85
- *
86
- * @class SyncronousLock
87
- * @implements TransactionLock
88
- */
89
- class SyncronousLock {
90
- constructor(counter = 1, onBegin, onEnd) {
91
- this.currentTransaction = undefined;
92
- this.lock = new Lock();
93
- this.counter = counter;
94
- this.pendingTransactions = [];
95
- this.onBegin = onBegin;
96
- this.onEnd = onEnd;
97
- }
98
- /**
99
- * @summary Submits a transaction to be processed
100
- * @param {Transaction} transaction
101
- */
102
- submit(transaction) {
103
- // eslint-disable-next-line @typescript-eslint/no-this-alias
104
- const self = this;
105
- self.lock.acquire().then(() => {
106
- if (self.currentTransaction &&
107
- self.currentTransaction.id === transaction.id) {
108
- self.lock.release();
109
- return transaction.fire();
110
- }
111
- if (self.counter > 0) {
112
- self.counter--;
113
- self.lock.release();
114
- return self.fireTransaction(transaction);
115
- }
116
- else {
117
- self.pendingTransactions.push(transaction);
118
- self.lock.release();
119
- }
120
- });
121
- }
122
- /**
123
- * @summary Executes a transaction
124
- *
125
- * @param {Transaction} transaction
126
- * @private
127
- */
128
- fireTransaction(transaction) {
129
- // eslint-disable-next-line @typescript-eslint/no-this-alias
130
- const self = this;
131
- self.lock.acquire().then(() => {
132
- self.currentTransaction = transaction;
133
- self.lock.release();
134
- if (self.onBegin)
135
- self.onBegin().then(() => {
136
- // all.call(
137
- // self,
138
- // `Firing transaction {0}. {1} remaining...`,
139
- // transaction.id,
140
- // this.pendingTransactions.length,
141
- // );
142
- transaction.fire();
143
- });
144
- else {
145
- // all.call(
146
- // self,
147
- // `Firing transaction {0}. {1} remaining...`,
148
- // transaction.id,
149
- // this.pendingTransactions.length,
150
- // );
151
- transaction.fire();
152
- }
153
- });
154
- }
155
- /**
156
- * @summary Releases The lock after the conclusion of a transaction
157
- */
158
- async release(err) {
159
- // eslint-disable-next-line @typescript-eslint/no-this-alias
160
- const self = this;
161
- return new Promise((resolve) => {
162
- self.lock.acquire().then(() => {
163
- if (!self.currentTransaction)
164
- console.warn("Trying to release an unexisting transaction. should never happen...");
165
- // debug.call(
166
- // self,
167
- // "Releasing transaction: {0}",
168
- // self.currentTransaction?.toString(true, true),
169
- // );
170
- self.currentTransaction = undefined;
171
- self.lock.release();
172
- const afterConclusionCB = () => {
173
- self.lock.acquire().then(() => {
174
- if (self.pendingTransactions.length > 0) {
175
- const transaction = self.pendingTransactions.shift();
176
- const cb = () => self.fireTransaction(transaction);
177
- //
178
- // all(
179
- // `Releasing Transaction Lock on transaction {0}`,
180
- // transaction.id,
181
- // );
182
- if (typeof globalThis.window ===
183
- "undefined")
184
- globalThis.process.nextTick(cb); // if you are on node
185
- else
186
- setTimeout(cb, 0); // if you are in the browser
187
- }
188
- else {
189
- self.counter++;
190
- }
191
- self.lock.release();
192
- resolve();
193
- });
194
- };
195
- if (self.onEnd)
196
- self.onEnd(err).then(() => afterConclusionCB());
197
- else
198
- afterConclusionCB();
199
- });
200
- });
201
- }
202
- }
203
-
204
- /**
205
- * @typedef {Object} TransactionalKeysType
206
- * @property {string} REFLECT - Key used for reflection metadata related to transactional models
207
- * @property {string} TRANSACTIONAL - Key used to identify transactional properties
208
- * @memberOf module:transactions
209
- */
210
- /**
211
- * @description Keys used for transactional operations
212
- * @summary Constant object containing string keys used throughout the transactional system for reflection and identification
213
- * @type {TransactionalKeysType}
214
- * @const TransactionalKeys
215
- * @memberOf module:transactions
216
- */
217
- const TransactionalKeys = {
218
- REFLECT: "model.transactional.",
219
- TRANSACTIONAL: "transactional",
220
- };
221
-
222
- function getObjectName(obj) {
223
- if (!obj)
224
- return;
225
- if (typeof obj === "string")
226
- return obj;
227
- if (obj.constructor &&
228
- obj.constructor.name &&
229
- ["Function", "Object"].indexOf(obj.constructor.name) === -1)
230
- return obj.constructor.name;
231
- if (typeof obj === "function" && obj.name)
232
- return obj.name;
233
- return obj.toString();
234
- }
235
-
236
- /**
237
- * @description Core transaction management class
238
- * @summary Manages transaction lifecycle, including creation, execution, and cleanup. Provides mechanisms for binding transactions to objects and methods, ensuring proper transaction context propagation.
239
- * @param {string} source - The source/origin of the transaction (typically a class name)
240
- * @param {string} [method] - The method name associated with the transaction
241
- * @param {function(): any} [action] - The function to execute within the transaction
242
- * @param {any[]} [metadata] - Additional metadata to associate with the transaction
243
- * @class Transaction
244
- * @example
245
- * // Creating and submitting a transaction
246
- * const transaction = new Transaction(
247
- * 'UserService',
248
- * 'createUser',
249
- * async () => {
250
- * // Transaction logic here
251
- * await db.insert('users', { name: 'John' });
252
- * }
253
- * );
254
- * Transaction.submit(transaction);
255
- *
256
- * // Using the transactional decorator
257
- * class UserService {
258
- * @transactional()
259
- * async createUser(data) {
260
- * // Method will be executed within a transaction
261
- * return await db.insert('users', data);
262
- * }
263
- * }
264
- * @mermaid
265
- * sequenceDiagram
266
- * participant C as Client Code
267
- * participant T as Transaction
268
- * participant L as TransactionLock
269
- * participant O as Original Method
270
- *
271
- * C->>T: new Transaction(source, method, action)
272
- * C->>T: Transaction.submit(transaction)
273
- * T->>L: submit(transaction)
274
- * L->>T: fire()
275
- * T->>O: Execute action()
276
- * O-->>T: Return result/error
277
- * T->>L: release(error?)
278
- * L-->>C: Return result/error
279
- */
280
- class Transaction {
281
- constructor(source, method, action, metadata) {
282
- this.id = Date.now();
283
- this.action = action;
284
- this.method = method;
285
- this.log = [[this.id, source, method].join(" | ")];
286
- this.source = source;
287
- this.metadata = metadata;
288
- }
289
- /**
290
- * @description Queues a transaction for execution
291
- * @summary Pushes a transaction to the queue and waits for its resolution. Creates a new transaction with the provided issuer and callback method, then submits it to the transaction lock.
292
- * @param {any} issuer - Any class instance that will be used as 'this' when calling the callbackMethod
293
- * @param {Function} callbackMethod - Callback function containing the transaction logic, will be called with the issuer as 'this'
294
- * @param {any[]} args - Arguments to pass to the method. Last one must be the callback function
295
- * @return {void}
296
- */
297
- static push(issuer, callbackMethod, ...args) {
298
- const callback = args.pop();
299
- if (!callback || typeof callback !== "function")
300
- throw new Error("Missing callback");
301
- const cb = (err, ...args) => {
302
- Transaction.getLock()
303
- .release(err)
304
- .then(() => callback(err, ...args));
305
- };
306
- const transaction = new Transaction(issuer.constructor.name, callbackMethod.name ? getObjectName(callbackMethod) : "Anonymous", () => {
307
- return callbackMethod.call(transaction.bindToTransaction(issuer), ...args, cb);
308
- });
309
- Transaction.getLock().submit(transaction);
310
- }
311
- /**
312
- * @description Configures the transaction lock implementation
313
- * @summary Sets the lock implementation to be used for transaction management, allowing customization of the transaction behavior
314
- * @param {TransactionLock} lock - The lock implementation to use for managing transactions
315
- * @return {void}
316
- */
317
- static setLock(lock) {
318
- this.lock = lock;
319
- }
320
- /**
321
- * @description Retrieves the current transaction lock
322
- * @summary Gets the current transaction lock instance, creating a default SyncronousLock if none exists
323
- * @return {TransactionLock} The current transaction lock implementation
324
- */
325
- static getLock() {
326
- if (!this.lock)
327
- this.lock = new SyncronousLock();
328
- return this.lock;
329
- }
330
- /**
331
- * @description Submits a transaction for processing
332
- * @summary Submits a transaction to the current transaction lock for processing and execution
333
- * @param {Transaction} transaction - The transaction to submit for processing
334
- * @return {void}
335
- */
336
- static submit(transaction) {
337
- Transaction.getLock().submit(transaction);
338
- }
339
- /**
340
- * @description Releases the transaction lock
341
- * @summary Releases the current transaction lock, optionally with an error, allowing the next transaction to proceed
342
- * @param {Error} [err] - Optional error that occurred during transaction execution
343
- * @return {Promise<void>} A promise that resolves when the lock has been released
344
- */
345
- static async release(err) {
346
- return Transaction.getLock().release(err);
347
- }
348
- /**
349
- * @description Retrieves transaction metadata
350
- * @summary Returns a copy of the metadata associated with this transaction, ensuring the original metadata remains unmodified
351
- * @return {any[] | undefined} A copy of the transaction metadata or undefined if no metadata exists
352
- */
353
- getMetadata() {
354
- return this.metadata ? [...this.metadata] : undefined;
355
- }
356
- /**
357
- * @description Links a new transaction to the current one
358
- * @summary Binds a new transaction operation to the current transaction, transferring logs and binding methods to maintain transaction context
359
- * @param {Transaction} nextTransaction - The new transaction to bind to the current one
360
- * @return {void}
361
- */
362
- bindTransaction(nextTransaction) {
363
- // all(`Binding the {0} to {1}`, nextTransaction, this);
364
- this.log.push(...nextTransaction.log);
365
- nextTransaction.bindTransaction = this.bindToTransaction.bind(this);
366
- nextTransaction.bindToTransaction = this.bindToTransaction.bind(this);
367
- this.action = nextTransaction.action;
368
- }
369
- /**
370
- * @description Binds an object to the current transaction context
371
- * @summary Binds a transactional decorated object to the transaction by ensuring all transactional methods automatically receive the current transaction as their first argument
372
- * @param {any} obj - The object to bind to the transaction
373
- * @return {any} The bound object with transaction-aware method wrappers
374
- */
375
- bindToTransaction(obj) {
376
- const transactionalMethods = dbDecorators.getAllPropertyDecoratorsRecursive(obj, undefined, TransactionalKeys.REFLECT);
377
- if (!transactionalMethods)
378
- return obj;
379
- // eslint-disable-next-line @typescript-eslint/no-this-alias
380
- const self = this;
381
- const boundObj = reflection.Reflection.getAllProperties(obj).reduce((accum, k) => {
382
- if (Object.keys(transactionalMethods).indexOf(k) !== -1 &&
383
- transactionalMethods[k].find((o) => o.key === TransactionalKeys.TRANSACTIONAL))
384
- accum[k] = (...args) => obj[k].call(obj.__originalObj || obj, self, ...args);
385
- else if (k === "clazz" || k === "constructor")
386
- accum[k] = obj[k];
387
- else if (typeof obj[k] === "function")
388
- accum[k] = obj[k].bind(obj.__originalObj || obj);
389
- else if (typeof obj[k] === "object" && obj[k].constructor) {
390
- const decs = reflection.Reflection.getClassDecorators(TransactionalKeys.REFLECT, obj[k]);
391
- if (decs.find((e) => e.key === TransactionalKeys.TRANSACTIONAL))
392
- accum[k] = self.bindToTransaction(obj[k]);
393
- else
394
- accum[k] = obj[k];
395
- }
396
- else
397
- accum[k] = obj[k];
398
- return accum;
399
- }, {});
400
- boundObj[dbDecorators.DBKeys.ORIGINAL] = obj[dbDecorators.DBKeys.ORIGINAL] || obj;
401
- boundObj.toString = () => getObjectName(boundObj[dbDecorators.DBKeys.ORIGINAL]) +
402
- " proxy for transaction " +
403
- this.id;
404
- return boundObj;
405
- }
406
- /**
407
- * @description Executes the transaction action
408
- * @summary Fires the transaction by executing its associated action function, throwing an error if no action is defined
409
- * @return {any} The result of the transaction action
410
- */
411
- fire() {
412
- if (!this.action)
413
- throw new Error(`Missing the method`);
414
- return this.action();
415
- }
416
- /**
417
- * @description Provides a string representation of the transaction
418
- * @summary Overrides the default toString method to provide a formatted string representation of the transaction, optionally including the transaction ID and log
419
- * @param {boolean} [withId=true] - Whether to include the transaction ID in the output
420
- * @param {boolean} [withLog=false] - Whether to include the transaction log in the output
421
- * @return {string} A string representation of the transaction
422
- */
423
- toString(withId = true, withLog = false) {
424
- return `${withId ? `[${this.id}]` : ""}[Transaction][${this.source}.${this.method}${withLog ? `]\nTransaction Log:\n${this.log.join("\n")}` : "]"}`;
425
- }
426
- /**
427
- * @description Generates a reflection metadata key for transactions
428
- * @summary Creates a prefixed reflection key for transaction-related metadata, ensuring proper namespacing
429
- * @param {string} key - The base key to prefix with the transaction reflection namespace
430
- * @return {string} The complete reflection key for transaction metadata
431
- * @function key
432
- */
433
- static key(key) {
434
- return TransactionalKeys.REFLECT + key;
435
- }
436
- }
437
-
438
- /**
439
- * @description Method decorator that enables transactional behavior
440
- * @summary Sets a class async method as transactional, wrapping it in a transaction context that can be managed by the transaction system. This decorator handles transaction creation, binding, and error handling.
441
- * @param {any[]} [data] - Optional metadata available to the {@link TransactionLock} implementation
442
- * @return {Function} A decorator function that wraps the original method with transactional behavior
443
- * @function transactional
444
- * @category Method Decorators
445
- * @mermaid
446
- * sequenceDiagram
447
- * participant C as Client Code
448
- * participant D as Decorator
449
- * participant T as Transaction
450
- * participant O as Original Method
451
- *
452
- * C->>D: Call decorated method
453
- * D->>D: Check if transaction exists in args
454
- *
455
- * alt Transaction exists in args
456
- * D->>T: Create updated transaction
457
- * T->>T: Bind to original transaction
458
- * T->>T: Fire transaction
459
- * else No transaction
460
- * D->>T: Create new transaction
461
- * T->>T: Submit transaction
462
- * end
463
- *
464
- * T->>O: Execute original method
465
- * O-->>T: Return result/error
466
- * T->>T: Release transaction
467
- * T-->>C: Return result/error
468
- * @category Decorators
469
- */
470
- function transactional(...data) {
471
- return function (target, propertyKey, descriptor) {
472
- if (!descriptor)
473
- throw new dbDecorators.InternalError("Missing descriptor. Should be impossible");
474
- reflection.metadata(Transaction.key(TransactionalKeys.TRANSACTIONAL), data)(target, propertyKey);
475
- const originalMethod = descriptor.value;
476
- const methodWrapper = function (...args) {
477
- // eslint-disable-next-line @typescript-eslint/no-this-alias
478
- const self = this;
479
- return new Promise((resolve, reject) => {
480
- const cb = (err, result) => {
481
- Transaction.release(err).then(() => {
482
- if (err)
483
- return reject(err);
484
- resolve(result);
485
- });
486
- };
487
- let transaction = args.shift();
488
- if (transaction instanceof Transaction) {
489
- const updatedTransaction = new Transaction(this.constructor.name, propertyKey, async () => {
490
- originalMethod
491
- .call(updatedTransaction.bindToTransaction(self), ...args)
492
- .then(resolve)
493
- .catch(reject);
494
- }, data.length ? data : undefined);
495
- transaction.bindTransaction(updatedTransaction);
496
- transaction.fire();
497
- }
498
- else {
499
- args.unshift(transaction);
500
- transaction = new Transaction(this.constructor.name, propertyKey, () => {
501
- originalMethod
502
- .call(transaction.bindToTransaction(self), ...args)
503
- .then((result) => cb(undefined, result))
504
- .catch(cb);
505
- }, data.length ? data : undefined);
506
- Transaction.submit(transaction);
507
- }
508
- });
509
- };
510
- Object.defineProperty(methodWrapper, "name", {
511
- value: propertyKey,
512
- });
513
- descriptor.value = methodWrapper;
514
- };
515
- }
516
- //
517
- // /**
518
- // * @summary Sets a class Async method as transactional
519
- // *
520
- // * @param {any[]} [metadata] option metadata available to the {@link TransactionLock}
521
- // *
522
- // * @function transactionalAsync
523
- // *
524
- // * @memberOf module:db-decorators.Decorators.transactions
525
- // */
526
- // export function transactionalAsync(...metadata: any[]) {
527
- // return function (
528
- // target: any,
529
- // propertyKey: string,
530
- // descriptor: PropertyDescriptor,
531
- // ) {
532
- // metadasta(getTransactionalKey(TransactionalKeys.TRANSACTIONAL))
533
- // Reflect.defineMetadata(
534
- // ,
535
- // {
536
- // type: "async",
537
- // metadata: metadata.length ? metadata : undefined,
538
- // } as TransactionalMetadata,
539
- // target,
540
- // propertyKey,
541
- // );
542
- //
543
- // const originalMethod = descriptor.value;
544
- //
545
- // const methodWrapper = function (this: any, ...args: any[]) {
546
- // const callback: Callback = args.pop();
547
- // if (!callback || typeof callback !== "function")
548
- // throw new CriticalError(`Missing Callback`);
549
- //
550
- // const cb = (err?: Err, ...args: any[]) => {
551
- // Transaction.release(err).then((_) => callback(err, ...args));
552
- // };
553
- //
554
- // const self = this;
555
- //
556
- // let transaction = args.shift();
557
- // if (transaction instanceof Transaction) {
558
- // const updatedTransaction: Transaction = new Transaction(
559
- // this.constructor.name,
560
- // propertyKey,
561
- // () => {
562
- // try {
563
- // return originalMethod.call(
564
- // updatedTransaction.bindToTransaction(self),
565
- // ...args,
566
- // callback,
567
- // );
568
- // } catch (e: any) {
569
- // return callback(e);
570
- // }
571
- // },
572
- // metadata.length ? metadata : undefined,
573
- // );
574
- //
575
- // transaction.bindTransaction(updatedTransaction);
576
- // transaction.fire();
577
- // } else {
578
- // args.unshift(transaction);
579
- // transaction = undefined;
580
- // transaction = new Transaction(
581
- // this.constructor.name,
582
- // propertyKey,
583
- // () => {
584
- // try {
585
- // return originalMethod.call(
586
- // transaction.bindToTransaction(self),
587
- // ...args,
588
- // cb,
589
- // );
590
- // } catch (e: any) {
591
- // return cb(e);
592
- // }
593
- // },
594
- // metadata.length ? metadata : undefined,
595
- // );
596
- // Transaction.submit(transaction);
597
- // }
598
- // };
599
- //
600
- // Object.defineProperty(methodWrapper, "name", {
601
- // value: propertyKey,
602
- // });
603
- // descriptor.value = methodWrapper;
604
- // };
605
- // }
606
- /**
607
- * @description Utility for handling super calls in transactional methods
608
- * @summary Wraps super method calls with the current transaction context when the super's method is also transactional, ensuring transaction continuity through the inheritance chain
609
- * @param {Function} method - The super method (must be bound to the proper this), e.g., super.create.bind(this)
610
- * @param {any[]} args - The arguments to call the method with
611
- * @return {any} The result of the super method call
612
- * @function transactionalSuperCall
613
- * @memberOf module:transactions
614
- */
615
- function transactionalSuperCall(method, ...args) {
616
- const lock = Transaction.getLock();
617
- const currentTransaction = lock.currentTransaction;
618
- return method(currentTransaction, ...args);
619
- }
620
-
621
- /**
622
- * @description Transactional decorators for TypeScript
623
- * @summary A comprehensive module providing transaction management capabilities for TypeScript applications. This module exposes decorators, locks, and utilities for implementing transactional behavior in your code, allowing for atomic operations, concurrency control, and error handling.
624
- * @module transactions
625
- */
626
- /**
627
- * @description Package version identifier
628
- * @summary Stores the current package version string, used for version tracking and compatibility checks
629
- * @const VERSION
630
- * @memberOf module:transactions
631
- */
632
- const VERSION = "0.1.3";
633
-
634
- exports.Lock = Lock;
635
- exports.SyncronousLock = SyncronousLock;
636
- exports.Transaction = Transaction;
637
- exports.TransactionalKeys = TransactionalKeys;
638
- exports.VERSION = VERSION;
639
- exports.transactional = transactional;
640
- exports.transactionalSuperCall = transactionalSuperCall;
641
-
642
- }));
643
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNhY3Rpb25hbC1kZWNvcmF0b3JzLmNqcyIsInNvdXJjZXMiOlsiLi4vc3JjL2xvY2tzL0xvY2sudHMiLCIuLi9zcmMvbG9ja3MvU3luY3Jvbm91c0xvY2sudHMiLCIuLi9zcmMvY29uc3RhbnRzLnRzIiwiLi4vc3JjL3V0aWxzLnRzIiwiLi4vc3JjL1RyYW5zYWN0aW9uLnRzIiwiLi4vc3JjL2RlY29yYXRvcnMudHMiLCIuLi9zcmMvaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTG9ja0NhbGxhYmxlIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEJhc2UgbG9jayBpbXBsZW1lbnRhdGlvbiBmb3IgY29uY3VycmVuY3kgY29udHJvbFxuICogQHN1bW1hcnkgUHJvdmlkZXMgYSBiYXNpYyBsb2NrIG1lY2hhbmlzbSBmb3IgY29udHJvbGxpbmcgYWNjZXNzIHRvIHNoYXJlZCByZXNvdXJjZXMsIHdpdGggc3VwcG9ydCBmb3IgcXVldWluZyBhbmQgZXhlY3V0aW5nIGZ1bmN0aW9ucyB3aGVuIHRoZSBsb2NrIGlzIGF2YWlsYWJsZVxuICogQGNsYXNzIExvY2tcbiAqIEBleGFtcGxlXG4gKiAvLyBVc2luZyB0aGUgTG9jayBjbGFzcyB0byBleGVjdXRlIGEgZnVuY3Rpb24gd2l0aCBleGNsdXNpdmUgYWNjZXNzXG4gKiBjb25zdCBsb2NrID0gbmV3IExvY2soKTtcbiAqIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGxvY2suZXhlY3V0ZShhc3luYyAoKSA9PiB7XG4gKiAgIC8vIFRoaXMgY29kZSB3aWxsIHJ1biB3aXRoIGV4Y2x1c2l2ZSBhY2Nlc3NcbiAqICAgcmV0dXJuIGF3YWl0IHBlcmZvcm1Dcml0aWNhbE9wZXJhdGlvbigpO1xuICogfSk7XG4gKi9cbmV4cG9ydCBjbGFzcyBMb2NrIHtcbiAgcHJpdmF0ZSBxdWV1ZTogTG9ja0NhbGxhYmxlW10gPSBbXTtcbiAgcHJpdmF0ZSBsb2NrZWQgPSBmYWxzZTtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEV4ZWN1dGVzIGEgZnVuY3Rpb24gd2l0aCBleGNsdXNpdmUgbG9jayBhY2Nlc3NcbiAgICogQHN1bW1hcnkgQWNxdWlyZXMgdGhlIGxvY2ssIGV4ZWN1dGVzIHRoZSBwcm92aWRlZCBmdW5jdGlvbiwgYW5kIHJlbGVhc2VzIHRoZSBsb2NrIGFmdGVyd2FyZCwgZW5zdXJpbmcgcHJvcGVyIGNsZWFudXAgZXZlbiBpZiB0aGUgZnVuY3Rpb24gdGhyb3dzIGFuIGVycm9yXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgLSBUaGUgZnVuY3Rpb24gdG8gZXhlY3V0ZSB3aGVuIHRoZSBsb2NrIGlzIGFjcXVpcmVkXG4gICAqIEByZXR1cm4ge1Byb21pc2U8YW55Pn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGUgcmVzdWx0IG9mIHRoZSBleGVjdXRlZCBmdW5jdGlvblxuICAgKi9cbiAgYXN5bmMgZXhlY3V0ZShmdW5jOiAoKSA9PiBhbnkpIHtcbiAgICBhd2FpdCB0aGlzLmFjcXVpcmUoKTtcbiAgICBsZXQgcmVzdWx0OiBhbnk7XG4gICAgdHJ5IHtcbiAgICAgIHJlc3VsdCA9IGF3YWl0IFByb21pc2UucmVzb2x2ZShmdW5jKCkpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgdGhpcy5yZWxlYXNlKCk7XG4gICAgICB0aHJvdyBlO1xuICAgIH1cbiAgICB0aGlzLnJlbGVhc2UoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IHdhaXRzIHRvIGFjcXVpcmUgdGhlIGxvY2tcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtpc3N1ZXJdXG4gICAqL1xuICBhc3luYyBhY3F1aXJlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdGhpcy1hbGlhc1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIGlmIChzZWxmLmxvY2tlZCkge1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiBzZWxmLnF1ZXVlLnB1c2gocmVzb2x2ZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzZWxmLmxvY2tlZCA9IHRydWU7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IHJlbGVhc2VzIHRoZSBsb2NrXG4gICAqL1xuICByZWxlYXNlKCkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdGhpcy1hbGlhc1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIGNvbnN0IG5leHQ6IExvY2tDYWxsYWJsZSB8IHVuZGVmaW5lZCA9IHNlbGYucXVldWUuc2hpZnQoKTtcbiAgICBpZiAobmV4dCkge1xuICAgICAgaWYgKFxuICAgICAgICB0eXBlb2YgKGdsb2JhbFRoaXMgYXMgdW5rbm93biBhcyB7IHdpbmRvdzogYW55IH0pLndpbmRvdyA9PT0gXCJ1bmRlZmluZWRcIlxuICAgICAgKVxuICAgICAgICBnbG9iYWxUaGlzLnByb2Nlc3MubmV4dFRpY2sobmV4dCk7IC8vIGlmIHlvdSBhcmUgb24gbm9kZVxuICAgICAgZWxzZSBzZXRUaW1lb3V0KG5leHQsIDApOyAvLyBpZiB5b3UgYXJlIGluIHRoZSBicm93c2VyXG4gICAgfSBlbHNlIHtcbiAgICAgIHNlbGYubG9ja2VkID0gZmFsc2U7XG4gICAgfVxuICB9XG59XG4iLCJpbXBvcnQgeyBUcmFuc2FjdGlvbiB9IGZyb20gXCIuLi9UcmFuc2FjdGlvblwiO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb25Mb2NrIH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvVHJhbnNhY3Rpb25Mb2NrXCI7XG5pbXBvcnQgeyBMb2NrIH0gZnJvbSBcIi4vTG9ja1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IFNpbXBsZSBTeW5jaHJvbm91cyBMb2NrIGltcGxlbWVudGF0aW9uXG4gKiBAZGVzY3JpcHRpb24gZm9yIHRyYW5zYWN0aW9uIG1hbmFnZW1lbnRcbiAqIGFkYXB0ZWQgZnJvbSB7QGxpbmsgaHR0cHM6Ly93d3cudGFsa2luZ2hpZ2h0ZWNoLmNvbS9lbi9jcmVhdGluZy1hLWpzLWxvY2stZm9yLWEtcmVzb3VyY2UvfVxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBbY291bnRlcl0gdGhlIG51bWJlciBvZiBzaW11bHRhbmVvdXMgdHJhbnNhY3Rpb25zIGFsbG93ZWQuIGRlZmF1bHRzIHRvIDFcbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtvbkJlZ2luXSB0byBiZSBjYWxsZWQgYXQgdGhlIHN0YXJ0IG9mIHRoZSB0cmFuc2FjdGlvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gW29uRW5kXSB0byBiZSBjYWxsZWQgYXQgdGhlIGNvbmNsdXNpb24gb2YgdGhlIHRyYW5zYWN0aW9uXG4gKlxuICogQGNsYXNzIFN5bmNyb25vdXNMb2NrXG4gKiBAaW1wbGVtZW50cyBUcmFuc2FjdGlvbkxvY2tcbiAqL1xuZXhwb3J0IGNsYXNzIFN5bmNyb25vdXNMb2NrIGltcGxlbWVudHMgVHJhbnNhY3Rpb25Mb2NrIHtcbiAgcHJpdmF0ZSBjb3VudGVyOiBudW1iZXI7XG4gIHByaXZhdGUgcGVuZGluZ1RyYW5zYWN0aW9uczogVHJhbnNhY3Rpb25bXTtcbiAgY3VycmVudFRyYW5zYWN0aW9uPzogVHJhbnNhY3Rpb24gPSB1bmRlZmluZWQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgb25CZWdpbj86ICgpID0+IFByb21pc2U8dm9pZD47XG4gIHByaXZhdGUgcmVhZG9ubHkgb25FbmQ/OiAoZXJyPzogRXJyb3IpID0+IFByb21pc2U8dm9pZD47XG5cbiAgcHJpdmF0ZSByZWFkb25seSBsb2NrID0gbmV3IExvY2soKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBjb3VudGVyOiBudW1iZXIgPSAxLFxuICAgIG9uQmVnaW4/OiAoKSA9PiBQcm9taXNlPHZvaWQ+LFxuICAgIG9uRW5kPzogKGVycj86IEVycm9yKSA9PiBQcm9taXNlPHZvaWQ+XG4gICkge1xuICAgIHRoaXMuY291bnRlciA9IGNvdW50ZXI7XG4gICAgdGhpcy5wZW5kaW5nVHJhbnNhY3Rpb25zID0gW107XG4gICAgdGhpcy5vbkJlZ2luID0gb25CZWdpbjtcbiAgICB0aGlzLm9uRW5kID0gb25FbmQ7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgU3VibWl0cyBhIHRyYW5zYWN0aW9uIHRvIGJlIHByb2Nlc3NlZFxuICAgKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICAgKi9cbiAgc3VibWl0KHRyYW5zYWN0aW9uOiBUcmFuc2FjdGlvbik6IHZvaWQge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdGhpcy1hbGlhc1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIHNlbGYubG9jay5hY3F1aXJlKCkudGhlbigoKSA9PiB7XG4gICAgICBpZiAoXG4gICAgICAgIHNlbGYuY3VycmVudFRyYW5zYWN0aW9uICYmXG4gICAgICAgIHNlbGYuY3VycmVudFRyYW5zYWN0aW9uLmlkID09PSB0cmFuc2FjdGlvbi5pZFxuICAgICAgKSB7XG4gICAgICAgIHNlbGYubG9jay5yZWxlYXNlKCk7XG4gICAgICAgIHJldHVybiB0cmFuc2FjdGlvbi5maXJlKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzZWxmLmNvdW50ZXIgPiAwKSB7XG4gICAgICAgIHNlbGYuY291bnRlci0tO1xuICAgICAgICBzZWxmLmxvY2sucmVsZWFzZSgpO1xuICAgICAgICByZXR1cm4gc2VsZi5maXJlVHJhbnNhY3Rpb24odHJhbnNhY3Rpb24pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2VsZi5wZW5kaW5nVHJhbnNhY3Rpb25zLnB1c2godHJhbnNhY3Rpb24pO1xuICAgICAgICBzZWxmLmxvY2sucmVsZWFzZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IEV4ZWN1dGVzIGEgdHJhbnNhY3Rpb25cbiAgICpcbiAgICogQHBhcmFtIHtUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgZmlyZVRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uOiBUcmFuc2FjdGlvbikge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdGhpcy1hbGlhc1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIHNlbGYubG9jay5hY3F1aXJlKCkudGhlbigoKSA9PiB7XG4gICAgICBzZWxmLmN1cnJlbnRUcmFuc2FjdGlvbiA9IHRyYW5zYWN0aW9uO1xuICAgICAgc2VsZi5sb2NrLnJlbGVhc2UoKTtcbiAgICAgIGlmIChzZWxmLm9uQmVnaW4pXG4gICAgICAgIHNlbGYub25CZWdpbigpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIC8vIGFsbC5jYWxsKFxuICAgICAgICAgIC8vICAgc2VsZixcbiAgICAgICAgICAvLyAgIGBGaXJpbmcgdHJhbnNhY3Rpb24gezB9LiB7MX0gcmVtYWluaW5nLi4uYCxcbiAgICAgICAgICAvLyAgIHRyYW5zYWN0aW9uLmlkLFxuICAgICAgICAgIC8vICAgdGhpcy5wZW5kaW5nVHJhbnNhY3Rpb25zLmxlbmd0aCxcbiAgICAgICAgICAvLyApO1xuICAgICAgICAgIHRyYW5zYWN0aW9uLmZpcmUoKTtcbiAgICAgICAgfSk7XG4gICAgICBlbHNlIHtcbiAgICAgICAgLy8gYWxsLmNhbGwoXG4gICAgICAgIC8vICAgc2VsZixcbiAgICAgICAgLy8gICBgRmlyaW5nIHRyYW5zYWN0aW9uIHswfS4gezF9IHJlbWFpbmluZy4uLmAsXG4gICAgICAgIC8vICAgdHJhbnNhY3Rpb24uaWQsXG4gICAgICAgIC8vICAgdGhpcy5wZW5kaW5nVHJhbnNhY3Rpb25zLmxlbmd0aCxcbiAgICAgICAgLy8gKTtcbiAgICAgICAgdHJhbnNhY3Rpb24uZmlyZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIC8qKlxuICAgKiBAc3VtbWFyeSBSZWxlYXNlcyBUaGUgbG9jayBhZnRlciB0aGUgY29uY2x1c2lvbiBvZiBhIHRyYW5zYWN0aW9uXG4gICAqL1xuICBhc3luYyByZWxlYXNlKGVycj86IEVycm9yKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby10aGlzLWFsaWFzXG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICBzZWxmLmxvY2suYWNxdWlyZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICBpZiAoIXNlbGYuY3VycmVudFRyYW5zYWN0aW9uKVxuICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgIFwiVHJ5aW5nIHRvIHJlbGVhc2UgYW4gdW5leGlzdGluZyB0cmFuc2FjdGlvbi4gc2hvdWxkIG5ldmVyIGhhcHBlbi4uLlwiXG4gICAgICAgICAgKTtcbiAgICAgICAgLy8gZGVidWcuY2FsbChcbiAgICAgICAgLy8gICBzZWxmLFxuICAgICAgICAvLyAgIFwiUmVsZWFzaW5nIHRyYW5zYWN0aW9uOiB7MH1cIixcbiAgICAgICAgLy8gICBzZWxmLmN1cnJlbnRUcmFuc2FjdGlvbj8udG9TdHJpbmcodHJ1ZSwgdHJ1ZSksXG4gICAgICAgIC8vICk7XG4gICAgICAgIHNlbGYuY3VycmVudFRyYW5zYWN0aW9uID0gdW5kZWZpbmVkO1xuICAgICAgICBzZWxmLmxvY2sucmVsZWFzZSgpO1xuXG4gICAgICAgIGNvbnN0IGFmdGVyQ29uY2x1c2lvbkNCID0gKCkgPT4ge1xuICAgICAgICAgIHNlbGYubG9jay5hY3F1aXJlKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICBpZiAoc2VsZi5wZW5kaW5nVHJhbnNhY3Rpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPVxuICAgICAgICAgICAgICAgIHNlbGYucGVuZGluZ1RyYW5zYWN0aW9ucy5zaGlmdCgpIGFzIFRyYW5zYWN0aW9uO1xuXG4gICAgICAgICAgICAgIGNvbnN0IGNiID0gKCkgPT4gc2VsZi5maXJlVHJhbnNhY3Rpb24odHJhbnNhY3Rpb24pO1xuICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAvLyBhbGwoXG4gICAgICAgICAgICAgIC8vICAgYFJlbGVhc2luZyBUcmFuc2FjdGlvbiBMb2NrIG9uIHRyYW5zYWN0aW9uIHswfWAsXG4gICAgICAgICAgICAgIC8vICAgdHJhbnNhY3Rpb24uaWQsXG4gICAgICAgICAgICAgIC8vICk7XG5cbiAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIHR5cGVvZiAoZ2xvYmFsVGhpcyBhcyB1bmtub3duIGFzIHsgd2luZG93OiBhbnkgfSkud2luZG93ID09PVxuICAgICAgICAgICAgICAgIFwidW5kZWZpbmVkXCJcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIGdsb2JhbFRoaXMucHJvY2Vzcy5uZXh0VGljayhjYik7IC8vIGlmIHlvdSBhcmUgb24gbm9kZVxuICAgICAgICAgICAgICBlbHNlIHNldFRpbWVvdXQoY2IsIDApOyAvLyBpZiB5b3UgYXJlIGluIHRoZSBicm93c2VyXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBzZWxmLmNvdW50ZXIrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNlbGYubG9jay5yZWxlYXNlKCk7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKHNlbGYub25FbmQpIHNlbGYub25FbmQoZXJyKS50aGVuKCgpID0+IGFmdGVyQ29uY2x1c2lvbkNCKCkpO1xuICAgICAgICBlbHNlIGFmdGVyQ29uY2x1c2lvbkNCKCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxufVxuIiwiLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBUcmFuc2FjdGlvbmFsS2V5c1R5cGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBSRUZMRUNUIC0gS2V5IHVzZWQgZm9yIHJlZmxlY3Rpb24gbWV0YWRhdGEgcmVsYXRlZCB0byB0cmFuc2FjdGlvbmFsIG1vZGVsc1xuICogQHByb3BlcnR5IHtzdHJpbmd9IFRSQU5TQUNUSU9OQUwgLSBLZXkgdXNlZCB0byBpZGVudGlmeSB0cmFuc2FjdGlvbmFsIHByb3BlcnRpZXNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6dHJhbnNhY3Rpb25zXG4gKi9cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gS2V5cyB1c2VkIGZvciB0cmFuc2FjdGlvbmFsIG9wZXJhdGlvbnNcbiAqIEBzdW1tYXJ5IENvbnN0YW50IG9iamVjdCBjb250YWluaW5nIHN0cmluZyBrZXlzIHVzZWQgdGhyb3VnaG91dCB0aGUgdHJhbnNhY3Rpb25hbCBzeXN0ZW0gZm9yIHJlZmxlY3Rpb24gYW5kIGlkZW50aWZpY2F0aW9uXG4gKiBAdHlwZSB7VHJhbnNhY3Rpb25hbEtleXNUeXBlfVxuICogQGNvbnN0IFRyYW5zYWN0aW9uYWxLZXlzXG4gKiBAbWVtYmVyT2YgbW9kdWxlOnRyYW5zYWN0aW9uc1xuICovXG5leHBvcnQgY29uc3QgVHJhbnNhY3Rpb25hbEtleXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gIFJFRkxFQ1Q6IFwibW9kZWwudHJhbnNhY3Rpb25hbC5cIixcbiAgVFJBTlNBQ1RJT05BTDogXCJ0cmFuc2FjdGlvbmFsXCIsXG59O1xuIiwiZXhwb3J0IGZ1bmN0aW9uIGdldE9iamVjdE5hbWUob2JqOiBhbnkpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBpZiAoIW9iaikgcmV0dXJuO1xuICBpZiAodHlwZW9mIG9iaiA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIG9iajtcbiAgaWYgKFxuICAgIG9iai5jb25zdHJ1Y3RvciAmJlxuICAgIG9iai5jb25zdHJ1Y3Rvci5uYW1lICYmXG4gICAgW1wiRnVuY3Rpb25cIiwgXCJPYmplY3RcIl0uaW5kZXhPZihvYmouY29uc3RydWN0b3IubmFtZSkgPT09IC0xXG4gIClcbiAgICByZXR1cm4gb2JqLmNvbnN0cnVjdG9yLm5hbWU7XG4gIGlmICh0eXBlb2Ygb2JqID09PSBcImZ1bmN0aW9uXCIgJiYgb2JqLm5hbWUpIHJldHVybiBvYmoubmFtZTtcbiAgcmV0dXJuIG9iai50b1N0cmluZygpO1xufVxuIiwiaW1wb3J0IHsgVHJhbnNhY3Rpb25Mb2NrIH0gZnJvbSBcIi4vaW50ZXJmYWNlcy9UcmFuc2FjdGlvbkxvY2tcIjtcbmltcG9ydCB7IFJlZmxlY3Rpb24gfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcbmltcG9ydCB7IENhbGxiYWNrIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IFN5bmNyb25vdXNMb2NrIH0gZnJvbSBcIi4vbG9ja3MvU3luY3Jvbm91c0xvY2tcIjtcbmltcG9ydCB7XG4gIERCS2V5cyxcbiAgZ2V0QWxsUHJvcGVydHlEZWNvcmF0b3JzUmVjdXJzaXZlLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IGdldE9iamVjdE5hbWUgfSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb25hbEtleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ29yZSB0cmFuc2FjdGlvbiBtYW5hZ2VtZW50IGNsYXNzXG4gKiBAc3VtbWFyeSBNYW5hZ2VzIHRyYW5zYWN0aW9uIGxpZmVjeWNsZSwgaW5jbHVkaW5nIGNyZWF0aW9uLCBleGVjdXRpb24sIGFuZCBjbGVhbnVwLiBQcm92aWRlcyBtZWNoYW5pc21zIGZvciBiaW5kaW5nIHRyYW5zYWN0aW9ucyB0byBvYmplY3RzIGFuZCBtZXRob2RzLCBlbnN1cmluZyBwcm9wZXIgdHJhbnNhY3Rpb24gY29udGV4dCBwcm9wYWdhdGlvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBUaGUgc291cmNlL29yaWdpbiBvZiB0aGUgdHJhbnNhY3Rpb24gKHR5cGljYWxseSBhIGNsYXNzIG5hbWUpXG4gKiBAcGFyYW0ge3N0cmluZ30gW21ldGhvZF0gLSBUaGUgbWV0aG9kIG5hbWUgYXNzb2NpYXRlZCB3aXRoIHRoZSB0cmFuc2FjdGlvblxuICogQHBhcmFtIHtmdW5jdGlvbigpOiBhbnl9IFthY3Rpb25dIC0gVGhlIGZ1bmN0aW9uIHRvIGV4ZWN1dGUgd2l0aGluIHRoZSB0cmFuc2FjdGlvblxuICogQHBhcmFtIHthbnlbXX0gW21ldGFkYXRhXSAtIEFkZGl0aW9uYWwgbWV0YWRhdGEgdG8gYXNzb2NpYXRlIHdpdGggdGhlIHRyYW5zYWN0aW9uXG4gKiBAY2xhc3MgVHJhbnNhY3Rpb25cbiAqIEBleGFtcGxlXG4gKiAvLyBDcmVhdGluZyBhbmQgc3VibWl0dGluZyBhIHRyYW5zYWN0aW9uXG4gKiBjb25zdCB0cmFuc2FjdGlvbiA9IG5ldyBUcmFuc2FjdGlvbihcbiAqICAgJ1VzZXJTZXJ2aWNlJyxcbiAqICAgJ2NyZWF0ZVVzZXInLFxuICogICBhc3luYyAoKSA9PiB7XG4gKiAgICAgLy8gVHJhbnNhY3Rpb24gbG9naWMgaGVyZVxuICogICAgIGF3YWl0IGRiLmluc2VydCgndXNlcnMnLCB7IG5hbWU6ICdKb2huJyB9KTtcbiAqICAgfVxuICogKTtcbiAqIFRyYW5zYWN0aW9uLnN1Ym1pdCh0cmFuc2FjdGlvbik7XG4gKiBcbiAqIC8vIFVzaW5nIHRoZSB0cmFuc2FjdGlvbmFsIGRlY29yYXRvclxuICogY2xhc3MgVXNlclNlcnZpY2Uge1xuICogICBAdHJhbnNhY3Rpb25hbCgpXG4gKiAgIGFzeW5jIGNyZWF0ZVVzZXIoZGF0YSkge1xuICogICAgIC8vIE1ldGhvZCB3aWxsIGJlIGV4ZWN1dGVkIHdpdGhpbiBhIHRyYW5zYWN0aW9uXG4gKiAgICAgcmV0dXJuIGF3YWl0IGRiLmluc2VydCgndXNlcnMnLCBkYXRhKTtcbiAqICAgfVxuICogfVxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDIGFzIENsaWVudCBDb2RlXG4gKiAgIHBhcnRpY2lwYW50IFQgYXMgVHJhbnNhY3Rpb25cbiAqICAgcGFydGljaXBhbnQgTCBhcyBUcmFuc2FjdGlvbkxvY2tcbiAqICAgcGFydGljaXBhbnQgTyBhcyBPcmlnaW5hbCBNZXRob2RcbiAqICAgXG4gKiAgIEMtPj5UOiBuZXcgVHJhbnNhY3Rpb24oc291cmNlLCBtZXRob2QsIGFjdGlvbilcbiAqICAgQy0+PlQ6IFRyYW5zYWN0aW9uLnN1Ym1pdCh0cmFuc2FjdGlvbilcbiAqICAgVC0+Pkw6IHN1Ym1pdCh0cmFuc2FjdGlvbilcbiAqICAgTC0+PlQ6IGZpcmUoKVxuICogICBULT4+TzogRXhlY3V0ZSBhY3Rpb24oKVxuICogICBPLS0+PlQ6IFJldHVybiByZXN1bHQvZXJyb3JcbiAqICAgVC0+Pkw6IHJlbGVhc2UoZXJyb3I/KVxuICogICBMLS0+PkM6IFJldHVybiByZXN1bHQvZXJyb3JcbiAqL1xuZXhwb3J0IGNsYXNzIFRyYW5zYWN0aW9uIHtcbiAgcmVhZG9ubHkgaWQ6IG51bWJlcjtcbiAgcHJvdGVjdGVkIGFjdGlvbj86ICgpID0+IGFueTtcbiAgcmVhZG9ubHkgbWV0aG9kPzogc3RyaW5nO1xuICByZWFkb25seSBzb3VyY2U/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGxvZzogc3RyaW5nW107XG4gIHByaXZhdGUgcmVhZG9ubHkgbWV0YWRhdGE/OiBhbnlbXTtcblxuICBwcml2YXRlIHN0YXRpYyBsb2NrOiBUcmFuc2FjdGlvbkxvY2s7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgc291cmNlOiBzdHJpbmcsXG4gICAgbWV0aG9kPzogc3RyaW5nLFxuICAgIGFjdGlvbj86ICgpID0+IGFueSxcbiAgICBtZXRhZGF0YT86IGFueVtdXG4gICkge1xuICAgIHRoaXMuaWQgPSBEYXRlLm5vdygpO1xuICAgIHRoaXMuYWN0aW9uID0gYWN0aW9uO1xuICAgIHRoaXMubWV0aG9kID0gbWV0aG9kO1xuICAgIHRoaXMubG9nID0gW1t0aGlzLmlkLCBzb3VyY2UsIG1ldGhvZF0uam9pbihcIiB8IFwiKV07XG4gICAgdGhpcy5zb3VyY2UgPSBzb3VyY2U7XG4gICAgdGhpcy5tZXRhZGF0YSA9IG1ldGFkYXRhO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBRdWV1ZXMgYSB0cmFuc2FjdGlvbiBmb3IgZXhlY3V0aW9uXG4gICAqIEBzdW1tYXJ5IFB1c2hlcyBhIHRyYW5zYWN0aW9uIHRvIHRoZSBxdWV1ZSBhbmQgd2FpdHMgZm9yIGl0cyByZXNvbHV0aW9uLiBDcmVhdGVzIGEgbmV3IHRyYW5zYWN0aW9uIHdpdGggdGhlIHByb3ZpZGVkIGlzc3VlciBhbmQgY2FsbGJhY2sgbWV0aG9kLCB0aGVuIHN1Ym1pdHMgaXQgdG8gdGhlIHRyYW5zYWN0aW9uIGxvY2suXG4gICAqIEBwYXJhbSB7YW55fSBpc3N1ZXIgLSBBbnkgY2xhc3MgaW5zdGFuY2UgdGhhdCB3aWxsIGJlIHVzZWQgYXMgJ3RoaXMnIHdoZW4gY2FsbGluZyB0aGUgY2FsbGJhY2tNZXRob2RcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tNZXRob2QgLSBDYWxsYmFjayBmdW5jdGlvbiBjb250YWluaW5nIHRoZSB0cmFuc2FjdGlvbiBsb2dpYywgd2lsbCBiZSBjYWxsZWQgd2l0aCB0aGUgaXNzdWVyIGFzICd0aGlzJ1xuICAgKiBAcGFyYW0ge2FueVtdfSBhcmdzIC0gQXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIG1ldGhvZC4gTGFzdCBvbmUgbXVzdCBiZSB0aGUgY2FsbGJhY2sgZnVuY3Rpb25cbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIHN0YXRpYyBwdXNoKFxuICAgIGlzc3VlcjogYW55LFxuICAgIGNhbGxiYWNrTWV0aG9kOiAoLi4uYXJneno6IChhbnkgfCBDYWxsYmFjaylbXSkgPT4gdm9pZCxcbiAgICAuLi5hcmdzOiAoYW55IHwgQ2FsbGJhY2spW11cbiAgKSB7XG4gICAgY29uc3QgY2FsbGJhY2s6IENhbGxiYWNrID0gYXJncy5wb3AoKTtcbiAgICBpZiAoIWNhbGxiYWNrIHx8IHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBjYWxsYmFja1wiKTtcbiAgICBjb25zdCBjYiA9IChlcnI/OiBFcnJvciwgLi4uYXJnczogYW55W10pID0+IHtcbiAgICAgIFRyYW5zYWN0aW9uLmdldExvY2soKVxuICAgICAgICAucmVsZWFzZShlcnIpXG4gICAgICAgIC50aGVuKCgpID0+IGNhbGxiYWNrKGVyciwgLi4uYXJncykpO1xuICAgIH07XG4gICAgY29uc3QgdHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uID0gbmV3IFRyYW5zYWN0aW9uKFxuICAgICAgaXNzdWVyLmNvbnN0cnVjdG9yLm5hbWUsXG4gICAgICBjYWxsYmFja01ldGhvZC5uYW1lID8gZ2V0T2JqZWN0TmFtZShjYWxsYmFja01ldGhvZCkgOiBcIkFub255bW91c1wiLFxuICAgICAgKCkgPT4ge1xuICAgICAgICByZXR1cm4gY2FsbGJhY2tNZXRob2QuY2FsbChcbiAgICAgICAgICB0cmFuc2FjdGlvbi5iaW5kVG9UcmFuc2FjdGlvbihpc3N1ZXIpLFxuICAgICAgICAgIC4uLmFyZ3MsXG4gICAgICAgICAgY2JcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICApO1xuICAgIFRyYW5zYWN0aW9uLmdldExvY2soKS5zdWJtaXQodHJhbnNhY3Rpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDb25maWd1cmVzIHRoZSB0cmFuc2FjdGlvbiBsb2NrIGltcGxlbWVudGF0aW9uXG4gICAqIEBzdW1tYXJ5IFNldHMgdGhlIGxvY2sgaW1wbGVtZW50YXRpb24gdG8gYmUgdXNlZCBmb3IgdHJhbnNhY3Rpb24gbWFuYWdlbWVudCwgYWxsb3dpbmcgY3VzdG9taXphdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gYmVoYXZpb3JcbiAgICogQHBhcmFtIHtUcmFuc2FjdGlvbkxvY2t9IGxvY2sgLSBUaGUgbG9jayBpbXBsZW1lbnRhdGlvbiB0byB1c2UgZm9yIG1hbmFnaW5nIHRyYW5zYWN0aW9uc1xuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgc3RhdGljIHNldExvY2sobG9jazogVHJhbnNhY3Rpb25Mb2NrKSB7XG4gICAgdGhpcy5sb2NrID0gbG9jaztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIHRoZSBjdXJyZW50IHRyYW5zYWN0aW9uIGxvY2tcbiAgICogQHN1bW1hcnkgR2V0cyB0aGUgY3VycmVudCB0cmFuc2FjdGlvbiBsb2NrIGluc3RhbmNlLCBjcmVhdGluZyBhIGRlZmF1bHQgU3luY3Jvbm91c0xvY2sgaWYgbm9uZSBleGlzdHNcbiAgICogQHJldHVybiB7VHJhbnNhY3Rpb25Mb2NrfSBUaGUgY3VycmVudCB0cmFuc2FjdGlvbiBsb2NrIGltcGxlbWVudGF0aW9uXG4gICAqL1xuICBzdGF0aWMgZ2V0TG9jaygpOiBUcmFuc2FjdGlvbkxvY2sge1xuICAgIGlmICghdGhpcy5sb2NrKSB0aGlzLmxvY2sgPSBuZXcgU3luY3Jvbm91c0xvY2soKTtcbiAgICByZXR1cm4gdGhpcy5sb2NrO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTdWJtaXRzIGEgdHJhbnNhY3Rpb24gZm9yIHByb2Nlc3NpbmdcbiAgICogQHN1bW1hcnkgU3VibWl0cyBhIHRyYW5zYWN0aW9uIHRvIHRoZSBjdXJyZW50IHRyYW5zYWN0aW9uIGxvY2sgZm9yIHByb2Nlc3NpbmcgYW5kIGV4ZWN1dGlvblxuICAgKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvbiAtIFRoZSB0cmFuc2FjdGlvbiB0byBzdWJtaXQgZm9yIHByb2Nlc3NpbmdcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIHN0YXRpYyBzdWJtaXQodHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uKSB7XG4gICAgVHJhbnNhY3Rpb24uZ2V0TG9jaygpLnN1Ym1pdCh0cmFuc2FjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlbGVhc2VzIHRoZSB0cmFuc2FjdGlvbiBsb2NrXG4gICAqIEBzdW1tYXJ5IFJlbGVhc2VzIHRoZSBjdXJyZW50IHRyYW5zYWN0aW9uIGxvY2ssIG9wdGlvbmFsbHkgd2l0aCBhbiBlcnJvciwgYWxsb3dpbmcgdGhlIG5leHQgdHJhbnNhY3Rpb24gdG8gcHJvY2VlZFxuICAgKiBAcGFyYW0ge0Vycm9yfSBbZXJyXSAtIE9wdGlvbmFsIGVycm9yIHRoYXQgb2NjdXJyZWQgZHVyaW5nIHRyYW5zYWN0aW9uIGV4ZWN1dGlvblxuICAgKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBsb2NrIGhhcyBiZWVuIHJlbGVhc2VkXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgcmVsZWFzZShlcnI/OiBFcnJvcikge1xuICAgIHJldHVybiBUcmFuc2FjdGlvbi5nZXRMb2NrKCkucmVsZWFzZShlcnIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgdHJhbnNhY3Rpb24gbWV0YWRhdGFcbiAgICogQHN1bW1hcnkgUmV0dXJucyBhIGNvcHkgb2YgdGhlIG1ldGFkYXRhIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHRyYW5zYWN0aW9uLCBlbnN1cmluZyB0aGUgb3JpZ2luYWwgbWV0YWRhdGEgcmVtYWlucyB1bm1vZGlmaWVkXG4gICAqIEByZXR1cm4ge2FueVtdIHwgdW5kZWZpbmVkfSBBIGNvcHkgb2YgdGhlIHRyYW5zYWN0aW9uIG1ldGFkYXRhIG9yIHVuZGVmaW5lZCBpZiBubyBtZXRhZGF0YSBleGlzdHNcbiAgICovXG4gIGdldE1ldGFkYXRhKCkge1xuICAgIHJldHVybiB0aGlzLm1ldGFkYXRhID8gWy4uLnRoaXMubWV0YWRhdGFdIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMaW5rcyBhIG5ldyB0cmFuc2FjdGlvbiB0byB0aGUgY3VycmVudCBvbmVcbiAgICogQHN1bW1hcnkgQmluZHMgYSBuZXcgdHJhbnNhY3Rpb24gb3BlcmF0aW9uIHRvIHRoZSBjdXJyZW50IHRyYW5zYWN0aW9uLCB0cmFuc2ZlcnJpbmcgbG9ncyBhbmQgYmluZGluZyBtZXRob2RzIHRvIG1haW50YWluIHRyYW5zYWN0aW9uIGNvbnRleHRcbiAgICogQHBhcmFtIHtUcmFuc2FjdGlvbn0gbmV4dFRyYW5zYWN0aW9uIC0gVGhlIG5ldyB0cmFuc2FjdGlvbiB0byBiaW5kIHRvIHRoZSBjdXJyZW50IG9uZVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgYmluZFRyYW5zYWN0aW9uKG5leHRUcmFuc2FjdGlvbjogVHJhbnNhY3Rpb24pIHtcbiAgICAvLyBhbGwoYEJpbmRpbmcgdGhlIHswfSB0byB7MX1gLCBuZXh0VHJhbnNhY3Rpb24sIHRoaXMpO1xuICAgIHRoaXMubG9nLnB1c2goLi4ubmV4dFRyYW5zYWN0aW9uLmxvZyk7XG4gICAgbmV4dFRyYW5zYWN0aW9uLmJpbmRUcmFuc2FjdGlvbiA9IHRoaXMuYmluZFRvVHJhbnNhY3Rpb24uYmluZCh0aGlzKTtcbiAgICBuZXh0VHJhbnNhY3Rpb24uYmluZFRvVHJhbnNhY3Rpb24gPSB0aGlzLmJpbmRUb1RyYW5zYWN0aW9uLmJpbmQodGhpcyk7XG4gICAgdGhpcy5hY3Rpb24gPSBuZXh0VHJhbnNhY3Rpb24uYWN0aW9uO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBCaW5kcyBhbiBvYmplY3QgdG8gdGhlIGN1cnJlbnQgdHJhbnNhY3Rpb24gY29udGV4dFxuICAgKiBAc3VtbWFyeSBCaW5kcyBhIHRyYW5zYWN0aW9uYWwgZGVjb3JhdGVkIG9iamVjdCB0byB0aGUgdHJhbnNhY3Rpb24gYnkgZW5zdXJpbmcgYWxsIHRyYW5zYWN0aW9uYWwgbWV0aG9kcyBhdXRvbWF0aWNhbGx5IHJlY2VpdmUgdGhlIGN1cnJlbnQgdHJhbnNhY3Rpb24gYXMgdGhlaXIgZmlyc3QgYXJndW1lbnRcbiAgICogQHBhcmFtIHthbnl9IG9iaiAtIFRoZSBvYmplY3QgdG8gYmluZCB0byB0aGUgdHJhbnNhY3Rpb25cbiAgICogQHJldHVybiB7YW55fSBUaGUgYm91bmQgb2JqZWN0IHdpdGggdHJhbnNhY3Rpb24tYXdhcmUgbWV0aG9kIHdyYXBwZXJzXG4gICAqL1xuICBiaW5kVG9UcmFuc2FjdGlvbihvYmo6IGFueSk6IGFueSB7XG4gICAgY29uc3QgdHJhbnNhY3Rpb25hbE1ldGhvZHMgPSBnZXRBbGxQcm9wZXJ0eURlY29yYXRvcnNSZWN1cnNpdmUoXG4gICAgICBvYmosXG4gICAgICB1bmRlZmluZWQsXG4gICAgICBUcmFuc2FjdGlvbmFsS2V5cy5SRUZMRUNUXG4gICAgKTtcbiAgICBpZiAoIXRyYW5zYWN0aW9uYWxNZXRob2RzKSByZXR1cm4gb2JqO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdGhpcy1hbGlhc1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgY29uc3QgYm91bmRPYmogPSBSZWZsZWN0aW9uLmdldEFsbFByb3BlcnRpZXMob2JqKS5yZWR1Y2UoXG4gICAgICAoYWNjdW06IGFueSwgazogc3RyaW5nKSA9PiB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBPYmplY3Qua2V5cyh0cmFuc2FjdGlvbmFsTWV0aG9kcykuaW5kZXhPZihrKSAhPT0gLTEgJiZcbiAgICAgICAgICB0cmFuc2FjdGlvbmFsTWV0aG9kc1trXS5maW5kKFxuICAgICAgICAgICAgKG8pID0+IG8ua2V5ID09PSBUcmFuc2FjdGlvbmFsS2V5cy5UUkFOU0FDVElPTkFMXG4gICAgICAgICAgKVxuICAgICAgICApXG4gICAgICAgICAgYWNjdW1ba10gPSAoLi4uYXJnczogYW55W10pID0+XG4gICAgICAgICAgICBvYmpba10uY2FsbChvYmouX19vcmlnaW5hbE9iaiB8fCBvYmosIHNlbGYsIC4uLmFyZ3MpO1xuICAgICAgICBlbHNlIGlmIChrID09PSBcImNsYXp6XCIgfHwgayA9PT0gXCJjb25zdHJ1Y3RvclwiKSBhY2N1bVtrXSA9IG9ialtrXTtcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9ialtrXSA9PT0gXCJmdW5jdGlvblwiKVxuICAgICAgICAgIGFjY3VtW2tdID0gb2JqW2tdLmJpbmQob2JqLl9fb3JpZ2luYWxPYmogfHwgb2JqKTtcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9ialtrXSA9PT0gXCJvYmplY3RcIiAmJiBvYmpba10uY29uc3RydWN0b3IpIHtcbiAgICAgICAgICBjb25zdCBkZWNzID0gUmVmbGVjdGlvbi5nZXRDbGFzc0RlY29yYXRvcnMoXG4gICAgICAgICAgICBUcmFuc2FjdGlvbmFsS2V5cy5SRUZMRUNULFxuICAgICAgICAgICAgb2JqW2tdXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoZGVjcy5maW5kKChlOiBhbnkpID0+IGUua2V5ID09PSBUcmFuc2FjdGlvbmFsS2V5cy5UUkFOU0FDVElPTkFMKSlcbiAgICAgICAgICAgIGFjY3VtW2tdID0gc2VsZi5iaW5kVG9UcmFuc2FjdGlvbihvYmpba10pO1xuICAgICAgICAgIGVsc2UgYWNjdW1ba10gPSBvYmpba107XG4gICAgICAgIH0gZWxzZSBhY2N1bVtrXSA9IG9ialtrXTtcblxuICAgICAgICByZXR1cm4gYWNjdW07XG4gICAgICB9LFxuICAgICAge31cbiAgICApO1xuXG4gICAgYm91bmRPYmpbREJLZXlzLk9SSUdJTkFMXSA9IG9ialtEQktleXMuT1JJR0lOQUxdIHx8IG9iajtcbiAgICBib3VuZE9iai50b1N0cmluZyA9ICgpID0+XG4gICAgICBnZXRPYmplY3ROYW1lKGJvdW5kT2JqW0RCS2V5cy5PUklHSU5BTF0pICtcbiAgICAgIFwiIHByb3h5IGZvciB0cmFuc2FjdGlvbiBcIiArXG4gICAgICB0aGlzLmlkO1xuXG4gICAgcmV0dXJuIGJvdW5kT2JqO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBFeGVjdXRlcyB0aGUgdHJhbnNhY3Rpb24gYWN0aW9uXG4gICAqIEBzdW1tYXJ5IEZpcmVzIHRoZSB0cmFuc2FjdGlvbiBieSBleGVjdXRpbmcgaXRzIGFzc29jaWF0ZWQgYWN0aW9uIGZ1bmN0aW9uLCB0aHJvd2luZyBhbiBlcnJvciBpZiBubyBhY3Rpb24gaXMgZGVmaW5lZFxuICAgKiBAcmV0dXJuIHthbnl9IFRoZSByZXN1bHQgb2YgdGhlIHRyYW5zYWN0aW9uIGFjdGlvblxuICAgKi9cbiAgZmlyZSgpIHtcbiAgICBpZiAoIXRoaXMuYWN0aW9uKSB0aHJvdyBuZXcgRXJyb3IoYE1pc3NpbmcgdGhlIG1ldGhvZGApO1xuICAgIHJldHVybiB0aGlzLmFjdGlvbigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBQcm92aWRlcyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb25cbiAgICogQHN1bW1hcnkgT3ZlcnJpZGVzIHRoZSBkZWZhdWx0IHRvU3RyaW5nIG1ldGhvZCB0byBwcm92aWRlIGEgZm9ybWF0dGVkIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24sIG9wdGlvbmFsbHkgaW5jbHVkaW5nIHRoZSB0cmFuc2FjdGlvbiBJRCBhbmQgbG9nXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW3dpdGhJZD10cnVlXSAtIFdoZXRoZXIgdG8gaW5jbHVkZSB0aGUgdHJhbnNhY3Rpb24gSUQgaW4gdGhlIG91dHB1dFxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFt3aXRoTG9nPWZhbHNlXSAtIFdoZXRoZXIgdG8gaW5jbHVkZSB0aGUgdHJhbnNhY3Rpb24gbG9nIGluIHRoZSBvdXRwdXRcbiAgICogQHJldHVybiB7c3RyaW5nfSBBIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb25cbiAgICovXG4gIHRvU3RyaW5nKHdpdGhJZCA9IHRydWUsIHdpdGhMb2cgPSBmYWxzZSkge1xuICAgIHJldHVybiBgJHt3aXRoSWQgPyBgWyR7dGhpcy5pZH1dYCA6IFwiXCJ9W1RyYW5zYWN0aW9uXVske3RoaXMuc291cmNlfS4ke3RoaXMubWV0aG9kfSR7XG4gICAgICB3aXRoTG9nID8gYF1cXG5UcmFuc2FjdGlvbiBMb2c6XFxuJHt0aGlzLmxvZy5qb2luKFwiXFxuXCIpfWAgOiBcIl1cIlxuICAgIH1gO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZW5lcmF0ZXMgYSByZWZsZWN0aW9uIG1ldGFkYXRhIGtleSBmb3IgdHJhbnNhY3Rpb25zXG4gICAqIEBzdW1tYXJ5IENyZWF0ZXMgYSBwcmVmaXhlZCByZWZsZWN0aW9uIGtleSBmb3IgdHJhbnNhY3Rpb24tcmVsYXRlZCBtZXRhZGF0YSwgZW5zdXJpbmcgcHJvcGVyIG5hbWVzcGFjaW5nXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgLSBUaGUgYmFzZSBrZXkgdG8gcHJlZml4IHdpdGggdGhlIHRyYW5zYWN0aW9uIHJlZmxlY3Rpb24gbmFtZXNwYWNlXG4gICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGNvbXBsZXRlIHJlZmxlY3Rpb24ga2V5IGZvciB0cmFuc2FjdGlvbiBtZXRhZGF0YVxuICAgKiBAZnVuY3Rpb24ga2V5XG4gICAqL1xuICBzdGF0aWMga2V5KGtleTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIFRyYW5zYWN0aW9uYWxLZXlzLlJFRkxFQ1QgKyBrZXk7XG4gIH1cbn1cbiIsImltcG9ydCB7IFRyYW5zYWN0aW9uYWxLZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBtZXRhZGF0YSB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb24gfSBmcm9tIFwiLi9UcmFuc2FjdGlvblwiO1xuaW1wb3J0IHsgSW50ZXJuYWxFcnJvciB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNZXRob2QgZGVjb3JhdG9yIHRoYXQgZW5hYmxlcyB0cmFuc2FjdGlvbmFsIGJlaGF2aW9yXG4gKiBAc3VtbWFyeSBTZXRzIGEgY2xhc3MgYXN5bmMgbWV0aG9kIGFzIHRyYW5zYWN0aW9uYWwsIHdyYXBwaW5nIGl0IGluIGEgdHJhbnNhY3Rpb24gY29udGV4dCB0aGF0IGNhbiBiZSBtYW5hZ2VkIGJ5IHRoZSB0cmFuc2FjdGlvbiBzeXN0ZW0uIFRoaXMgZGVjb3JhdG9yIGhhbmRsZXMgdHJhbnNhY3Rpb24gY3JlYXRpb24sIGJpbmRpbmcsIGFuZCBlcnJvciBoYW5kbGluZy5cbiAqIEBwYXJhbSB7YW55W119IFtkYXRhXSAtIE9wdGlvbmFsIG1ldGFkYXRhIGF2YWlsYWJsZSB0byB0aGUge0BsaW5rIFRyYW5zYWN0aW9uTG9ja30gaW1wbGVtZW50YXRpb25cbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIGRlY29yYXRvciBmdW5jdGlvbiB0aGF0IHdyYXBzIHRoZSBvcmlnaW5hbCBtZXRob2Qgd2l0aCB0cmFuc2FjdGlvbmFsIGJlaGF2aW9yXG4gKiBAZnVuY3Rpb24gdHJhbnNhY3Rpb25hbFxuICogQGNhdGVnb3J5IE1ldGhvZCBEZWNvcmF0b3JzXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IEMgYXMgQ2xpZW50IENvZGVcbiAqICAgcGFydGljaXBhbnQgRCBhcyBEZWNvcmF0b3JcbiAqICAgcGFydGljaXBhbnQgVCBhcyBUcmFuc2FjdGlvblxuICogICBwYXJ0aWNpcGFudCBPIGFzIE9yaWdpbmFsIE1ldGhvZFxuICpcbiAqICAgQy0+PkQ6IENhbGwgZGVjb3JhdGVkIG1ldGhvZFxuICogICBELT4+RDogQ2hlY2sgaWYgdHJhbnNhY3Rpb24gZXhpc3RzIGluIGFyZ3NcbiAqXG4gKiAgIGFsdCBUcmFuc2FjdGlvbiBleGlzdHMgaW4gYXJnc1xuICogICAgIEQtPj5UOiBDcmVhdGUgdXBkYXRlZCB0cmFuc2FjdGlvblxuICogICAgIFQtPj5UOiBCaW5kIHRvIG9yaWdpbmFsIHRyYW5zYWN0aW9uXG4gKiAgICAgVC0+PlQ6IEZpcmUgdHJhbnNhY3Rpb25cbiAqICAgZWxzZSBObyB0cmFuc2FjdGlvblxuICogICAgIEQtPj5UOiBDcmVhdGUgbmV3IHRyYW5zYWN0aW9uXG4gKiAgICAgVC0+PlQ6IFN1Ym1pdCB0cmFuc2FjdGlvblxuICogICBlbmRcbiAqXG4gKiAgIFQtPj5POiBFeGVjdXRlIG9yaWdpbmFsIG1ldGhvZFxuICogICBPLS0+PlQ6IFJldHVybiByZXN1bHQvZXJyb3JcbiAqICAgVC0+PlQ6IFJlbGVhc2UgdHJhbnNhY3Rpb25cbiAqICAgVC0tPj5DOiBSZXR1cm4gcmVzdWx0L2Vycm9yXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNhY3Rpb25hbCguLi5kYXRhOiBhbnlbXSkge1xuICByZXR1cm4gZnVuY3Rpb24gKFxuICAgIHRhcmdldDogYW55LFxuICAgIHByb3BlcnR5S2V5PzogYW55LFxuICAgIGRlc2NyaXB0b3I/OiBQcm9wZXJ0eURlc2NyaXB0b3JcbiAgKSB7XG4gICAgaWYgKCFkZXNjcmlwdG9yKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJNaXNzaW5nIGRlc2NyaXB0b3IuIFNob3VsZCBiZSBpbXBvc3NpYmxlXCIpO1xuICAgIG1ldGFkYXRhKFRyYW5zYWN0aW9uLmtleShUcmFuc2FjdGlvbmFsS2V5cy5UUkFOU0FDVElPTkFMKSwgZGF0YSkoXG4gICAgICB0YXJnZXQsXG4gICAgICBwcm9wZXJ0eUtleVxuICAgICk7XG5cbiAgICBjb25zdCBvcmlnaW5hbE1ldGhvZCA9IGRlc2NyaXB0b3IudmFsdWU7XG5cbiAgICBjb25zdCBtZXRob2RXcmFwcGVyID0gZnVuY3Rpb24gKHRoaXM6IGFueSwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPGFueT4ge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby10aGlzLWFsaWFzXG4gICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxhbnk+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgY29uc3QgY2IgPSAoZXJyPzogRXJyb3IsIHJlc3VsdD86IGFueSkgPT4ge1xuICAgICAgICAgIFRyYW5zYWN0aW9uLnJlbGVhc2UoZXJyKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnIpIHJldHVybiByZWplY3QoZXJyKTtcbiAgICAgICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfTtcblxuICAgICAgICBsZXQgdHJhbnNhY3Rpb24gPSBhcmdzLnNoaWZ0KCk7XG4gICAgICAgIGlmICh0cmFuc2FjdGlvbiBpbnN0YW5jZW9mIFRyYW5zYWN0aW9uKSB7XG4gICAgICAgICAgY29uc3QgdXBkYXRlZFRyYW5zYWN0aW9uOiBUcmFuc2FjdGlvbiA9IG5ldyBUcmFuc2FjdGlvbihcbiAgICAgICAgICAgIHRoaXMuY29uc3RydWN0b3IubmFtZSxcbiAgICAgICAgICAgIHByb3BlcnR5S2V5LFxuICAgICAgICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICBvcmlnaW5hbE1ldGhvZFxuICAgICAgICAgICAgICAgIC5jYWxsKHVwZGF0ZWRUcmFuc2FjdGlvbi5iaW5kVG9UcmFuc2FjdGlvbihzZWxmKSwgLi4uYXJncylcbiAgICAgICAgICAgICAgICAudGhlbihyZXNvbHZlKVxuICAgICAgICAgICAgICAgIC5jYXRjaChyZWplY3QpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRhdGEubGVuZ3RoID8gZGF0YSA6IHVuZGVmaW5lZFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICB0cmFuc2FjdGlvbi5iaW5kVHJhbnNhY3Rpb24odXBkYXRlZFRyYW5zYWN0aW9uKTtcbiAgICAgICAgICB0cmFuc2FjdGlvbi5maXJlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYXJncy51bnNoaWZ0KHRyYW5zYWN0aW9uKTtcbiAgICAgICAgICB0cmFuc2FjdGlvbiA9IG5ldyBUcmFuc2FjdGlvbihcbiAgICAgICAgICAgIHRoaXMuY29uc3RydWN0b3IubmFtZSxcbiAgICAgICAgICAgIHByb3BlcnR5S2V5LFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICBvcmlnaW5hbE1ldGhvZFxuICAgICAgICAgICAgICAgIC5jYWxsKHRyYW5zYWN0aW9uLmJpbmRUb1RyYW5zYWN0aW9uKHNlbGYpLCAuLi5hcmdzKVxuICAgICAgICAgICAgICAgIC50aGVuKChyZXN1bHQ6IGFueSkgPT4gY2IodW5kZWZpbmVkLCByZXN1bHQpKVxuICAgICAgICAgICAgICAgIC5jYXRjaChjYik7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZGF0YS5sZW5ndGggPyBkYXRhIDogdW5kZWZpbmVkXG4gICAgICAgICAgKTtcbiAgICAgICAgICBUcmFuc2FjdGlvbi5zdWJtaXQodHJhbnNhY3Rpb24pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG1ldGhvZFdyYXBwZXIsIFwibmFtZVwiLCB7XG4gICAgICB2YWx1ZTogcHJvcGVydHlLZXksXG4gICAgfSk7XG4gICAgZGVzY3JpcHRvci52YWx1ZSA9IG1ldGhvZFdyYXBwZXI7XG4gIH07XG59XG4vL1xuLy8gLyoqXG4vLyAgKiBAc3VtbWFyeSBTZXRzIGEgY2xhc3MgQXN5bmMgbWV0aG9kIGFzIHRyYW5zYWN0aW9uYWxcbi8vICAqXG4vLyAgKiBAcGFyYW0ge2FueVtdfSAgW21ldGFkYXRhXSBvcHRpb24gbWV0YWRhdGEgYXZhaWxhYmxlIHRvIHRoZSB7QGxpbmsgVHJhbnNhY3Rpb25Mb2NrfVxuLy8gICpcbi8vICAqIEBmdW5jdGlvbiB0cmFuc2FjdGlvbmFsQXN5bmNcbi8vICAqXG4vLyAgKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnMuRGVjb3JhdG9ycy50cmFuc2FjdGlvbnNcbi8vICAqL1xuLy8gZXhwb3J0IGZ1bmN0aW9uIHRyYW5zYWN0aW9uYWxBc3luYyguLi5tZXRhZGF0YTogYW55W10pIHtcbi8vICAgcmV0dXJuIGZ1bmN0aW9uIChcbi8vICAgICB0YXJnZXQ6IGFueSxcbi8vICAgICBwcm9wZXJ0eUtleTogc3RyaW5nLFxuLy8gICAgIGRlc2NyaXB0b3I6IFByb3BlcnR5RGVzY3JpcHRvcixcbi8vICAgKSB7XG4vLyAgICAgbWV0YWRhc3RhKGdldFRyYW5zYWN0aW9uYWxLZXkoVHJhbnNhY3Rpb25hbEtleXMuVFJBTlNBQ1RJT05BTCkpXG4vLyAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShcbi8vICAgICAgICxcbi8vICAgICAgIHtcbi8vICAgICAgICAgdHlwZTogXCJhc3luY1wiLFxuLy8gICAgICAgICBtZXRhZGF0YTogbWV0YWRhdGEubGVuZ3RoID8gbWV0YWRhdGEgOiB1bmRlZmluZWQsXG4vLyAgICAgICB9IGFzIFRyYW5zYWN0aW9uYWxNZXRhZGF0YSxcbi8vICAgICAgIHRhcmdldCxcbi8vICAgICAgIHByb3BlcnR5S2V5LFxuLy8gICAgICk7XG4vL1xuLy8gICAgIGNvbnN0IG9yaWdpbmFsTWV0aG9kID0gZGVzY3JpcHRvci52YWx1ZTtcbi8vXG4vLyAgICAgY29uc3QgbWV0aG9kV3JhcHBlciA9IGZ1bmN0aW9uICh0aGlzOiBhbnksIC4uLmFyZ3M6IGFueVtdKSB7XG4vLyAgICAgICBjb25zdCBjYWxsYmFjazogQ2FsbGJhY2sgPSBhcmdzLnBvcCgpO1xuLy8gICAgICAgaWYgKCFjYWxsYmFjayB8fCB0eXBlb2YgY2FsbGJhY2sgIT09IFwiZnVuY3Rpb25cIilcbi8vICAgICAgICAgdGhyb3cgbmV3IENyaXRpY2FsRXJyb3IoYE1pc3NpbmcgQ2FsbGJhY2tgKTtcbi8vXG4vLyAgICAgICBjb25zdCBjYiA9IChlcnI/OiBFcnIsIC4uLmFyZ3M6IGFueVtdKSA9PiB7XG4vLyAgICAgICAgIFRyYW5zYWN0aW9uLnJlbGVhc2UoZXJyKS50aGVuKChfKSA9PiBjYWxsYmFjayhlcnIsIC4uLmFyZ3MpKTtcbi8vICAgICAgIH07XG4vL1xuLy8gICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4vL1xuLy8gICAgICAgbGV0IHRyYW5zYWN0aW9uID0gYXJncy5zaGlmdCgpO1xuLy8gICAgICAgaWYgKHRyYW5zYWN0aW9uIGluc3RhbmNlb2YgVHJhbnNhY3Rpb24pIHtcbi8vICAgICAgICAgY29uc3QgdXBkYXRlZFRyYW5zYWN0aW9uOiBUcmFuc2FjdGlvbiA9IG5ldyBUcmFuc2FjdGlvbihcbi8vICAgICAgICAgICB0aGlzLmNvbnN0cnVjdG9yLm5hbWUsXG4vLyAgICAgICAgICAgcHJvcGVydHlLZXksXG4vLyAgICAgICAgICAgKCkgPT4ge1xuLy8gICAgICAgICAgICAgdHJ5IHtcbi8vICAgICAgICAgICAgICAgcmV0dXJuIG9yaWdpbmFsTWV0aG9kLmNhbGwoXG4vLyAgICAgICAgICAgICAgICAgdXBkYXRlZFRyYW5zYWN0aW9uLmJpbmRUb1RyYW5zYWN0aW9uKHNlbGYpLFxuLy8gICAgICAgICAgICAgICAgIC4uLmFyZ3MsXG4vLyAgICAgICAgICAgICAgICAgY2FsbGJhY2ssXG4vLyAgICAgICAgICAgICAgICk7XG4vLyAgICAgICAgICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbi8vICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGUpO1xuLy8gICAgICAgICAgICAgfVxuLy8gICAgICAgICAgIH0sXG4vLyAgICAgICAgICAgbWV0YWRhdGEubGVuZ3RoID8gbWV0YWRhdGEgOiB1bmRlZmluZWQsXG4vLyAgICAgICAgICk7XG4vL1xuLy8gICAgICAgICB0cmFuc2FjdGlvbi5iaW5kVHJhbnNhY3Rpb24odXBkYXRlZFRyYW5zYWN0aW9uKTtcbi8vICAgICAgICAgdHJhbnNhY3Rpb24uZmlyZSgpO1xuLy8gICAgICAgfSBlbHNlIHtcbi8vICAgICAgICAgYXJncy51bnNoaWZ0KHRyYW5zYWN0aW9uKTtcbi8vICAgICAgICAgdHJhbnNhY3Rpb24gPSB1bmRlZmluZWQ7XG4vLyAgICAgICAgIHRyYW5zYWN0aW9uID0gbmV3IFRyYW5zYWN0aW9uKFxuLy8gICAgICAgICAgIHRoaXMuY29uc3RydWN0b3IubmFtZSxcbi8vICAgICAgICAgICBwcm9wZXJ0eUtleSxcbi8vICAgICAgICAgICAoKSA9PiB7XG4vLyAgICAgICAgICAgICB0cnkge1xuLy8gICAgICAgICAgICAgICByZXR1cm4gb3JpZ2luYWxNZXRob2QuY2FsbChcbi8vICAgICAgICAgICAgICAgICB0cmFuc2FjdGlvbi5iaW5kVG9UcmFuc2FjdGlvbihzZWxmKSxcbi8vICAgICAgICAgICAgICAgICAuLi5hcmdzLFxuLy8gICAgICAgICAgICAgICAgIGNiLFxuLy8gICAgICAgICAgICAgICApO1xuLy8gICAgICAgICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4vLyAgICAgICAgICAgICAgIHJldHVybiBjYihlKTtcbi8vICAgICAgICAgICAgIH1cbi8vICAgICAgICAgICB9LFxuLy8gICAgICAgICAgIG1ldGFkYXRhLmxlbmd0aCA/IG1ldGFkYXRhIDogdW5kZWZpbmVkLFxuLy8gICAgICAgICApO1xuLy8gICAgICAgICBUcmFuc2FjdGlvbi5zdWJtaXQodHJhbnNhY3Rpb24pO1xuLy8gICAgICAgfVxuLy8gICAgIH07XG4vL1xuLy8gICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtZXRob2RXcmFwcGVyLCBcIm5hbWVcIiwge1xuLy8gICAgICAgdmFsdWU6IHByb3BlcnR5S2V5LFxuLy8gICAgIH0pO1xuLy8gICAgIGRlc2NyaXB0b3IudmFsdWUgPSBtZXRob2RXcmFwcGVyO1xuLy8gICB9O1xuLy8gfVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBVdGlsaXR5IGZvciBoYW5kbGluZyBzdXBlciBjYWxscyBpbiB0cmFuc2FjdGlvbmFsIG1ldGhvZHNcbiAqIEBzdW1tYXJ5IFdyYXBzIHN1cGVyIG1ldGhvZCBjYWxscyB3aXRoIHRoZSBjdXJyZW50IHRyYW5zYWN0aW9uIGNvbnRleHQgd2hlbiB0aGUgc3VwZXIncyBtZXRob2QgaXMgYWxzbyB0cmFuc2FjdGlvbmFsLCBlbnN1cmluZyB0cmFuc2FjdGlvbiBjb250aW51aXR5IHRocm91Z2ggdGhlIGluaGVyaXRhbmNlIGNoYWluXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBtZXRob2QgLSBUaGUgc3VwZXIgbWV0aG9kIChtdXN0IGJlIGJvdW5kIHRvIHRoZSBwcm9wZXIgdGhpcyksIGUuZy4sIHN1cGVyLmNyZWF0ZS5iaW5kKHRoaXMpXG4gKiBAcGFyYW0ge2FueVtdfSBhcmdzIC0gVGhlIGFyZ3VtZW50cyB0byBjYWxsIHRoZSBtZXRob2Qgd2l0aFxuICogQHJldHVybiB7YW55fSBUaGUgcmVzdWx0IG9mIHRoZSBzdXBlciBtZXRob2QgY2FsbFxuICogQGZ1bmN0aW9uIHRyYW5zYWN0aW9uYWxTdXBlckNhbGxcbiAqIEBtZW1iZXJPZiBtb2R1bGU6dHJhbnNhY3Rpb25zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2FjdGlvbmFsU3VwZXJDYWxsKG1ldGhvZDogYW55LCAuLi5hcmdzOiBhbnkpIHtcbiAgY29uc3QgbG9jayA9IFRyYW5zYWN0aW9uLmdldExvY2soKTtcbiAgY29uc3QgY3VycmVudFRyYW5zYWN0aW9uID0gbG9jay5jdXJyZW50VHJhbnNhY3Rpb247XG4gIHJldHVybiBtZXRob2QoY3VycmVudFRyYW5zYWN0aW9uLCAuLi5hcmdzKTtcbn1cbiIsImV4cG9ydCAqIGZyb20gXCIuL2ludGVyZmFjZXNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2xvY2tzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1RyYW5zYWN0aW9uXCI7XG5leHBvcnQgKiBmcm9tIFwiLi90eXBlc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBUcmFuc2FjdGlvbmFsIGRlY29yYXRvcnMgZm9yIFR5cGVTY3JpcHRcbiAqIEBzdW1tYXJ5IEEgY29tcHJlaGVuc2l2ZSBtb2R1bGUgcHJvdmlkaW5nIHRyYW5zYWN0aW9uIG1hbmFnZW1lbnQgY2FwYWJpbGl0aWVzIGZvciBUeXBlU2NyaXB0IGFwcGxpY2F0aW9ucy4gVGhpcyBtb2R1bGUgZXhwb3NlcyBkZWNvcmF0b3JzLCBsb2NrcywgYW5kIHV0aWxpdGllcyBmb3IgaW1wbGVtZW50aW5nIHRyYW5zYWN0aW9uYWwgYmVoYXZpb3IgaW4geW91ciBjb2RlLCBhbGxvd2luZyBmb3IgYXRvbWljIG9wZXJhdGlvbnMsIGNvbmN1cnJlbmN5IGNvbnRyb2wsIGFuZCBlcnJvciBoYW5kbGluZy5cbiAqIEBtb2R1bGUgdHJhbnNhY3Rpb25zXG4gKi9cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUGFja2FnZSB2ZXJzaW9uIGlkZW50aWZpZXJcbiAqIEBzdW1tYXJ5IFN0b3JlcyB0aGUgY3VycmVudCBwYWNrYWdlIHZlcnNpb24gc3RyaW5nLCB1c2VkIGZvciB2ZXJzaW9uIHRyYWNraW5nIGFuZCBjb21wYXRpYmlsaXR5IGNoZWNrc1xuICogQGNvbnN0IFZFUlNJT05cbiAqIEBtZW1iZXJPZiBtb2R1bGU6dHJhbnNhY3Rpb25zXG4gKi9cbmV4cG9ydCBjb25zdCBWRVJTSU9OID0gXCIjI1ZFUlNJT04jI1wiO1xuIl0sIm5hbWVzIjpbImdldEFsbFByb3BlcnR5RGVjb3JhdG9yc1JlY3Vyc2l2ZSIsIlJlZmxlY3Rpb24iLCJEQktleXMiLCJJbnRlcm5hbEVycm9yIiwibWV0YWRhdGEiXSwibWFwcGluZ3MiOiI7Ozs7OztJQUVBOzs7Ozs7Ozs7OztJQVdHO1VBQ1UsSUFBSSxDQUFBO0lBQWpCLElBQUEsV0FBQSxHQUFBO1lBQ1UsSUFBSyxDQUFBLEtBQUEsR0FBbUIsRUFBRTtZQUMxQixJQUFNLENBQUEsTUFBQSxHQUFHLEtBQUs7O0lBRXRCOzs7OztJQUtHO1FBQ0gsTUFBTSxPQUFPLENBQUMsSUFBZSxFQUFBO0lBQzNCLFFBQUEsTUFBTSxJQUFJLENBQUMsT0FBTyxFQUFFO0lBQ3BCLFFBQUEsSUFBSSxNQUFXO0lBQ2YsUUFBQSxJQUFJO2dCQUNGLE1BQU0sR0FBRyxN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
1
+ var t,e;t=this,e=function(t,e,n){"use strict";class o{constructor(){this.queue=[],this.locked=!1}async execute(t){let e;await this.acquire();try{e=await Promise.resolve(t())}catch(t){throw this.release(),t}return this.release(),e}async acquire(){const t=this;return t.locked?new Promise(e=>t.queue.push(e)):(t.locked=!0,Promise.resolve())}release(){const t=this.queue.shift();t?void 0===globalThis.window?globalThis.process.nextTick(t):setTimeout(t,0):this.locked=!1}}class i{constructor(t=1,e,n){this.currentTransaction=void 0,this.lock=new o,this.counter=t,this.pendingTransactions=[],this.onBegin=e,this.onEnd=n}submit(t){const e=this;e.lock.acquire().then(()=>e.currentTransaction&&e.currentTransaction.id===t.id?(e.lock.release(),t.fire()):e.counter>0?(e.counter--,e.lock.release(),e.fireTransaction(t)):(e.pendingTransactions.push(t),void e.lock.release()))}fireTransaction(t){const e=this;e.lock.acquire().then(()=>{e.currentTransaction=t,e.lock.release(),e.onBegin?e.onBegin().then(()=>{t.fire()}):t.fire()})}async release(t){const e=this;return new Promise(n=>{e.lock.acquire().then(()=>{e.currentTransaction,e.currentTransaction=void 0,e.lock.release();const o=()=>{e.lock.acquire().then(()=>{if(e.pendingTransactions.length>0){const t=e.pendingTransactions.shift(),n=()=>e.fireTransaction(t);void 0===globalThis.window?globalThis.process.nextTick(n):setTimeout(n,0)}else e.counter++;e.lock.release(),n()})};e.onEnd?e.onEnd(t).then(()=>o()):o()})})}}const s={REFLECT:"model.transactional.",TRANSACTIONAL:"transactional"};function r(t){if(t)return"string"==typeof t?t:t.constructor&&t.constructor.name&&-1===["Function","Object"].indexOf(t.constructor.name)?t.constructor.name:"function"==typeof t&&t.name?t.name:t.toString()}class c{constructor(t,e,n,o){this.id=Date.now(),this.action=n,this.method=e,this.log=[[this.id,t,e].join(" | ")],this.source=t,this.metadata=o}static push(t,e,...n){const o=n.pop();if(!o||"function"!=typeof o)throw Error("Missing callback");const i=(t,...e)=>{c.getLock().release(t).then(()=>o(t,...e))},s=new c(t.constructor.name,e.name?r(e):"Anonymous",()=>e.call(s.bindToTransaction(t),...n,i));c.getLock().submit(s)}static setLock(t){this.lock=t}static getLock(){return this.lock||(this.lock=new i),this.lock}static submit(t){c.getLock().submit(t)}static async release(t){return c.getLock().release(t)}getMetadata(){return this.metadata?[...this.metadata]:void 0}bindTransaction(t){this.log.push(...t.log),t.bindTransaction=this.bindToTransaction.bind(this),t.bindToTransaction=this.bindToTransaction.bind(this),this.action=t.action}bindToTransaction(t){const o=n.getAllPropertyDecoratorsRecursive(t,void 0,s.REFLECT);if(!o)return t;const i=this,c=e.Reflection.getAllProperties(t).reduce((n,r)=>(-1!==Object.keys(o).indexOf(r)&&o[r].find(t=>t.key===s.TRANSACTIONAL)?n[r]=(...e)=>t[r].call(t.__originalObj||t,i,...e):"clazz"===r||"constructor"===r?n[r]=t[r]:"function"==typeof t[r]?n[r]=t[r].bind(t.__originalObj||t):"object"==typeof t[r]&&t[r].constructor&&e.Reflection.getClassDecorators(s.REFLECT,t[r]).find(t=>t.key===s.TRANSACTIONAL)?n[r]=i.bindToTransaction(t[r]):n[r]=t[r],n),{});return c[n.DBKeys.ORIGINAL]=t[n.DBKeys.ORIGINAL]||t,c.toString=()=>r(c[n.DBKeys.ORIGINAL])+" proxy for transaction "+this.id,c}fire(){if(!this.action)throw Error("Missing the method");return this.action()}toString(t=!0,e=!1){return`${t?`[${this.id}]`:""}[Transaction][${this.source}.${this.method}${e?"]\nTransaction Log:\n"+this.log.join("\n"):"]"}`}static key(t){return s.REFLECT+t}}t.Lock=o,t.SyncronousLock=i,t.Transaction=c,t.TransactionalKeys=s,t.VERSION="##VERSION##",t.transactional=function(...t){return function(o,i,r){if(!r)throw new n.InternalError("Missing descriptor. Should be impossible");e.metadata(c.key(s.TRANSACTIONAL),t)(o,i);const a=r.value,l=function(...e){const n=this;return new Promise((o,s)=>{const r=(t,e)=>{c.release(t).then(()=>{if(t)return s(t);o(e)})};let l=e.shift();if(l instanceof c){const r=new c(this.constructor.name,i,async()=>{a.call(r.bindToTransaction(n),...e).then(o).catch(s)},t.length?t:void 0);l.bindTransaction(r),l.fire()}else e.unshift(l),l=new c(this.constructor.name,i,()=>{a.call(l.bindToTransaction(n),...e).then(t=>r(void 0,t)).catch(r)},t.length?t:void 0),c.submit(l)})};Object.defineProperty(l,"name",{value:i}),r.value=l}},t.transactionalSuperCall=(t,...e)=>t(c.getLock().currentTransaction,...e)},"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@decaf-ts/reflection"),require("@decaf-ts/db-decorators")):"function"==typeof define&&define.amd?define(["exports","@decaf-ts/reflection","@decaf-ts/db-decorators"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self)["transactional-decorators"]={},t.decafTsReflection,t.decafTsDbDecorators);
2
+ //# sourceMappingURL=transactional-decorators.cjs.map