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,304 @@
1
+ // src/events/index.ts
2
+ var JoopSubject = class {
3
+ _listeners = [];
4
+ subscribe(listener) {
5
+ this._listeners.push(listener);
6
+ return () => {
7
+ this._listeners = this._listeners.filter((l) => l !== listener);
8
+ };
9
+ }
10
+ next(value) {
11
+ for (const listener of this._listeners) {
12
+ listener(value);
13
+ }
14
+ }
15
+ asObservable() {
16
+ return new JoopObservable((listener) => this.subscribe(listener));
17
+ }
18
+ };
19
+ var JoopBehaviorSubject = class extends JoopSubject {
20
+ _value;
21
+ constructor(initialValue) {
22
+ super();
23
+ this._value = initialValue;
24
+ }
25
+ getValue() {
26
+ return this._value;
27
+ }
28
+ next(value) {
29
+ this._value = value;
30
+ super.next(value);
31
+ }
32
+ subscribe(listener) {
33
+ listener(this._value);
34
+ return super.subscribe(listener);
35
+ }
36
+ asObservable() {
37
+ return new JoopObservable((listener) => this.subscribe(listener));
38
+ }
39
+ };
40
+ var JoopObservable = class {
41
+ constructor(_subscribeFn) {
42
+ this._subscribeFn = _subscribeFn;
43
+ }
44
+ _subscribeFn;
45
+ subscribe(listener) {
46
+ return this._subscribeFn(listener);
47
+ }
48
+ /** Returns the current value without subscribing (only meaningful for BehaviorSubject-backed observables). */
49
+ getOnce() {
50
+ let result;
51
+ const unsub = this.subscribe((v) => {
52
+ result = v;
53
+ });
54
+ unsub();
55
+ return result;
56
+ }
57
+ };
58
+
59
+ // src/ai/ai-client.ts
60
+ var PROVIDER_DEFAULTS = {
61
+ openai: { baseUrl: "https://api.openai.com" },
62
+ anthropic: { baseUrl: "https://api.anthropic.com" },
63
+ gemini: { baseUrl: "https://generativelanguage.googleapis.com" },
64
+ ollama: { baseUrl: "http://localhost:11434" },
65
+ custom: { baseUrl: "" }
66
+ };
67
+ var JoopAiClient = class {
68
+ _cfg;
69
+ _usage$ = new JoopBehaviorSubject({ promptTokens: 0, completionTokens: 0, totalTokens: 0 });
70
+ _abort = null;
71
+ _history = [];
72
+ constructor(config) {
73
+ this._cfg = config;
74
+ }
75
+ configure(patch) {
76
+ this._cfg = { ...this._cfg, ...patch };
77
+ }
78
+ lastUsage() {
79
+ return this._usage$.getValue();
80
+ }
81
+ usage$() {
82
+ return this._usage$.asObservable();
83
+ }
84
+ getHistory() {
85
+ return [...this._history];
86
+ }
87
+ clearHistory() {
88
+ this._history = [];
89
+ }
90
+ abort() {
91
+ this._abort?.abort();
92
+ this._abort = null;
93
+ }
94
+ /** Approximate token count (4 chars ≈ 1 token) */
95
+ estimateTokens(text) {
96
+ return Math.ceil(text.length / 4);
97
+ }
98
+ async complete(prompt, opts = {}) {
99
+ return this.chat([{ role: "user", content: prompt }], opts);
100
+ }
101
+ async chat(messages, opts = {}) {
102
+ this._abort = new AbortController();
103
+ const signal = opts.signal ? _combineSignals(opts.signal, this._abort.signal) : this._abort.signal;
104
+ const allMessages = [];
105
+ if (this._cfg.systemPrompt) allMessages.push({ role: "system", content: this._cfg.systemPrompt });
106
+ allMessages.push(...this._history, ...messages);
107
+ const result = opts.stream !== false ? await this._streamChat(allMessages, opts, signal) : await this._fetchChat(allMessages, opts, signal);
108
+ for (const m of messages) this._history.push(m);
109
+ this._history.push({ role: "assistant", content: result });
110
+ opts.onComplete?.(result);
111
+ return result;
112
+ }
113
+ async _fetchChat(messages, opts, signal) {
114
+ const { url, headers, body } = this._buildRequest(messages, opts, false);
115
+ const res = await fetch(url, { method: "POST", headers, body: JSON.stringify(body), signal });
116
+ if (!res.ok) throw new Error(`JoopAiClient: ${res.status} ${await res.text()}`);
117
+ const json = await res.json();
118
+ return this._extractContent(json);
119
+ }
120
+ async _streamChat(messages, opts, signal) {
121
+ const { url, headers, body } = this._buildRequest(messages, opts, true);
122
+ const res = await fetch(url, { method: "POST", headers, body: JSON.stringify(body), signal });
123
+ if (!res.ok) throw new Error(`JoopAiClient: ${res.status} ${await res.text()}`);
124
+ const reader = res.body.getReader();
125
+ const decoder = new TextDecoder();
126
+ let full = "";
127
+ let buf = "";
128
+ while (true) {
129
+ const { done, value } = await reader.read();
130
+ if (done) break;
131
+ buf += decoder.decode(value, { stream: true });
132
+ const lines = buf.split("\n");
133
+ buf = lines.pop() ?? "";
134
+ for (const line of lines) {
135
+ const token = this._parseStreamLine(line.trim());
136
+ if (token) {
137
+ full += token;
138
+ opts.onChunk?.(token);
139
+ }
140
+ }
141
+ }
142
+ return full;
143
+ }
144
+ _buildRequest(messages, opts, stream) {
145
+ const { provider, apiKey, model, maxTokens, temperature } = this._cfg;
146
+ const baseUrl = this._cfg.baseUrl ?? PROVIDER_DEFAULTS[provider].baseUrl;
147
+ const mt = opts.maxTokens ?? maxTokens ?? 1024;
148
+ const temp = opts.temperature ?? temperature ?? 0.7;
149
+ switch (provider) {
150
+ case "openai":
151
+ case "custom":
152
+ return {
153
+ url: `${baseUrl}/v1/chat/completions`,
154
+ headers: { "Content-Type": "application/json", ...apiKey ? { Authorization: `Bearer ${apiKey}` } : {} },
155
+ body: { model, messages, stream, max_tokens: mt, temperature: temp }
156
+ };
157
+ case "anthropic":
158
+ return {
159
+ url: `${baseUrl}/v1/messages`,
160
+ headers: { "Content-Type": "application/json", "x-api-key": apiKey ?? "", "anthropic-version": "2023-06-01" },
161
+ body: {
162
+ model,
163
+ stream,
164
+ max_tokens: mt,
165
+ temperature: temp,
166
+ system: messages.find((m) => m.role === "system")?.content,
167
+ messages: messages.filter((m) => m.role !== "system")
168
+ }
169
+ };
170
+ case "gemini": {
171
+ const contents = messages.filter((m) => m.role !== "system").map((m) => ({ role: m.role === "assistant" ? "model" : "user", parts: [{ text: m.content }] }));
172
+ const path = stream ? "streamGenerateContent?alt=sse" : "generateContent";
173
+ return {
174
+ url: `${baseUrl}/v1beta/models/${model}:${path}${apiKey ? `&key=${apiKey}` : ""}`,
175
+ headers: { "Content-Type": "application/json" },
176
+ body: { contents, generationConfig: { maxOutputTokens: mt, temperature: temp } }
177
+ };
178
+ }
179
+ case "ollama":
180
+ return {
181
+ url: `${baseUrl}/api/chat`,
182
+ headers: { "Content-Type": "application/json" },
183
+ body: { model, messages, stream, options: { num_predict: mt, temperature: temp } }
184
+ };
185
+ }
186
+ }
187
+ _parseStreamLine(line) {
188
+ if (!line.startsWith("data: ") && !line.startsWith("{")) return "";
189
+ const raw = line.startsWith("data: ") ? line.slice(6) : line;
190
+ if (raw === "[DONE]") return "";
191
+ try {
192
+ const json = JSON.parse(raw);
193
+ const oaChoice = json?.choices?.[0];
194
+ if (oaChoice?.delta?.content) return oaChoice.delta.content;
195
+ if (json?.type === "content_block_delta") return json?.delta?.text ?? "";
196
+ const gmPart = json?.candidates?.[0]?.content?.parts?.[0];
197
+ if (gmPart?.text) return gmPart.text;
198
+ if (json?.message?.content) return json.message.content;
199
+ } catch {
200
+ }
201
+ return "";
202
+ }
203
+ _extractContent(json) {
204
+ const j = json;
205
+ const oa = j?.choices?.[0]?.message?.content;
206
+ if (oa) return oa;
207
+ const an = j?.content?.[0]?.text;
208
+ if (an) return an;
209
+ const gm = j?.candidates?.[0]?.content?.parts?.[0]?.text;
210
+ if (gm) return gm;
211
+ const ol = j?.message?.content;
212
+ if (ol) return ol;
213
+ return "";
214
+ }
215
+ };
216
+ function _combineSignals(...signals) {
217
+ const ctrl = new AbortController();
218
+ for (const s of signals) s.addEventListener("abort", () => ctrl.abort(), { once: true });
219
+ return ctrl.signal;
220
+ }
221
+
222
+ // src/ai/tool-registry.ts
223
+ var JoopToolRegistry = class {
224
+ _tools = /* @__PURE__ */ new Map();
225
+ register(tool) {
226
+ if (this._tools.has(tool.name)) throw new Error(`Tool '${tool.name}' already registered. Use update() to replace.`);
227
+ this._tools.set(tool.name, tool);
228
+ }
229
+ update(tool) {
230
+ this._tools.set(tool.name, tool);
231
+ }
232
+ unregister(name) {
233
+ this._tools.delete(name);
234
+ }
235
+ has(name) {
236
+ return this._tools.has(name);
237
+ }
238
+ list() {
239
+ return Array.from(this._tools.keys());
240
+ }
241
+ get(name) {
242
+ return this._tools.get(name);
243
+ }
244
+ clear() {
245
+ this._tools.clear();
246
+ }
247
+ async dispatch(call) {
248
+ const tool = this._tools.get(call.name);
249
+ if (!tool) return { name: call.name, result: null, error: `Unknown tool: ${call.name}`, durationMs: 0 };
250
+ const args = typeof call.arguments === "string" ? JSON.parse(call.arguments) : call.arguments;
251
+ const t0 = Date.now();
252
+ try {
253
+ const result = await tool.handler(args);
254
+ return { name: call.name, result, durationMs: Date.now() - t0 };
255
+ } catch (e) {
256
+ return { name: call.name, result: null, error: String(e), durationMs: Date.now() - t0 };
257
+ }
258
+ }
259
+ /** Dispatch multiple tool calls in parallel */
260
+ async dispatchAll(calls) {
261
+ return Promise.all(calls.map((c) => this.dispatch(c)));
262
+ }
263
+ /** Format for OpenAI function-calling */
264
+ toOpenAiFormat() {
265
+ return Array.from(this._tools.values()).map((t) => ({
266
+ type: "function",
267
+ function: {
268
+ name: t.name,
269
+ description: t.description,
270
+ parameters: {
271
+ type: "object",
272
+ properties: t.parameters,
273
+ required: t.required ?? []
274
+ }
275
+ }
276
+ }));
277
+ }
278
+ /** Format for Anthropic tool-use */
279
+ toAnthropicFormat() {
280
+ return Array.from(this._tools.values()).map((t) => ({
281
+ name: t.name,
282
+ description: t.description,
283
+ input_schema: {
284
+ type: "object",
285
+ properties: t.parameters,
286
+ required: t.required ?? []
287
+ }
288
+ }));
289
+ }
290
+ /** Format for Google Gemini function declarations */
291
+ toGeminiFormat() {
292
+ return [{
293
+ function_declarations: Array.from(this._tools.values()).map((t) => ({
294
+ name: t.name,
295
+ description: t.description,
296
+ parameters: { type: "object", properties: t.parameters, required: t.required ?? [] }
297
+ }))
298
+ }];
299
+ }
300
+ };
301
+
302
+ export { JoopAiClient, JoopToolRegistry };
303
+ //# sourceMappingURL=index.mjs.map
304
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/events/index.ts","../../src/ai/ai-client.ts","../../src/ai/tool-registry.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["export type Unsubscribe = () => void;\nexport type Listener<T> = (value: T) => void;\n\n/**\n * Lightweight pub/sub subject — emits to all current subscribers.\n * Replaces RxJS Subject without pulling in the full RxJS dependency.\n */\nexport class JoopSubject<T> {\n private _listeners: Listener<T>[] = [];\n\n subscribe(listener: Listener<T>): Unsubscribe {\n this._listeners.push(listener);\n return () => {\n this._listeners = this._listeners.filter(l => l !== listener);\n };\n }\n\n next(value: T): void {\n for (const listener of this._listeners) {\n listener(value);\n }\n }\n\n asObservable(): JoopObservable<T> {\n return new JoopObservable<T>(listener => this.subscribe(listener));\n }\n}\n\n/**\n * Stateful subject — replays the current value to any new subscriber immediately.\n * Replaces RxJS BehaviorSubject.\n */\nexport class JoopBehaviorSubject<T> extends JoopSubject<T> {\n private _value: T;\n\n constructor(initialValue: T) {\n super();\n this._value = initialValue;\n }\n\n getValue(): T {\n return this._value;\n }\n\n override next(value: T): void {\n this._value = value;\n super.next(value);\n }\n\n override subscribe(listener: Listener<T>): Unsubscribe {\n listener(this._value);\n return super.subscribe(listener);\n }\n\n override asObservable(): JoopObservable<T> {\n return new JoopObservable<T>(listener => this.subscribe(listener));\n }\n}\n\n/**\n * Read-only observable handle returned from asObservable().\n */\nexport class JoopObservable<T> {\n constructor(private _subscribeFn: (listener: Listener<T>) => Unsubscribe) {}\n\n subscribe(listener: Listener<T>): Unsubscribe {\n return this._subscribeFn(listener);\n }\n\n /** Returns the current value without subscribing (only meaningful for BehaviorSubject-backed observables). */\n getOnce(): T | undefined {\n let result: T | undefined;\n const unsub = this.subscribe(v => { result = v; });\n unsub();\n return result;\n }\n}\n","import { JoopBehaviorSubject } from '../events';\n\nexport type JoopAiProvider = 'openai' | 'anthropic' | 'gemini' | 'ollama' | 'custom';\n\nexport interface JoopAiMessage {\n role: 'system' | 'user' | 'assistant';\n content: string;\n}\n\nexport interface JoopAiConfig {\n provider: JoopAiProvider;\n apiKey?: string;\n baseUrl?: string;\n model: string;\n maxTokens?: number;\n temperature?: number;\n systemPrompt?: string;\n timeout?: number;\n}\n\nexport interface JoopAiStreamOptions {\n stream?: boolean;\n onChunk?: (token: string) => void;\n onComplete?: (full: string) => void;\n signal?: AbortSignal;\n maxTokens?: number;\n temperature?: number;\n}\n\nexport interface JoopAiUsage {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n}\n\nconst PROVIDER_DEFAULTS: Record<JoopAiProvider, { baseUrl: string }> = {\n openai: { baseUrl: 'https://api.openai.com' },\n anthropic: { baseUrl: 'https://api.anthropic.com' },\n gemini: { baseUrl: 'https://generativelanguage.googleapis.com' },\n ollama: { baseUrl: 'http://localhost:11434' },\n custom: { baseUrl: '' },\n};\n\nexport class JoopAiClient {\n private _cfg: JoopAiConfig;\n private _usage$ = new JoopBehaviorSubject<JoopAiUsage>({ promptTokens: 0, completionTokens: 0, totalTokens: 0 });\n private _abort: AbortController | null = null;\n private _history: JoopAiMessage[] = [];\n\n constructor(config: JoopAiConfig) { this._cfg = config; }\n\n configure(patch: Partial<JoopAiConfig>): void { this._cfg = { ...this._cfg, ...patch }; }\n lastUsage(): JoopAiUsage { return this._usage$.getValue(); }\n usage$() { return this._usage$.asObservable(); }\n getHistory(): JoopAiMessage[] { return [...this._history]; }\n clearHistory(): void { this._history = []; }\n\n abort(): void { this._abort?.abort(); this._abort = null; }\n\n /** Approximate token count (4 chars ≈ 1 token) */\n estimateTokens(text: string): number { return Math.ceil(text.length / 4); }\n\n async complete(prompt: string, opts: JoopAiStreamOptions = {}): Promise<string> {\n return this.chat([{ role: 'user', content: prompt }], opts);\n }\n\n async chat(messages: JoopAiMessage[], opts: JoopAiStreamOptions = {}): Promise<string> {\n this._abort = new AbortController();\n const signal = opts.signal\n ? _combineSignals(opts.signal, this._abort.signal)\n : this._abort.signal;\n\n const allMessages: JoopAiMessage[] = [];\n if (this._cfg.systemPrompt) allMessages.push({ role: 'system', content: this._cfg.systemPrompt });\n allMessages.push(...this._history, ...messages);\n\n const result = opts.stream !== false\n ? await this._streamChat(allMessages, opts, signal)\n : await this._fetchChat(allMessages, opts, signal);\n\n // Append to history\n for (const m of messages) this._history.push(m);\n this._history.push({ role: 'assistant', content: result });\n\n opts.onComplete?.(result);\n return result;\n }\n\n private async _fetchChat(messages: JoopAiMessage[], opts: JoopAiStreamOptions, signal: AbortSignal): Promise<string> {\n const { url, headers, body } = this._buildRequest(messages, opts, false);\n const res = await fetch(url, { method: 'POST', headers, body: JSON.stringify(body), signal });\n if (!res.ok) throw new Error(`JoopAiClient: ${res.status} ${await res.text()}`);\n const json = await res.json();\n return this._extractContent(json);\n }\n\n private async _streamChat(messages: JoopAiMessage[], opts: JoopAiStreamOptions, signal: AbortSignal): Promise<string> {\n const { url, headers, body } = this._buildRequest(messages, opts, true);\n const res = await fetch(url, { method: 'POST', headers, body: JSON.stringify(body), signal });\n if (!res.ok) throw new Error(`JoopAiClient: ${res.status} ${await res.text()}`);\n\n const reader = res.body!.getReader();\n const decoder = new TextDecoder();\n let full = '';\n let buf = '';\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buf += decoder.decode(value, { stream: true });\n const lines = buf.split('\\n');\n buf = lines.pop() ?? '';\n for (const line of lines) {\n const token = this._parseStreamLine(line.trim());\n if (token) { full += token; opts.onChunk?.(token); }\n }\n }\n return full;\n }\n\n private _buildRequest(messages: JoopAiMessage[], opts: JoopAiStreamOptions, stream: boolean): { url: string; headers: Record<string, string>; body: unknown } {\n const { provider, apiKey, model, maxTokens, temperature } = this._cfg;\n const baseUrl = this._cfg.baseUrl ?? PROVIDER_DEFAULTS[provider].baseUrl;\n const mt = opts.maxTokens ?? maxTokens ?? 1024;\n const temp = opts.temperature ?? temperature ?? 0.7;\n\n switch (provider) {\n case 'openai':\n case 'custom':\n return {\n url: `${baseUrl}/v1/chat/completions`,\n headers: { 'Content-Type': 'application/json', ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}) },\n body: { model, messages, stream, max_tokens: mt, temperature: temp },\n };\n case 'anthropic':\n return {\n url: `${baseUrl}/v1/messages`,\n headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey ?? '', 'anthropic-version': '2023-06-01' },\n body: {\n model, stream, max_tokens: mt, temperature: temp,\n system: messages.find(m => m.role === 'system')?.content,\n messages: messages.filter(m => m.role !== 'system'),\n },\n };\n case 'gemini': {\n const contents = messages.filter(m => m.role !== 'system').map(m => ({ role: m.role === 'assistant' ? 'model' : 'user', parts: [{ text: m.content }] }));\n const path = stream ? 'streamGenerateContent?alt=sse' : 'generateContent';\n return {\n url: `${baseUrl}/v1beta/models/${model}:${path}${apiKey ? `&key=${apiKey}` : ''}`,\n headers: { 'Content-Type': 'application/json' },\n body: { contents, generationConfig: { maxOutputTokens: mt, temperature: temp } },\n };\n }\n case 'ollama':\n return {\n url: `${baseUrl}/api/chat`,\n headers: { 'Content-Type': 'application/json' },\n body: { model, messages, stream, options: { num_predict: mt, temperature: temp } },\n };\n }\n }\n\n private _parseStreamLine(line: string): string {\n if (!line.startsWith('data: ') && !line.startsWith('{')) return '';\n const raw = line.startsWith('data: ') ? line.slice(6) : line;\n if (raw === '[DONE]') return '';\n try {\n const json = JSON.parse(raw);\n // OpenAI\n const oaChoice = json?.choices?.[0];\n if (oaChoice?.delta?.content) return oaChoice.delta.content;\n // Anthropic\n if (json?.type === 'content_block_delta') return json?.delta?.text ?? '';\n // Gemini\n const gmPart = json?.candidates?.[0]?.content?.parts?.[0];\n if (gmPart?.text) return gmPart.text;\n // Ollama\n if (json?.message?.content) return json.message.content;\n } catch {}\n return '';\n }\n\n private _extractContent(json: unknown): string {\n const j = json as Record<string, unknown>;\n // OpenAI\n const oa = (j?.choices as Array<{message:{content:string}}>)?.[0]?.message?.content;\n if (oa) return oa;\n // Anthropic\n const an = (j?.content as Array<{text:string}>)?.[0]?.text;\n if (an) return an;\n // Gemini\n const gm = ((j?.candidates as Array<{content:{parts:Array<{text:string}>}}>)?.[0]?.content?.parts)?.[0]?.text;\n if (gm) return gm;\n // Ollama\n const ol = (j?.message as {content:string})?.content;\n if (ol) return ol;\n return '';\n }\n}\n\nfunction _combineSignals(...signals: AbortSignal[]): AbortSignal {\n const ctrl = new AbortController();\n for (const s of signals) s.addEventListener('abort', () => ctrl.abort(), { once: true });\n return ctrl.signal;\n}\n","export interface JoopToolParameter {\n type: 'string' | 'number' | 'boolean' | 'object' | 'array';\n description?: string;\n enum?: unknown[];\n items?: JoopToolParameter;\n properties?: Record<string, JoopToolParameter>;\n required?: string[];\n}\n\nexport interface JoopToolDefinition {\n name: string;\n description: string;\n parameters: Record<string, JoopToolParameter>;\n required?: string[];\n handler: (args: Record<string, unknown>) => Promise<unknown>;\n}\n\nexport interface JoopToolCall {\n name: string;\n arguments: string | Record<string, unknown>;\n}\n\nexport interface JoopToolResult {\n name: string;\n result: unknown;\n error?: string;\n durationMs: number;\n}\n\nexport class JoopToolRegistry {\n private _tools = new Map<string, JoopToolDefinition>();\n\n register(tool: JoopToolDefinition): void {\n if (this._tools.has(tool.name)) throw new Error(`Tool '${tool.name}' already registered. Use update() to replace.`);\n this._tools.set(tool.name, tool);\n }\n\n update(tool: JoopToolDefinition): void { this._tools.set(tool.name, tool); }\n unregister(name: string): void { this._tools.delete(name); }\n has(name: string): boolean { return this._tools.has(name); }\n list(): string[] { return Array.from(this._tools.keys()); }\n get(name: string): JoopToolDefinition | undefined { return this._tools.get(name); }\n clear(): void { this._tools.clear(); }\n\n async dispatch(call: JoopToolCall): Promise<JoopToolResult> {\n const tool = this._tools.get(call.name);\n if (!tool) return { name: call.name, result: null, error: `Unknown tool: ${call.name}`, durationMs: 0 };\n\n const args = typeof call.arguments === 'string' ? JSON.parse(call.arguments) : call.arguments;\n const t0 = Date.now();\n try {\n const result = await tool.handler(args as Record<string, unknown>);\n return { name: call.name, result, durationMs: Date.now() - t0 };\n } catch (e) {\n return { name: call.name, result: null, error: String(e), durationMs: Date.now() - t0 };\n }\n }\n\n /** Dispatch multiple tool calls in parallel */\n async dispatchAll(calls: JoopToolCall[]): Promise<JoopToolResult[]> {\n return Promise.all(calls.map(c => this.dispatch(c)));\n }\n\n /** Format for OpenAI function-calling */\n toOpenAiFormat(): object[] {\n return Array.from(this._tools.values()).map(t => ({\n type: 'function',\n function: {\n name: t.name,\n description: t.description,\n parameters: {\n type: 'object',\n properties: t.parameters,\n required: t.required ?? [],\n },\n },\n }));\n }\n\n /** Format for Anthropic tool-use */\n toAnthropicFormat(): object[] {\n return Array.from(this._tools.values()).map(t => ({\n name: t.name,\n description: t.description,\n input_schema: {\n type: 'object',\n properties: t.parameters,\n required: t.required ?? [],\n },\n }));\n }\n\n /** Format for Google Gemini function declarations */\n toGeminiFormat(): object[] {\n return [{\n function_declarations: Array.from(this._tools.values()).map(t => ({\n name: t.name,\n description: t.description,\n parameters: { type: 'object', properties: t.parameters, required: t.required ?? [] },\n })),\n }];\n }\n}\n"]}
@@ -0,0 +1,42 @@
1
+ import { J as JoopObservable } from '../index-Dz0gOur2.mjs';
2
+
3
+ interface JoopAnalyticsEvent {
4
+ name: string;
5
+ properties?: Record<string, unknown>;
6
+ timestamp: number;
7
+ sessionId?: string;
8
+ userId?: string;
9
+ }
10
+ interface JoopAnalyticsAdapter {
11
+ name: string;
12
+ track?(event: JoopAnalyticsEvent): void;
13
+ page?(name: string, properties?: Record<string, unknown>): void;
14
+ identify?(userId: string, traits?: Record<string, unknown>): void;
15
+ }
16
+ declare class JoopAnalyticsService {
17
+ private _adapters;
18
+ private _context;
19
+ private _userId;
20
+ private _sessionId;
21
+ private _event$;
22
+ private _queue;
23
+ private _enabled;
24
+ addAdapter(adapter: JoopAnalyticsAdapter): void;
25
+ removeAdapter(name: string): void;
26
+ enable(): void;
27
+ disable(): void;
28
+ setContext(ctx: Record<string, unknown>): void;
29
+ setUser(userId: string, traits?: Record<string, unknown>): void;
30
+ setSession(sessionId: string): void;
31
+ track(name: string, properties?: Record<string, unknown>): void;
32
+ page(name: string, properties?: Record<string, unknown>): void;
33
+ identify(userId: string, traits?: Record<string, unknown>): void;
34
+ /** Subscribe to all tracked events (useful for debugging) */
35
+ events$(): JoopObservable<JoopAnalyticsEvent>;
36
+ /** Flush the pre-adapter queue (e.g. after lazy-loading analytics) */
37
+ flush(): void;
38
+ getQueueSize(): number;
39
+ }
40
+ declare const consoleAnalyticsAdapter: JoopAnalyticsAdapter;
41
+
42
+ export { type JoopAnalyticsAdapter, type JoopAnalyticsEvent, JoopAnalyticsService, consoleAnalyticsAdapter };
@@ -0,0 +1,42 @@
1
+ import { J as JoopObservable } from '../index-Dz0gOur2.js';
2
+
3
+ interface JoopAnalyticsEvent {
4
+ name: string;
5
+ properties?: Record<string, unknown>;
6
+ timestamp: number;
7
+ sessionId?: string;
8
+ userId?: string;
9
+ }
10
+ interface JoopAnalyticsAdapter {
11
+ name: string;
12
+ track?(event: JoopAnalyticsEvent): void;
13
+ page?(name: string, properties?: Record<string, unknown>): void;
14
+ identify?(userId: string, traits?: Record<string, unknown>): void;
15
+ }
16
+ declare class JoopAnalyticsService {
17
+ private _adapters;
18
+ private _context;
19
+ private _userId;
20
+ private _sessionId;
21
+ private _event$;
22
+ private _queue;
23
+ private _enabled;
24
+ addAdapter(adapter: JoopAnalyticsAdapter): void;
25
+ removeAdapter(name: string): void;
26
+ enable(): void;
27
+ disable(): void;
28
+ setContext(ctx: Record<string, unknown>): void;
29
+ setUser(userId: string, traits?: Record<string, unknown>): void;
30
+ setSession(sessionId: string): void;
31
+ track(name: string, properties?: Record<string, unknown>): void;
32
+ page(name: string, properties?: Record<string, unknown>): void;
33
+ identify(userId: string, traits?: Record<string, unknown>): void;
34
+ /** Subscribe to all tracked events (useful for debugging) */
35
+ events$(): JoopObservable<JoopAnalyticsEvent>;
36
+ /** Flush the pre-adapter queue (e.g. after lazy-loading analytics) */
37
+ flush(): void;
38
+ getQueueSize(): number;
39
+ }
40
+ declare const consoleAnalyticsAdapter: JoopAnalyticsAdapter;
41
+
42
+ export { type JoopAnalyticsAdapter, type JoopAnalyticsEvent, JoopAnalyticsService, consoleAnalyticsAdapter };
@@ -0,0 +1,139 @@
1
+ 'use strict';
2
+
3
+ // src/events/index.ts
4
+ var JoopSubject = class {
5
+ _listeners = [];
6
+ subscribe(listener) {
7
+ this._listeners.push(listener);
8
+ return () => {
9
+ this._listeners = this._listeners.filter((l) => l !== listener);
10
+ };
11
+ }
12
+ next(value) {
13
+ for (const listener of this._listeners) {
14
+ listener(value);
15
+ }
16
+ }
17
+ asObservable() {
18
+ return new JoopObservable((listener) => this.subscribe(listener));
19
+ }
20
+ };
21
+ var JoopObservable = class {
22
+ constructor(_subscribeFn) {
23
+ this._subscribeFn = _subscribeFn;
24
+ }
25
+ _subscribeFn;
26
+ subscribe(listener) {
27
+ return this._subscribeFn(listener);
28
+ }
29
+ /** Returns the current value without subscribing (only meaningful for BehaviorSubject-backed observables). */
30
+ getOnce() {
31
+ let result;
32
+ const unsub = this.subscribe((v) => {
33
+ result = v;
34
+ });
35
+ unsub();
36
+ return result;
37
+ }
38
+ };
39
+
40
+ // src/analytics/analytics.service.ts
41
+ var JoopAnalyticsService = class {
42
+ _adapters = [];
43
+ _context = {};
44
+ _userId = "";
45
+ _sessionId = "";
46
+ _event$ = new JoopSubject();
47
+ _queue = [];
48
+ _enabled = true;
49
+ addAdapter(adapter) {
50
+ if (!this._adapters.find((a) => a.name === adapter.name)) {
51
+ this._adapters.push(adapter);
52
+ for (const ev of this._queue) adapter.track?.(ev);
53
+ }
54
+ }
55
+ removeAdapter(name) {
56
+ this._adapters = this._adapters.filter((a) => a.name !== name);
57
+ }
58
+ enable() {
59
+ this._enabled = true;
60
+ }
61
+ disable() {
62
+ this._enabled = false;
63
+ }
64
+ setContext(ctx) {
65
+ this._context = { ...this._context, ...ctx };
66
+ }
67
+ setUser(userId, traits) {
68
+ this._userId = userId;
69
+ this._adapters.forEach((a) => a.identify?.(userId, traits));
70
+ }
71
+ setSession(sessionId) {
72
+ this._sessionId = sessionId;
73
+ }
74
+ track(name, properties) {
75
+ if (!this._enabled) return;
76
+ const event = {
77
+ name,
78
+ properties: { ...this._context, ...properties },
79
+ timestamp: Date.now(),
80
+ userId: this._userId || void 0,
81
+ sessionId: this._sessionId || void 0
82
+ };
83
+ this._event$.next(event);
84
+ if (this._adapters.length === 0) {
85
+ this._queue.push(event);
86
+ return;
87
+ }
88
+ this._adapters.forEach((a) => {
89
+ try {
90
+ a.track?.(event);
91
+ } catch {
92
+ }
93
+ });
94
+ }
95
+ page(name, properties) {
96
+ if (!this._enabled) return;
97
+ const merged = { ...this._context, ...properties };
98
+ this._adapters.forEach((a) => {
99
+ try {
100
+ a.page?.(name, merged);
101
+ } catch {
102
+ }
103
+ });
104
+ this.track(`page:${name}`, merged);
105
+ }
106
+ identify(userId, traits) {
107
+ this.setUser(userId, traits);
108
+ }
109
+ /** Subscribe to all tracked events (useful for debugging) */
110
+ events$() {
111
+ return this._event$.asObservable();
112
+ }
113
+ /** Flush the pre-adapter queue (e.g. after lazy-loading analytics) */
114
+ flush() {
115
+ for (const ev of this._queue) {
116
+ this._adapters.forEach((a) => {
117
+ try {
118
+ a.track?.(ev);
119
+ } catch {
120
+ }
121
+ });
122
+ }
123
+ this._queue = [];
124
+ }
125
+ getQueueSize() {
126
+ return this._queue.length;
127
+ }
128
+ };
129
+ var consoleAnalyticsAdapter = {
130
+ name: "console",
131
+ track: (e) => console.log(`[analytics:track] ${e.name}`, e.properties),
132
+ page: (name) => console.log(`[analytics:page] ${name}`),
133
+ identify: (id) => console.log(`[analytics:identify] ${id}`)
134
+ };
135
+
136
+ exports.JoopAnalyticsService = JoopAnalyticsService;
137
+ exports.consoleAnalyticsAdapter = consoleAnalyticsAdapter;
138
+ //# sourceMappingURL=index.js.map
139
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/events/index.ts","../../src/analytics/analytics.service.ts"],"names":[],"mappings":";;;AAOO,IAAM,cAAN,MAAqB;AAAA,EAClB,aAA4B,EAAC;AAAA,EAErC,UAAU,QAAA,EAAoC;AAC5C,IAAA,IAAA,CAAK,UAAA,CAAW,KAAK,QAAQ,CAAA;AAC7B,IAAA,OAAO,MAAM;AACX,MAAA,IAAA,CAAK,aAAa,IAAA,CAAK,UAAA,CAAW,MAAA,CAAO,CAAA,CAAA,KAAK,MAAM,QAAQ,CAAA;AAAA,IAC9D,CAAA;AAAA,EACF;AAAA,EAEA,KAAK,KAAA,EAAgB;AACnB,IAAA,KAAA,MAAW,QAAA,IAAY,KAAK,UAAA,EAAY;AACtC,MAAA,QAAA,CAAS,KAAK,CAAA;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,YAAA,GAAkC;AAChC,IAAA,OAAO,IAAI,cAAA,CAAkB,CAAA,QAAA,KAAY,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA;AAAA,EACnE;AACF,CAAA;AAoCO,IAAM,iBAAN,MAAwB;AAAA,EAC7B,YAAoB,YAAA,EAAsD;AAAtD,IAAA,IAAA,CAAA,YAAA,GAAA,YAAA;AAAA,EAAuD;AAAA,EAAvD,YAAA;AAAA,EAEpB,UAAU,QAAA,EAAoC;AAC5C,IAAA,OAAO,IAAA,CAAK,aAAa,QAAQ,CAAA;AAAA,EACnC;AAAA;AAAA,EAGA,OAAA,GAAyB;AACvB,IAAA,IAAI,MAAA;AACJ,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,SAAA,CAAU,CAAA,CAAA,KAAK;AAAE,MAAA,MAAA,GAAS,CAAA;AAAA,IAAG,CAAC,CAAA;AACjD,IAAA,KAAA,EAAM;AACN,IAAA,OAAO,MAAA;AAAA,EACT;AACF,CAAA;;;AC3DO,IAAM,uBAAN,MAA2B;AAAA,EACxB,YAAoC,EAAC;AAAA,EACrC,WAAoC,EAAC;AAAA,EACrC,OAAA,GAAU,EAAA;AAAA,EACV,UAAA,GAAa,EAAA;AAAA,EACb,OAAA,GAAU,IAAI,WAAA,EAAgC;AAAA,EAC9C,SAA+B,EAAC;AAAA,EAChC,QAAA,GAAW,IAAA;AAAA,EAEnB,WAAW,OAAA,EAAqC;AAC9C,IAAA,IAAI,CAAC,KAAK,SAAA,CAAU,IAAA,CAAK,OAAK,CAAA,CAAE,IAAA,KAAS,OAAA,CAAQ,IAAI,CAAA,EAAG;AACtD,MAAA,IAAA,CAAK,SAAA,CAAU,KAAK,OAAO,CAAA;AAE3B,MAAA,KAAA,MAAW,EAAA,IAAM,IAAA,CAAK,MAAA,EAAQ,OAAA,CAAQ,QAAQ,EAAE,CAAA;AAAA,IAClD;AAAA,EACF;AAAA,EAEA,cAAc,IAAA,EAAoB;AAChC,IAAA,IAAA,CAAK,YAAY,IAAA,CAAK,SAAA,CAAU,OAAO,CAAA,CAAA,KAAK,CAAA,CAAE,SAAS,IAAI,CAAA;AAAA,EAC7D;AAAA,EAEA,MAAA,GAAe;AAAE,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAAA,EAAM;AAAA,EACvC,OAAA,GAAgB;AAAE,IAAA,IAAA,CAAK,QAAA,GAAW,KAAA;AAAA,EAAO;AAAA,EAEzC,WAAW,GAAA,EAAoC;AAC7C,IAAA,IAAA,CAAK,WAAW,EAAE,GAAG,IAAA,CAAK,QAAA,EAAU,GAAG,GAAA,EAAI;AAAA,EAC7C;AAAA,EAEA,OAAA,CAAQ,QAAgB,MAAA,EAAwC;AAC9D,IAAA,IAAA,CAAK,OAAA,GAAU,MAAA;AACf,IAAA,IAAA,CAAK,UAAU,OAAA,CAAQ,CAAA,CAAA,KAAK,EAAE,QAAA,GAAW,MAAA,EAAQ,MAAM,CAAC,CAAA;AAAA,EAC1D;AAAA,EAEA,WAAW,SAAA,EAAyB;AAAE,IAAA,IAAA,CAAK,UAAA,GAAa,SAAA;AAAA,EAAW;AAAA,EAEnE,KAAA,CAAM,MAAc,UAAA,EAA4C;AAC9D,IAAA,IAAI,CAAC,KAAK,QAAA,EAAU;AACpB,IAAA,MAAM,KAAA,GAA4B;AAAA,MAChC,IAAA;AAAA,MACA,YAAY,EAAE,GAAG,IAAA,CAAK,QAAA,EAAU,GAAG,UAAA,EAAW;AAAA,MAC9C,SAAA,EAAW,KAAK,GAAA,EAAI;AAAA,MACpB,MAAA,EAAQ,KAAK,OAAA,IAAW,MAAA;AAAA,MACxB,SAAA,EAAW,KAAK,UAAA,IAAc;AAAA,KAChC;AACA,IAAA,IAAA,CAAK,OAAA,CAAQ,KAAK,KAAK,CAAA;AACvB,IAAA,IAAI,IAAA,CAAK,SAAA,CAAU,MAAA,KAAW,CAAA,EAAG;AAAE,MAAA,IAAA,CAAK,MAAA,CAAO,KAAK,KAAK,CAAA;AAAG,MAAA;AAAA,IAAQ;AACpE,IAAA,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAA,CAAA,KAAK;AAAE,MAAA,IAAI;AAAE,QAAA,CAAA,CAAE,QAAQ,KAAK,CAAA;AAAA,MAAG,CAAA,CAAA,MAAQ;AAAA,MAA+B;AAAA,IAAE,CAAC,CAAA;AAAA,EAClG;AAAA,EAEA,IAAA,CAAK,MAAc,UAAA,EAA4C;AAC7D,IAAA,IAAI,CAAC,KAAK,QAAA,EAAU;AACpB,IAAA,MAAM,SAAS,EAAE,GAAG,IAAA,CAAK,QAAA,EAAU,GAAG,UAAA,EAAW;AACjD,IAAA,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAA,CAAA,KAAK;AAAE,MAAA,IAAI;AAAE,QAAA,CAAA,CAAE,IAAA,GAAO,MAAM,MAAM,CAAA;AAAA,MAAG,CAAA,CAAA,MAAQ;AAAA,MAAQ;AAAA,IAAE,CAAC,CAAA;AAC/E,IAAA,IAAA,CAAK,KAAA,CAAM,CAAA,KAAA,EAAQ,IAAI,CAAA,CAAA,EAAI,MAAM,CAAA;AAAA,EACnC;AAAA,EAEA,QAAA,CAAS,QAAgB,MAAA,EAAwC;AAC/D,IAAA,IAAA,CAAK,OAAA,CAAQ,QAAQ,MAAM,CAAA;AAAA,EAC7B;AAAA;AAAA,EAGA,OAAA,GAAU;AAAE,IAAA,OAAO,IAAA,CAAK,QAAQ,YAAA,EAAa;AAAA,EAAG;AAAA;AAAA,EAGhD,KAAA,GAAc;AACZ,IAAA,KAAA,MAAW,EAAA,IAAM,KAAK,MAAA,EAAQ;AAC5B,MAAA,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAA,CAAA,KAAK;AAAE,QAAA,IAAI;AAAE,UAAA,CAAA,CAAE,QAAQ,EAAE,CAAA;AAAA,QAAG,CAAA,CAAA,MAAQ;AAAA,QAAQ;AAAA,MAAE,CAAC,CAAA;AAAA,IACxE;AACA,IAAA,IAAA,CAAK,SAAS,EAAC;AAAA,EACjB;AAAA,EAEA,YAAA,GAAuB;AAAE,IAAA,OAAO,KAAK,MAAA,CAAO,MAAA;AAAA,EAAQ;AACtD;AAGO,IAAM,uBAAA,GAAgD;AAAA,EAC3D,IAAA,EAAM,SAAA;AAAA,EACN,KAAA,EAAO,CAAC,CAAA,KAAM,OAAA,CAAQ,GAAA,CAAI,qBAAqB,CAAA,CAAE,IAAI,CAAA,CAAA,EAAI,CAAA,CAAE,UAAU,CAAA;AAAA,EACrE,MAAM,CAAC,IAAA,KAAS,QAAQ,GAAA,CAAI,CAAA,iBAAA,EAAoB,IAAI,CAAA,CAAE,CAAA;AAAA,EACtD,UAAU,CAAC,EAAA,KAAO,QAAQ,GAAA,CAAI,CAAA,qBAAA,EAAwB,EAAE,CAAA,CAAE;AAC5D","file":"index.js","sourcesContent":["export type Unsubscribe = () => void;\nexport type Listener<T> = (value: T) => void;\n\n/**\n * Lightweight pub/sub subject — emits to all current subscribers.\n * Replaces RxJS Subject without pulling in the full RxJS dependency.\n */\nexport class JoopSubject<T> {\n private _listeners: Listener<T>[] = [];\n\n subscribe(listener: Listener<T>): Unsubscribe {\n this._listeners.push(listener);\n return () => {\n this._listeners = this._listeners.filter(l => l !== listener);\n };\n }\n\n next(value: T): void {\n for (const listener of this._listeners) {\n listener(value);\n }\n }\n\n asObservable(): JoopObservable<T> {\n return new JoopObservable<T>(listener => this.subscribe(listener));\n }\n}\n\n/**\n * Stateful subject — replays the current value to any new subscriber immediately.\n * Replaces RxJS BehaviorSubject.\n */\nexport class JoopBehaviorSubject<T> extends JoopSubject<T> {\n private _value: T;\n\n constructor(initialValue: T) {\n super();\n this._value = initialValue;\n }\n\n getValue(): T {\n return this._value;\n }\n\n override next(value: T): void {\n this._value = value;\n super.next(value);\n }\n\n override subscribe(listener: Listener<T>): Unsubscribe {\n listener(this._value);\n return super.subscribe(listener);\n }\n\n override asObservable(): JoopObservable<T> {\n return new JoopObservable<T>(listener => this.subscribe(listener));\n }\n}\n\n/**\n * Read-only observable handle returned from asObservable().\n */\nexport class JoopObservable<T> {\n constructor(private _subscribeFn: (listener: Listener<T>) => Unsubscribe) {}\n\n subscribe(listener: Listener<T>): Unsubscribe {\n return this._subscribeFn(listener);\n }\n\n /** Returns the current value without subscribing (only meaningful for BehaviorSubject-backed observables). */\n getOnce(): T | undefined {\n let result: T | undefined;\n const unsub = this.subscribe(v => { result = v; });\n unsub();\n return result;\n }\n}\n","import { JoopSubject } from '../events';\n\nexport interface JoopAnalyticsEvent {\n name: string;\n properties?: Record<string, unknown>;\n timestamp: number;\n sessionId?: string;\n userId?: string;\n}\n\nexport interface JoopAnalyticsAdapter {\n name: string;\n track?(event: JoopAnalyticsEvent): void;\n page?(name: string, properties?: Record<string, unknown>): void;\n identify?(userId: string, traits?: Record<string, unknown>): void;\n}\n\nexport class JoopAnalyticsService {\n private _adapters: JoopAnalyticsAdapter[] = [];\n private _context: Record<string, unknown> = {};\n private _userId = '';\n private _sessionId = '';\n private _event$ = new JoopSubject<JoopAnalyticsEvent>();\n private _queue: JoopAnalyticsEvent[] = [];\n private _enabled = true;\n\n addAdapter(adapter: JoopAnalyticsAdapter): void {\n if (!this._adapters.find(a => a.name === adapter.name)) {\n this._adapters.push(adapter);\n // drain queued events to new adapter\n for (const ev of this._queue) adapter.track?.(ev);\n }\n }\n\n removeAdapter(name: string): void {\n this._adapters = this._adapters.filter(a => a.name !== name);\n }\n\n enable(): void { this._enabled = true; }\n disable(): void { this._enabled = false; }\n\n setContext(ctx: Record<string, unknown>): void {\n this._context = { ...this._context, ...ctx };\n }\n\n setUser(userId: string, traits?: Record<string, unknown>): void {\n this._userId = userId;\n this._adapters.forEach(a => a.identify?.(userId, traits));\n }\n\n setSession(sessionId: string): void { this._sessionId = sessionId; }\n\n track(name: string, properties?: Record<string, unknown>): void {\n if (!this._enabled) return;\n const event: JoopAnalyticsEvent = {\n name,\n properties: { ...this._context, ...properties },\n timestamp: Date.now(),\n userId: this._userId || undefined,\n sessionId: this._sessionId || undefined,\n };\n this._event$.next(event);\n if (this._adapters.length === 0) { this._queue.push(event); return; }\n this._adapters.forEach(a => { try { a.track?.(event); } catch { /* isolate adapter errors */ } });\n }\n\n page(name: string, properties?: Record<string, unknown>): void {\n if (!this._enabled) return;\n const merged = { ...this._context, ...properties };\n this._adapters.forEach(a => { try { a.page?.(name, merged); } catch { /* */ } });\n this.track(`page:${name}`, merged);\n }\n\n identify(userId: string, traits?: Record<string, unknown>): void {\n this.setUser(userId, traits);\n }\n\n /** Subscribe to all tracked events (useful for debugging) */\n events$() { return this._event$.asObservable(); }\n\n /** Flush the pre-adapter queue (e.g. after lazy-loading analytics) */\n flush(): void {\n for (const ev of this._queue) {\n this._adapters.forEach(a => { try { a.track?.(ev); } catch { /* */ } });\n }\n this._queue = [];\n }\n\n getQueueSize(): number { return this._queue.length; }\n}\n\n// ── Built-in console adapter (for development) ────────────────────────────\nexport const consoleAnalyticsAdapter: JoopAnalyticsAdapter = {\n name: 'console',\n track: (e) => console.log(`[analytics:track] ${e.name}`, e.properties),\n page: (name) => console.log(`[analytics:page] ${name}`),\n identify: (id) => console.log(`[analytics:identify] ${id}`),\n};\n"]}