@decaf-ts/core 0.5.1 → 0.5.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.
- package/LICENSE.md +21 -157
- package/README.md +652 -15
- package/dist/core.cjs +2110 -132
- package/dist/core.esm.cjs +2111 -133
- package/lib/esm/identity/decorators.d.ts +52 -7
- package/lib/esm/identity/decorators.js +53 -8
- package/lib/esm/identity/utils.d.ts +19 -0
- package/lib/esm/identity/utils.js +20 -1
- package/lib/esm/index.d.ts +9 -2
- package/lib/esm/index.js +10 -3
- package/lib/esm/interfaces/ErrorParser.d.ts +12 -0
- package/lib/esm/interfaces/ErrorParser.js +1 -1
- package/lib/esm/interfaces/Executor.d.ts +13 -0
- package/lib/esm/interfaces/Executor.js +1 -1
- package/lib/esm/interfaces/Observable.d.ts +27 -0
- package/lib/esm/interfaces/Observable.js +1 -1
- package/lib/esm/interfaces/Observer.d.ts +12 -0
- package/lib/esm/interfaces/Observer.js +1 -1
- package/lib/esm/interfaces/Paginatable.d.ts +15 -0
- package/lib/esm/interfaces/Paginatable.js +1 -1
- package/lib/esm/interfaces/Queriable.d.ts +34 -9
- package/lib/esm/interfaces/Queriable.js +1 -1
- package/lib/esm/interfaces/RawExecutor.d.ts +14 -0
- package/lib/esm/interfaces/RawExecutor.js +1 -1
- package/lib/esm/interfaces/SequenceOptions.d.ts +52 -0
- package/lib/esm/interfaces/SequenceOptions.js +19 -1
- package/lib/esm/model/BaseModel.d.ts +31 -0
- package/lib/esm/model/BaseModel.js +24 -1
- package/lib/esm/model/construction.d.ts +433 -0
- package/lib/esm/model/construction.js +441 -2
- package/lib/esm/model/decorators.d.ts +159 -29
- package/lib/esm/model/decorators.js +160 -30
- package/lib/esm/model/types.d.ts +9 -0
- package/lib/esm/model/types.js +1 -1
- package/lib/esm/persistence/Adapter.d.ts +358 -17
- package/lib/esm/persistence/Adapter.js +287 -19
- package/lib/esm/persistence/Dispatch.d.ts +114 -1
- package/lib/esm/persistence/Dispatch.js +102 -4
- package/lib/esm/persistence/ObserverHandler.d.ts +95 -0
- package/lib/esm/persistence/ObserverHandler.js +96 -1
- package/lib/esm/persistence/Sequence.d.ts +89 -0
- package/lib/esm/persistence/Sequence.js +70 -1
- package/lib/esm/persistence/constants.d.ts +22 -0
- package/lib/esm/persistence/constants.js +23 -1
- package/lib/esm/persistence/decorators.d.ts +10 -0
- package/lib/esm/persistence/decorators.js +11 -1
- package/lib/esm/persistence/errors.d.ts +23 -0
- package/lib/esm/persistence/errors.js +24 -1
- package/lib/esm/persistence/types.d.ts +18 -0
- package/lib/esm/persistence/types.js +1 -1
- package/lib/esm/query/Condition.d.ts +78 -31
- package/lib/esm/query/Condition.js +132 -53
- package/lib/esm/query/Paginator.d.ts +56 -0
- package/lib/esm/query/Paginator.js +57 -1
- package/lib/esm/query/Statement.d.ts +51 -0
- package/lib/esm/query/Statement.js +52 -1
- package/lib/esm/query/constants.d.ts +25 -0
- package/lib/esm/query/constants.js +26 -1
- package/lib/esm/query/errors.d.ts +14 -0
- package/lib/esm/query/errors.js +15 -1
- package/lib/esm/query/options.d.ts +21 -3
- package/lib/esm/query/options.js +1 -1
- package/lib/esm/query/selectors.d.ts +26 -0
- package/lib/esm/query/selectors.js +1 -1
- package/lib/esm/ram/RamAdapter.d.ts +311 -0
- package/lib/esm/ram/RamAdapter.js +312 -1
- package/lib/esm/ram/RamContext.d.ts +16 -1
- package/lib/esm/ram/RamContext.js +18 -3
- package/lib/esm/ram/RamPaginator.d.ts +43 -0
- package/lib/esm/ram/RamPaginator.js +54 -2
- package/lib/esm/ram/RamSequence.d.ts +61 -0
- package/lib/esm/ram/RamSequence.js +63 -2
- package/lib/esm/ram/RamStatement.d.ts +74 -0
- package/lib/esm/ram/RamStatement.js +75 -1
- package/lib/esm/ram/constants.d.ts +8 -0
- package/lib/esm/ram/constants.js +9 -1
- package/lib/esm/ram/handlers.d.ts +19 -0
- package/lib/esm/ram/handlers.js +20 -1
- package/lib/esm/ram/model/RamSequence.d.ts +25 -0
- package/lib/esm/ram/model/RamSequence.js +19 -1
- package/lib/esm/ram/types.d.ts +42 -0
- package/lib/esm/ram/types.js +1 -1
- package/lib/esm/repository/Repository.d.ts +363 -8
- package/lib/esm/repository/Repository.js +361 -16
- package/lib/esm/repository/constants.d.ts +25 -0
- package/lib/esm/repository/constants.js +26 -1
- package/lib/esm/repository/decorators.d.ts +27 -0
- package/lib/esm/repository/decorators.js +28 -1
- package/lib/esm/repository/errors.d.ts +12 -5
- package/lib/esm/repository/errors.js +13 -6
- package/lib/esm/repository/injectables.d.ts +18 -0
- package/lib/esm/repository/injectables.js +19 -1
- package/lib/esm/repository/types.d.ts +15 -0
- package/lib/esm/repository/types.js +1 -1
- package/lib/esm/repository/utils.d.ts +11 -0
- package/lib/esm/repository/utils.js +12 -1
- package/lib/esm/utils/decorators.d.ts +8 -0
- package/lib/esm/utils/decorators.js +9 -1
- package/lib/esm/utils/errors.d.ts +46 -0
- package/lib/esm/utils/errors.js +47 -1
- package/lib/identity/decorators.cjs +53 -8
- package/lib/identity/decorators.d.ts +52 -7
- package/lib/identity/utils.cjs +20 -1
- package/lib/identity/utils.d.ts +19 -0
- package/lib/index.cjs +10 -3
- package/lib/index.d.ts +9 -2
- package/lib/interfaces/ErrorParser.cjs +1 -1
- package/lib/interfaces/ErrorParser.d.ts +12 -0
- package/lib/interfaces/Executor.cjs +1 -1
- package/lib/interfaces/Executor.d.ts +13 -0
- package/lib/interfaces/Observable.cjs +1 -1
- package/lib/interfaces/Observable.d.ts +27 -0
- package/lib/interfaces/Observer.cjs +1 -1
- package/lib/interfaces/Observer.d.ts +12 -0
- package/lib/interfaces/Paginatable.cjs +1 -1
- package/lib/interfaces/Paginatable.d.ts +15 -0
- package/lib/interfaces/Queriable.cjs +1 -1
- package/lib/interfaces/Queriable.d.ts +34 -9
- package/lib/interfaces/RawExecutor.cjs +1 -1
- package/lib/interfaces/RawExecutor.d.ts +14 -0
- package/lib/interfaces/SequenceOptions.cjs +19 -1
- package/lib/interfaces/SequenceOptions.d.ts +52 -0
- package/lib/model/BaseModel.cjs +24 -1
- package/lib/model/BaseModel.d.ts +31 -0
- package/lib/model/construction.cjs +441 -2
- package/lib/model/construction.d.ts +433 -0
- package/lib/model/decorators.cjs +160 -30
- package/lib/model/decorators.d.ts +159 -29
- package/lib/model/types.cjs +1 -1
- package/lib/model/types.d.ts +9 -0
- package/lib/persistence/Adapter.cjs +287 -19
- package/lib/persistence/Adapter.d.ts +358 -17
- package/lib/persistence/Dispatch.cjs +102 -4
- package/lib/persistence/Dispatch.d.ts +114 -1
- package/lib/persistence/ObserverHandler.cjs +96 -1
- package/lib/persistence/ObserverHandler.d.ts +95 -0
- package/lib/persistence/Sequence.cjs +70 -1
- package/lib/persistence/Sequence.d.ts +89 -0
- package/lib/persistence/constants.cjs +23 -1
- package/lib/persistence/constants.d.ts +22 -0
- package/lib/persistence/decorators.cjs +11 -1
- package/lib/persistence/decorators.d.ts +10 -0
- package/lib/persistence/errors.cjs +24 -1
- package/lib/persistence/errors.d.ts +23 -0
- package/lib/persistence/types.cjs +1 -1
- package/lib/persistence/types.d.ts +18 -0
- package/lib/query/Condition.cjs +132 -53
- package/lib/query/Condition.d.ts +78 -31
- package/lib/query/Paginator.cjs +57 -1
- package/lib/query/Paginator.d.ts +56 -0
- package/lib/query/Statement.cjs +52 -1
- package/lib/query/Statement.d.ts +51 -0
- package/lib/query/constants.cjs +26 -1
- package/lib/query/constants.d.ts +25 -0
- package/lib/query/errors.cjs +15 -1
- package/lib/query/errors.d.ts +14 -0
- package/lib/query/options.cjs +1 -1
- package/lib/query/options.d.ts +21 -3
- package/lib/query/selectors.cjs +1 -1
- package/lib/query/selectors.d.ts +26 -0
- package/lib/ram/RamAdapter.cjs +312 -1
- package/lib/ram/RamAdapter.d.ts +311 -0
- package/lib/ram/RamContext.cjs +18 -3
- package/lib/ram/RamContext.d.ts +16 -1
- package/lib/ram/RamPaginator.cjs +54 -2
- package/lib/ram/RamPaginator.d.ts +43 -0
- package/lib/ram/RamSequence.cjs +63 -2
- package/lib/ram/RamSequence.d.ts +61 -0
- package/lib/ram/RamStatement.cjs +75 -1
- package/lib/ram/RamStatement.d.ts +74 -0
- package/lib/ram/constants.cjs +9 -1
- package/lib/ram/constants.d.ts +8 -0
- package/lib/ram/handlers.cjs +20 -1
- package/lib/ram/handlers.d.ts +19 -0
- package/lib/ram/model/RamSequence.cjs +19 -1
- package/lib/ram/model/RamSequence.d.ts +25 -0
- package/lib/ram/types.cjs +1 -1
- package/lib/ram/types.d.ts +42 -0
- package/lib/repository/Repository.cjs +360 -15
- package/lib/repository/Repository.d.ts +363 -8
- package/lib/repository/constants.cjs +26 -1
- package/lib/repository/constants.d.ts +25 -0
- package/lib/repository/decorators.cjs +28 -1
- package/lib/repository/decorators.d.ts +27 -0
- package/lib/repository/errors.cjs +13 -6
- package/lib/repository/errors.d.ts +12 -5
- package/lib/repository/injectables.cjs +19 -1
- package/lib/repository/injectables.d.ts +18 -0
- package/lib/repository/types.cjs +1 -1
- package/lib/repository/types.d.ts +15 -0
- package/lib/repository/utils.cjs +12 -1
- package/lib/repository/utils.d.ts +11 -0
- package/lib/utils/decorators.cjs +9 -1
- package/lib/utils/decorators.d.ts +8 -0
- package/lib/utils/errors.cjs +47 -1
- package/lib/utils/errors.d.ts +46 -0
- package/package.json +5 -5
@@ -4,15 +4,128 @@ import { Observable, Observer } from "../interfaces";
|
|
4
4
|
import { Adapter } from "./Adapter";
|
5
5
|
import { Logger } from "@decaf-ts/logging";
|
6
6
|
import { EventIds } from "./types";
|
7
|
+
/**
|
8
|
+
* @description Dispatches database operation events to observers
|
9
|
+
* @summary The Dispatch class implements the Observable interface and is responsible for intercepting
|
10
|
+
* database operations from an Adapter and notifying observers when changes occur. It uses proxies to
|
11
|
+
* wrap the adapter's CRUD methods and automatically trigger observer updates after operations complete.
|
12
|
+
* @template Y - The native database driver type
|
13
|
+
* @param {void} - No constructor parameters
|
14
|
+
* @class Dispatch
|
15
|
+
* @example
|
16
|
+
* ```typescript
|
17
|
+
* // Creating and using a Dispatch instance
|
18
|
+
* const dispatch = new Dispatch<PostgresDriver>();
|
19
|
+
*
|
20
|
+
* // Connect it to an adapter
|
21
|
+
* const adapter = new PostgresAdapter(connection);
|
22
|
+
* dispatch.observe(adapter);
|
23
|
+
*
|
24
|
+
* // Now any CRUD operations on the adapter will automatically
|
25
|
+
* // trigger observer notifications
|
26
|
+
* await adapter.create('users', 123, userModel);
|
27
|
+
* // Observers will be notified about the creation
|
28
|
+
*
|
29
|
+
* // When done, you can disconnect
|
30
|
+
* dispatch.unObserve(adapter);
|
31
|
+
* ```
|
32
|
+
*/
|
7
33
|
export declare class Dispatch<Y> implements Observable {
|
34
|
+
/**
|
35
|
+
* @description The adapter being observed
|
36
|
+
* @summary Reference to the database adapter whose operations are being monitored
|
37
|
+
*/
|
8
38
|
protected adapter?: Adapter<Y, any, any, any>;
|
39
|
+
/**
|
40
|
+
* @description The native database driver
|
41
|
+
* @summary Reference to the underlying database driver from the adapter
|
42
|
+
*/
|
9
43
|
protected native?: Y;
|
44
|
+
/**
|
45
|
+
* @description List of model constructors
|
46
|
+
* @summary Array of model constructors that are registered with the adapter
|
47
|
+
*/
|
10
48
|
protected models: ModelConstructor<any>[];
|
49
|
+
/**
|
50
|
+
* @description Logger instance
|
51
|
+
* @summary Logger for recording dispatch activities
|
52
|
+
*/
|
11
53
|
private logger;
|
54
|
+
/**
|
55
|
+
* @description Accessor for the logger
|
56
|
+
* @summary Gets or initializes the logger for this dispatch instance
|
57
|
+
* @return {Logger} The logger instance
|
58
|
+
*/
|
12
59
|
protected get log(): Logger;
|
60
|
+
/**
|
61
|
+
* @description Creates a new Dispatch instance
|
62
|
+
* @summary Initializes a new Dispatch instance without any adapter
|
63
|
+
*/
|
13
64
|
constructor();
|
14
|
-
|
65
|
+
/**
|
66
|
+
* @description Initializes the dispatch by proxying adapter methods
|
67
|
+
* @summary Sets up proxies on the adapter's CRUD methods to intercept operations and notify observers.
|
68
|
+
* This method is called automatically when an adapter is observed.
|
69
|
+
* @return {Promise<void>} A promise that resolves when initialization is complete
|
70
|
+
* @mermaid
|
71
|
+
* sequenceDiagram
|
72
|
+
* participant Dispatch
|
73
|
+
* participant Adapter
|
74
|
+
* participant Proxy
|
75
|
+
*
|
76
|
+
* Dispatch->>Dispatch: initialize()
|
77
|
+
* Dispatch->>Dispatch: Check if adapter exists
|
78
|
+
* alt No adapter
|
79
|
+
* Dispatch-->>Dispatch: Throw InternalError
|
80
|
+
* end
|
81
|
+
*
|
82
|
+
* loop For each CRUD method
|
83
|
+
* Dispatch->>Adapter: Check if method exists
|
84
|
+
* alt Method doesn't exist
|
85
|
+
* Dispatch-->>Dispatch: Throw InternalError
|
86
|
+
* end
|
87
|
+
*
|
88
|
+
* Dispatch->>Adapter: Get property descriptor
|
89
|
+
* loop While descriptor not found
|
90
|
+
* Dispatch->>Adapter: Check prototype chain
|
91
|
+
* end
|
92
|
+
*
|
93
|
+
* alt Descriptor not found or not writable
|
94
|
+
* Dispatch->>Dispatch: Log error and continue
|
95
|
+
* else Descriptor found and writable
|
96
|
+
* Dispatch->>Proxy: Create proxy for method
|
97
|
+
* Dispatch->>Adapter: Replace method with proxy
|
98
|
+
* end
|
99
|
+
* end
|
100
|
+
*/
|
101
|
+
protected initialize(): Promise<void>;
|
102
|
+
/**
|
103
|
+
* @description Closes the dispatch
|
104
|
+
* @summary Performs any necessary cleanup when the dispatch is no longer needed
|
105
|
+
* @return {Promise<void>} A promise that resolves when closing is complete
|
106
|
+
*/
|
107
|
+
close(): Promise<void>;
|
108
|
+
/**
|
109
|
+
* @description Starts observing an adapter
|
110
|
+
* @summary Connects this dispatch to an adapter to monitor its operations
|
111
|
+
* @param {Adapter<Y, any, any, any>} observer - The adapter to observe
|
112
|
+
* @return {void}
|
113
|
+
*/
|
15
114
|
observe(observer: Adapter<Y, any, any, any>): void;
|
115
|
+
/**
|
116
|
+
* @description Stops observing an adapter
|
117
|
+
* @summary Disconnects this dispatch from an adapter
|
118
|
+
* @param {Observer} observer - The adapter to stop observing
|
119
|
+
* @return {void}
|
120
|
+
*/
|
16
121
|
unObserve(observer: Observer): void;
|
122
|
+
/**
|
123
|
+
* @description Updates observers about a database event
|
124
|
+
* @summary Notifies observers about a change in the database
|
125
|
+
* @param {string} table - The name of the table where the change occurred
|
126
|
+
* @param {OperationKeys|BulkCrudOperationKeys|string} event - The type of operation that occurred
|
127
|
+
* @param {EventIds} id - The identifier(s) of the affected record(s)
|
128
|
+
* @return {Promise<void>} A promise that resolves when all observers have been notified
|
129
|
+
*/
|
17
130
|
updateObservers(table: string, event: OperationKeys | BulkCrudOperationKeys | string, id: EventIds): Promise<void>;
|
18
131
|
}
|
@@ -2,25 +2,120 @@
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.ObserverHandler = void 0;
|
4
4
|
const db_decorators_1 = require("@decaf-ts/db-decorators");
|
5
|
+
/**
|
6
|
+
* @description Manages a collection of observers for database events
|
7
|
+
* @summary The ObserverHandler class implements the Observable interface and provides a centralized
|
8
|
+
* way to manage multiple observers. It allows registering observers with optional filters to control
|
9
|
+
* which events they receive notifications for, and handles the process of notifying all relevant
|
10
|
+
* observers when database events occur.
|
11
|
+
* @class ObserverHandler
|
12
|
+
* @example
|
13
|
+
* ```typescript
|
14
|
+
* // Create an observer handler
|
15
|
+
* const handler = new ObserverHandler();
|
16
|
+
*
|
17
|
+
* // Register an observer
|
18
|
+
* const myObserver = {
|
19
|
+
* refresh: async (table, event, id) => {
|
20
|
+
* console.log(`Change in ${table}: ${event} for ID ${id}`);
|
21
|
+
* }
|
22
|
+
* };
|
23
|
+
*
|
24
|
+
* // Add observer with a filter for only user table events
|
25
|
+
* handler.observe(myObserver, (table, event, id) => table === 'users');
|
26
|
+
*
|
27
|
+
* // Notify observers about an event
|
28
|
+
* await handler.updateObservers(logger, 'users', 'CREATE', 123);
|
29
|
+
*
|
30
|
+
* // Remove an observer when no longer needed
|
31
|
+
* handler.unObserve(myObserver);
|
32
|
+
* ```
|
33
|
+
*/
|
5
34
|
class ObserverHandler {
|
6
35
|
constructor() {
|
36
|
+
/**
|
37
|
+
* @description Collection of registered observers
|
38
|
+
* @summary Array of observer objects along with their optional filters
|
39
|
+
*/
|
7
40
|
this.observers = [];
|
8
41
|
}
|
42
|
+
/**
|
43
|
+
* @description Gets the number of registered observers
|
44
|
+
* @summary Returns the count of observers currently registered with this handler
|
45
|
+
* @return {number} The number of registered observers
|
46
|
+
*/
|
9
47
|
count() {
|
10
48
|
return this.observers.length;
|
11
49
|
}
|
50
|
+
/**
|
51
|
+
* @description Registers a new observer
|
52
|
+
* @summary Adds an observer to the collection with an optional filter function
|
53
|
+
* @param {Observer} observer - The observer to register
|
54
|
+
* @param {ObserverFilter} [filter] - Optional filter function to determine which events the observer receives
|
55
|
+
* @return {void}
|
56
|
+
*/
|
12
57
|
observe(observer, filter) {
|
13
58
|
const index = this.observers.map((o) => o.observer).indexOf(observer);
|
14
59
|
if (index !== -1)
|
15
60
|
throw new db_decorators_1.InternalError("Observer already registered");
|
16
61
|
this.observers.push({ observer: observer, filter: filter });
|
17
62
|
}
|
63
|
+
/**
|
64
|
+
* @description Unregisters an observer
|
65
|
+
* @summary Removes an observer from the collection
|
66
|
+
* @param {Observer} observer - The observer to unregister
|
67
|
+
* @return {void}
|
68
|
+
*/
|
18
69
|
unObserve(observer) {
|
19
70
|
const index = this.observers.map((o) => o.observer).indexOf(observer);
|
20
71
|
if (index === -1)
|
21
72
|
throw new db_decorators_1.InternalError("Failed to find Observer");
|
22
73
|
this.observers.splice(index, 1);
|
23
74
|
}
|
75
|
+
/**
|
76
|
+
* @description Notifies all relevant observers about a database event
|
77
|
+
* @summary Filters observers based on their filter functions and calls refresh on each matching observer
|
78
|
+
* @param {Logger} log - Logger for recording notification activities
|
79
|
+
* @param {string} table - The name of the table where the event occurred
|
80
|
+
* @param {OperationKeys|BulkCrudOperationKeys|string} event - The type of operation that occurred
|
81
|
+
* @param {EventIds} id - The identifier(s) of the affected record(s)
|
82
|
+
* @param {...any[]} args - Additional arguments to pass to the observers
|
83
|
+
* @return {Promise<void>} A promise that resolves when all observers have been notified
|
84
|
+
* @mermaid
|
85
|
+
* sequenceDiagram
|
86
|
+
* participant Client
|
87
|
+
* participant ObserverHandler
|
88
|
+
* participant Observer
|
89
|
+
*
|
90
|
+
* Client->>ObserverHandler: updateObservers(log, table, event, id, ...args)
|
91
|
+
*
|
92
|
+
* ObserverHandler->>ObserverHandler: Filter observers
|
93
|
+
*
|
94
|
+
* loop For each observer with matching filter
|
95
|
+
* alt Observer has filter
|
96
|
+
* ObserverHandler->>Observer: Apply filter(table, event, id)
|
97
|
+
* alt Filter throws error
|
98
|
+
* ObserverHandler->>Logger: Log error
|
99
|
+
* ObserverHandler-->>ObserverHandler: Skip observer
|
100
|
+
* else Filter returns true
|
101
|
+
* ObserverHandler->>Observer: refresh(table, event, id, ...args)
|
102
|
+
* else Filter returns false
|
103
|
+
* ObserverHandler-->>ObserverHandler: Skip observer
|
104
|
+
* end
|
105
|
+
* else No filter
|
106
|
+
* ObserverHandler->>Observer: refresh(table, event, id, ...args)
|
107
|
+
* end
|
108
|
+
* end
|
109
|
+
*
|
110
|
+
* ObserverHandler->>ObserverHandler: Process results
|
111
|
+
* loop For each result
|
112
|
+
* alt Result is rejected
|
113
|
+
* ObserverHandler->>Logger: Log error
|
114
|
+
* end
|
115
|
+
* end
|
116
|
+
*
|
117
|
+
* ObserverHandler-->>Client: Return
|
118
|
+
*/
|
24
119
|
async updateObservers(log, table, event, id, ...args) {
|
25
120
|
const results = await Promise.allSettled(this.observers
|
26
121
|
.filter((o) => {
|
@@ -43,4 +138,4 @@ class ObserverHandler {
|
|
43
138
|
}
|
44
139
|
}
|
45
140
|
exports.ObserverHandler = ObserverHandler;
|
46
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiT2JzZXJ2ZXJIYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3BlcnNpc3RlbmNlL09ic2VydmVySGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSwyREFJaUM7QUFHakMsTUFBYSxlQUFlO0lBQTVCO1FBQ3FCLGNBQVMsR0FHdEIsRUFBRSxDQUFDO0lBZ0RYLENBQUM7SUE5Q0MsS0FBSztRQUNILE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUM7SUFDL0IsQ0FBQztJQUVELE9BQU8sQ0FBQyxRQUFrQixFQUFFLE1BQXVCO1FBQ2pELE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3RFLElBQUksS0FBSyxLQUFLLENBQUMsQ0FBQztZQUFFLE1BQU0sSUFBSSw2QkFBYSxDQUFDLDZCQUE2QixDQUFDLENBQUM7UUFDekUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQzlELENBQUM7SUFFRCxTQUFTLENBQUMsUUFBa0I7UUFDMUIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDdEUsSUFBSSxLQUFLLEtBQUssQ0FBQyxDQUFDO1lBQUUsTUFBTSxJQUFJLDZCQUFhLENBQUMseUJBQXlCLENBQUMsQ0FBQztRQUNyRSxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDbEMsQ0FBQztJQUVELEtBQUssQ0FBQyxlQUFlLENBQ25CLEdBQVcsRUFDWCxLQUFhLEVBQ2IsS0FBcUQsRUFDckQsRUFBWSxFQUNaLEdBQUcsSUFBVztRQUVkLE1BQU0sT0FBTyxHQUFHLE1BQU0sT0FBTyxDQUFDLFVBQVUsQ0FDdEMsSUFBSSxDQUFDLFNBQVM7YUFDWCxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtZQUNaLE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDckIsSUFBSSxDQUFDLE1BQU07Z0JBQUUsT0FBTyxJQUFJLENBQUM7WUFDekIsSUFBSSxDQUFDO2dCQUNILE9BQU8sTUFBTSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDbEMsQ0FBQztZQUFDLE9BQU8sQ0FBVSxFQUFFLENBQUM7Z0JBQ3BCLEdBQUcsQ0FBQyxLQUFLLENBQ1AsNkJBQTZCLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQzNELENBQUM7Z0JBQ0YsT0FBTyxLQUFLLENBQUM7WUFDZixDQUFDO1FBQ0gsQ0FBQyxDQUFDO2FBQ0QsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQzdELENBQUM7UUFDRixPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQzVCLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxVQUFVO2dCQUM5QixHQUFHLENBQUMsS0FBSyxDQUNQLCtCQUErQixJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxLQUFLLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FDaEYsQ0FBQztRQUNOLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGO0FBcERELDBDQW9EQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE9ic2VydmFibGUsIE9ic2VydmVyIH0gZnJvbSBcIi4uL2ludGVyZmFjZXNcIjtcbmltcG9ydCB7IEV2ZW50SWRzLCBPYnNlcnZlckZpbHRlciB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQge1xuICBCdWxrQ3J1ZE9wZXJhdGlvbktleXMsXG4gIEludGVybmFsRXJyb3IsXG4gIE9wZXJhdGlvbktleXMsXG59IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5cbmV4cG9ydCBjbGFzcyBPYnNlcnZlckhhbmRsZXIgaW1wbGVtZW50cyBPYnNlcnZhYmxlIHtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IG9ic2VydmVyczoge1xuICAgIG9ic2VydmVyOiBPYnNlcnZlcjtcbiAgICBmaWx0ZXI/OiBPYnNlcnZlckZpbHRlcjtcbiAgfVtdID0gW107XG5cbiAgY291bnQoKSB7XG4gICAgcmV0dXJuIHRoaXMub2JzZXJ2ZXJzLmxlbmd0aDtcbiAgfVxuXG4gIG9ic2VydmUob2JzZXJ2ZXI6IE9ic2VydmVyLCBmaWx0ZXI/OiBPYnNlcnZlckZpbHRlcik6IHZvaWQge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5vYnNlcnZlcnMubWFwKChvKSA9PiBvLm9ic2VydmVyKS5pbmRleE9mKG9ic2VydmVyKTtcbiAgICBpZiAoaW5kZXggIT09IC0xKSB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIk9ic2VydmVyIGFscmVhZHkgcmVnaXN0ZXJlZFwiKTtcbiAgICB0aGlzLm9ic2VydmVycy5wdXNoKHsgb2JzZXJ2ZXI6IG9ic2VydmVyLCBmaWx0ZXI6IGZpbHRlciB9KTtcbiAgfVxuXG4gIHVuT2JzZXJ2ZShvYnNlcnZlcjogT2JzZXJ2ZXIpOiB2b2lkIHtcbiAgICBjb25zdCBpbmRleCA9IHRoaXMub2JzZXJ2ZXJzLm1hcCgobykgPT4gby5vYnNlcnZlcikuaW5kZXhPZihvYnNlcnZlcik7XG4gICAgaWYgKGluZGV4ID09PSAtMSkgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJGYWlsZWQgdG8gZmluZCBPYnNlcnZlclwiKTtcbiAgICB0aGlzLm9ic2VydmVycy5zcGxpY2UoaW5kZXgsIDEpO1xuICB9XG5cbiAgYXN5bmMgdXBkYXRlT2JzZXJ2ZXJzKFxuICAgIGxvZzogTG9nZ2VyLFxuICAgIHRhYmxlOiBzdHJpbmcsXG4gICAgZXZlbnQ6IE9wZXJhdGlvbktleXMgfCBCdWxrQ3J1ZE9wZXJhdGlvbktleXMgfCBzdHJpbmcsXG4gICAgaWQ6IEV2ZW50SWRzLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQoXG4gICAgICB0aGlzLm9ic2VydmVyc1xuICAgICAgICAuZmlsdGVyKChvKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBmaWx0ZXIgfSA9IG87XG4gICAgICAgICAgaWYgKCFmaWx0ZXIpIHJldHVybiB0cnVlO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gZmlsdGVyKHRhYmxlLCBldmVudCwgaWQpO1xuICAgICAgICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgICAgICAgIGxvZy5lcnJvcihcbiAgICAgICAgICAgICAgYEZhaWxlZCB0byBmaWx0ZXIgb2JzZXJ2ZXIgJHtvLm9ic2VydmVyLnRvU3RyaW5nKCl9OiAke2V9YFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5tYXAoKG8pID0+IG8ub2JzZXJ2ZXIucmVmcmVzaCh0YWJsZSwgZXZlbnQsIGlkLCAuLi5hcmdzKSlcbiAgICApO1xuICAgIHJlc3VsdHMuZm9yRWFjaCgocmVzdWx0LCBpKSA9PiB7XG4gICAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gXCJyZWplY3RlZFwiKVxuICAgICAgICBsb2cuZXJyb3IoXG4gICAgICAgICAgYEZhaWxlZCB0byB1cGRhdGUgb2JzZXJ2YWJsZSAke3RoaXMub2JzZXJ2ZXJzW2ldLnRvU3RyaW5nKCl9OiAke3Jlc3VsdC5yZWFzb259YFxuICAgICAgICApO1xuICAgIH0pO1xuICB9XG59XG4iXX0=
|
141
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiT2JzZXJ2ZXJIYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3BlcnNpc3RlbmNlL09ic2VydmVySGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSwyREFJaUM7QUFHakM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E0Qkc7QUFDSCxNQUFhLGVBQWU7SUFBNUI7UUFDRTs7O1dBR0c7UUFDZ0IsY0FBUyxHQUd0QixFQUFFLENBQUM7SUE4R1gsQ0FBQztJQTVHQzs7OztPQUlHO0lBQ0gsS0FBSztRQUNILE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUM7SUFDL0IsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILE9BQU8sQ0FBQyxRQUFrQixFQUFFLE1BQXVCO1FBQ2pELE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3RFLElBQUksS0FBSyxLQUFLLENBQUMsQ0FBQztZQUFFLE1BQU0sSUFBSSw2QkFBYSxDQUFDLDZCQUE2QixDQUFDLENBQUM7UUFDekUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQzlELENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILFNBQVMsQ0FBQyxRQUFrQjtRQUMxQixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN0RSxJQUFJLEtBQUssS0FBSyxDQUFDLENBQUM7WUFBRSxNQUFNLElBQUksNkJBQWEsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO1FBQ3JFLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0EyQ0c7SUFDSCxLQUFLLENBQUMsZUFBZSxDQUNuQixHQUFXLEVBQ1gsS0FBYSxFQUNiLEtBQXFELEVBQ3JELEVBQVksRUFDWixHQUFHLElBQVc7UUFFZCxNQUFNLE9BQU8sR0FBRyxNQUFNLE9BQU8sQ0FBQyxVQUFVLENBQ3RDLElBQUksQ0FBQyxTQUFTO2FBQ1gsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7WUFDWixNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ3JCLElBQUksQ0FBQyxNQUFNO2dCQUFFLE9BQU8sSUFBSSxDQUFDO1lBQ3pCLElBQUksQ0FBQztnQkFDSCxPQUFPLE1BQU0sQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ2xDLENBQUM7WUFBQyxPQUFPLENBQVUsRUFBRSxDQUFDO2dCQUNwQixHQUFHLENBQUMsS0FBSyxDQUNQLDZCQUE2QixDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUMzRCxDQUFDO2dCQUNGLE9BQU8sS0FBSyxDQUFDO1lBQ2YsQ0FBQztRQUNILENBQUMsQ0FBQzthQUNELEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUM3RCxDQUFDO1FBQ0YsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUM1QixJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssVUFBVTtnQkFDOUIsR0FBRyxDQUFDLEtBQUssQ0FDUCwrQkFBK0IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsS0FBSyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQ2hGLENBQUM7UUFDTixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQXRIRCwwQ0FzSEMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBPYnNlcnZhYmxlLCBPYnNlcnZlciB9IGZyb20gXCIuLi9pbnRlcmZhY2VzXCI7XG5pbXBvcnQgeyBFdmVudElkcywgT2JzZXJ2ZXJGaWx0ZXIgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHtcbiAgQnVsa0NydWRPcGVyYXRpb25LZXlzLFxuICBJbnRlcm5hbEVycm9yLFxuICBPcGVyYXRpb25LZXlzLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IExvZ2dlciB9IGZyb20gXCJAZGVjYWYtdHMvbG9nZ2luZ1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNYW5hZ2VzIGEgY29sbGVjdGlvbiBvZiBvYnNlcnZlcnMgZm9yIGRhdGFiYXNlIGV2ZW50c1xuICogQHN1bW1hcnkgVGhlIE9ic2VydmVySGFuZGxlciBjbGFzcyBpbXBsZW1lbnRzIHRoZSBPYnNlcnZhYmxlIGludGVyZmFjZSBhbmQgcHJvdmlkZXMgYSBjZW50cmFsaXplZFxuICogd2F5IHRvIG1hbmFnZSBtdWx0aXBsZSBvYnNlcnZlcnMuIEl0IGFsbG93cyByZWdpc3RlcmluZyBvYnNlcnZlcnMgd2l0aCBvcHRpb25hbCBmaWx0ZXJzIHRvIGNvbnRyb2xcbiAqIHdoaWNoIGV2ZW50cyB0aGV5IHJlY2VpdmUgbm90aWZpY2F0aW9ucyBmb3IsIGFuZCBoYW5kbGVzIHRoZSBwcm9jZXNzIG9mIG5vdGlmeWluZyBhbGwgcmVsZXZhbnRcbiAqIG9ic2VydmVycyB3aGVuIGRhdGFiYXNlIGV2ZW50cyBvY2N1ci5cbiAqIEBjbGFzcyBPYnNlcnZlckhhbmRsZXJcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBDcmVhdGUgYW4gb2JzZXJ2ZXIgaGFuZGxlclxuICogY29uc3QgaGFuZGxlciA9IG5ldyBPYnNlcnZlckhhbmRsZXIoKTtcbiAqIFxuICogLy8gUmVnaXN0ZXIgYW4gb2JzZXJ2ZXJcbiAqIGNvbnN0IG15T2JzZXJ2ZXIgPSB7XG4gKiAgIHJlZnJlc2g6IGFzeW5jICh0YWJsZSwgZXZlbnQsIGlkKSA9PiB7XG4gKiAgICAgY29uc29sZS5sb2coYENoYW5nZSBpbiAke3RhYmxlfTogJHtldmVudH0gZm9yIElEICR7aWR9YCk7XG4gKiAgIH1cbiAqIH07XG4gKiBcbiAqIC8vIEFkZCBvYnNlcnZlciB3aXRoIGEgZmlsdGVyIGZvciBvbmx5IHVzZXIgdGFibGUgZXZlbnRzXG4gKiBoYW5kbGVyLm9ic2VydmUobXlPYnNlcnZlciwgKHRhYmxlLCBldmVudCwgaWQpID0+IHRhYmxlID09PSAndXNlcnMnKTtcbiAqIFxuICogLy8gTm90aWZ5IG9ic2VydmVycyBhYm91dCBhbiBldmVudFxuICogYXdhaXQgaGFuZGxlci51cGRhdGVPYnNlcnZlcnMobG9nZ2VyLCAndXNlcnMnLCAnQ1JFQVRFJywgMTIzKTtcbiAqIFxuICogLy8gUmVtb3ZlIGFuIG9ic2VydmVyIHdoZW4gbm8gbG9uZ2VyIG5lZWRlZFxuICogaGFuZGxlci51bk9ic2VydmUobXlPYnNlcnZlcik7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNsYXNzIE9ic2VydmVySGFuZGxlciBpbXBsZW1lbnRzIE9ic2VydmFibGUge1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENvbGxlY3Rpb24gb2YgcmVnaXN0ZXJlZCBvYnNlcnZlcnNcbiAgICogQHN1bW1hcnkgQXJyYXkgb2Ygb2JzZXJ2ZXIgb2JqZWN0cyBhbG9uZyB3aXRoIHRoZWlyIG9wdGlvbmFsIGZpbHRlcnNcbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSBvYnNlcnZlcnM6IHtcbiAgICBvYnNlcnZlcjogT2JzZXJ2ZXI7XG4gICAgZmlsdGVyPzogT2JzZXJ2ZXJGaWx0ZXI7XG4gIH1bXSA9IFtdO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gR2V0cyB0aGUgbnVtYmVyIG9mIHJlZ2lzdGVyZWQgb2JzZXJ2ZXJzXG4gICAqIEBzdW1tYXJ5IFJldHVybnMgdGhlIGNvdW50IG9mIG9ic2VydmVycyBjdXJyZW50bHkgcmVnaXN0ZXJlZCB3aXRoIHRoaXMgaGFuZGxlclxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBudW1iZXIgb2YgcmVnaXN0ZXJlZCBvYnNlcnZlcnNcbiAgICovXG4gIGNvdW50KCkge1xuICAgIHJldHVybiB0aGlzLm9ic2VydmVycy5sZW5ndGg7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlZ2lzdGVycyBhIG5ldyBvYnNlcnZlclxuICAgKiBAc3VtbWFyeSBBZGRzIGFuIG9ic2VydmVyIHRvIHRoZSBjb2xsZWN0aW9uIHdpdGggYW4gb3B0aW9uYWwgZmlsdGVyIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7T2JzZXJ2ZXJ9IG9ic2VydmVyIC0gVGhlIG9ic2VydmVyIHRvIHJlZ2lzdGVyXG4gICAqIEBwYXJhbSB7T2JzZXJ2ZXJGaWx0ZXJ9IFtmaWx0ZXJdIC0gT3B0aW9uYWwgZmlsdGVyIGZ1bmN0aW9uIHRvIGRldGVybWluZSB3aGljaCBldmVudHMgdGhlIG9ic2VydmVyIHJlY2VpdmVzXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBvYnNlcnZlKG9ic2VydmVyOiBPYnNlcnZlciwgZmlsdGVyPzogT2JzZXJ2ZXJGaWx0ZXIpOiB2b2lkIHtcbiAgICBjb25zdCBpbmRleCA9IHRoaXMub2JzZXJ2ZXJzLm1hcCgobykgPT4gby5vYnNlcnZlcikuaW5kZXhPZihvYnNlcnZlcik7XG4gICAgaWYgKGluZGV4ICE9PSAtMSkgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJPYnNlcnZlciBhbHJlYWR5IHJlZ2lzdGVyZWRcIik7XG4gICAgdGhpcy5vYnNlcnZlcnMucHVzaCh7IG9ic2VydmVyOiBvYnNlcnZlciwgZmlsdGVyOiBmaWx0ZXIgfSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFVucmVnaXN0ZXJzIGFuIG9ic2VydmVyXG4gICAqIEBzdW1tYXJ5IFJlbW92ZXMgYW4gb2JzZXJ2ZXIgZnJvbSB0aGUgY29sbGVjdGlvblxuICAgKiBAcGFyYW0ge09ic2VydmVyfSBvYnNlcnZlciAtIFRoZSBvYnNlcnZlciB0byB1bnJlZ2lzdGVyXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICB1bk9ic2VydmUob2JzZXJ2ZXI6IE9ic2VydmVyKTogdm9pZCB7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLm9ic2VydmVycy5tYXAoKG8pID0+IG8ub2JzZXJ2ZXIpLmluZGV4T2Yob2JzZXJ2ZXIpO1xuICAgIGlmIChpbmRleCA9PT0gLTEpIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiRmFpbGVkIHRvIGZpbmQgT2JzZXJ2ZXJcIik7XG4gICAgdGhpcy5vYnNlcnZlcnMuc3BsaWNlKGluZGV4LCAxKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTm90aWZpZXMgYWxsIHJlbGV2YW50IG9ic2VydmVycyBhYm91dCBhIGRhdGFiYXNlIGV2ZW50XG4gICAqIEBzdW1tYXJ5IEZpbHRlcnMgb2JzZXJ2ZXJzIGJhc2VkIG9uIHRoZWlyIGZpbHRlciBmdW5jdGlvbnMgYW5kIGNhbGxzIHJlZnJlc2ggb24gZWFjaCBtYXRjaGluZyBvYnNlcnZlclxuICAgKiBAcGFyYW0ge0xvZ2dlcn0gbG9nIC0gTG9nZ2VyIGZvciByZWNvcmRpbmcgbm90aWZpY2F0aW9uIGFjdGl2aXRpZXNcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlIC0gVGhlIG5hbWUgb2YgdGhlIHRhYmxlIHdoZXJlIHRoZSBldmVudCBvY2N1cnJlZFxuICAgKiBAcGFyYW0ge09wZXJhdGlvbktleXN8QnVsa0NydWRPcGVyYXRpb25LZXlzfHN0cmluZ30gZXZlbnQgLSBUaGUgdHlwZSBvZiBvcGVyYXRpb24gdGhhdCBvY2N1cnJlZFxuICAgKiBAcGFyYW0ge0V2ZW50SWRzfSBpZCAtIFRoZSBpZGVudGlmaWVyKHMpIG9mIHRoZSBhZmZlY3RlZCByZWNvcmQocylcbiAgICogQHBhcmFtIHsuLi5hbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIG9ic2VydmVyc1xuICAgKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIGFsbCBvYnNlcnZlcnMgaGF2ZSBiZWVuIG5vdGlmaWVkXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICAgKiAgIHBhcnRpY2lwYW50IE9ic2VydmVySGFuZGxlclxuICAgKiAgIHBhcnRpY2lwYW50IE9ic2VydmVyXG4gICAqICAgXG4gICAqICAgQ2xpZW50LT4+T2JzZXJ2ZXJIYW5kbGVyOiB1cGRhdGVPYnNlcnZlcnMobG9nLCB0YWJsZSwgZXZlbnQsIGlkLCAuLi5hcmdzKVxuICAgKiAgIFxuICAgKiAgIE9ic2VydmVySGFuZGxlci0+Pk9ic2VydmVySGFuZGxlcjogRmlsdGVyIG9ic2VydmVyc1xuICAgKiAgIFxuICAgKiAgIGxvb3AgRm9yIGVhY2ggb2JzZXJ2ZXIgd2l0aCBtYXRjaGluZyBmaWx0ZXJcbiAgICogICAgIGFsdCBPYnNlcnZlciBoYXMgZmlsdGVyXG4gICAqICAgICAgIE9ic2VydmVySGFuZGxlci0+Pk9ic2VydmVyOiBBcHBseSBmaWx0ZXIodGFibGUsIGV2ZW50LCBpZClcbiAgICogICAgICAgYWx0IEZpbHRlciB0aHJvd3MgZXJyb3JcbiAgICogICAgICAgICBPYnNlcnZlckhhbmRsZXItPj5Mb2dnZXI6IExvZyBlcnJvclxuICAgKiAgICAgICAgIE9ic2VydmVySGFuZGxlci0tPj5PYnNlcnZlckhhbmRsZXI6IFNraXAgb2JzZXJ2ZXJcbiAgICogICAgICAgZWxzZSBGaWx0ZXIgcmV0dXJucyB0cnVlXG4gICAqICAgICAgICAgT2JzZXJ2ZXJIYW5kbGVyLT4+T2JzZXJ2ZXI6IHJlZnJlc2godGFibGUsIGV2ZW50LCBpZCwgLi4uYXJncylcbiAgICogICAgICAgZWxzZSBGaWx0ZXIgcmV0dXJucyBmYWxzZVxuICAgKiAgICAgICAgIE9ic2VydmVySGFuZGxlci0tPj5PYnNlcnZlckhhbmRsZXI6IFNraXAgb2JzZXJ2ZXJcbiAgICogICAgICAgZW5kXG4gICAqICAgICBlbHNlIE5vIGZpbHRlclxuICAgKiAgICAgICBPYnNlcnZlckhhbmRsZXItPj5PYnNlcnZlcjogcmVmcmVzaCh0YWJsZSwgZXZlbnQsIGlkLCAuLi5hcmdzKVxuICAgKiAgICAgZW5kXG4gICAqICAgZW5kXG4gICAqICAgXG4gICAqICAgT2JzZXJ2ZXJIYW5kbGVyLT4+T2JzZXJ2ZXJIYW5kbGVyOiBQcm9jZXNzIHJlc3VsdHNcbiAgICogICBsb29wIEZvciBlYWNoIHJlc3VsdFxuICAgKiAgICAgYWx0IFJlc3VsdCBpcyByZWplY3RlZFxuICAgKiAgICAgICBPYnNlcnZlckhhbmRsZXItPj5Mb2dnZXI6IExvZyBlcnJvclxuICAgKiAgICAgZW5kXG4gICAqICAgZW5kXG4gICAqICAgXG4gICAqICAgT2JzZXJ2ZXJIYW5kbGVyLS0+PkNsaWVudDogUmV0dXJuXG4gICAqL1xuICBhc3luYyB1cGRhdGVPYnNlcnZlcnMoXG4gICAgbG9nOiBMb2dnZXIsXG4gICAgdGFibGU6IHN0cmluZyxcbiAgICBldmVudDogT3BlcmF0aW9uS2V5cyB8IEJ1bGtDcnVkT3BlcmF0aW9uS2V5cyB8IHN0cmluZyxcbiAgICBpZDogRXZlbnRJZHMsXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChcbiAgICAgIHRoaXMub2JzZXJ2ZXJzXG4gICAgICAgIC5maWx0ZXIoKG8pID0+IHtcbiAgICAgICAgICBjb25zdCB7IGZpbHRlciB9ID0gbztcbiAgICAgICAgICBpZiAoIWZpbHRlcikgcmV0dXJuIHRydWU7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBmaWx0ZXIodGFibGUsIGV2ZW50LCBpZCk7XG4gICAgICAgICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgICAgICAgbG9nLmVycm9yKFxuICAgICAgICAgICAgICBgRmFpbGVkIHRvIGZpbHRlciBvYnNlcnZlciAke28ub2JzZXJ2ZXIudG9TdHJpbmcoKX06ICR7ZX1gXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLm1hcCgobykgPT4gby5vYnNlcnZlci5yZWZyZXNoKHRhYmxlLCBldmVudCwgaWQsIC4uLmFyZ3MpKVxuICAgICk7XG4gICAgcmVzdWx0cy5mb3JFYWNoKChyZXN1bHQsIGkpID0+IHtcbiAgICAgIGlmIChyZXN1bHQuc3RhdHVzID09PSBcInJlamVjdGVkXCIpXG4gICAgICAgIGxvZy5lcnJvcihcbiAgICAgICAgICBgRmFpbGVkIHRvIHVwZGF0ZSBvYnNlcnZhYmxlICR7dGhpcy5vYnNlcnZlcnNbaV0udG9TdHJpbmcoKX06ICR7cmVzdWx0LnJlYXNvbn1gXG4gICAgICAgICk7XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==
|
@@ -2,13 +2,108 @@ import { Observable, Observer } from "../interfaces";
|
|
2
2
|
import { EventIds, ObserverFilter } from "./types";
|
3
3
|
import { BulkCrudOperationKeys, OperationKeys } from "@decaf-ts/db-decorators";
|
4
4
|
import { Logger } from "@decaf-ts/logging";
|
5
|
+
/**
|
6
|
+
* @description Manages a collection of observers for database events
|
7
|
+
* @summary The ObserverHandler class implements the Observable interface and provides a centralized
|
8
|
+
* way to manage multiple observers. It allows registering observers with optional filters to control
|
9
|
+
* which events they receive notifications for, and handles the process of notifying all relevant
|
10
|
+
* observers when database events occur.
|
11
|
+
* @class ObserverHandler
|
12
|
+
* @example
|
13
|
+
* ```typescript
|
14
|
+
* // Create an observer handler
|
15
|
+
* const handler = new ObserverHandler();
|
16
|
+
*
|
17
|
+
* // Register an observer
|
18
|
+
* const myObserver = {
|
19
|
+
* refresh: async (table, event, id) => {
|
20
|
+
* console.log(`Change in ${table}: ${event} for ID ${id}`);
|
21
|
+
* }
|
22
|
+
* };
|
23
|
+
*
|
24
|
+
* // Add observer with a filter for only user table events
|
25
|
+
* handler.observe(myObserver, (table, event, id) => table === 'users');
|
26
|
+
*
|
27
|
+
* // Notify observers about an event
|
28
|
+
* await handler.updateObservers(logger, 'users', 'CREATE', 123);
|
29
|
+
*
|
30
|
+
* // Remove an observer when no longer needed
|
31
|
+
* handler.unObserve(myObserver);
|
32
|
+
* ```
|
33
|
+
*/
|
5
34
|
export declare class ObserverHandler implements Observable {
|
35
|
+
/**
|
36
|
+
* @description Collection of registered observers
|
37
|
+
* @summary Array of observer objects along with their optional filters
|
38
|
+
*/
|
6
39
|
protected readonly observers: {
|
7
40
|
observer: Observer;
|
8
41
|
filter?: ObserverFilter;
|
9
42
|
}[];
|
43
|
+
/**
|
44
|
+
* @description Gets the number of registered observers
|
45
|
+
* @summary Returns the count of observers currently registered with this handler
|
46
|
+
* @return {number} The number of registered observers
|
47
|
+
*/
|
10
48
|
count(): number;
|
49
|
+
/**
|
50
|
+
* @description Registers a new observer
|
51
|
+
* @summary Adds an observer to the collection with an optional filter function
|
52
|
+
* @param {Observer} observer - The observer to register
|
53
|
+
* @param {ObserverFilter} [filter] - Optional filter function to determine which events the observer receives
|
54
|
+
* @return {void}
|
55
|
+
*/
|
11
56
|
observe(observer: Observer, filter?: ObserverFilter): void;
|
57
|
+
/**
|
58
|
+
* @description Unregisters an observer
|
59
|
+
* @summary Removes an observer from the collection
|
60
|
+
* @param {Observer} observer - The observer to unregister
|
61
|
+
* @return {void}
|
62
|
+
*/
|
12
63
|
unObserve(observer: Observer): void;
|
64
|
+
/**
|
65
|
+
* @description Notifies all relevant observers about a database event
|
66
|
+
* @summary Filters observers based on their filter functions and calls refresh on each matching observer
|
67
|
+
* @param {Logger} log - Logger for recording notification activities
|
68
|
+
* @param {string} table - The name of the table where the event occurred
|
69
|
+
* @param {OperationKeys|BulkCrudOperationKeys|string} event - The type of operation that occurred
|
70
|
+
* @param {EventIds} id - The identifier(s) of the affected record(s)
|
71
|
+
* @param {...any[]} args - Additional arguments to pass to the observers
|
72
|
+
* @return {Promise<void>} A promise that resolves when all observers have been notified
|
73
|
+
* @mermaid
|
74
|
+
* sequenceDiagram
|
75
|
+
* participant Client
|
76
|
+
* participant ObserverHandler
|
77
|
+
* participant Observer
|
78
|
+
*
|
79
|
+
* Client->>ObserverHandler: updateObservers(log, table, event, id, ...args)
|
80
|
+
*
|
81
|
+
* ObserverHandler->>ObserverHandler: Filter observers
|
82
|
+
*
|
83
|
+
* loop For each observer with matching filter
|
84
|
+
* alt Observer has filter
|
85
|
+
* ObserverHandler->>Observer: Apply filter(table, event, id)
|
86
|
+
* alt Filter throws error
|
87
|
+
* ObserverHandler->>Logger: Log error
|
88
|
+
* ObserverHandler-->>ObserverHandler: Skip observer
|
89
|
+
* else Filter returns true
|
90
|
+
* ObserverHandler->>Observer: refresh(table, event, id, ...args)
|
91
|
+
* else Filter returns false
|
92
|
+
* ObserverHandler-->>ObserverHandler: Skip observer
|
93
|
+
* end
|
94
|
+
* else No filter
|
95
|
+
* ObserverHandler->>Observer: refresh(table, event, id, ...args)
|
96
|
+
* end
|
97
|
+
* end
|
98
|
+
*
|
99
|
+
* ObserverHandler->>ObserverHandler: Process results
|
100
|
+
* loop For each result
|
101
|
+
* alt Result is rejected
|
102
|
+
* ObserverHandler->>Logger: Log error
|
103
|
+
* end
|
104
|
+
* end
|
105
|
+
*
|
106
|
+
* ObserverHandler-->>Client: Return
|
107
|
+
*/
|
13
108
|
updateObservers(log: Logger, table: string, event: OperationKeys | BulkCrudOperationKeys | string, id: EventIds, ...args: any[]): Promise<void>;
|
14
109
|
}
|
@@ -4,18 +4,87 @@ exports.Sequence = void 0;
|
|
4
4
|
const utils_1 = require("./../identity/utils.cjs");
|
5
5
|
const db_decorators_1 = require("@decaf-ts/db-decorators");
|
6
6
|
const logging_1 = require("@decaf-ts/logging");
|
7
|
+
/**
|
8
|
+
* @description Abstract base class for sequence generation
|
9
|
+
* @summary Provides a framework for generating sequential values (like primary keys) in the persistence layer.
|
10
|
+
* Implementations of this class handle the specifics of how sequences are stored and incremented in different
|
11
|
+
* database systems.
|
12
|
+
* @param {SequenceOptions} options - Configuration options for the sequence generator
|
13
|
+
* @class Sequence
|
14
|
+
* @example
|
15
|
+
* ```typescript
|
16
|
+
* // Example implementation for a specific database
|
17
|
+
* class PostgresSequence extends Sequence {
|
18
|
+
* constructor(options: SequenceOptions) {
|
19
|
+
* super(options);
|
20
|
+
* }
|
21
|
+
*
|
22
|
+
* async next(): Promise<number> {
|
23
|
+
* // Implementation to get next value from PostgreSQL sequence
|
24
|
+
* const result = await this.options.executor.raw(`SELECT nextval('${this.options.name}')`);
|
25
|
+
* return parseInt(result.rows[0].nextval);
|
26
|
+
* }
|
27
|
+
*
|
28
|
+
* async current(): Promise<number> {
|
29
|
+
* // Implementation to get current value from PostgreSQL sequence
|
30
|
+
* const result = await this.options.executor.raw(`SELECT currval('${this.options.name}')`);
|
31
|
+
* return parseInt(result.rows[0].currval);
|
32
|
+
* }
|
33
|
+
*
|
34
|
+
* async range(count: number): Promise<number[]> {
|
35
|
+
* // Implementation to get a range of values
|
36
|
+
* const values: number[] = [];
|
37
|
+
* for (let i = 0; i < count; i++) {
|
38
|
+
* values.push(await this.next());
|
39
|
+
* }
|
40
|
+
* return values;
|
41
|
+
* }
|
42
|
+
* }
|
43
|
+
*
|
44
|
+
* // Usage
|
45
|
+
* const sequence = new PostgresSequence({
|
46
|
+
* name: 'user_id_seq',
|
47
|
+
* executor: dbExecutor
|
48
|
+
* });
|
49
|
+
*
|
50
|
+
* const nextId = await sequence.next();
|
51
|
+
* ```
|
52
|
+
*/
|
7
53
|
class Sequence {
|
54
|
+
/**
|
55
|
+
* @description Accessor for the logger instance
|
56
|
+
* @summary Gets or initializes the logger for this sequence
|
57
|
+
* @return {Logger} The logger instance
|
58
|
+
*/
|
8
59
|
get log() {
|
9
60
|
if (!this.logger)
|
10
61
|
this.logger = logging_1.Logging.for(this);
|
11
62
|
return this.logger;
|
12
63
|
}
|
64
|
+
/**
|
65
|
+
* @description Creates a new sequence instance
|
66
|
+
* @summary Protected constructor that initializes the sequence with the provided options
|
67
|
+
*/
|
13
68
|
constructor(options) {
|
14
69
|
this.options = options;
|
15
70
|
}
|
71
|
+
/**
|
72
|
+
* @description Gets the primary key sequence name for a model
|
73
|
+
* @summary Utility method that returns the standardized sequence name for a model's primary key
|
74
|
+
* @template M - The model type
|
75
|
+
* @param {M|Constructor<M>} model - The model instance or constructor
|
76
|
+
* @return {string} The sequence name for the model's primary key
|
77
|
+
*/
|
16
78
|
static pk(model) {
|
17
79
|
return (0, utils_1.sequenceNameForModel)(model, "pk");
|
18
80
|
}
|
81
|
+
/**
|
82
|
+
* @description Parses a sequence value to the appropriate type
|
83
|
+
* @summary Converts a sequence value to the specified type (Number or BigInt)
|
84
|
+
* @param {"Number"|"BigInt"|undefined} type - The target type to convert to
|
85
|
+
* @param {string|number|bigint} value - The value to convert
|
86
|
+
* @return {string|number|bigint} The converted value
|
87
|
+
*/
|
19
88
|
static parseValue(type, value) {
|
20
89
|
switch (type) {
|
21
90
|
case "Number":
|
@@ -32,4 +101,4 @@ class Sequence {
|
|
32
101
|
}
|
33
102
|
}
|
34
103
|
exports.Sequence = Sequence;
|
35
|
-
//# sourceMappingURL=data:application/json;base64,
|
104
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2VxdWVuY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcGVyc2lzdGVuY2UvU2VxdWVuY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EsbURBQXlEO0FBRXpELDJEQUF3RDtBQUN4RCwrQ0FBb0Q7QUFFcEQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTZDRztBQUNILE1BQXNCLFFBQVE7SUFPNUI7Ozs7T0FJRztJQUNILElBQWMsR0FBRztRQUNmLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTTtZQUFFLElBQUksQ0FBQyxNQUFNLEdBQUcsaUJBQU8sQ0FBQyxHQUFHLENBQUMsSUFBVyxDQUFDLENBQUM7UUFDekQsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3JCLENBQUM7SUFFRDs7O09BR0c7SUFDSCxZQUF5QyxPQUF3QjtRQUF4QixZQUFPLEdBQVAsT0FBTyxDQUFpQjtJQUFHLENBQUM7SUF3QnJFOzs7Ozs7T0FNRztJQUNILE1BQU0sQ0FBQyxFQUFFLENBQWtCLEtBQXlCO1FBQ2xELE9BQU8sSUFBQSw0QkFBb0IsRUFBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDM0MsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILE1BQU0sQ0FBQyxVQUFVLENBQ2YsSUFBcUMsRUFDckMsS0FBK0I7UUFFL0IsUUFBUSxJQUFJLEVBQUUsQ0FBQztZQUNiLEtBQUssUUFBUTtnQkFDWCxPQUFPLE9BQU8sS0FBSyxLQUFLLFFBQVE7b0JBQzlCLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO29CQUNqQixDQUFDLENBQUMsT0FBTyxLQUFLLEtBQUssUUFBUTt3QkFDekIsQ0FBQyxDQUFDLEtBQUs7d0JBQ1AsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN0QixLQUFLLFFBQVE7Z0JBQ1gsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDdkI7Z0JBQ0UsTUFBTSxJQUFJLDZCQUFhLENBQUMscUJBQXFCLENBQUMsQ0FBQztRQUNuRCxDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBaEZELDRCQWdGQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbnN0cnVjdG9yLCBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IHNlcXVlbmNlTmFtZUZvck1vZGVsIH0gZnJvbSBcIi4uL2lkZW50aXR5L3V0aWxzXCI7XG5pbXBvcnQgeyBTZXF1ZW5jZU9wdGlvbnMgfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9TZXF1ZW5jZU9wdGlvbnNcIjtcbmltcG9ydCB7IEludGVybmFsRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IExvZ2dlciwgTG9nZ2luZyB9IGZyb20gXCJAZGVjYWYtdHMvbG9nZ2luZ1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBBYnN0cmFjdCBiYXNlIGNsYXNzIGZvciBzZXF1ZW5jZSBnZW5lcmF0aW9uXG4gKiBAc3VtbWFyeSBQcm92aWRlcyBhIGZyYW1ld29yayBmb3IgZ2VuZXJhdGluZyBzZXF1ZW50aWFsIHZhbHVlcyAobGlrZSBwcmltYXJ5IGtleXMpIGluIHRoZSBwZXJzaXN0ZW5jZSBsYXllci5cbiAqIEltcGxlbWVudGF0aW9ucyBvZiB0aGlzIGNsYXNzIGhhbmRsZSB0aGUgc3BlY2lmaWNzIG9mIGhvdyBzZXF1ZW5jZXMgYXJlIHN0b3JlZCBhbmQgaW5jcmVtZW50ZWQgaW4gZGlmZmVyZW50XG4gKiBkYXRhYmFzZSBzeXN0ZW1zLlxuICogQHBhcmFtIHtTZXF1ZW5jZU9wdGlvbnN9IG9wdGlvbnMgLSBDb25maWd1cmF0aW9uIG9wdGlvbnMgZm9yIHRoZSBzZXF1ZW5jZSBnZW5lcmF0b3JcbiAqIEBjbGFzcyBTZXF1ZW5jZVxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIEV4YW1wbGUgaW1wbGVtZW50YXRpb24gZm9yIGEgc3BlY2lmaWMgZGF0YWJhc2VcbiAqIGNsYXNzIFBvc3RncmVzU2VxdWVuY2UgZXh0ZW5kcyBTZXF1ZW5jZSB7XG4gKiAgIGNvbnN0cnVjdG9yKG9wdGlvbnM6IFNlcXVlbmNlT3B0aW9ucykge1xuICogICAgIHN1cGVyKG9wdGlvbnMpO1xuICogICB9XG4gKlxuICogICBhc3luYyBuZXh0KCk6IFByb21pc2U8bnVtYmVyPiB7XG4gKiAgICAgLy8gSW1wbGVtZW50YXRpb24gdG8gZ2V0IG5leHQgdmFsdWUgZnJvbSBQb3N0Z3JlU1FMIHNlcXVlbmNlXG4gKiAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5vcHRpb25zLmV4ZWN1dG9yLnJhdyhgU0VMRUNUIG5leHR2YWwoJyR7dGhpcy5vcHRpb25zLm5hbWV9JylgKTtcbiAqICAgICByZXR1cm4gcGFyc2VJbnQocmVzdWx0LnJvd3NbMF0ubmV4dHZhbCk7XG4gKiAgIH1cbiAqXG4gKiAgIGFzeW5jIGN1cnJlbnQoKTogUHJvbWlzZTxudW1iZXI+IHtcbiAqICAgICAvLyBJbXBsZW1lbnRhdGlvbiB0byBnZXQgY3VycmVudCB2YWx1ZSBmcm9tIFBvc3RncmVTUUwgc2VxdWVuY2VcbiAqICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLm9wdGlvbnMuZXhlY3V0b3IucmF3KGBTRUxFQ1QgY3VycnZhbCgnJHt0aGlzLm9wdGlvbnMubmFtZX0nKWApO1xuICogICAgIHJldHVybiBwYXJzZUludChyZXN1bHQucm93c1swXS5jdXJydmFsKTtcbiAqICAgfVxuICpcbiAqICAgYXN5bmMgcmFuZ2UoY291bnQ6IG51bWJlcik6IFByb21pc2U8bnVtYmVyW10+IHtcbiAqICAgICAvLyBJbXBsZW1lbnRhdGlvbiB0byBnZXQgYSByYW5nZSBvZiB2YWx1ZXNcbiAqICAgICBjb25zdCB2YWx1ZXM6IG51bWJlcltdID0gW107XG4gKiAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XG4gKiAgICAgICB2YWx1ZXMucHVzaChhd2FpdCB0aGlzLm5leHQoKSk7XG4gKiAgICAgfVxuICogICAgIHJldHVybiB2YWx1ZXM7XG4gKiAgIH1cbiAqIH1cbiAqXG4gKiAvLyBVc2FnZVxuICogY29uc3Qgc2VxdWVuY2UgPSBuZXcgUG9zdGdyZXNTZXF1ZW5jZSh7XG4gKiAgIG5hbWU6ICd1c2VyX2lkX3NlcScsXG4gKiAgIGV4ZWN1dG9yOiBkYkV4ZWN1dG9yXG4gKiB9KTtcbiAqXG4gKiBjb25zdCBuZXh0SWQgPSBhd2FpdCBzZXF1ZW5jZS5uZXh0KCk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFNlcXVlbmNlIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2dnZXIgaW5zdGFuY2UgZm9yIHRoaXMgc2VxdWVuY2VcbiAgICogQHN1bW1hcnkgTGF6aWx5IGluaXRpYWxpemVkIGxvZ2dlciBmb3IgdGhlIHNlcXVlbmNlIGluc3RhbmNlXG4gICAqL1xuICBwcml2YXRlIGxvZ2dlciE6IExvZ2dlcjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEFjY2Vzc29yIGZvciB0aGUgbG9nZ2VyIGluc3RhbmNlXG4gICAqIEBzdW1tYXJ5IEdldHMgb3IgaW5pdGlhbGl6ZXMgdGhlIGxvZ2dlciBmb3IgdGhpcyBzZXF1ZW5jZVxuICAgKiBAcmV0dXJuIHtMb2dnZXJ9IFRoZSBsb2dnZXIgaW5zdGFuY2VcbiAgICovXG4gIHByb3RlY3RlZCBnZXQgbG9nKCkge1xuICAgIGlmICghdGhpcy5sb2dnZXIpIHRoaXMubG9nZ2VyID0gTG9nZ2luZy5mb3IodGhpcyBhcyBhbnkpO1xuICAgIHJldHVybiB0aGlzLmxvZ2dlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIG5ldyBzZXF1ZW5jZSBpbnN0YW5jZVxuICAgKiBAc3VtbWFyeSBQcm90ZWN0ZWQgY29uc3RydWN0b3IgdGhhdCBpbml0aWFsaXplcyB0aGUgc2VxdWVuY2Ugd2l0aCB0aGUgcHJvdmlkZWQgb3B0aW9uc1xuICAgKi9cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKHByb3RlY3RlZCByZWFkb25seSBvcHRpb25zOiBTZXF1ZW5jZU9wdGlvbnMpIHt9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZXRzIHRoZSBuZXh0IHZhbHVlIGluIHRoZSBzZXF1ZW5jZVxuICAgKiBAc3VtbWFyeSBSZXRyaWV2ZXMgdGhlIG5leHQgdmFsdWUgZnJvbSB0aGUgc2VxdWVuY2UsIGluY3JlbWVudGluZyBpdCBpbiB0aGUgcHJvY2Vzc1xuICAgKiBAcmV0dXJuIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBuZXh0IHZhbHVlIGluIHRoZSBzZXF1ZW5jZVxuICAgKi9cbiAgYWJzdHJhY3QgbmV4dCgpOiBQcm9taXNlPHN0cmluZyB8IG51bWJlciB8IGJpZ2ludD47XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZXRzIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBzZXF1ZW5jZVxuICAgKiBAc3VtbWFyeSBSZXRyaWV2ZXMgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIHNlcXVlbmNlIHdpdGhvdXQgaW5jcmVtZW50aW5nIGl0XG4gICAqIEByZXR1cm4gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIGN1cnJlbnQgdmFsdWUgaW4gdGhlIHNlcXVlbmNlXG4gICAqL1xuICBhYnN0cmFjdCBjdXJyZW50KCk6IFByb21pc2U8c3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50PjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEdldHMgYSByYW5nZSBvZiBzZXF1ZW50aWFsIHZhbHVlc1xuICAgKiBAc3VtbWFyeSBSZXRyaWV2ZXMgbXVsdGlwbGUgc2VxdWVudGlhbCB2YWx1ZXMgYXQgb25jZSwgd2hpY2ggY2FuIGJlIG1vcmUgZWZmaWNpZW50IHRoYW4gY2FsbGluZyBuZXh0KCkgbXVsdGlwbGUgdGltZXNcbiAgICogQHBhcmFtIHtudW1iZXJ9IGNvdW50IC0gVGhlIG51bWJlciBvZiBzZXF1ZW50aWFsIHZhbHVlcyB0byByZXRyaWV2ZVxuICAgKiBAcmV0dXJuIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIGFycmF5IG9mIHNlcXVlbnRpYWwgdmFsdWVzXG4gICAqL1xuICBhYnN0cmFjdCByYW5nZShjb3VudDogbnVtYmVyKTogUHJvbWlzZTwobnVtYmVyIHwgc3RyaW5nIHwgYmlnaW50KVtdPjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEdldHMgdGhlIHByaW1hcnkga2V5IHNlcXVlbmNlIG5hbWUgZm9yIGEgbW9kZWxcbiAgICogQHN1bW1hcnkgVXRpbGl0eSBtZXRob2QgdGhhdCByZXR1cm5zIHRoZSBzdGFuZGFyZGl6ZWQgc2VxdWVuY2UgbmFtZSBmb3IgYSBtb2RlbCdzIHByaW1hcnkga2V5XG4gICAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGVcbiAgICogQHBhcmFtIHtNfENvbnN0cnVjdG9yPE0+fSBtb2RlbCAtIFRoZSBtb2RlbCBpbnN0YW5jZSBvciBjb25zdHJ1Y3RvclxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBzZXF1ZW5jZSBuYW1lIGZvciB0aGUgbW9kZWwncyBwcmltYXJ5IGtleVxuICAgKi9cbiAgc3RhdGljIHBrPE0gZXh0ZW5kcyBNb2RlbD4obW9kZWw6IE0gfCBDb25zdHJ1Y3RvcjxNPikge1xuICAgIHJldHVybiBzZXF1ZW5jZU5hbWVGb3JNb2RlbChtb2RlbCwgXCJwa1wiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUGFyc2VzIGEgc2VxdWVuY2UgdmFsdWUgdG8gdGhlIGFwcHJvcHJpYXRlIHR5cGVcbiAgICogQHN1bW1hcnkgQ29udmVydHMgYSBzZXF1ZW5jZSB2YWx1ZSB0byB0aGUgc3BlY2lmaWVkIHR5cGUgKE51bWJlciBvciBCaWdJbnQpXG4gICAqIEBwYXJhbSB7XCJOdW1iZXJcInxcIkJpZ0ludFwifHVuZGVmaW5lZH0gdHlwZSAtIFRoZSB0YXJnZXQgdHlwZSB0byBjb252ZXJ0IHRvXG4gICAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcnxiaWdpbnR9IHZhbHVlIC0gVGhlIHZhbHVlIHRvIGNvbnZlcnRcbiAgICogQHJldHVybiB7c3RyaW5nfG51bWJlcnxiaWdpbnR9IFRoZSBjb252ZXJ0ZWQgdmFsdWVcbiAgICovXG4gIHN0YXRpYyBwYXJzZVZhbHVlKFxuICAgIHR5cGU6IFwiTnVtYmVyXCIgfCBcIkJpZ0ludFwiIHwgdW5kZWZpbmVkLFxuICAgIHZhbHVlOiBzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnRcbiAgKTogc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50IHtcbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgIGNhc2UgXCJOdW1iZXJcIjpcbiAgICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIlxuICAgICAgICAgID8gcGFyc2VJbnQodmFsdWUpXG4gICAgICAgICAgOiB0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCJcbiAgICAgICAgICAgID8gdmFsdWVcbiAgICAgICAgICAgIDogQmlnSW50KHZhbHVlKTtcbiAgICAgIGNhc2UgXCJCaWdJbnRcIjpcbiAgICAgICAgcmV0dXJuIEJpZ0ludCh2YWx1ZSk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIlNob3VsZCBuZXZlciBoYXBwZW5cIik7XG4gICAgfVxuICB9XG59XG4iXX0=
|
@@ -1,14 +1,103 @@
|
|
1
1
|
import { Constructor, Model } from "@decaf-ts/decorator-validation";
|
2
2
|
import { SequenceOptions } from "../interfaces/SequenceOptions";
|
3
3
|
import { Logger } from "@decaf-ts/logging";
|
4
|
+
/**
|
5
|
+
* @description Abstract base class for sequence generation
|
6
|
+
* @summary Provides a framework for generating sequential values (like primary keys) in the persistence layer.
|
7
|
+
* Implementations of this class handle the specifics of how sequences are stored and incremented in different
|
8
|
+
* database systems.
|
9
|
+
* @param {SequenceOptions} options - Configuration options for the sequence generator
|
10
|
+
* @class Sequence
|
11
|
+
* @example
|
12
|
+
* ```typescript
|
13
|
+
* // Example implementation for a specific database
|
14
|
+
* class PostgresSequence extends Sequence {
|
15
|
+
* constructor(options: SequenceOptions) {
|
16
|
+
* super(options);
|
17
|
+
* }
|
18
|
+
*
|
19
|
+
* async next(): Promise<number> {
|
20
|
+
* // Implementation to get next value from PostgreSQL sequence
|
21
|
+
* const result = await this.options.executor.raw(`SELECT nextval('${this.options.name}')`);
|
22
|
+
* return parseInt(result.rows[0].nextval);
|
23
|
+
* }
|
24
|
+
*
|
25
|
+
* async current(): Promise<number> {
|
26
|
+
* // Implementation to get current value from PostgreSQL sequence
|
27
|
+
* const result = await this.options.executor.raw(`SELECT currval('${this.options.name}')`);
|
28
|
+
* return parseInt(result.rows[0].currval);
|
29
|
+
* }
|
30
|
+
*
|
31
|
+
* async range(count: number): Promise<number[]> {
|
32
|
+
* // Implementation to get a range of values
|
33
|
+
* const values: number[] = [];
|
34
|
+
* for (let i = 0; i < count; i++) {
|
35
|
+
* values.push(await this.next());
|
36
|
+
* }
|
37
|
+
* return values;
|
38
|
+
* }
|
39
|
+
* }
|
40
|
+
*
|
41
|
+
* // Usage
|
42
|
+
* const sequence = new PostgresSequence({
|
43
|
+
* name: 'user_id_seq',
|
44
|
+
* executor: dbExecutor
|
45
|
+
* });
|
46
|
+
*
|
47
|
+
* const nextId = await sequence.next();
|
48
|
+
* ```
|
49
|
+
*/
|
4
50
|
export declare abstract class Sequence {
|
5
51
|
protected readonly options: SequenceOptions;
|
52
|
+
/**
|
53
|
+
* @description Logger instance for this sequence
|
54
|
+
* @summary Lazily initialized logger for the sequence instance
|
55
|
+
*/
|
6
56
|
private logger;
|
57
|
+
/**
|
58
|
+
* @description Accessor for the logger instance
|
59
|
+
* @summary Gets or initializes the logger for this sequence
|
60
|
+
* @return {Logger} The logger instance
|
61
|
+
*/
|
7
62
|
protected get log(): Logger;
|
63
|
+
/**
|
64
|
+
* @description Creates a new sequence instance
|
65
|
+
* @summary Protected constructor that initializes the sequence with the provided options
|
66
|
+
*/
|
8
67
|
protected constructor(options: SequenceOptions);
|
68
|
+
/**
|
69
|
+
* @description Gets the next value in the sequence
|
70
|
+
* @summary Retrieves the next value from the sequence, incrementing it in the process
|
71
|
+
* @return A promise that resolves to the next value in the sequence
|
72
|
+
*/
|
9
73
|
abstract next(): Promise<string | number | bigint>;
|
74
|
+
/**
|
75
|
+
* @description Gets the current value of the sequence
|
76
|
+
* @summary Retrieves the current value of the sequence without incrementing it
|
77
|
+
* @return A promise that resolves to the current value in the sequence
|
78
|
+
*/
|
10
79
|
abstract current(): Promise<string | number | bigint>;
|
80
|
+
/**
|
81
|
+
* @description Gets a range of sequential values
|
82
|
+
* @summary Retrieves multiple sequential values at once, which can be more efficient than calling next() multiple times
|
83
|
+
* @param {number} count - The number of sequential values to retrieve
|
84
|
+
* @return A promise that resolves to an array of sequential values
|
85
|
+
*/
|
11
86
|
abstract range(count: number): Promise<(number | string | bigint)[]>;
|
87
|
+
/**
|
88
|
+
* @description Gets the primary key sequence name for a model
|
89
|
+
* @summary Utility method that returns the standardized sequence name for a model's primary key
|
90
|
+
* @template M - The model type
|
91
|
+
* @param {M|Constructor<M>} model - The model instance or constructor
|
92
|
+
* @return {string} The sequence name for the model's primary key
|
93
|
+
*/
|
12
94
|
static pk<M extends Model>(model: M | Constructor<M>): string;
|
95
|
+
/**
|
96
|
+
* @description Parses a sequence value to the appropriate type
|
97
|
+
* @summary Converts a sequence value to the specified type (Number or BigInt)
|
98
|
+
* @param {"Number"|"BigInt"|undefined} type - The target type to convert to
|
99
|
+
* @param {string|number|bigint} value - The value to convert
|
100
|
+
* @return {string|number|bigint} The converted value
|
101
|
+
*/
|
13
102
|
static parseValue(type: "Number" | "BigInt" | undefined, value: string | number | bigint): string | number | bigint;
|
14
103
|
}
|