@resq-sw/decorators 0.1.0

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 (187) hide show
  1. package/README.md +277 -0
  2. package/lib/_utils.d.ts +46 -0
  3. package/lib/_utils.d.ts.map +1 -0
  4. package/lib/_utils.js +91 -0
  5. package/lib/_utils.js.map +1 -0
  6. package/lib/after/after.d.ts +60 -0
  7. package/lib/after/after.d.ts.map +1 -0
  8. package/lib/after/after.fn.d.ts +39 -0
  9. package/lib/after/after.fn.d.ts.map +1 -0
  10. package/lib/after/after.fn.js +59 -0
  11. package/lib/after/after.fn.js.map +1 -0
  12. package/lib/after/after.js +41 -0
  13. package/lib/after/after.js.map +1 -0
  14. package/lib/after/after.types.d.ts +86 -0
  15. package/lib/after/after.types.d.ts.map +1 -0
  16. package/lib/after/after.types.js +0 -0
  17. package/lib/after/index.d.ts +3 -0
  18. package/lib/after/index.js +2 -0
  19. package/lib/before/before.d.ts +61 -0
  20. package/lib/before/before.d.ts.map +1 -0
  21. package/lib/before/before.fn.d.ts +39 -0
  22. package/lib/before/before.fn.d.ts.map +1 -0
  23. package/lib/before/before.fn.js +51 -0
  24. package/lib/before/before.fn.js.map +1 -0
  25. package/lib/before/before.js +40 -0
  26. package/lib/before/before.js.map +1 -0
  27. package/lib/before/before.types.d.ts +48 -0
  28. package/lib/before/before.types.d.ts.map +1 -0
  29. package/lib/before/before.types.js +0 -0
  30. package/lib/before/index.d.ts +3 -0
  31. package/lib/before/index.js +2 -0
  32. package/lib/bind/bind.d.ts +75 -0
  33. package/lib/bind/bind.d.ts.map +1 -0
  34. package/lib/bind/bind.fn.d.ts +46 -0
  35. package/lib/bind/bind.fn.d.ts.map +1 -0
  36. package/lib/bind/bind.fn.js +39 -0
  37. package/lib/bind/bind.fn.js.map +1 -0
  38. package/lib/bind/bind.js +64 -0
  39. package/lib/bind/bind.js.map +1 -0
  40. package/lib/bind/bind.types.d.ts +36 -0
  41. package/lib/bind/bind.types.d.ts.map +1 -0
  42. package/lib/bind/bind.types.js +0 -0
  43. package/lib/bind/index.d.ts +3 -0
  44. package/lib/bind/index.js +2 -0
  45. package/lib/debounce/debounce.d.ts +34 -0
  46. package/lib/debounce/debounce.d.ts.map +1 -0
  47. package/lib/debounce/debounce.fn.d.ts +40 -0
  48. package/lib/debounce/debounce.fn.d.ts.map +1 -0
  49. package/lib/debounce/debounce.fn.js +47 -0
  50. package/lib/debounce/debounce.fn.js.map +1 -0
  51. package/lib/debounce/debounce.js +48 -0
  52. package/lib/debounce/debounce.js.map +1 -0
  53. package/lib/debounce/index.d.ts +2 -0
  54. package/lib/debounce/index.js +2 -0
  55. package/lib/delay/delay.d.ts +35 -0
  56. package/lib/delay/delay.d.ts.map +1 -0
  57. package/lib/delay/delay.fn.d.ts +33 -0
  58. package/lib/delay/delay.fn.d.ts.map +1 -0
  59. package/lib/delay/delay.fn.js +38 -0
  60. package/lib/delay/delay.fn.js.map +1 -0
  61. package/lib/delay/delay.js +43 -0
  62. package/lib/delay/delay.js.map +1 -0
  63. package/lib/delay/index.d.ts +2 -0
  64. package/lib/delay/index.js +2 -0
  65. package/lib/delegate/delegate.d.ts +48 -0
  66. package/lib/delegate/delegate.d.ts.map +1 -0
  67. package/lib/delegate/delegate.fn.d.ts +57 -0
  68. package/lib/delegate/delegate.fn.d.ts.map +1 -0
  69. package/lib/delegate/delegate.fn.js +55 -0
  70. package/lib/delegate/delegate.fn.js.map +1 -0
  71. package/lib/delegate/delegate.js +56 -0
  72. package/lib/delegate/delegate.js.map +1 -0
  73. package/lib/delegate/delegate.types.d.ts +45 -0
  74. package/lib/delegate/delegate.types.d.ts.map +1 -0
  75. package/lib/delegate/delegate.types.js +0 -0
  76. package/lib/delegate/index.d.ts +3 -0
  77. package/lib/delegate/index.js +2 -0
  78. package/lib/exec-time/exec-time.d.ts +42 -0
  79. package/lib/exec-time/exec-time.d.ts.map +1 -0
  80. package/lib/exec-time/exec-time.fn.d.ts +50 -0
  81. package/lib/exec-time/exec-time.fn.d.ts.map +1 -0
  82. package/lib/exec-time/exec-time.fn.js +91 -0
  83. package/lib/exec-time/exec-time.fn.js.map +1 -0
  84. package/lib/exec-time/exec-time.js +55 -0
  85. package/lib/exec-time/exec-time.js.map +1 -0
  86. package/lib/exec-time/exec-time.types.d.ts +70 -0
  87. package/lib/exec-time/exec-time.types.d.ts.map +1 -0
  88. package/lib/exec-time/exec-time.types.js +0 -0
  89. package/lib/exec-time/index.d.ts +4 -0
  90. package/lib/exec-time/index.js +3 -0
  91. package/lib/execute/execute.d.ts +78 -0
  92. package/lib/execute/execute.d.ts.map +1 -0
  93. package/lib/execute/execute.js +82 -0
  94. package/lib/execute/execute.js.map +1 -0
  95. package/lib/execute/index.d.ts +2 -0
  96. package/lib/execute/index.js +2 -0
  97. package/lib/index.d.ts +30 -0
  98. package/lib/index.js +19 -0
  99. package/lib/memoize/index.d.ts +3 -0
  100. package/lib/memoize/index.js +2 -0
  101. package/lib/memoize/memoize.d.ts +67 -0
  102. package/lib/memoize/memoize.d.ts.map +1 -0
  103. package/lib/memoize/memoize.fn.d.ts +69 -0
  104. package/lib/memoize/memoize.fn.d.ts.map +1 -0
  105. package/lib/memoize/memoize.fn.js +43 -0
  106. package/lib/memoize/memoize.fn.js.map +1 -0
  107. package/lib/memoize/memoize.js +40 -0
  108. package/lib/memoize/memoize.js.map +1 -0
  109. package/lib/memoize/memoize.types.d.ts +107 -0
  110. package/lib/memoize/memoize.types.d.ts.map +1 -0
  111. package/lib/memoize/memoize.types.js +0 -0
  112. package/lib/memoize-async/index.d.ts +4 -0
  113. package/lib/memoize-async/index.js +3 -0
  114. package/lib/memoize-async/memoize-async.d.ts +68 -0
  115. package/lib/memoize-async/memoize-async.d.ts.map +1 -0
  116. package/lib/memoize-async/memoize-async.fn.d.ts +69 -0
  117. package/lib/memoize-async/memoize-async.fn.d.ts.map +1 -0
  118. package/lib/memoize-async/memoize-async.fn.js +52 -0
  119. package/lib/memoize-async/memoize-async.fn.js.map +1 -0
  120. package/lib/memoize-async/memoize-async.js +15 -0
  121. package/lib/memoize-async/memoize-async.js.map +1 -0
  122. package/lib/memoize-async/memoize-async.types.d.ts +74 -0
  123. package/lib/memoize-async/memoize-async.types.d.ts.map +1 -0
  124. package/lib/memoize-async/memoize-async.types.js +0 -0
  125. package/lib/observer/index.d.ts +3 -0
  126. package/lib/observer/index.js +2 -0
  127. package/lib/observer/observer.d.ts +54 -0
  128. package/lib/observer/observer.d.ts.map +1 -0
  129. package/lib/observer/observer.js +85 -0
  130. package/lib/observer/observer.js.map +1 -0
  131. package/lib/observer/observer.types.d.ts +41 -0
  132. package/lib/observer/observer.types.d.ts.map +1 -0
  133. package/lib/observer/observer.types.js +0 -0
  134. package/lib/rate-limit/index.d.ts +4 -0
  135. package/lib/rate-limit/index.js +3 -0
  136. package/lib/rate-limit/rate-limit.d.ts +58 -0
  137. package/lib/rate-limit/rate-limit.d.ts.map +1 -0
  138. package/lib/rate-limit/rate-limit.fn.d.ts +43 -0
  139. package/lib/rate-limit/rate-limit.fn.d.ts.map +1 -0
  140. package/lib/rate-limit/rate-limit.fn.js +56 -0
  141. package/lib/rate-limit/rate-limit.fn.js.map +1 -0
  142. package/lib/rate-limit/rate-limit.js +65 -0
  143. package/lib/rate-limit/rate-limit.js.map +1 -0
  144. package/lib/rate-limit/rate-limit.types.d.ts +148 -0
  145. package/lib/rate-limit/rate-limit.types.d.ts.map +1 -0
  146. package/lib/rate-limit/rate-limit.types.js +0 -0
  147. package/lib/rate-limit/simple-rate-limit-counter.d.ts +89 -0
  148. package/lib/rate-limit/simple-rate-limit-counter.d.ts.map +1 -0
  149. package/lib/rate-limit/simple-rate-limit-counter.js +98 -0
  150. package/lib/rate-limit/simple-rate-limit-counter.js.map +1 -0
  151. package/lib/readonly/index.d.ts +3 -0
  152. package/lib/readonly/index.js +2 -0
  153. package/lib/readonly/readonly.d.ts +39 -0
  154. package/lib/readonly/readonly.d.ts.map +1 -0
  155. package/lib/readonly/readonly.js +43 -0
  156. package/lib/readonly/readonly.js.map +1 -0
  157. package/lib/readonly/readonly.types.d.ts +40 -0
  158. package/lib/readonly/readonly.types.d.ts.map +1 -0
  159. package/lib/readonly/readonly.types.js +0 -0
  160. package/lib/throttle/index.d.ts +2 -0
  161. package/lib/throttle/index.js +2 -0
  162. package/lib/throttle/throttle.d.ts +35 -0
  163. package/lib/throttle/throttle.d.ts.map +1 -0
  164. package/lib/throttle/throttle.fn.d.ts +42 -0
  165. package/lib/throttle/throttle.fn.d.ts.map +1 -0
  166. package/lib/throttle/throttle.fn.js +52 -0
  167. package/lib/throttle/throttle.fn.js.map +1 -0
  168. package/lib/throttle/throttle.js +43 -0
  169. package/lib/throttle/throttle.js.map +1 -0
  170. package/lib/throttle-async/index.d.ts +2 -0
  171. package/lib/throttle-async/index.js +2 -0
  172. package/lib/throttle-async/throttle-async-executor.d.ts +79 -0
  173. package/lib/throttle-async/throttle-async-executor.d.ts.map +1 -0
  174. package/lib/throttle-async/throttle-async-executor.js +122 -0
  175. package/lib/throttle-async/throttle-async-executor.js.map +1 -0
  176. package/lib/throttle-async/throttle-async.d.ts +68 -0
  177. package/lib/throttle-async/throttle-async.d.ts.map +1 -0
  178. package/lib/throttle-async/throttle-async.fn.d.ts +41 -0
  179. package/lib/throttle-async/throttle-async.fn.d.ts.map +1 -0
  180. package/lib/throttle-async/throttle-async.fn.js +46 -0
  181. package/lib/throttle-async/throttle-async.fn.js.map +1 -0
  182. package/lib/throttle-async/throttle-async.js +45 -0
  183. package/lib/throttle-async/throttle-async.js.map +1 -0
  184. package/lib/types.d.ts +81 -0
  185. package/lib/types.d.ts.map +1 -0
  186. package/lib/types.js +0 -0
  187. package/package.json +40 -0
@@ -0,0 +1,86 @@
1
+ //#region src/after/after.types.d.ts
2
+ /**
3
+ * Copyright 2026 ResQ
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * Function signature for after hooks.
19
+ *
20
+ * @template D - The return type of the decorated method
21
+ * @param {AfterParams<D>} [x] - Parameters containing args and response
22
+ * @returns {void}
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * const afterHook: AfterFunc<string> = ({ args, response }) => {
27
+ * console.log(`Method returned: ${response}`);
28
+ * };
29
+ * ```
30
+ */
31
+ type AfterFunc<D> = (x?: AfterParams<D>) => void;
32
+ /**
33
+ * Configuration options for the @after decorator.
34
+ *
35
+ * @interface AfterConfig
36
+ * @template T - The type of the class containing the decorated method
37
+ * @template D - The return type of the decorated method
38
+ * @property {AfterFunc<D> | keyof T} func - The after function to execute, or a method name on the class
39
+ * @property {boolean} [wait=false] - Whether to wait for the after function to complete before returning
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * // Using a function reference
44
+ * const config1: AfterConfig<MyClass, string> = {
45
+ * func: ({ args, response }) => console.log(response),
46
+ * wait: false
47
+ * };
48
+
49
+ * // Using a method name
50
+ * const config2: AfterConfig<MyClass, string> = {
51
+ * func: 'logResult', // Calls this.logResult()
52
+ * wait: true
53
+ * };
54
+ * ```
55
+ */
56
+ interface AfterConfig<T = any, D = any> {
57
+ /** The after function to execute, or a method name on the class */
58
+ func: AfterFunc<D> | keyof T;
59
+ /** Whether to wait for the after function to complete before returning */
60
+ wait?: boolean;
61
+ }
62
+ /**
63
+ * Parameters passed to the after hook function.
64
+ *
65
+ * @interface AfterParams
66
+ * @template D - The return type of the decorated method
67
+ * @property {any[]} args - The arguments passed to the decorated method
68
+ * @property {D} response - The return value of the decorated method
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * const params: AfterParams<number> = {
73
+ * args: ['input', 42],
74
+ * response: 100
75
+ * };
76
+ * ```
77
+ */
78
+ interface AfterParams<D = any> {
79
+ /** The arguments passed to the decorated method */
80
+ args: unknown[];
81
+ /** The return value of the decorated method */
82
+ response: D;
83
+ }
84
+ //#endregion
85
+ export { AfterConfig, AfterFunc, AfterParams };
86
+ //# sourceMappingURL=after.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"after.types.d.ts","names":[],"sources":["../../src/after/after.types.ts"],"mappings":";;AA8BA;;;;;;;;;;AA0BA;;;;;;;;;;;;;;;;;AAuBA;KAjDY,SAAA,OAAgB,CAAA,GAAI,WAAA,CAAY,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;UA0B3B,WAAA;;EAEf,IAAA,EAAM,SAAA,CAAU,CAAA,UAAW,CAAA;;EAE3B,IAAA;AAAA;;;;;;;;;;;;;;;;;UAmBe,WAAA;;EAEf,IAAA;;EAEA,QAAA,EAAU,CAAA;AAAA"}
File without changes
@@ -0,0 +1,3 @@
1
+ import { AfterConfig, AfterFunc, AfterParams } from "./after.types.js";
2
+ import { after } from "./after.js";
3
+ export { AfterConfig, AfterFunc, AfterParams, after };
@@ -0,0 +1,2 @@
1
+ import { after } from "./after.js";
2
+ export { after };
@@ -0,0 +1,61 @@
1
+ import { Decorator } from "../types.js";
2
+ import { BeforeConfig } from "./before.types.js";
3
+
4
+ //#region src/before/before.d.ts
5
+ /**
6
+ * @fileoverview Before decorator - executes a function before the decorated method.
7
+ * Useful for validation, authentication, or preprocessing before method execution.
8
+ *
9
+ * @module @resq/typescript/decorators/before
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * class MyService {
14
+ * @before({
15
+ * func: 'validateInput',
16
+ * wait: true // Wait for before function to complete
17
+ * })
18
+ * saveData(data: any) {
19
+ * database.save(data);
20
+ * }
21
+ *
22
+ * validateInput() {
23
+ * if (!this.isValid) {
24
+ * throw new Error('Invalid state');
25
+ * }
26
+ * }
27
+ * }
28
+ * ```
29
+ *
30
+ * @copyright Copyright (c) 2026 ResQ
31
+ * @license MIT
32
+ */
33
+ /**
34
+ * Decorator that executes a function before the decorated method.
35
+ * The before function is called before the method body executes.
36
+ *
37
+ * @template T - The type of the class containing the decorated method
38
+ * @param {BeforeConfig<T>} config - Configuration for the before hook
39
+ * @returns {Decorator<T>} The decorator function
40
+ *
41
+ * @throws {Error} When applied to a non-method property
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * class DataProcessor {
46
+ * @before({
47
+ * func: function() {
48
+ * console.log('About to process...');
49
+ * },
50
+ * wait: false
51
+ * })
52
+ * processItems(items: string[]): number {
53
+ * return items.length;
54
+ * }
55
+ * }
56
+ * ```
57
+ */
58
+ declare function before<T = any>(config: BeforeConfig<T>): Decorator<T>;
59
+ //#endregion
60
+ export { before };
61
+ //# sourceMappingURL=before.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"before.d.ts","names":[],"sources":["../../src/before/before.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA0EgB,MAAA,SAAA,CAAgB,MAAA,EAAQ,YAAA,CAAa,CAAA,IAAK,SAAA,CAAU,CAAA"}
@@ -0,0 +1,39 @@
1
+ import { Method } from "../types.js";
2
+ import { BeforeConfig } from "./before.types.js";
3
+
4
+ //#region src/before/before.fn.d.ts
5
+ /**
6
+ * Wraps a method to execute a before hook function before the method runs.
7
+ *
8
+ * @template D - The return type of the original method
9
+ * @template A - The argument types of the original method
10
+ * @param {Method<D, A>} originalMethod - The method to wrap
11
+ * @param {BeforeConfig<any>} config - Configuration for the before hook
12
+ * @returns {Method<Promise<D>, A>} The wrapped method
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * class Service {
17
+ * process(data: string): string {
18
+ * return data.toUpperCase();
19
+ * }
20
+ * }
21
+ *
22
+ * const service = new Service();
23
+ * const wrapped = beforeFn(
24
+ * service.process.bind(service),
25
+ * {
26
+ * func: () => {
27
+ * console.log('About to process...');
28
+ * },
29
+ * wait: false
30
+ * }
31
+ * );
32
+ *
33
+ * await wrapped('hello'); // Logs "About to process..." then returns "HELLO"
34
+ * ```
35
+ */
36
+ declare function beforeFn<D = any, A extends any[] = any[]>(originalMethod: Method<D, A>, config: BeforeConfig<any>): Method<Promise<D>, A>;
37
+ //#endregion
38
+ export { beforeFn };
39
+ //# sourceMappingURL=before.fn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"before.fn.d.ts","names":[],"sources":["../../src/before/before.fn.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkDgB,QAAA,kCAAA,CACd,cAAA,EAAgB,MAAA,CAAO,CAAA,EAAG,CAAA,GAC1B,MAAA,EAAQ,YAAA,QACP,MAAA,CAAO,OAAA,CAAQ,CAAA,GAAI,CAAA"}
@@ -0,0 +1,51 @@
1
+ //#region src/before/before.fn.ts
2
+ /**
3
+ * Wraps a method to execute a before hook function before the method runs.
4
+ *
5
+ * @template D - The return type of the original method
6
+ * @template A - The argument types of the original method
7
+ * @param {Method<D, A>} originalMethod - The method to wrap
8
+ * @param {BeforeConfig<any>} config - Configuration for the before hook
9
+ * @returns {Method<Promise<D>, A>} The wrapped method
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * class Service {
14
+ * process(data: string): string {
15
+ * return data.toUpperCase();
16
+ * }
17
+ * }
18
+ *
19
+ * const service = new Service();
20
+ * const wrapped = beforeFn(
21
+ * service.process.bind(service),
22
+ * {
23
+ * func: () => {
24
+ * console.log('About to process...');
25
+ * },
26
+ * wait: false
27
+ * }
28
+ * );
29
+ *
30
+ * await wrapped('hello'); // Logs "About to process..." then returns "HELLO"
31
+ * ```
32
+ */
33
+ function beforeFn(originalMethod, config) {
34
+ const resolvedConfig = {
35
+ wait: false,
36
+ ...config
37
+ };
38
+ return async function(...args) {
39
+ const beforeFunc = typeof resolvedConfig.func === "string" ? this[resolvedConfig.func].bind(this) : resolvedConfig.func;
40
+ if (resolvedConfig.wait) {
41
+ await beforeFunc();
42
+ return originalMethod.apply(this, args);
43
+ }
44
+ beforeFunc();
45
+ return originalMethod.apply(this, args);
46
+ };
47
+ }
48
+ //#endregion
49
+ export { beforeFn };
50
+
51
+ //# sourceMappingURL=before.fn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"before.fn.js","names":[],"sources":["../../src/before/before.fn.ts"],"sourcesContent":["/**\n * Copyright 2026 ResQ\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { Method } from '../types.js';\nimport type { BeforeConfig } from './before.types.js';\n\n/**\n * Wraps a method to execute a before hook function before the method runs.\n *\n * @template D - The return type of the original method\n * @template A - The argument types of the original method\n * @param {Method<D, A>} originalMethod - The method to wrap\n * @param {BeforeConfig<any>} config - Configuration for the before hook\n * @returns {Method<Promise<D>, A>} The wrapped method\n *\n * @example\n * ```typescript\n * class Service {\n * process(data: string): string {\n * return data.toUpperCase();\n * }\n * }\n *\n * const service = new Service();\n * const wrapped = beforeFn(\n * service.process.bind(service),\n * {\n * func: () => {\n * console.log('About to process...');\n * },\n * wait: false\n * }\n * );\n *\n * await wrapped('hello'); // Logs \"About to process...\" then returns \"HELLO\"\n * ```\n */\nexport function beforeFn<D = any, A extends any[] = any[]>(\n originalMethod: Method<D, A>,\n config: BeforeConfig<any>,\n): Method<Promise<D>, A> {\n const resolvedConfig: BeforeConfig<any> = {\n wait: false,\n ...config,\n };\n\n return async function (this: any, ...args: A): Promise<D> {\n const beforeFunc =\n typeof resolvedConfig.func === 'string'\n ? this[resolvedConfig.func].bind(this)\n : resolvedConfig.func;\n\n if (resolvedConfig.wait) {\n await beforeFunc();\n return originalMethod.apply(this, args);\n }\n\n beforeFunc();\n return originalMethod.apply(this, args);\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkDA,SAAgB,SACd,gBACA,QACuB;CACvB,MAAM,iBAAoC;EACxC,MAAM;EACN,GAAG;EACJ;AAED,QAAO,eAA2B,GAAG,MAAqB;EACxD,MAAM,aACJ,OAAO,eAAe,SAAS,WAC3B,KAAK,eAAe,MAAM,KAAK,KAAK,GACpC,eAAe;AAErB,MAAI,eAAe,MAAM;AACvB,SAAM,YAAY;AAClB,UAAO,eAAe,MAAM,MAAM,KAAK;;AAGzC,cAAY;AACZ,SAAO,eAAe,MAAM,MAAM,KAAK"}
@@ -0,0 +1,40 @@
1
+ import { beforeFn } from "./before.fn.js";
2
+ //#region src/before/before.ts
3
+ /**
4
+ * Decorator that executes a function before the decorated method.
5
+ * The before function is called before the method body executes.
6
+ *
7
+ * @template T - The type of the class containing the decorated method
8
+ * @param {BeforeConfig<T>} config - Configuration for the before hook
9
+ * @returns {Decorator<T>} The decorator function
10
+ *
11
+ * @throws {Error} When applied to a non-method property
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * class DataProcessor {
16
+ * @before({
17
+ * func: function() {
18
+ * console.log('About to process...');
19
+ * },
20
+ * wait: false
21
+ * })
22
+ * processItems(items: string[]): number {
23
+ * return items.length;
24
+ * }
25
+ * }
26
+ * ```
27
+ */
28
+ function before(config) {
29
+ return (target, propertyName, descriptor) => {
30
+ if (descriptor.value) {
31
+ descriptor.value = beforeFn(descriptor.value, config);
32
+ return descriptor;
33
+ }
34
+ throw new Error("@before is applicable only on a methods.");
35
+ };
36
+ }
37
+ //#endregion
38
+ export { before };
39
+
40
+ //# sourceMappingURL=before.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"before.js","names":[],"sources":["../../src/before/before.ts"],"sourcesContent":["/**\n * Copyright 2026 ResQ\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @fileoverview Before decorator - executes a function before the decorated method.\n * Useful for validation, authentication, or preprocessing before method execution.\n *\n * @module @resq/typescript/decorators/before\n *\n * @example\n * ```typescript\n * class MyService {\n * @before({\n * func: 'validateInput',\n * wait: true // Wait for before function to complete\n * })\n * saveData(data: any) {\n * database.save(data);\n * }\n *\n * validateInput() {\n * if (!this.isValid) {\n * throw new Error('Invalid state');\n * }\n * }\n * }\n * ```\n *\n * @copyright Copyright (c) 2026 ResQ\n * @license MIT\n */\n\nimport type { Decorator, Method } from '../types.js';\nimport { beforeFn } from './before.fn.js';\nimport type { BeforeConfig } from './before.types.js';\n\n/**\n * Decorator that executes a function before the decorated method.\n * The before function is called before the method body executes.\n *\n * @template T - The type of the class containing the decorated method\n * @param {BeforeConfig<T>} config - Configuration for the before hook\n * @returns {Decorator<T>} The decorator function\n *\n * @throws {Error} When applied to a non-method property\n *\n * @example\n * ```typescript\n * class DataProcessor {\n * @before({\n * func: function() {\n * console.log('About to process...');\n * },\n * wait: false\n * })\n * processItems(items: string[]): number {\n * return items.length;\n * }\n * }\n * ```\n */\nexport function before<T = any>(config: BeforeConfig<T>): Decorator<T> {\n return (\n target: T,\n propertyName: keyof T,\n descriptor: TypedPropertyDescriptor<Method<any>>,\n ): TypedPropertyDescriptor<Method<any>> => {\n if (descriptor.value) {\n descriptor.value = beforeFn(descriptor.value, config);\n\n return descriptor;\n }\n throw new Error('@before is applicable only on a methods.');\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA0EA,SAAgB,OAAgB,QAAuC;AACrE,SACE,QACA,cACA,eACyC;AACzC,MAAI,WAAW,OAAO;AACpB,cAAW,QAAQ,SAAS,WAAW,OAAO,OAAO;AAErD,UAAO;;AAET,QAAM,IAAI,MAAM,2CAA2C"}
@@ -0,0 +1,48 @@
1
+ //#region src/before/before.types.d.ts
2
+ /**
3
+ * Copyright 2026 ResQ
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * Configuration options for the @before decorator.
19
+ *
20
+ * @interface BeforeConfig
21
+ * @template T - The type of the class containing the decorated method
22
+ * @property {((...args: any[]) => any) | keyof T} func - The before function to execute, or a method name on the class
23
+ * @property {boolean} [wait=false] - Whether to wait for the before function to complete before executing the method
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * // Using a function reference
28
+ * const config1: BeforeConfig<MyClass> = {
29
+ * func: () => console.log('Before method'),
30
+ * wait: false
31
+ * };
32
+
33
+ * // Using a method name
34
+ * const config2: BeforeConfig<MyClass> = {
35
+ * func: 'validate',
36
+ * wait: true
37
+ * };
38
+ * ```
39
+ */
40
+ interface BeforeConfig<T> {
41
+ /** The before function to execute, or a method name on the class */
42
+ func: ((...args: unknown[]) => unknown) | keyof T;
43
+ /** Whether to wait for the before function to complete before executing the method */
44
+ wait?: boolean;
45
+ }
46
+ //#endregion
47
+ export { BeforeConfig };
48
+ //# sourceMappingURL=before.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"before.types.d.ts","names":[],"sources":["../../src/before/before.types.ts"],"mappings":";;AAuCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAAiB,YAAA;;EAEf,IAAA,OAAW,IAAA,iCAAqC,CAAA;;EAEhD,IAAA;AAAA"}
File without changes
@@ -0,0 +1,3 @@
1
+ import { BeforeConfig } from "./before.types.js";
2
+ import { before } from "./before.js";
3
+ export { BeforeConfig, before };
@@ -0,0 +1,2 @@
1
+ import { before } from "./before.js";
2
+ export { before };
@@ -0,0 +1,75 @@
1
+ import { Method } from "../types.js";
2
+
3
+ //#region src/bind/bind.d.ts
4
+ /**
5
+ * @fileoverview Bind decorator - automatically binds class methods to their
6
+ * instance context. Ensures `this` always refers to the class instance.
7
+ *
8
+ * @module @resq/typescript/decorators/bind
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * class EventHandler {
13
+ * private count = 0;
14
+ *
15
+ * @bind
16
+ * handleClick(event: MouseEvent): void {
17
+ * this.count++; // `this` correctly refers to EventHandler instance
18
+ * console.log(`Clicked ${this.count} times`);
19
+ * }
20
+ * }
21
+ *
22
+ * const handler = new EventHandler();
23
+ * button.addEventListener('click', handler.handleClick);
24
+ * // Works correctly even when passed as callback
25
+ * ```
26
+ *
27
+ * @copyright Copyright (c) 2026 ResQ
28
+ * @license MIT
29
+ */
30
+ /**
31
+ * Decorator that automatically binds a method to its class instance.
32
+ * This ensures `this` always refers to the class instance, even when
33
+ * the method is passed as a callback or stored separately.
34
+ *
35
+ * Uses lazy binding on first access for better performance.
36
+ *
37
+ * @template T - The type of the class containing the decorated method
38
+ * @param {T} _target - The class prototype (unused)
39
+ * @param {string | symbol} propertyKey - The name of the method
40
+ * @param {TypedPropertyDescriptor<Method<unknown>>} descriptor - The property descriptor
41
+ * @returns {TypedPropertyDescriptor<Method<unknown>>} The modified descriptor
42
+ *
43
+ * @throws {Error} When applied to a non-method property
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * class MyClass {
48
+ * private value = 42;
49
+ *
50
+ * @bind
51
+ * getValue(): number {
52
+ * return this.value;
53
+ * }
54
+ *
55
+ * @bind
56
+ * async fetchData(): Promise<Data> {
57
+ * return await this.api.getData();
58
+ * }
59
+ * }
60
+ *
61
+ * const instance = new MyClass();
62
+ *
63
+ * // Works correctly when passed as callback
64
+ * const getValue = instance.getValue;
65
+ * console.log(getValue()); // 42
66
+ *
67
+ * // Works with async methods too
68
+ * const fetchData = instance.fetchData;
69
+ * const data = await fetchData();
70
+ * ```
71
+ */
72
+ declare function bind<T = unknown>(_target: T, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<Method<unknown>>): TypedPropertyDescriptor<Method<unknown>>;
73
+ //#endregion
74
+ export { bind };
75
+ //# sourceMappingURL=bind.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bind.d.ts","names":[],"sources":["../../src/bind/bind.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuFA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAgB,IAAA,aAAA,CACd,OAAA,EAAS,CAAA,EACT,WAAA,mBACA,UAAA,EAAY,uBAAA,CAAwB,MAAA,aACnC,uBAAA,CAAwB,MAAA"}
@@ -0,0 +1,46 @@
1
+ import { Method } from "../types.js";
2
+
3
+ //#region src/bind/bind.fn.d.ts
4
+ /**
5
+ * @fileoverview Bind function implementation - creates a bound version of a method.
6
+ *
7
+ * @module @resq/typescript/decorators/bind.fn
8
+ *
9
+ * @copyright Copyright (c) 2026 ResQ
10
+ * @license MIT
11
+ */
12
+ /**
13
+ * Creates a bound version of a method.
14
+ *
15
+ * @template D - The return type of the original method
16
+ * @template A - The argument types of the original method
17
+ * @param {Method<D, A>} originalMethod - The method to bind
18
+ * @param {unknown} context - The context (`this`) to bind to
19
+ * @returns {Method<D, A>} The bound method
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * class Calculator {
24
+ * private multiplier = 10;
25
+ *
26
+ * multiply(value: number): number {
27
+ * return value * this.multiplier;
28
+ * }
29
+ * }
30
+ *
31
+ * const calc = new Calculator();
32
+ *
33
+ * // Create bound version
34
+ * const boundMultiply = bindFn(calc.multiply.bind(calc), calc);
35
+ * const result = boundMultiply(5); // 50
36
+ *
37
+ * // Can also be used with different context
38
+ * const calc2 = new Calculator();
39
+ * // calc2.multiplier = 20;
40
+ * const boundToCalc2 = bindFn(calc.multiply, calc2);
41
+ * ```
42
+ */
43
+ declare function bindFn<D = unknown, A extends unknown[] = unknown[]>(originalMethod: Method<D, A>, context: unknown): Method<D, A>;
44
+ //#endregion
45
+ export { bindFn };
46
+ //# sourceMappingURL=bind.fn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bind.fn.d.ts","names":[],"sources":["../../src/bind/bind.fn.ts"],"mappings":";;;;;;;;;;;;;AA0CA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAgB,MAAA,8CAAA,CACd,cAAA,EAAgB,MAAA,CAAO,CAAA,EAAG,CAAA,GAC1B,OAAA,YACC,MAAA,CAAO,CAAA,EAAG,CAAA"}
@@ -0,0 +1,39 @@
1
+ //#region src/bind/bind.fn.ts
2
+ /**
3
+ * Creates a bound version of a method.
4
+ *
5
+ * @template D - The return type of the original method
6
+ * @template A - The argument types of the original method
7
+ * @param {Method<D, A>} originalMethod - The method to bind
8
+ * @param {unknown} context - The context (`this`) to bind to
9
+ * @returns {Method<D, A>} The bound method
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * class Calculator {
14
+ * private multiplier = 10;
15
+ *
16
+ * multiply(value: number): number {
17
+ * return value * this.multiplier;
18
+ * }
19
+ * }
20
+ *
21
+ * const calc = new Calculator();
22
+ *
23
+ * // Create bound version
24
+ * const boundMultiply = bindFn(calc.multiply.bind(calc), calc);
25
+ * const result = boundMultiply(5); // 50
26
+ *
27
+ * // Can also be used with different context
28
+ * const calc2 = new Calculator();
29
+ * // calc2.multiplier = 20;
30
+ * const boundToCalc2 = bindFn(calc.multiply, calc2);
31
+ * ```
32
+ */
33
+ function bindFn(originalMethod, context) {
34
+ return originalMethod.bind(context);
35
+ }
36
+ //#endregion
37
+ export { bindFn };
38
+
39
+ //# sourceMappingURL=bind.fn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bind.fn.js","names":[],"sources":["../../src/bind/bind.fn.ts"],"sourcesContent":["/**\n * @fileoverview Bind function implementation - creates a bound version of a method.\n *\n * @module @resq/typescript/decorators/bind.fn\n *\n * @copyright Copyright (c) 2026 ResQ\n * @license MIT\n */\n\nimport type { Method } from '../types.js';\n\n/**\n * Creates a bound version of a method.\n *\n * @template D - The return type of the original method\n * @template A - The argument types of the original method\n * @param {Method<D, A>} originalMethod - The method to bind\n * @param {unknown} context - The context (`this`) to bind to\n * @returns {Method<D, A>} The bound method\n *\n * @example\n * ```typescript\n * class Calculator {\n * private multiplier = 10;\n *\n * multiply(value: number): number {\n * return value * this.multiplier;\n * }\n * }\n *\n * const calc = new Calculator();\n *\n * // Create bound version\n * const boundMultiply = bindFn(calc.multiply.bind(calc), calc);\n * const result = boundMultiply(5); // 50\n *\n * // Can also be used with different context\n * const calc2 = new Calculator();\n * // calc2.multiplier = 20;\n * const boundToCalc2 = bindFn(calc.multiply, calc2);\n * ```\n */\nexport function bindFn<D = unknown, A extends unknown[] = unknown[]>(\n originalMethod: Method<D, A>,\n context: unknown,\n): Method<D, A> {\n return originalMethod.bind(context);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,SAAgB,OACd,gBACA,SACc;AACd,QAAO,eAAe,KAAK,QAAQ"}
@@ -0,0 +1,64 @@
1
+ //#region src/bind/bind.ts
2
+ /**
3
+ * Decorator that automatically binds a method to its class instance.
4
+ * This ensures `this` always refers to the class instance, even when
5
+ * the method is passed as a callback or stored separately.
6
+ *
7
+ * Uses lazy binding on first access for better performance.
8
+ *
9
+ * @template T - The type of the class containing the decorated method
10
+ * @param {T} _target - The class prototype (unused)
11
+ * @param {string | symbol} propertyKey - The name of the method
12
+ * @param {TypedPropertyDescriptor<Method<unknown>>} descriptor - The property descriptor
13
+ * @returns {TypedPropertyDescriptor<Method<unknown>>} The modified descriptor
14
+ *
15
+ * @throws {Error} When applied to a non-method property
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * class MyClass {
20
+ * private value = 42;
21
+ *
22
+ * @bind
23
+ * getValue(): number {
24
+ * return this.value;
25
+ * }
26
+ *
27
+ * @bind
28
+ * async fetchData(): Promise<Data> {
29
+ * return await this.api.getData();
30
+ * }
31
+ * }
32
+ *
33
+ * const instance = new MyClass();
34
+ *
35
+ * // Works correctly when passed as callback
36
+ * const getValue = instance.getValue;
37
+ * console.log(getValue()); // 42
38
+ *
39
+ * // Works with async methods too
40
+ * const fetchData = instance.fetchData;
41
+ * const data = await fetchData();
42
+ * ```
43
+ */
44
+ function bind(_target, propertyKey, descriptor) {
45
+ const originalMethod = descriptor.value;
46
+ if (!originalMethod) throw new Error("@bind is applicable only on methods.");
47
+ return {
48
+ configurable: true,
49
+ enumerable: false,
50
+ get() {
51
+ const boundMethod = originalMethod.bind(this);
52
+ Object.defineProperty(this, propertyKey, {
53
+ value: boundMethod,
54
+ configurable: true,
55
+ writable: true
56
+ });
57
+ return boundMethod;
58
+ }
59
+ };
60
+ }
61
+ //#endregion
62
+ export { bind };
63
+
64
+ //# sourceMappingURL=bind.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bind.js","names":[],"sources":["../../src/bind/bind.ts"],"sourcesContent":["/*\n * Copyright 2026 ResQ\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @fileoverview Bind decorator - automatically binds class methods to their\n * instance context. Ensures `this` always refers to the class instance.\n *\n * @module @resq/typescript/decorators/bind\n *\n * @example\n * ```typescript\n * class EventHandler {\n * private count = 0;\n *\n * @bind\n * handleClick(event: MouseEvent): void {\n * this.count++; // `this` correctly refers to EventHandler instance\n * console.log(`Clicked ${this.count} times`);\n * }\n * }\n *\n * const handler = new EventHandler();\n * button.addEventListener('click', handler.handleClick);\n * // Works correctly even when passed as callback\n * ```\n *\n * @copyright Copyright (c) 2026 ResQ\n * @license MIT\n */\n\nimport type { Method } from '../types.js';\n\n/**\n * Decorator that automatically binds a method to its class instance.\n * This ensures `this` always refers to the class instance, even when\n * the method is passed as a callback or stored separately.\n *\n * Uses lazy binding on first access for better performance.\n *\n * @template T - The type of the class containing the decorated method\n * @param {T} _target - The class prototype (unused)\n * @param {string | symbol} propertyKey - The name of the method\n * @param {TypedPropertyDescriptor<Method<unknown>>} descriptor - The property descriptor\n * @returns {TypedPropertyDescriptor<Method<unknown>>} The modified descriptor\n *\n * @throws {Error} When applied to a non-method property\n *\n * @example\n * ```typescript\n * class MyClass {\n * private value = 42;\n *\n * @bind\n * getValue(): number {\n * return this.value;\n * }\n *\n * @bind\n * async fetchData(): Promise<Data> {\n * return await this.api.getData();\n * }\n * }\n *\n * const instance = new MyClass();\n *\n * // Works correctly when passed as callback\n * const getValue = instance.getValue;\n * console.log(getValue()); // 42\n *\n * // Works with async methods too\n * const fetchData = instance.fetchData;\n * const data = await fetchData();\n * ```\n */\nexport function bind<T = unknown>(\n _target: T,\n propertyKey: string | symbol,\n descriptor: TypedPropertyDescriptor<Method<unknown>>,\n): TypedPropertyDescriptor<Method<unknown>> {\n const originalMethod = descriptor.value;\n\n if (!originalMethod) {\n throw new Error('@bind is applicable only on methods.');\n }\n\n // Use a getter to lazily bind the method on first access\n return {\n configurable: true,\n enumerable: false,\n get(this: object): Method<unknown> {\n const boundMethod = originalMethod.bind(this);\n\n // Define the bound method directly on the instance for subsequent accesses\n Object.defineProperty(this, propertyKey, {\n value: boundMethod,\n configurable: true,\n writable: true,\n });\n\n return boundMethod;\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuFA,SAAgB,KACd,SACA,aACA,YAC0C;CAC1C,MAAM,iBAAiB,WAAW;AAElC,KAAI,CAAC,eACH,OAAM,IAAI,MAAM,uCAAuC;AAIzD,QAAO;EACL,cAAc;EACd,YAAY;EACZ,MAAmC;GACjC,MAAM,cAAc,eAAe,KAAK,KAAK;AAG7C,UAAO,eAAe,MAAM,aAAa;IACvC,OAAO;IACP,cAAc;IACd,UAAU;IACX,CAAC;AAEF,UAAO;;EAEV"}
@@ -0,0 +1,36 @@
1
+ //#region src/bind/bind.types.d.ts
2
+ /**
3
+ * @fileoverview Type definitions for the Bind decorator.
4
+ * Provides configuration types for the bind decorator.
5
+ *
6
+ * @module @resq/typescript/decorators/bind/types
7
+ *
8
+ * @copyright Copyright (c) 2026 ResQ
9
+ * @license MIT
10
+ */
11
+ /**
12
+ * Configuration options for the bind decorator.
13
+ *
14
+ * @interface BindConfig
15
+ * @property {boolean} [lazy=true] - If true, the method is bound lazily on first access.
16
+ * If false, the method is bound at decoration time.
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * // Lazy binding (default) - binds on first access
21
+ * const lazyConfig: BindConfig = { lazy: true };
22
+ *
23
+ * // Eager binding - binds immediately
24
+ * const eagerConfig: BindConfig = { lazy: false };
25
+ * ```
26
+ */
27
+ interface BindConfig {
28
+ /**
29
+ * If true, the method is bound lazily on first access.
30
+ * If false (default), the method is bound at decoration time.
31
+ */
32
+ lazy?: boolean;
33
+ }
34
+ //#endregion
35
+ export { BindConfig };
36
+ //# sourceMappingURL=bind.types.d.ts.map