@tstdl/base 0.92.167 → 0.93.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 (317) hide show
  1. package/application/application.d.ts +12 -18
  2. package/application/application.js +48 -69
  3. package/application/index.d.ts +1 -5
  4. package/application/index.js +1 -5
  5. package/application/providers.d.ts +10 -0
  6. package/application/providers.js +54 -0
  7. package/audit/audit.model.d.ts +15 -0
  8. package/audit/audit.model.js +73 -0
  9. package/audit/auditor.d.ts +42 -0
  10. package/audit/auditor.js +111 -0
  11. package/audit/index.d.ts +3 -0
  12. package/audit/index.js +3 -0
  13. package/audit/types.d.ts +22 -0
  14. package/audit/types.js +19 -0
  15. package/authentication/client/authentication.service.d.ts +1 -3
  16. package/authentication/client/authentication.service.js +4 -5
  17. package/browser/browser-context-controller.d.ts +2 -4
  18. package/browser/browser-context-controller.js +5 -6
  19. package/browser/browser-controller.d.ts +2 -4
  20. package/browser/browser-controller.js +3 -4
  21. package/browser/browser.service.d.ts +1 -3
  22. package/browser/browser.service.js +1 -2
  23. package/browser/page-controller.d.ts +2 -4
  24. package/browser/page-controller.js +7 -8
  25. package/browser/utils.js +3 -3
  26. package/cancellation/token.d.ts +104 -41
  27. package/cancellation/token.js +125 -54
  28. package/core.d.ts +1 -13
  29. package/core.js +1 -46
  30. package/disposable/disposable.d.ts +0 -8
  31. package/disposable/disposable.js +1 -3
  32. package/disposable/index.d.ts +0 -6
  33. package/disposable/index.js +0 -6
  34. package/disposable/using.d.ts +0 -1
  35. package/disposable/using.js +2 -3
  36. package/distributed-loop/distributed-loop.js +2 -2
  37. package/errors/utils.js +4 -1
  38. package/examples/api/authentication.js +11 -5
  39. package/examples/api/basic-overview.js +17 -12
  40. package/examples/api/custom-authentication.js +13 -7
  41. package/examples/api/streaming.js +15 -12
  42. package/examples/browser/basic.js +6 -3
  43. package/examples/document-management/main.js +6 -3
  44. package/examples/http/client.js +7 -3
  45. package/examples/mail/basic.js +9 -7
  46. package/examples/pdf/basic.js +8 -6
  47. package/examples/template/basic.js +7 -5
  48. package/http/client/http-client-request.d.ts +1 -2
  49. package/http/client/http-client-request.js +1 -2
  50. package/http/server/http-server.d.ts +1 -3
  51. package/http/server/http-server.js +0 -1
  52. package/http/server/node/node-http-server.d.ts +1 -2
  53. package/http/server/node/node-http-server.js +1 -2
  54. package/import.js +1 -1
  55. package/injector/injector.d.ts +1 -1
  56. package/injector/types.d.ts +3 -4
  57. package/lock/lock.d.ts +40 -21
  58. package/lock/lock.js +74 -1
  59. package/lock/postgres/drizzle/0000_busy_tattoo.sql +7 -0
  60. package/lock/postgres/drizzle/meta/0000_snapshot.json +65 -0
  61. package/lock/postgres/drizzle/meta/_journal.json +13 -0
  62. package/lock/postgres/drizzle.config.js +11 -0
  63. package/lock/postgres/index.d.ts +2 -0
  64. package/lock/postgres/index.js +2 -0
  65. package/lock/postgres/lock.d.ts +14 -0
  66. package/lock/postgres/lock.js +127 -0
  67. package/lock/postgres/models/index.d.ts +2 -0
  68. package/lock/postgres/models/index.js +2 -0
  69. package/lock/postgres/models/lock.model.d.ts +7 -0
  70. package/{examples/orm/user.model.js → lock/postgres/models/lock.model.js} +22 -30
  71. package/lock/postgres/models/schemas.d.ts +3 -0
  72. package/lock/postgres/models/schemas.js +4 -0
  73. package/lock/postgres/module.d.ts +6 -0
  74. package/lock/postgres/module.js +26 -0
  75. package/lock/postgres/provider.d.ts +6 -0
  76. package/lock/postgres/provider.js +29 -0
  77. package/lock/provider.d.ts +12 -2
  78. package/lock/provider.js +24 -1
  79. package/lock/web/web-lock.d.ts +4 -3
  80. package/lock/web/web-lock.js +49 -42
  81. package/lock/web/web-lock.provider.d.ts +0 -3
  82. package/lock/web/web-lock.provider.js +5 -22
  83. package/logger/formatter.d.ts +13 -0
  84. package/logger/formatter.js +3 -0
  85. package/logger/formatters/index.d.ts +2 -0
  86. package/logger/formatters/index.js +2 -0
  87. package/logger/formatters/json.d.ts +5 -0
  88. package/logger/formatters/json.js +33 -0
  89. package/logger/formatters/pretty-print.d.ts +5 -0
  90. package/logger/formatters/pretty-print.js +55 -0
  91. package/logger/index.d.ts +5 -2
  92. package/logger/index.js +5 -2
  93. package/logger/level.d.ts +10 -8
  94. package/logger/level.js +9 -9
  95. package/logger/logger.d.ts +21 -30
  96. package/logger/logger.js +98 -26
  97. package/logger/manager.d.ts +20 -0
  98. package/logger/manager.js +86 -0
  99. package/logger/tokens.d.ts +1 -1
  100. package/logger/tokens.js +1 -1
  101. package/logger/transport.d.ts +14 -0
  102. package/logger/transport.js +16 -0
  103. package/logger/transports/console.d.ts +14 -0
  104. package/logger/transports/console.js +36 -0
  105. package/logger/transports/index.d.ts +1 -0
  106. package/logger/transports/index.js +1 -0
  107. package/mail/clients/nodemailer.mail-client.d.ts +0 -1
  108. package/mail/clients/nodemailer.mail-client.js +9 -7
  109. package/message-bus/local/local-message-bus.js +2 -2
  110. package/message-bus/message-bus-base.d.ts +2 -3
  111. package/message-bus/message-bus-base.js +5 -6
  112. package/message-bus/message-bus.d.ts +1 -2
  113. package/message-bus/message-bus.js +1 -2
  114. package/module/index.d.ts +0 -2
  115. package/module/index.js +0 -2
  116. package/module/module.d.ts +17 -18
  117. package/module/module.js +47 -12
  118. package/module/modules/function.module.d.ts +6 -6
  119. package/module/modules/function.module.js +25 -9
  120. package/module/modules/web-server.module.d.ts +2 -10
  121. package/module/modules/web-server.module.js +3 -11
  122. package/openid-connect/index.d.ts +0 -2
  123. package/openid-connect/index.js +0 -2
  124. package/openid-connect/oidc-state.model.d.ts +4 -5
  125. package/openid-connect/oidc-state.model.js +51 -1
  126. package/openid-connect/oidc.service-model.d.ts +1 -1
  127. package/openid-connect/oidc.service.d.ts +2 -6
  128. package/openid-connect/oidc.service.js +24 -37
  129. package/orm/decorators.d.ts +10 -1
  130. package/orm/decorators.js +8 -0
  131. package/orm/server/repository.d.ts +3 -1
  132. package/orm/server/repository.js +32 -3
  133. package/package.json +19 -29
  134. package/pdf/pdf.service.js +9 -9
  135. package/pool/pool.d.ts +1 -3
  136. package/pool/pool.js +3 -4
  137. package/queue/postgres/job.model.d.ts +1 -2
  138. package/queue/postgres/job.model.js +1 -2
  139. package/queue/postgres/module.js +1 -1
  140. package/threading/thread-pool.d.ts +1 -3
  141. package/threading/thread-pool.js +7 -8
  142. package/utils/format-error.d.ts +7 -0
  143. package/utils/format-error.js +59 -17
  144. package/utils/function/memoize.d.ts +22 -7
  145. package/utils/function/memoize.js +82 -23
  146. package/utils/index.d.ts +1 -0
  147. package/utils/index.js +1 -0
  148. package/utils/object/dereference.d.ts +51 -19
  149. package/utils/object/dereference.js +52 -43
  150. package/utils/timing.js +2 -2
  151. package/utils/try-chain.d.ts +22 -0
  152. package/utils/try-chain.js +46 -0
  153. package/database/entity-repository.d.ts +0 -50
  154. package/database/entity-repository.js +0 -3
  155. package/database/entity.d.ts +0 -7
  156. package/database/entity.js +0 -1
  157. package/database/id.d.ts +0 -1
  158. package/database/id.js +0 -9
  159. package/database/index.d.ts +0 -11
  160. package/database/index.js +0 -11
  161. package/database/module.d.ts +0 -8
  162. package/database/module.js +0 -11
  163. package/database/mongo/classes.d.ts +0 -21
  164. package/database/mongo/classes.js +0 -26
  165. package/database/mongo/index.d.ts +0 -15
  166. package/database/mongo/index.js +0 -15
  167. package/database/mongo/model/document.d.ts +0 -29
  168. package/database/mongo/model/document.js +0 -63
  169. package/database/mongo/model/index.d.ts +0 -1
  170. package/database/mongo/model/index.js +0 -1
  171. package/database/mongo/module.d.ts +0 -8
  172. package/database/mongo/module.js +0 -68
  173. package/database/mongo/mongo-base.repository.d.ts +0 -103
  174. package/database/mongo/mongo-base.repository.js +0 -263
  175. package/database/mongo/mongo-bulk.d.ts +0 -35
  176. package/database/mongo/mongo-bulk.js +0 -90
  177. package/database/mongo/mongo-entity-repository.d.ts +0 -98
  178. package/database/mongo/mongo-entity-repository.js +0 -278
  179. package/database/mongo/operations.d.ts +0 -10
  180. package/database/mongo/operations.js +0 -54
  181. package/database/mongo/query-converter.d.ts +0 -6
  182. package/database/mongo/query-converter.js +0 -83
  183. package/database/mongo/simple-entity-repository.d.ts +0 -7
  184. package/database/mongo/simple-entity-repository.js +0 -6
  185. package/database/mongo/types.d.ts +0 -50
  186. package/database/mongo/types.js +0 -3
  187. package/database/query.d.ts +0 -121
  188. package/database/query.js +0 -7
  189. package/database/utils.d.ts +0 -2
  190. package/database/utils.js +0 -3
  191. package/disposable/async-disposer.d.ts +0 -35
  192. package/disposable/async-disposer.js +0 -125
  193. package/examples/orm/drizzle.config.js +0 -6
  194. package/examples/orm/schemas.d.ts +0 -3
  195. package/examples/orm/schemas.js +0 -4
  196. package/examples/orm/test.d.ts +0 -1
  197. package/examples/orm/test.js +0 -11
  198. package/examples/orm/user.model.d.ts +0 -13
  199. package/key-value-store/mongo/index.d.ts +0 -6
  200. package/key-value-store/mongo/index.js +0 -6
  201. package/key-value-store/mongo/module.d.ts +0 -8
  202. package/key-value-store/mongo/module.js +0 -18
  203. package/key-value-store/mongo/mongo-key-value-store.provider.d.ts +0 -8
  204. package/key-value-store/mongo/mongo-key-value-store.provider.js +0 -26
  205. package/key-value-store/mongo/mongo-key-value.model.d.ts +0 -7
  206. package/key-value-store/mongo/mongo-key-value.model.js +0 -1
  207. package/key-value-store/mongo/mongo-key-value.repository.d.ts +0 -10
  208. package/key-value-store/mongo/mongo-key-value.repository.js +0 -31
  209. package/key-value-store/mongo/mongo-key-value.store.d.ts +0 -15
  210. package/key-value-store/mongo/mongo-key-value.store.js +0 -82
  211. package/key-value-store/mongo/tokens.d.ts +0 -3
  212. package/key-value-store/mongo/tokens.js +0 -2
  213. package/lock/mongo/index.d.ts +0 -5
  214. package/lock/mongo/index.js +0 -5
  215. package/lock/mongo/lock.d.ts +0 -14
  216. package/lock/mongo/lock.js +0 -125
  217. package/lock/mongo/model.d.ts +0 -6
  218. package/lock/mongo/model.js +0 -1
  219. package/lock/mongo/module.d.ts +0 -12
  220. package/lock/mongo/module.js +0 -20
  221. package/lock/mongo/mongo-lock-repository.d.ts +0 -14
  222. package/lock/mongo/mongo-lock-repository.js +0 -67
  223. package/lock/mongo/provider.d.ts +0 -8
  224. package/lock/mongo/provider.js +0 -36
  225. package/logger/console/index.d.ts +0 -1
  226. package/logger/console/index.js +0 -1
  227. package/logger/console/logger.d.ts +0 -11
  228. package/logger/console/logger.js +0 -64
  229. package/logger/noop/index.d.ts +0 -1
  230. package/logger/noop/index.js +0 -1
  231. package/logger/noop/logger.d.ts +0 -9
  232. package/logger/noop/logger.js +0 -21
  233. package/migration/index.d.ts +0 -9
  234. package/migration/index.js +0 -9
  235. package/migration/migration-state-repository.d.ts +0 -4
  236. package/migration/migration-state-repository.js +0 -3
  237. package/migration/migration-state.d.ts +0 -6
  238. package/migration/migration-state.js +0 -1
  239. package/migration/migrator.d.ts +0 -23
  240. package/migration/migrator.js +0 -76
  241. package/migration/mongo/index.d.ts +0 -2
  242. package/migration/mongo/index.js +0 -2
  243. package/migration/mongo/migration-state-repository.d.ts +0 -11
  244. package/migration/mongo/migration-state-repository.js +0 -32
  245. package/migration/mongo/module.d.ts +0 -12
  246. package/migration/mongo/module.js +0 -17
  247. package/module/module-base.d.ts +0 -18
  248. package/module/module-base.js +0 -40
  249. package/module/module-metric-reporter.d.ts +0 -29
  250. package/module/module-metric-reporter.js +0 -62
  251. package/openid-connect/mongo-oidc-state.repository.d.ts +0 -21
  252. package/openid-connect/mongo-oidc-state.repository.js +0 -52
  253. package/openid-connect/oidc-state.repository.d.ts +0 -4
  254. package/openid-connect/oidc-state.repository.js +0 -3
  255. package/process-shutdown.d.ts +0 -9
  256. package/process-shutdown.js +0 -65
  257. package/queue/mongo/index.d.ts +0 -4
  258. package/queue/mongo/index.js +0 -4
  259. package/queue/mongo/job.d.ts +0 -12
  260. package/queue/mongo/job.js +0 -1
  261. package/queue/mongo/mongo-job.repository.d.ts +0 -13
  262. package/queue/mongo/mongo-job.repository.js +0 -54
  263. package/queue/mongo/queue.d.ts +0 -38
  264. package/queue/mongo/queue.js +0 -266
  265. package/queue/mongo/queue.provider.d.ts +0 -18
  266. package/queue/mongo/queue.provider.js +0 -38
  267. package/search-index/elastic/config.d.ts +0 -8
  268. package/search-index/elastic/config.js +0 -26
  269. package/search-index/elastic/index.d.ts +0 -8
  270. package/search-index/elastic/index.js +0 -8
  271. package/search-index/elastic/keyword-rewriter.d.ts +0 -8
  272. package/search-index/elastic/keyword-rewriter.js +0 -18
  273. package/search-index/elastic/model/elastic-query.d.ts +0 -16
  274. package/search-index/elastic/model/elastic-query.js +0 -1
  275. package/search-index/elastic/model/index-mapping.d.ts +0 -26
  276. package/search-index/elastic/model/index-mapping.js +0 -4
  277. package/search-index/elastic/model/index.d.ts +0 -3
  278. package/search-index/elastic/model/index.js +0 -3
  279. package/search-index/elastic/model/sort.d.ts +0 -8
  280. package/search-index/elastic/model/sort.js +0 -1
  281. package/search-index/elastic/module.d.ts +0 -10
  282. package/search-index/elastic/module.js +0 -49
  283. package/search-index/elastic/query-builder/boolean-query-builder.d.ts +0 -11
  284. package/search-index/elastic/query-builder/boolean-query-builder.js +0 -52
  285. package/search-index/elastic/query-builder/index.d.ts +0 -1
  286. package/search-index/elastic/query-builder/index.js +0 -1
  287. package/search-index/elastic/query-converter.d.ts +0 -9
  288. package/search-index/elastic/query-converter.js +0 -183
  289. package/search-index/elastic/search-index.d.ts +0 -30
  290. package/search-index/elastic/search-index.js +0 -144
  291. package/search-index/elastic/sort-converter.d.ts +0 -4
  292. package/search-index/elastic/sort-converter.js +0 -14
  293. package/search-index/elastic/types.d.ts +0 -5
  294. package/search-index/elastic/types.js +0 -1
  295. package/search-index/error.d.ts +0 -10
  296. package/search-index/error.js +0 -14
  297. package/search-index/index.d.ts +0 -3
  298. package/search-index/index.js +0 -3
  299. package/search-index/memory/index.d.ts +0 -1
  300. package/search-index/memory/index.js +0 -1
  301. package/search-index/memory/memory-search-index.d.ts +0 -19
  302. package/search-index/memory/memory-search-index.js +0 -144
  303. package/search-index/search-index.d.ts +0 -46
  304. package/search-index/search-index.js +0 -31
  305. package/search-index/search-result.d.ts +0 -12
  306. package/search-index/search-result.js +0 -1
  307. package/theme/adapters/css-adapter.d.ts +0 -5
  308. package/theme/adapters/css-adapter.js +0 -29
  309. package/theme/adapters/index.d.ts +0 -2
  310. package/theme/adapters/index.js +0 -2
  311. package/theme/adapters/tailwind-adapter.d.ts +0 -18
  312. package/theme/adapters/tailwind-adapter.js +0 -32
  313. package/theme/index.d.ts +0 -1
  314. package/theme/index.js +0 -1
  315. package/theme/theme-service.d.ts +0 -43
  316. package/theme/theme-service.js +0 -128
  317. /package/{examples/orm → lock/postgres}/drizzle.config.d.ts +0 -0
@@ -1,7 +1,8 @@
1
1
  import { IterableWeakMap } from '../../data-structures/iterable-weak-map.js';
2
2
  import { MultiKeyMap } from '../../data-structures/multi-key-map.js';
3
3
  import { createAccessorDecorator } from '../../reflection/index.js';
4
- import { assertDefinedPass, isDefined } from '../type-guards.js';
4
+ import { assertDefinedPass, isDefined } from '../../utils/type-guards.js';
5
+ import { hasOwnProperty } from '../object/object.js';
5
6
  /**
6
7
  * Memoizes a function with an arbitrary number of parameters. If you only need a single parameter, {@link memoizeSingle} is faster
7
8
  * @param fn function memoize
@@ -46,47 +47,105 @@ export function memoizeClassSingle(type, options = {}) {
46
47
  return memoizeSingle((parameter) => new type(parameter), options);
47
48
  }
48
49
  /**
49
- * Memoizes an accessor (getter)
50
+ * Memoizes the result of a class getter, ensuring the getter's logic is
51
+ * executed only once per instance.
52
+ *
53
+ * Subsequent accesses to the getter will return the cached value.
54
+ *
55
+ * @param strategy The memoization strategy to use.
56
+ * - `attach`: (Default) Uses `Symbol` properties to store the cached value directly on the class instance. This is generally faster but adds hidden properties to the instance.
57
+ * - `weak-map`: Uses a `WeakMap` to store the cached value, with the class instance as the key. This avoids adding any properties to the instance, keeping it "clean".
50
58
  *
51
59
  * @example
52
60
  * ```typescript
53
- * class MyClass {
61
+ * class MyEvaluator {
54
62
  * @Memoize()
55
- * get myValue() {
56
- * // expensive calculation
57
- * return 123;
63
+ * get result() {
64
+ * // This expensive result creation only happens once per instance.
65
+ * return this.computeExpensiveResult();
58
66
  * }
59
67
  * }
68
+ *
69
+ * const service = new MyEvaluator();
70
+ * const s1 = service.result; // Logs "Creating new result..."
71
+ * const s2 = service.result; // Does not log anything, returns cached result.
72
+ * console.log(s1 === s2); // true
60
73
  * ```
61
74
  *
62
75
  * @remarks
63
- * The getter will be called only once for each instance of the class.
76
+ * If the decorated property has a corresponding setter, calling the setter will
77
+ * invalidate the cache. The getter will be re-evaluated on its next access.
78
+ *
79
+ * @returns An accessor decorator function.
64
80
  */
65
- export function Memoize() {
66
- const cache = new WeakMap();
81
+ export function Memoize(strategy = 'attach') {
67
82
  return createAccessorDecorator({
68
83
  handler: (data) => {
69
84
  const getter = assertDefinedPass(data.descriptor.get, 'Memoize requires an getter for accessors.'); // eslint-disable-line @typescript-eslint/unbound-method
70
85
  const setter = data.descriptor.set; // eslint-disable-line @typescript-eslint/unbound-method
71
- function cachedGetter() {
72
- if (cache.has(this)) {
73
- return cache.get(this); // eslint-disable-line @typescript-eslint/no-unsafe-return
74
- }
75
- const value = getter.call(this);
76
- cache.set(this, value);
77
- return value; // eslint-disable-line @typescript-eslint/no-unsafe-return
86
+ if (strategy == 'attach') {
87
+ return createAttachMemoizeHandler(data.propertyKey, getter, setter);
78
88
  }
79
- function cachedSetter(value) {
80
- setter?.call(this, value);
81
- cache.delete(this);
89
+ else {
90
+ return createWeakMapMemoizeHandler(getter, setter);
82
91
  }
83
- return {
84
- get: cachedGetter,
85
- set: isDefined(setter) ? cachedSetter : undefined,
86
- };
92
+ ;
87
93
  },
88
94
  });
89
95
  }
96
+ function createAttachMemoizeHandler(propertyKey, getter, setter) {
97
+ const stateKey = Symbol(`memoization[${String(propertyKey)}]`);
98
+ function getState(instance) {
99
+ if (!hasOwnProperty(instance, stateKey)) {
100
+ Object.defineProperty(instance, stateKey, {
101
+ value: { hasValue: false, value: undefined },
102
+ writable: false,
103
+ configurable: true,
104
+ enumerable: false,
105
+ });
106
+ }
107
+ return instance[stateKey];
108
+ }
109
+ function cachedGetter() {
110
+ const state = getState(this);
111
+ if (state.hasValue) {
112
+ return state.value;
113
+ }
114
+ const value = getter.call(this);
115
+ state.hasValue = true;
116
+ state.value = value;
117
+ return value;
118
+ }
119
+ function cachedSetter(value) {
120
+ setter.call(this, value);
121
+ if (hasOwnProperty(this, stateKey)) {
122
+ this[stateKey].hasValue = false;
123
+ this[stateKey].value = undefined;
124
+ }
125
+ }
126
+ return {
127
+ get: cachedGetter,
128
+ set: isDefined(setter) ? cachedSetter : undefined,
129
+ };
130
+ }
131
+ function createWeakMapMemoizeHandler(getter, setter) {
132
+ const cache = new WeakMap();
133
+ function cachedGetter() {
134
+ if (cache.has(this)) {
135
+ return cache.get(this);
136
+ }
137
+ const value = getter.call(this);
138
+ cache.set(this, value);
139
+ return value;
140
+ }
141
+ ;
142
+ function cachedSetter(value) {
143
+ setter.call(this, value);
144
+ cache.delete(this);
145
+ }
146
+ ;
147
+ return { get: cachedGetter, set: isDefined(setter) ? cachedSetter : undefined };
148
+ }
90
149
  function getMemoizedName(fn) {
91
150
  return `memoized${fn.name[0]?.toUpperCase() ?? ''}${fn.name.slice(1)}`;
92
151
  }
package/utils/index.d.ts CHANGED
@@ -49,6 +49,7 @@ export * from './sort.js';
49
49
  export * from './throw.js';
50
50
  export * from './timer.js';
51
51
  export * from './timing.js';
52
+ export * from './try-chain.js';
52
53
  export * from './try-ignore.js';
53
54
  export * from './type-guards.js';
54
55
  export * from './type-of.js';
package/utils/index.js CHANGED
@@ -49,6 +49,7 @@ export * from './sort.js';
49
49
  export * from './throw.js';
50
50
  export * from './timer.js';
51
51
  export * from './timing.js';
52
+ export * from './try-chain.js';
52
53
  export * from './try-ignore.js';
53
54
  export * from './type-guards.js';
54
55
  export * from './type-of.js';
@@ -1,34 +1,66 @@
1
1
  import { type JsonPathInput } from '../../json-path/index.js';
2
+ type CachedDereferencer<TOptional extends boolean | undefined> = TOptional extends true ? (<T = unknown>(object: object, reference: JsonPathInput) => T | undefined) : (<T = unknown>(object: object, reference: JsonPathInput) => T);
2
3
  export type DereferenceOptions = {
4
+ /**
5
+ * If true, the dereferencer will not throw an error if an intermediate
6
+ * property is null or undefined, and will return `undefined` instead.
7
+ * @default false
8
+ */
3
9
  optional?: boolean;
10
+ /**
11
+ * Method to use for dereferencing.
12
+ * - 'loop': Uses a simple loop to traverse the object. More robust, works in all environments.
13
+ * - 'function': Dynamically generates a function for dereferencing. Slow to compile, but faster at runtime - may not work in all environments. Automatically falls back to 'loop' if generation fails.
14
+ *
15
+ * @default 'loop' for `dereference`; 'function' for `compileDereferencer` and `getCachedDereference`
16
+ */
17
+ method?: 'loop' | 'function';
4
18
  };
5
19
  /**
6
- * Compiles a dereferencer for a specific reference
7
- * @param object object to dereference
8
- * @param reference path to property in dot notation or {@link JsonPath}
9
- * @returns referenced value
20
+ * Compiles a dereferencer for a specific reference path.
21
+ * This is the most performant option if you need to access the same path on many different objects.
22
+ *
23
+ * @param reference - Path to a property, e.g., 'a.b.c' or ['a', 'b', 'c'].
24
+ * @param options - Dereferencing options.
25
+ * @returns A specialized function to retrieve a value from an object.
10
26
  */
11
- export declare function compileDereferencer(reference: JsonPathInput, options?: DereferenceOptions): (object: object) => unknown;
27
+ export declare function compileDereferencer<T = unknown>(reference: JsonPathInput, options: DereferenceOptions & {
28
+ optional: true;
29
+ }): (object: object) => T | undefined;
30
+ export declare function compileDereferencer<T = unknown>(reference: JsonPathInput, options?: DereferenceOptions): (object: object) => T;
12
31
  /**
13
- * Dereference a reference
32
+ * Dereferences a value from an object using a reference path.
14
33
  *
15
- * @description useful if you dereference a reference a few times at most
34
+ * @description
35
+ * Best for one-off use. For repeated access, use `compileDereferencer` or `getCachedDereference`.
16
36
  *
17
- * also take a look at {@link getCachedDereference} and {@link compileDereferencer} if you need to dereference multiple times
18
- * @param object object to dereference
19
- * @param reference path to property in dot notation or {@link JsonPath}
20
- * @returns referenced value
37
+ * @param object - The object to access.
38
+ * @param reference - Path to a property, e.g., 'a.b.c' or ['a', 'b', 'c'].
39
+ * @param options - Dereferencing options.
40
+ * @returns The referenced value.
21
41
  */
22
- export declare function dereference(object: object, reference: JsonPathInput, options?: DereferenceOptions): unknown;
42
+ export declare function dereference<T = unknown>(object: object, reference: JsonPathInput, options: DereferenceOptions & {
43
+ optional: true;
44
+ }): T | undefined;
45
+ export declare function dereference<T = unknown>(object: object, reference: JsonPathInput, options?: DereferenceOptions): T;
23
46
  /**
24
- * Cached version of {@link dereference}. It caches the internally used dereferencer, but it does *not* cache the referenced value
47
+ * Returns a cached dereferencing function.
48
+ * The function caches the compiled dereferencer for each path, but not the resulting values.
25
49
  *
26
50
  * @description
27
- * useful if you dereference multiple references, each multiple times
51
+ * Ideal for applications that frequently access various, but repeating, paths on different objects.
52
+ *
53
+ * @example
54
+ * const optionalDeref = getCachedDereference({ optional: true });
55
+ * const value = optionalDeref(myObj, 'a.b.c'); // value is T | undefined
56
+ *
57
+ * const requiredDeref = getCachedDereference();
58
+ * const value2 = requiredDeref(myObj, 'a.b.c'); // value2 is T
28
59
  *
29
- * also take a look at {@link dereference} and {@link compileDereferencer} for other use cases
30
- * @param object object to dereference
31
- * @param reference path to property in dot notation or {@link JsonPath}
32
- * @returns referenced value
60
+ * @param options - Dereferencing options. These options are fixed for the lifetime of the returned function.
61
+ * @returns A function that takes an object and a reference and returns the value.
33
62
  */
34
- export declare function getCachedDereference(options?: DereferenceOptions): typeof dereference;
63
+ export declare function getCachedDereference<TOptional extends boolean | undefined>(options?: DereferenceOptions & {
64
+ optional: TOptional;
65
+ }): CachedDereferencer<TOptional>;
66
+ export {};
@@ -1,62 +1,71 @@
1
1
  import { JsonPath } from '../../json-path/index.js';
2
2
  import { memoizeSingle } from '../function/memoize.js';
3
- import { isNullOrUndefined } from '../type-guards.js';
4
- /**
5
- * Compiles a dereferencer for a specific reference
6
- * @param object object to dereference
7
- * @param reference path to property in dot notation or {@link JsonPath}
8
- * @returns referenced value
9
- */
10
- export function compileDereferencer(reference, options) {
11
- const nodes = JsonPath.from(reference).nodes;
12
- if (options?.optional == true) {
13
- return function optionalDereferencer(object) {
14
- let target = object;
15
- for (let i = 0; i < nodes.length; i++) { // eslint-disable-line @typescript-eslint/prefer-for-of
16
- if (isNullOrUndefined(target)) {
17
- return undefined;
18
- }
19
- target = target[nodes[i]];
20
- }
21
- return target;
22
- };
23
- }
3
+ import { isNullOrUndefined, isSymbol } from '../type-guards.js';
4
+ function compileLoopDereferencer(nodes, isOptional) {
24
5
  return function dereferencer(object) {
25
6
  let target = object;
26
7
  for (let i = 0; i < nodes.length; i++) { // eslint-disable-line @typescript-eslint/prefer-for-of
8
+ if (isOptional && isNullOrUndefined(target)) {
9
+ return undefined;
10
+ }
27
11
  target = target[nodes[i]];
28
12
  }
29
13
  return target;
30
14
  };
31
15
  }
32
- /**
33
- * Dereference a reference
34
- *
35
- * @description useful if you dereference a reference a few times at most
36
- *
37
- * also take a look at {@link getCachedDereference} and {@link compileDereferencer} if you need to dereference multiple times
38
- * @param object object to dereference
39
- * @param reference path to property in dot notation or {@link JsonPath}
40
- * @returns referenced value
41
- */
16
+ function compileFunctionDereferencer(nodes, isOptional) {
17
+ const accessor = isOptional
18
+ // Generates code like: obj?.['prop1']?.['prop2']
19
+ ? nodes.map((node) => `?.['${node.replace(/'/g, '\\\'')}']`).join('')
20
+ // Generates code like: obj['prop1']['prop2']
21
+ : nodes.map((node) => `['${node.replace(/'/g, '\\\'')}']`).join('');
22
+ const body = `
23
+ "use strict";
24
+ return object${accessor};
25
+ `;
26
+ return new Function('object', body);
27
+ }
28
+ export function compileDereferencer(reference, options) {
29
+ const nodes = JsonPath.from(reference).nodes;
30
+ const isOptional = options?.optional ?? false;
31
+ if (options?.method === 'loop') {
32
+ return compileLoopDereferencer(nodes, isOptional);
33
+ }
34
+ try {
35
+ for (const node of nodes) {
36
+ if (isSymbol(node)) {
37
+ throw new Error('Cannot compile function dereferencer for paths containing symbols');
38
+ }
39
+ }
40
+ return compileFunctionDereferencer(nodes, isOptional);
41
+ }
42
+ catch {
43
+ return compileLoopDereferencer(nodes, isOptional);
44
+ }
45
+ }
42
46
  export function dereference(object, reference, options) {
43
- return compileDereferencer(reference, options)(object);
47
+ return compileDereferencer(reference, { method: 'loop', ...options })(object);
44
48
  }
45
49
  /**
46
- * Cached version of {@link dereference}. It caches the internally used dereferencer, but it does *not* cache the referenced value
50
+ * Returns a cached dereferencing function.
51
+ * The function caches the compiled dereferencer for each path, but not the resulting values.
47
52
  *
48
53
  * @description
49
- * useful if you dereference multiple references, each multiple times
54
+ * Ideal for applications that frequently access various, but repeating, paths on different objects.
55
+ *
56
+ * @example
57
+ * const optionalDeref = getCachedDereference({ optional: true });
58
+ * const value = optionalDeref(myObj, 'a.b.c'); // value is T | undefined
50
59
  *
51
- * also take a look at {@link dereference} and {@link compileDereferencer} for other use cases
52
- * @param object object to dereference
53
- * @param reference path to property in dot notation or {@link JsonPath}
54
- * @returns referenced value
60
+ * const requiredDeref = getCachedDereference();
61
+ * const value2 = requiredDeref(myObj, 'a.b.c'); // value2 is T
62
+ *
63
+ * @param options - Dereferencing options. These options are fixed for the lifetime of the returned function.
64
+ * @returns A function that takes an object and a reference and returns the value.
55
65
  */
56
66
  export function getCachedDereference(options) {
57
- const memoizedDereferencer = memoizeSingle(compileDereferencer);
58
- function cachedDereference(object, reference) {
59
- return memoizedDereferencer(reference, options)(object);
60
- }
61
- return cachedDereference;
67
+ const memoizedCompiler = memoizeSingle((reference) => compileDereferencer(reference, options));
68
+ return function cachedDereference(object, reference) {
69
+ return memoizedCompiler(reference)(object);
70
+ };
62
71
  }
package/utils/timing.js CHANGED
@@ -29,8 +29,8 @@ export async function cancelableTimeout(milliseconds, cancelSignal) {
29
29
  }
30
30
  /** Timeout until specified time */
31
31
  export async function cancelableTimeoutUntil(timestamp, cancelSignal) {
32
- const left = timestamp.valueOf() - Date.now();
33
- return await cancelableTimeout(left, cancelSignal);
32
+ const millisecondsLeft = timestamp.valueOf() - Date.now();
33
+ return await cancelableTimeout(millisecondsLeft, cancelSignal);
34
34
  }
35
35
  export async function withTimeout(milliseconds, promiseOrProvider, options) {
36
36
  const abortController = new AbortController();
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Executes a series of functions (strategies) in order until one succeeds.
3
+ * If all strategies fail by throwing an error, the fallback function is executed.
4
+ *
5
+ * @template T The expected return type.
6
+ * @param strategies An array of functions to attempt, in order.
7
+ * @param fallback Optional function to execute if all strategies fail.
8
+ * @param onError Optional callback to handle/log errors from failing strategies.
9
+ * @returns The result of the first successful strategy or the fallback.
10
+ */
11
+ export declare function tryChain<T>(strategies: (() => T)[], onError?: (error: unknown, index: number) => void): T;
12
+ /**
13
+ * Executes a series of functions (strategies) in order until one succeeds.
14
+ * If all strategies fail by throwing an error, the fallback function is executed.
15
+ *
16
+ * @template T The expected return type.
17
+ * @param strategies An array of functions to attempt, in order.
18
+ * @param fallback Optional function to execute if all strategies fail.
19
+ * @param onError Optional callback to handle/log errors from failing strategies.
20
+ * @returns The result of the first successful strategy or the fallback.
21
+ */
22
+ export declare function tryChainAsync<T>(strategies: (() => T | Promise<T>)[], onError?: (error: unknown, index: number) => void): Promise<T>;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Executes a series of functions (strategies) in order until one succeeds.
3
+ * If all strategies fail by throwing an error, the fallback function is executed.
4
+ *
5
+ * @template T The expected return type.
6
+ * @param strategies An array of functions to attempt, in order.
7
+ * @param fallback Optional function to execute if all strategies fail.
8
+ * @param onError Optional callback to handle/log errors from failing strategies.
9
+ * @returns The result of the first successful strategy or the fallback.
10
+ */
11
+ export function tryChain(strategies, onError) {
12
+ const errors = [];
13
+ for (const [index, strategy] of strategies.entries()) {
14
+ try {
15
+ return strategy();
16
+ }
17
+ catch (error) {
18
+ errors.push(error);
19
+ onError?.(error, index);
20
+ }
21
+ }
22
+ throw new AggregateError(errors, 'All strategies failed and no fallback provided');
23
+ }
24
+ /**
25
+ * Executes a series of functions (strategies) in order until one succeeds.
26
+ * If all strategies fail by throwing an error, the fallback function is executed.
27
+ *
28
+ * @template T The expected return type.
29
+ * @param strategies An array of functions to attempt, in order.
30
+ * @param fallback Optional function to execute if all strategies fail.
31
+ * @param onError Optional callback to handle/log errors from failing strategies.
32
+ * @returns The result of the first successful strategy or the fallback.
33
+ */
34
+ export async function tryChainAsync(strategies, onError) {
35
+ const errors = [];
36
+ for (const [index, strategy] of strategies.entries()) {
37
+ try {
38
+ return await strategy();
39
+ }
40
+ catch (error) {
41
+ errors.push(error);
42
+ onError?.(error, index);
43
+ }
44
+ }
45
+ throw new AggregateError(errors, 'All strategies failed and no fallback provided');
46
+ }
@@ -1,50 +0,0 @@
1
- import type { Entity, MaybeNewEntity } from './entity.js';
2
- import type { Query, QueryOptions } from './query.js';
3
- export declare const repositoryType: unique symbol;
4
- export type UpdateOptions = {
5
- upsert?: boolean;
6
- };
7
- export type EntityPatch<T extends Entity = Entity> = Partial<Omit<T, 'id'>>;
8
- export declare abstract class EntityRepository<T extends Entity = Entity> {
9
- readonly [repositoryType]: T;
10
- abstract load<U extends T = T>(id: string): Promise<U>;
11
- abstract tryLoad<U extends T = T>(id: string): Promise<U | undefined>;
12
- abstract loadByFilter<U extends T = T>(query: Query<U>, options?: QueryOptions<U>): Promise<U>;
13
- abstract tryLoadByFilter<U extends T = T>(query: Query<U>, options?: QueryOptions<U>): Promise<U | undefined>;
14
- abstract loadMany<U extends T = T>(ids: string[], options?: QueryOptions<U>): Promise<U[]>;
15
- abstract loadManyCursor<U extends T = T>(ids: string[], options?: QueryOptions<U>): AsyncIterableIterator<U>;
16
- abstract loadManyByFilter<U extends T = T>(query: Query<U>, options?: QueryOptions<U>): Promise<U[]>;
17
- abstract loadManyByFilterCursor<U extends T = T>(query: Query<U>, options?: QueryOptions<U>): AsyncIterableIterator<U>;
18
- abstract loadAll<U extends T = T>(options?: QueryOptions<U>): Promise<U[]>;
19
- abstract loadAllCursor<U extends T = T>(options?: QueryOptions<U>): AsyncIterableIterator<U>;
20
- abstract loadAndDelete<U extends T = T>(id: string): Promise<U>;
21
- abstract tryLoadAndDelete<U extends T = T>(id: string): Promise<U | undefined>;
22
- abstract loadByFilterAndDelete<U extends T = T>(query: Query<U>, options?: QueryOptions<U>): Promise<U>;
23
- abstract tryLoadByFilterAndDelete<U extends T = T>(query: Query<U>, options?: QueryOptions<U>): Promise<U | undefined>;
24
- abstract loadAndPatch<U extends T = T>(id: string, patch: EntityPatch<U>, includePatch: boolean): Promise<U>;
25
- abstract tryLoadAndPatch<U extends T = T>(id: string, patch: EntityPatch<U>, includePatch: boolean): Promise<U | undefined>;
26
- abstract loadByFilterAndPatch<U extends T = T>(query: Query<U>, patch: EntityPatch<U>, includePatch: boolean, options?: QueryOptions<U>): Promise<U>;
27
- abstract tryLoadByFilterAndPatch<U extends T = T>(query: Query<U>, patch: EntityPatch<U>, includePatch: boolean, options?: QueryOptions<U>): Promise<U | undefined>;
28
- abstract count(allowEstimation?: boolean): Promise<number>;
29
- abstract countByFilter<U extends T>(query: Query<U>, allowEstimation?: boolean): Promise<number>;
30
- abstract has(id: string): Promise<boolean>;
31
- abstract hasByFilter<U extends T>(query: Query<U>): Promise<boolean>;
32
- abstract hasMany(ids: string[]): Promise<string[]>;
33
- abstract hasAll(ids: string[]): Promise<boolean>;
34
- abstract insert<U extends T>(entity: MaybeNewEntity<U>): Promise<U>;
35
- abstract insertMany<U extends T>(entities: MaybeNewEntity<U>[]): Promise<U[]>;
36
- abstract insertIfNotExists<U extends T>(entity: MaybeNewEntity<U>): Promise<U | undefined>;
37
- abstract insertIfNotExistsByFilter<U extends T>(query: Query<U>, entity: MaybeNewEntity<U>): Promise<U | undefined>;
38
- abstract update<U extends T>(entity: U, options?: UpdateOptions): Promise<boolean>;
39
- abstract updateMany<U extends T>(entities: U[], options?: UpdateOptions): Promise<number>;
40
- abstract patch<U extends T = T>(entity: U, patch: EntityPatch<U>): Promise<boolean>;
41
- abstract patchMany<U extends T = T>(entities: U[], patch: EntityPatch<U>): Promise<number>;
42
- abstract patchByFilter<U extends T = T>(query: Query<U>, patch: EntityPatch<U>): Promise<boolean>;
43
- abstract patchManyByFilter<U extends T = T>(query: Query<U>, patch: EntityPatch<U>): Promise<number>;
44
- abstract delete<U extends T>(entity: U): Promise<boolean>;
45
- abstract deleteMany<U extends T>(entities: U[]): Promise<number>;
46
- abstract deleteById(id: string): Promise<boolean>;
47
- abstract deleteManyById(ids: string[]): Promise<number>;
48
- abstract deleteByFilter<U extends T = T>(query: Query<U>): Promise<boolean>;
49
- abstract deleteManyByFilter<U extends T = T>(query: Query<U>): Promise<number>;
50
- }
@@ -1,3 +0,0 @@
1
- export const repositoryType = Symbol('repositoryType');
2
- export class EntityRepository {
3
- }
@@ -1,7 +0,0 @@
1
- export type Entity<Id = string> = {
2
- id: Id;
3
- };
4
- export type NewEntity<T extends Entity | MaybeNewEntity = Entity> = Omit<T, 'id'>;
5
- export type MaybeNewEntity<T extends Entity = Entity> = NewEntity<T> & {
6
- id?: T['id'];
7
- };
@@ -1 +0,0 @@
1
- export {};
package/database/id.d.ts DELETED
@@ -1 +0,0 @@
1
- export declare function getNewId(): string;
package/database/id.js DELETED
@@ -1,9 +0,0 @@
1
- import { Alphabet } from '../utils/alphabet.js';
2
- import { getRandomString } from '../utils/random.js';
3
- import { isDefined } from '../utils/type-guards.js';
4
- import { databaseModuleConfig } from './module.js';
5
- export function getNewId() {
6
- return isDefined(databaseModuleConfig.idGenerator)
7
- ? databaseModuleConfig.idGenerator()
8
- : getRandomString(databaseModuleConfig.idLength ?? 15, databaseModuleConfig.idAlphabet ?? Alphabet.LowerUpperCaseNumbers);
9
- }
@@ -1,11 +0,0 @@
1
- /**
2
- * Repository abstractions
3
- *
4
- * @module Database
5
- */
6
- export * from './entity-repository.js';
7
- export * from './entity.js';
8
- export * from './id.js';
9
- export * from './module.js';
10
- export * from './query.js';
11
- export * from './utils.js';
package/database/index.js DELETED
@@ -1,11 +0,0 @@
1
- /**
2
- * Repository abstractions
3
- *
4
- * @module Database
5
- */
6
- export * from './entity-repository.js';
7
- export * from './entity.js';
8
- export * from './id.js';
9
- export * from './module.js';
10
- export * from './query.js';
11
- export * from './utils.js';
@@ -1,8 +0,0 @@
1
- import { Alphabet } from '../utils/alphabet.js';
2
- export type DatabaseModuleConfig = {
3
- idLength?: number;
4
- idAlphabet?: Alphabet;
5
- idGenerator?: () => string;
6
- };
7
- export declare const databaseModuleConfig: DatabaseModuleConfig;
8
- export declare function configureDatabase(config: DatabaseModuleConfig): void;
@@ -1,11 +0,0 @@
1
- import { Alphabet } from '../utils/alphabet.js';
2
- export const databaseModuleConfig = {
3
- idLength: 15,
4
- idAlphabet: Alphabet.LowerUpperCaseNumbers,
5
- idGenerator: undefined
6
- };
7
- export function configureDatabase(config) {
8
- databaseModuleConfig.idLength = config.idLength;
9
- databaseModuleConfig.idAlphabet = config.idAlphabet;
10
- databaseModuleConfig.idGenerator = config.idGenerator;
11
- }
@@ -1,21 +0,0 @@
1
- import type { Entity } from '../../database/index.js';
2
- import type { Resolvable, resolveArgumentType } from '../../injector/interfaces.js';
3
- import { Db, Collection as MongoCollection, MongoClient as MongoMongoClient } from 'mongodb';
4
- import type { MongoDocument } from './model/document.js';
5
- import type { MongoConnection, MongoRepositoryConfig } from './types.js';
6
- export type MongoClientArgument = MongoConnection;
7
- /** database name */
8
- export type DatabaseArgument = string | {
9
- connection?: MongoConnection;
10
- database?: string;
11
- };
12
- export type CollectionArgument<T extends Entity<any> = Entity, TDb extends Entity<any> = T> = MongoRepositoryConfig<T, TDb>;
13
- export declare class MongoClient extends MongoMongoClient implements Resolvable<MongoClientArgument> {
14
- readonly [resolveArgumentType]: MongoClientArgument;
15
- }
16
- export declare class Database extends Db implements Resolvable<DatabaseArgument> {
17
- readonly [resolveArgumentType]: DatabaseArgument;
18
- }
19
- export declare class Collection<T extends Entity<any> = Entity, TDb extends Entity<any> = T> extends MongoCollection<MongoDocument<TDb>> implements Resolvable<CollectionArgument<T, TDb>> {
20
- readonly [resolveArgumentType]: CollectionArgument<T, TDb>;
21
- }
@@ -1,26 +0,0 @@
1
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
- return c > 3 && r && Object.defineProperty(target, key, r), r;
6
- };
7
- import { ReplaceClass } from '../../injector/decorators.js';
8
- import { Db, Collection as MongoCollection, MongoClient as MongoMongoClient } from 'mongodb';
9
- let MongoClient = class MongoClient extends MongoMongoClient {
10
- };
11
- MongoClient = __decorate([
12
- ReplaceClass(MongoMongoClient)
13
- ], MongoClient);
14
- export { MongoClient };
15
- let Database = class Database extends Db {
16
- };
17
- Database = __decorate([
18
- ReplaceClass(Db)
19
- ], Database);
20
- export { Database };
21
- let Collection = class Collection extends MongoCollection {
22
- };
23
- Collection = __decorate([
24
- ReplaceClass(MongoCollection)
25
- ], Collection);
26
- export { Collection };
@@ -1,15 +0,0 @@
1
- /**
2
- * MongoDB implemenation for Database module
3
- *
4
- * @module Database - MongoDB
5
- */
6
- export * from './classes.js';
7
- export * from './model/index.js';
8
- export * from './module.js';
9
- export * from './mongo-base.repository.js';
10
- export * from './mongo-bulk.js';
11
- export * from './mongo-entity-repository.js';
12
- export * from './operations.js';
13
- export * from './query-converter.js';
14
- export * from './simple-entity-repository.js';
15
- export * from './types.js';