joopjs 2.0.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 (259) hide show
  1. package/CHANGELOG.md +678 -0
  2. package/README.md +583 -0
  3. package/dist/a11y.service-C-DQQfgO.d.mts +143 -0
  4. package/dist/a11y.service-CauEJrJe.d.ts +143 -0
  5. package/dist/adapters-B6slG6hQ.d.mts +84 -0
  6. package/dist/adapters-B6slG6hQ.d.ts +84 -0
  7. package/dist/aes.service-CkoupAww.d.mts +95 -0
  8. package/dist/aes.service-CkoupAww.d.ts +95 -0
  9. package/dist/ai/index.d.mts +99 -0
  10. package/dist/ai/index.d.ts +99 -0
  11. package/dist/ai/index.js +307 -0
  12. package/dist/ai/index.js.map +1 -0
  13. package/dist/ai/index.mjs +304 -0
  14. package/dist/ai/index.mjs.map +1 -0
  15. package/dist/analytics/index.d.mts +42 -0
  16. package/dist/analytics/index.d.ts +42 -0
  17. package/dist/analytics/index.js +139 -0
  18. package/dist/analytics/index.js.map +1 -0
  19. package/dist/analytics/index.mjs +136 -0
  20. package/dist/analytics/index.mjs.map +1 -0
  21. package/dist/angular/index.d.mts +148 -0
  22. package/dist/angular/index.d.ts +148 -0
  23. package/dist/angular/index.js +122 -0
  24. package/dist/angular/index.js.map +1 -0
  25. package/dist/angular/index.mjs +101 -0
  26. package/dist/angular/index.mjs.map +1 -0
  27. package/dist/api/index.d.mts +128 -0
  28. package/dist/api/index.d.ts +128 -0
  29. package/dist/api/index.js +1358 -0
  30. package/dist/api/index.js.map +1 -0
  31. package/dist/api/index.mjs +1332 -0
  32. package/dist/api/index.mjs.map +1 -0
  33. package/dist/auth/index.d.mts +105 -0
  34. package/dist/auth/index.d.ts +105 -0
  35. package/dist/auth/index.js +989 -0
  36. package/dist/auth/index.js.map +1 -0
  37. package/dist/auth/index.mjs +979 -0
  38. package/dist/auth/index.mjs.map +1 -0
  39. package/dist/auth.service-DNVB-L4U.d.mts +16 -0
  40. package/dist/auth.service-PjUUSUIt.d.ts +16 -0
  41. package/dist/banking/index.d.mts +1530 -0
  42. package/dist/banking/index.d.ts +1530 -0
  43. package/dist/banking/index.js +4739 -0
  44. package/dist/banking/index.js.map +1 -0
  45. package/dist/banking/index.mjs +4661 -0
  46. package/dist/banking/index.mjs.map +1 -0
  47. package/dist/cache/index.d.mts +40 -0
  48. package/dist/cache/index.d.ts +40 -0
  49. package/dist/cache/index.js +174 -0
  50. package/dist/cache/index.js.map +1 -0
  51. package/dist/cache/index.mjs +172 -0
  52. package/dist/cache/index.mjs.map +1 -0
  53. package/dist/client-profile.service-BuPeXVp5.d.mts +28 -0
  54. package/dist/client-profile.service-D5bRRYQp.d.ts +28 -0
  55. package/dist/config.models-Cqg04fAQ.d.mts +84 -0
  56. package/dist/config.models-Cqg04fAQ.d.ts +84 -0
  57. package/dist/config.service-CrCvI-JS.d.ts +31 -0
  58. package/dist/config.service-Cz4QQLlf.d.mts +31 -0
  59. package/dist/core/index.d.mts +4 -0
  60. package/dist/core/index.d.ts +4 -0
  61. package/dist/core/index.js +631 -0
  62. package/dist/core/index.js.map +1 -0
  63. package/dist/core/index.mjs +619 -0
  64. package/dist/core/index.mjs.map +1 -0
  65. package/dist/crypto-utils-DriNhLdx.d.mts +30 -0
  66. package/dist/crypto-utils-DriNhLdx.d.ts +30 -0
  67. package/dist/data-storage.service-DT6xaTxE.d.ts +51 -0
  68. package/dist/data-storage.service-LvhGRCmw.d.mts +51 -0
  69. package/dist/deeplink/index.d.mts +39 -0
  70. package/dist/deeplink/index.d.ts +39 -0
  71. package/dist/deeplink/index.js +268 -0
  72. package/dist/deeplink/index.js.map +1 -0
  73. package/dist/deeplink/index.mjs +265 -0
  74. package/dist/deeplink/index.mjs.map +1 -0
  75. package/dist/deeplink.service-Ctd5u243.d.mts +35 -0
  76. package/dist/deeplink.service-uUuTnY9_.d.ts +35 -0
  77. package/dist/dev/index.d.mts +20 -0
  78. package/dist/dev/index.d.ts +20 -0
  79. package/dist/dev/index.js +51 -0
  80. package/dist/dev/index.js.map +1 -0
  81. package/dist/dev/index.mjs +49 -0
  82. package/dist/dev/index.mjs.map +1 -0
  83. package/dist/device/index.d.mts +108 -0
  84. package/dist/device/index.d.ts +108 -0
  85. package/dist/device/index.js +960 -0
  86. package/dist/device/index.js.map +1 -0
  87. package/dist/device/index.mjs +951 -0
  88. package/dist/device/index.mjs.map +1 -0
  89. package/dist/differential-privacy-BcAv1G80.d.mts +210 -0
  90. package/dist/differential-privacy-C8mAUjZr.d.ts +210 -0
  91. package/dist/encryption/index.d.mts +75 -0
  92. package/dist/encryption/index.d.ts +75 -0
  93. package/dist/encryption/index.js +605 -0
  94. package/dist/encryption/index.js.map +1 -0
  95. package/dist/encryption/index.mjs +598 -0
  96. package/dist/encryption/index.mjs.map +1 -0
  97. package/dist/form-validator-3tkmzr_o.d.mts +72 -0
  98. package/dist/form-validator-3tkmzr_o.d.ts +72 -0
  99. package/dist/forms/index.d.mts +59 -0
  100. package/dist/forms/index.d.ts +59 -0
  101. package/dist/forms/index.js +446 -0
  102. package/dist/forms/index.js.map +1 -0
  103. package/dist/forms/index.mjs +442 -0
  104. package/dist/forms/index.mjs.map +1 -0
  105. package/dist/i18n/index.d.mts +37 -0
  106. package/dist/i18n/index.d.ts +37 -0
  107. package/dist/i18n/index.js +147 -0
  108. package/dist/i18n/index.js.map +1 -0
  109. package/dist/i18n/index.mjs +145 -0
  110. package/dist/i18n/index.mjs.map +1 -0
  111. package/dist/idempotency.service-_6LqhivP.d.mts +372 -0
  112. package/dist/idempotency.service-eOKoISRD.d.ts +372 -0
  113. package/dist/index-B_ksKpS1.d.mts +202 -0
  114. package/dist/index-CqDKWTUP.d.mts +28 -0
  115. package/dist/index-CqDKWTUP.d.ts +28 -0
  116. package/dist/index-DFqEoX_l.d.ts +202 -0
  117. package/dist/index-Dz0gOur2.d.mts +36 -0
  118. package/dist/index-Dz0gOur2.d.ts +36 -0
  119. package/dist/index.d.mts +1336 -0
  120. package/dist/index.d.ts +1336 -0
  121. package/dist/index.js +19464 -0
  122. package/dist/index.js.map +1 -0
  123. package/dist/index.mjs +19155 -0
  124. package/dist/index.mjs.map +1 -0
  125. package/dist/india/index.d.mts +75 -0
  126. package/dist/india/index.d.ts +75 -0
  127. package/dist/india/index.js +325 -0
  128. package/dist/india/index.js.map +1 -0
  129. package/dist/india/index.mjs +303 -0
  130. package/dist/india/index.mjs.map +1 -0
  131. package/dist/joop-Bx7Iwj5p.d.mts +155 -0
  132. package/dist/joop-CA3DMeOO.d.ts +155 -0
  133. package/dist/native-bridge/index.d.mts +27 -0
  134. package/dist/native-bridge/index.d.ts +27 -0
  135. package/dist/native-bridge/index.js +98 -0
  136. package/dist/native-bridge/index.js.map +1 -0
  137. package/dist/native-bridge/index.mjs +96 -0
  138. package/dist/native-bridge/index.mjs.map +1 -0
  139. package/dist/network/index.d.mts +85 -0
  140. package/dist/network/index.d.ts +85 -0
  141. package/dist/network/index.js +454 -0
  142. package/dist/network/index.js.map +1 -0
  143. package/dist/network/index.mjs +451 -0
  144. package/dist/network/index.mjs.map +1 -0
  145. package/dist/network-monitor-BIwPSXme.d.mts +179 -0
  146. package/dist/network-monitor-Bqp2hvZr.d.ts +179 -0
  147. package/dist/notification.service-Dm4fvfZf.d.mts +25 -0
  148. package/dist/notification.service-tEMKatWJ.d.ts +25 -0
  149. package/dist/observability/index.d.mts +179 -0
  150. package/dist/observability/index.d.ts +179 -0
  151. package/dist/observability/index.js +559 -0
  152. package/dist/observability/index.js.map +1 -0
  153. package/dist/observability/index.mjs +552 -0
  154. package/dist/observability/index.mjs.map +1 -0
  155. package/dist/oidc-client-DIJcClmB.d.mts +190 -0
  156. package/dist/oidc-client-DxhyE59t.d.ts +190 -0
  157. package/dist/platform/index.d.mts +73 -0
  158. package/dist/platform/index.d.ts +73 -0
  159. package/dist/platform/index.js +127 -0
  160. package/dist/platform/index.js.map +1 -0
  161. package/dist/platform/index.mjs +125 -0
  162. package/dist/platform/index.mjs.map +1 -0
  163. package/dist/pwa/index.d.mts +31 -0
  164. package/dist/pwa/index.d.ts +31 -0
  165. package/dist/pwa/index.js +247 -0
  166. package/dist/pwa/index.js.map +1 -0
  167. package/dist/pwa/index.mjs +244 -0
  168. package/dist/pwa/index.mjs.map +1 -0
  169. package/dist/react/index.d.mts +133 -0
  170. package/dist/react/index.d.ts +133 -0
  171. package/dist/react/index.js +632 -0
  172. package/dist/react/index.js.map +1 -0
  173. package/dist/react/index.mjs +630 -0
  174. package/dist/react/index.mjs.map +1 -0
  175. package/dist/router/index.d.mts +39 -0
  176. package/dist/router/index.d.ts +39 -0
  177. package/dist/router/index.js +168 -0
  178. package/dist/router/index.js.map +1 -0
  179. package/dist/router/index.mjs +166 -0
  180. package/dist/router/index.mjs.map +1 -0
  181. package/dist/security/index.d.mts +206 -0
  182. package/dist/security/index.d.ts +206 -0
  183. package/dist/security/index.js +1297 -0
  184. package/dist/security/index.js.map +1 -0
  185. package/dist/security/index.mjs +1285 -0
  186. package/dist/security/index.mjs.map +1 -0
  187. package/dist/session/index.d.mts +115 -0
  188. package/dist/session/index.d.ts +115 -0
  189. package/dist/session/index.js +297 -0
  190. package/dist/session/index.js.map +1 -0
  191. package/dist/session/index.mjs +292 -0
  192. package/dist/session/index.mjs.map +1 -0
  193. package/dist/state/index.d.mts +43 -0
  194. package/dist/state/index.d.ts +43 -0
  195. package/dist/state/index.js +156 -0
  196. package/dist/state/index.js.map +1 -0
  197. package/dist/state/index.mjs +152 -0
  198. package/dist/state/index.mjs.map +1 -0
  199. package/dist/statement-parser-BHQtXwCM.d.ts +260 -0
  200. package/dist/statement-parser-C2qNmb49.d.mts +260 -0
  201. package/dist/storage/index.d.mts +40 -0
  202. package/dist/storage/index.d.ts +40 -0
  203. package/dist/storage/index.js +256 -0
  204. package/dist/storage/index.js.map +1 -0
  205. package/dist/storage/index.mjs +252 -0
  206. package/dist/storage/index.mjs.map +1 -0
  207. package/dist/sync/index.d.mts +69 -0
  208. package/dist/sync/index.d.ts +69 -0
  209. package/dist/sync/index.js +330 -0
  210. package/dist/sync/index.js.map +1 -0
  211. package/dist/sync/index.mjs +323 -0
  212. package/dist/sync/index.mjs.map +1 -0
  213. package/dist/sync-engine-DCIMRG5s.d.ts +61 -0
  214. package/dist/sync-engine-DZqyKHkK.d.mts +61 -0
  215. package/dist/theme/index.d.mts +53 -0
  216. package/dist/theme/index.d.ts +53 -0
  217. package/dist/theme/index.js +169 -0
  218. package/dist/theme/index.js.map +1 -0
  219. package/dist/theme/index.mjs +167 -0
  220. package/dist/theme/index.mjs.map +1 -0
  221. package/dist/ui/index.d.mts +66 -0
  222. package/dist/ui/index.d.ts +66 -0
  223. package/dist/ui/index.js +811 -0
  224. package/dist/ui/index.js.map +1 -0
  225. package/dist/ui/index.mjs +803 -0
  226. package/dist/ui/index.mjs.map +1 -0
  227. package/dist/utilities/index.d.mts +199 -0
  228. package/dist/utilities/index.d.ts +199 -0
  229. package/dist/utilities/index.js +1991 -0
  230. package/dist/utilities/index.js.map +1 -0
  231. package/dist/utilities/index.mjs +1923 -0
  232. package/dist/utilities/index.mjs.map +1 -0
  233. package/dist/validation/index.d.mts +60 -0
  234. package/dist/validation/index.d.ts +60 -0
  235. package/dist/validation/index.js +460 -0
  236. package/dist/validation/index.js.map +1 -0
  237. package/dist/validation/index.mjs +455 -0
  238. package/dist/validation/index.mjs.map +1 -0
  239. package/dist/vue/index.d.mts +135 -0
  240. package/dist/vue/index.d.ts +135 -0
  241. package/dist/vue/index.js +621 -0
  242. package/dist/vue/index.js.map +1 -0
  243. package/dist/vue/index.mjs +619 -0
  244. package/dist/vue/index.mjs.map +1 -0
  245. package/dist/watermark.service-Detur5tq.d.ts +235 -0
  246. package/dist/watermark.service-QNegMeQZ.d.mts +235 -0
  247. package/dist/workers/index.d.mts +42 -0
  248. package/dist/workers/index.d.ts +42 -0
  249. package/dist/workers/index.js +359 -0
  250. package/dist/workers/index.js.map +1 -0
  251. package/dist/workers/index.mjs +356 -0
  252. package/dist/workers/index.mjs.map +1 -0
  253. package/dist/workflow/index.d.mts +99 -0
  254. package/dist/workflow/index.d.ts +99 -0
  255. package/dist/workflow/index.js +282 -0
  256. package/dist/workflow/index.js.map +1 -0
  257. package/dist/workflow/index.mjs +279 -0
  258. package/dist/workflow/index.mjs.map +1 -0
  259. package/package.json +226 -0
@@ -0,0 +1,619 @@
1
+ // src/constants/index.ts
2
+ var DEFAULT_REQUEST_TIMEOUT = 3e4;
3
+
4
+ // src/utilities/common.utility.ts
5
+ function removeTrailingSlash(url) {
6
+ return url?.endsWith("/") ? url.slice(0, -1) : url;
7
+ }
8
+
9
+ // src/core/config/config.service.ts
10
+ var JoopConfigService = class {
11
+ _config = null;
12
+ /**
13
+ * Load config from a remote URL (e.g. config/settings.json) or use an already-resolved object.
14
+ */
15
+ async load(configOrUrl) {
16
+ if (configOrUrl && typeof configOrUrl === "object") {
17
+ this._config = configOrUrl;
18
+ return this._config;
19
+ }
20
+ const url = typeof configOrUrl === "string" ? configOrUrl : "config/settings.json";
21
+ const res = await fetch(url);
22
+ if (!res.ok) throw new Error(`Failed to load config from ${url}: ${res.statusText}`);
23
+ this._config = await res.json();
24
+ return this._config;
25
+ }
26
+ /** Set config directly without fetching. */
27
+ setConfig(config) {
28
+ this._config = config;
29
+ }
30
+ /** Generic key access. */
31
+ get(key) {
32
+ return this._raw?.[key];
33
+ }
34
+ get app() {
35
+ return this._raw.app;
36
+ }
37
+ get timeout() {
38
+ return this._raw.timeout;
39
+ }
40
+ get requestTimeout() {
41
+ return this._raw.timeout?.requestTimeout ?? DEFAULT_REQUEST_TIMEOUT;
42
+ }
43
+ get session() {
44
+ return this._raw.timeout?.session;
45
+ }
46
+ get localization() {
47
+ return this._raw.localization;
48
+ }
49
+ get loggerConfig() {
50
+ return this._raw.logger;
51
+ }
52
+ get isLoggerEnabled() {
53
+ return this._raw.logger?.enable ?? false;
54
+ }
55
+ get isLoggerDateEnabled() {
56
+ return this._raw.logger?.enableDate ?? false;
57
+ }
58
+ get loggerTypeConfig() {
59
+ return this._raw.logger?.typeConfig ?? {};
60
+ }
61
+ get logoutService() {
62
+ return this._raw.app?.logoutService ?? "";
63
+ }
64
+ get ignoreServices() {
65
+ return this._raw.timeout?.session?.ignoreServices ?? [];
66
+ }
67
+ get baseUrl() {
68
+ return removeTrailingSlash(this._raw.app?.baseUrl ?? "");
69
+ }
70
+ get isDevMode() {
71
+ return this._raw.isDevMode ?? false;
72
+ }
73
+ get _raw() {
74
+ if (!this._config) throw new Error("JoopConfigService: config not loaded. Call load() first.");
75
+ return this._config;
76
+ }
77
+ };
78
+ var configService = new JoopConfigService();
79
+
80
+ // src/events/index.ts
81
+ var JoopSubject = class {
82
+ _listeners = [];
83
+ subscribe(listener) {
84
+ this._listeners.push(listener);
85
+ return () => {
86
+ this._listeners = this._listeners.filter((l) => l !== listener);
87
+ };
88
+ }
89
+ next(value) {
90
+ for (const listener of this._listeners) {
91
+ listener(value);
92
+ }
93
+ }
94
+ asObservable() {
95
+ return new JoopObservable((listener) => this.subscribe(listener));
96
+ }
97
+ };
98
+ var JoopBehaviorSubject = class extends JoopSubject {
99
+ _value;
100
+ constructor(initialValue) {
101
+ super();
102
+ this._value = initialValue;
103
+ }
104
+ getValue() {
105
+ return this._value;
106
+ }
107
+ next(value) {
108
+ this._value = value;
109
+ super.next(value);
110
+ }
111
+ subscribe(listener) {
112
+ listener(this._value);
113
+ return super.subscribe(listener);
114
+ }
115
+ asObservable() {
116
+ return new JoopObservable((listener) => this.subscribe(listener));
117
+ }
118
+ };
119
+ var JoopObservable = class {
120
+ constructor(_subscribeFn) {
121
+ this._subscribeFn = _subscribeFn;
122
+ }
123
+ _subscribeFn;
124
+ subscribe(listener) {
125
+ return this._subscribeFn(listener);
126
+ }
127
+ /** Returns the current value without subscribing (only meaningful for BehaviorSubject-backed observables). */
128
+ getOnce() {
129
+ let result;
130
+ const unsub = this.subscribe((v) => {
131
+ result = v;
132
+ });
133
+ unsub();
134
+ return result;
135
+ }
136
+ };
137
+
138
+ // src/core/logger/logger.service.ts
139
+ var JoopLogger = class {
140
+ _logSubject = new JoopSubject();
141
+ _config = { enable: false };
142
+ configure(config) {
143
+ this._config = config;
144
+ }
145
+ debug(message, options) {
146
+ this._emit("debug", message, options);
147
+ }
148
+ log(message, options) {
149
+ this._emit("log", message, options);
150
+ }
151
+ info(message, options) {
152
+ this._emit("info", message, options);
153
+ }
154
+ warn(message, options) {
155
+ this._emit("warn", message, options);
156
+ }
157
+ error(message, options) {
158
+ this._emit("error", message, options);
159
+ }
160
+ /** Subscribe to all log entries (useful for remote logging). */
161
+ onLog(listener) {
162
+ return this._logSubject.subscribe(listener);
163
+ }
164
+ _shouldLog(level) {
165
+ if (!this._config.enable) return false;
166
+ const tc = this._config.typeConfig ?? {};
167
+ return !!(tc["all"] || tc[level]);
168
+ }
169
+ _emit(level, message, options) {
170
+ if (!this._shouldLog(level)) return;
171
+ const timestamp = this._config.enableDate || options?.isDateEnabled ? (/* @__PURE__ */ new Date()).toISOString() : void 0;
172
+ const entry = { level, message, timestamp, component: options?.componentName };
173
+ this._logSubject.next(entry);
174
+ const prefix = [timestamp, options?.componentName].filter(Boolean).join(" ");
175
+ const style = options?.color ? `color: ${options.color}` : "";
176
+ const text = prefix ? `${prefix} ${this._serialize(message)}` : this._serialize(message);
177
+ switch (level) {
178
+ case "debug":
179
+ return void console.debug(`%c${text}`, style);
180
+ case "log":
181
+ return void console.log(`%c${text}`, style);
182
+ case "info":
183
+ return void console.info(`%c${text}`, style);
184
+ case "warn":
185
+ return void console.warn(`%c${text}`, style);
186
+ case "error":
187
+ return void console.error(`%c${text}`, style);
188
+ }
189
+ }
190
+ _serialize(message) {
191
+ if (typeof message === "string") return message;
192
+ try {
193
+ return JSON.stringify(message);
194
+ } catch {
195
+ return String(message);
196
+ }
197
+ }
198
+ };
199
+ var logger = new JoopLogger();
200
+
201
+ // src/core/plugin.service.ts
202
+ var JoopPluginService = class {
203
+ _plugins = /* @__PURE__ */ new Map();
204
+ _context = {};
205
+ setContext(ctx) {
206
+ this._context = { ...this._context, ...ctx };
207
+ }
208
+ async use(plugin) {
209
+ if (this._plugins.has(plugin.name)) {
210
+ throw new Error(`Plugin "${plugin.name}" is already registered`);
211
+ }
212
+ await plugin.install(this._context);
213
+ this._plugins.set(plugin.name, plugin);
214
+ }
215
+ unuse(name) {
216
+ const plugin = this._plugins.get(name);
217
+ if (!plugin) return;
218
+ plugin.uninstall?.();
219
+ this._plugins.delete(name);
220
+ }
221
+ has(name) {
222
+ return this._plugins.has(name);
223
+ }
224
+ getAll() {
225
+ return [...this._plugins.values()];
226
+ }
227
+ unuseAll() {
228
+ [...this._plugins.keys()].forEach((n) => this.unuse(n));
229
+ }
230
+ };
231
+
232
+ // src/core/environment.service.ts
233
+ var JoopEnvironmentService = class {
234
+ _current = null;
235
+ _profiles = /* @__PURE__ */ new Map();
236
+ register(profile) {
237
+ this._profiles.set(profile.name, profile);
238
+ }
239
+ activate(name) {
240
+ const profile = this._profiles.get(name);
241
+ if (!profile) throw new Error(`Environment profile "${name}" not registered`);
242
+ this._current = profile;
243
+ }
244
+ detect() {
245
+ const nodeEnv = typeof globalThis !== "undefined" && globalThis.process?.env?.NODE_ENV;
246
+ if (nodeEnv) return nodeEnv;
247
+ if (typeof window !== "undefined") {
248
+ const host = window.location.hostname;
249
+ if (host === "localhost" || host === "127.0.0.1") return "development";
250
+ if (host.includes("staging") || host.includes("uat") || host.includes("test")) return "staging";
251
+ }
252
+ return "production";
253
+ }
254
+ get current() {
255
+ if (!this._current) throw new Error("No environment activated \u2014 call activate() first");
256
+ return this._current;
257
+ }
258
+ get name() {
259
+ return this.current.name;
260
+ }
261
+ get apiBaseUrl() {
262
+ return this.current.apiBaseUrl;
263
+ }
264
+ isDev() {
265
+ return this.current.name === "development";
266
+ }
267
+ isStaging() {
268
+ return this.current.name === "staging";
269
+ }
270
+ isProduction() {
271
+ return this.current.name === "production";
272
+ }
273
+ isFeatureEnabled(feature) {
274
+ return this.current.features?.[feature] ?? false;
275
+ }
276
+ get(key) {
277
+ return this.current[key];
278
+ }
279
+ };
280
+
281
+ // src/core/health.service.ts
282
+ var JoopHealthService = class {
283
+ _checks = [];
284
+ register(check) {
285
+ this._checks.push(check);
286
+ }
287
+ async runAll() {
288
+ return Promise.all(this._checks.map((c) => this._run(c)));
289
+ }
290
+ async run(name) {
291
+ const check = this._checks.find((c) => c.name === name);
292
+ return check ? this._run(check) : null;
293
+ }
294
+ async pingUrl(url, timeoutMs = 5e3) {
295
+ const start = performance.now();
296
+ try {
297
+ const controller = new AbortController();
298
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
299
+ const res = await fetch(url, { method: "HEAD", signal: controller.signal });
300
+ clearTimeout(timer);
301
+ return { name: url, healthy: res.ok, latencyMs: Math.round(performance.now() - start), timestamp: Date.now() };
302
+ } catch (err) {
303
+ return {
304
+ name: url,
305
+ healthy: false,
306
+ latencyMs: Math.round(performance.now() - start),
307
+ error: err instanceof Error ? err.message : String(err),
308
+ timestamp: Date.now()
309
+ };
310
+ }
311
+ }
312
+ async _run(check) {
313
+ const start = performance.now();
314
+ try {
315
+ const result = await Promise.race([
316
+ check.check(),
317
+ new Promise(
318
+ (_, reject) => setTimeout(() => reject(new Error("Health check timeout")), check.timeoutMs ?? 5e3)
319
+ )
320
+ ]);
321
+ return { name: check.name, healthy: result, latencyMs: Math.round(performance.now() - start), timestamp: Date.now() };
322
+ } catch (err) {
323
+ return {
324
+ name: check.name,
325
+ healthy: false,
326
+ latencyMs: Math.round(performance.now() - start),
327
+ error: err instanceof Error ? err.message : String(err),
328
+ timestamp: Date.now()
329
+ };
330
+ }
331
+ }
332
+ };
333
+
334
+ // src/core/feature-flag.service.ts
335
+ var JoopFeatureFlagService = class {
336
+ _flags = /* @__PURE__ */ new Map();
337
+ _overrides = /* @__PURE__ */ new Map();
338
+ _context = {};
339
+ _flags$ = new JoopBehaviorSubject(/* @__PURE__ */ new Map());
340
+ /** Register flag definitions */
341
+ define(flags) {
342
+ for (const f of flags) this._flags.set(f.key, f);
343
+ this._flags$.next(new Map(this._flags));
344
+ }
345
+ /** Load flags from a remote JSON endpoint */
346
+ async loadFromUrl(url) {
347
+ const res = await fetch(url);
348
+ const flags = await res.json();
349
+ this.define(flags);
350
+ }
351
+ /** Set user/environment context for targeting */
352
+ setContext(ctx) {
353
+ this._context = { ...this._context, ...ctx };
354
+ }
355
+ /** Check if a feature flag is enabled for the current context */
356
+ isEnabled(key, context) {
357
+ if (this._overrides.has(key)) return this._overrides.get(key);
358
+ const flag = this._flags.get(key);
359
+ if (!flag) return false;
360
+ if (!flag.enabled) return false;
361
+ const ctx = { ...this._context, ...context };
362
+ if (flag.environments?.length && ctx.environment && !flag.environments.includes(ctx.environment)) return false;
363
+ if (flag.allowedUsers?.length && ctx.userId && !flag.allowedUsers.includes(ctx.userId)) return false;
364
+ if (flag.rolloutPercent !== void 0 && ctx.userId) {
365
+ const hash = this._hash(`${key}:${ctx.userId}`);
366
+ if (hash % 100 >= flag.rolloutPercent) return false;
367
+ }
368
+ return true;
369
+ }
370
+ /** Get the variant string for a flag */
371
+ getVariant(key, context) {
372
+ if (!this.isEnabled(key, context)) return null;
373
+ return this._flags.get(key)?.variant ?? null;
374
+ }
375
+ /** Override a flag locally (for testing) */
376
+ setOverride(key, value) {
377
+ this._overrides.set(key, value);
378
+ this._flags$.next(new Map(this._flags));
379
+ }
380
+ clearOverrides() {
381
+ this._overrides.clear();
382
+ this._flags$.next(new Map(this._flags));
383
+ }
384
+ getAllFlags() {
385
+ return [...this._flags.values()];
386
+ }
387
+ getFlag(key) {
388
+ return this._flags.get(key);
389
+ }
390
+ flags$() {
391
+ return this._flags$.asObservable();
392
+ }
393
+ /** Simple deterministic hash for percentage rollouts */
394
+ _hash(str) {
395
+ let h = 2166136261;
396
+ for (let i = 0; i < str.length; i++) {
397
+ h ^= str.charCodeAt(i);
398
+ h = h * 16777619 >>> 0;
399
+ }
400
+ return h;
401
+ }
402
+ };
403
+
404
+ // src/core/rate-limiter.service.ts
405
+ var JoopTokenBucket = class {
406
+ _tokens;
407
+ _lastRefill;
408
+ _cap;
409
+ _rate;
410
+ constructor(config) {
411
+ this._cap = config.capacity;
412
+ this._rate = config.refillRate;
413
+ this._tokens = config.capacity;
414
+ this._lastRefill = Date.now();
415
+ }
416
+ _refill() {
417
+ const now = Date.now();
418
+ const elapsed = (now - this._lastRefill) / 1e3;
419
+ this._tokens = Math.min(this._cap, this._tokens + elapsed * this._rate);
420
+ this._lastRefill = now;
421
+ }
422
+ /** Returns true if tokens were available and consumed */
423
+ consume(tokens = 1) {
424
+ this._refill();
425
+ if (this._tokens < tokens) return false;
426
+ this._tokens -= tokens;
427
+ return true;
428
+ }
429
+ /** Waits until enough tokens are available, then consumes */
430
+ tryConsume(tokens = 1) {
431
+ return new Promise((resolve) => {
432
+ const attempt = () => {
433
+ if (this.consume(tokens)) {
434
+ resolve();
435
+ return;
436
+ }
437
+ const wait = Math.ceil((tokens - this._tokens) / this._rate * 1e3);
438
+ setTimeout(attempt, wait);
439
+ };
440
+ attempt();
441
+ });
442
+ }
443
+ available() {
444
+ this._refill();
445
+ return Math.floor(this._tokens);
446
+ }
447
+ reset() {
448
+ this._tokens = this._cap;
449
+ this._lastRefill = Date.now();
450
+ }
451
+ };
452
+ var JoopRateLimiter = class {
453
+ _buckets = /* @__PURE__ */ new Map();
454
+ _timers = /* @__PURE__ */ new Map();
455
+ /** Create or get a token bucket by key */
456
+ bucket(key, config) {
457
+ if (!this._buckets.has(key)) {
458
+ this._buckets.set(key, new JoopTokenBucket(config ?? { capacity: 10, refillRate: 1 }));
459
+ }
460
+ return this._buckets.get(key);
461
+ }
462
+ deleteBucket(key) {
463
+ this._buckets.delete(key);
464
+ }
465
+ /** Returns a throttled version — at most once per delayMs */
466
+ throttle(fn, delayMs) {
467
+ let lastCall = 0;
468
+ return (...args) => {
469
+ const now = Date.now();
470
+ if (now - lastCall >= delayMs) {
471
+ lastCall = now;
472
+ fn(...args);
473
+ }
474
+ };
475
+ }
476
+ /** Returns a debounced version — fires after delayMs of silence */
477
+ debounce(fn, delayMs, immediate = false) {
478
+ let timer = null;
479
+ return (...args) => {
480
+ if (timer) clearTimeout(timer);
481
+ if (immediate && !timer) fn(...args);
482
+ timer = setTimeout(() => {
483
+ timer = null;
484
+ if (!immediate) fn(...args);
485
+ }, delayMs);
486
+ };
487
+ }
488
+ /** Promise-based debounce — resolves when the debounced call fires */
489
+ debounceAsync(fn, delayMs) {
490
+ let timer = null;
491
+ let resolve = null;
492
+ let reject = null;
493
+ let pending = null;
494
+ return () => {
495
+ if (!pending) pending = new Promise((res, rej) => {
496
+ resolve = res;
497
+ reject = rej;
498
+ });
499
+ if (timer) clearTimeout(timer);
500
+ timer = setTimeout(async () => {
501
+ timer = null;
502
+ pending = null;
503
+ try {
504
+ const v = await fn();
505
+ resolve?.(v);
506
+ } catch (e) {
507
+ reject?.(e);
508
+ }
509
+ resolve = null;
510
+ reject = null;
511
+ }, delayMs);
512
+ return pending;
513
+ };
514
+ }
515
+ /** Ensure a function is called at most once per key in the given window */
516
+ once(key, fn, windowMs) {
517
+ if (this._timers.has(key)) return false;
518
+ fn();
519
+ this._timers.set(key, setTimeout(() => this._timers.delete(key), windowMs));
520
+ return true;
521
+ }
522
+ };
523
+
524
+ // src/core/consent.service.ts
525
+ var STORAGE_KEY = "joop_consent";
526
+ var ALL = ["necessary", "analytics", "marketing", "functional", "personalization"];
527
+ var DEFAULT_STATE = {
528
+ decided: false,
529
+ categories: { necessary: true, analytics: false, marketing: false, functional: false, personalization: false },
530
+ timestamp: null
531
+ };
532
+ var JoopConsentService = class {
533
+ _state$;
534
+ constructor(storageKey = STORAGE_KEY) {
535
+ this._state$ = new JoopBehaviorSubject(this._loadFrom(storageKey));
536
+ this._key = storageKey;
537
+ }
538
+ _key;
539
+ _loadFrom(key) {
540
+ try {
541
+ const raw = localStorage.getItem(key);
542
+ if (raw) return { ...DEFAULT_STATE, ...JSON.parse(raw) };
543
+ } catch {
544
+ }
545
+ return { ...DEFAULT_STATE, categories: { ...DEFAULT_STATE.categories } };
546
+ }
547
+ /** Grant one or more categories */
548
+ grant(categories) {
549
+ const cats = Array.isArray(categories) ? categories : [categories];
550
+ const s = this._state$.getValue();
551
+ const next = { ...s, decided: true, timestamp: Date.now(), categories: { ...s.categories } };
552
+ for (const c of cats) next.categories[c] = true;
553
+ this._state$.next(next);
554
+ this._persist(next);
555
+ }
556
+ /** Revoke one or more categories (cannot revoke 'necessary') */
557
+ revoke(categories) {
558
+ const cats = (Array.isArray(categories) ? categories : [categories]).filter((c) => c !== "necessary");
559
+ const s = this._state$.getValue();
560
+ const next = { ...s, decided: true, timestamp: Date.now(), categories: { ...s.categories } };
561
+ for (const c of cats) next.categories[c] = false;
562
+ this._state$.next(next);
563
+ this._persist(next);
564
+ }
565
+ /** Grant all categories at once */
566
+ acceptAll() {
567
+ this.grant(ALL);
568
+ }
569
+ /** Reject all non-necessary categories */
570
+ rejectAll() {
571
+ this.revoke(ALL.filter((c) => c !== "necessary"));
572
+ }
573
+ isGranted(category) {
574
+ return this._state$.getValue().categories[category] ?? false;
575
+ }
576
+ hasDecided() {
577
+ return this._state$.getValue().decided;
578
+ }
579
+ getAll() {
580
+ return { ...this._state$.getValue().categories };
581
+ }
582
+ getState() {
583
+ return this._state$.getValue();
584
+ }
585
+ state$() {
586
+ return this._state$.asObservable();
587
+ }
588
+ reset() {
589
+ const fresh = { ...DEFAULT_STATE, categories: { ...DEFAULT_STATE.categories } };
590
+ this._state$.next(fresh);
591
+ try {
592
+ localStorage.removeItem(this._key);
593
+ } catch {
594
+ }
595
+ }
596
+ onChange(handler) {
597
+ return this._state$.subscribe(handler);
598
+ }
599
+ onCategoryChange(category, handler) {
600
+ let prev = this.isGranted(category);
601
+ return this._state$.subscribe((s) => {
602
+ const cur = s.categories[category] ?? false;
603
+ if (cur !== prev) {
604
+ prev = cur;
605
+ handler(cur);
606
+ }
607
+ });
608
+ }
609
+ _persist(state) {
610
+ try {
611
+ localStorage.setItem(this._key, JSON.stringify(state));
612
+ } catch {
613
+ }
614
+ }
615
+ };
616
+
617
+ export { JoopConfigService, JoopConsentService, JoopEnvironmentService, JoopFeatureFlagService, JoopHealthService, JoopLogger, JoopPluginService, JoopRateLimiter, JoopTokenBucket, configService, logger };
618
+ //# sourceMappingURL=index.mjs.map
619
+ //# sourceMappingURL=index.mjs.map