@haex-space/vault-sdk 1.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 (59) hide show
  1. package/README.md +1551 -0
  2. package/dist/cli/index.d.mts +1 -0
  3. package/dist/cli/index.d.ts +1 -0
  4. package/dist/cli/index.js +455 -0
  5. package/dist/cli/index.js.map +1 -0
  6. package/dist/cli/index.mjs +430 -0
  7. package/dist/cli/index.mjs.map +1 -0
  8. package/dist/client-O_JEOzfx.d.mts +491 -0
  9. package/dist/client-O_JEOzfx.d.ts +491 -0
  10. package/dist/index.d.mts +124 -0
  11. package/dist/index.d.ts +124 -0
  12. package/dist/index.js +1429 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/index.mjs +1409 -0
  15. package/dist/index.mjs.map +1 -0
  16. package/dist/node.d.mts +25 -0
  17. package/dist/node.d.ts +25 -0
  18. package/dist/node.js +28 -0
  19. package/dist/node.js.map +1 -0
  20. package/dist/node.mjs +25 -0
  21. package/dist/node.mjs.map +1 -0
  22. package/dist/nuxt.d.mts +19 -0
  23. package/dist/nuxt.d.ts +19 -0
  24. package/dist/nuxt.js +473 -0
  25. package/dist/nuxt.js.map +1 -0
  26. package/dist/nuxt.mjs +470 -0
  27. package/dist/nuxt.mjs.map +1 -0
  28. package/dist/react.d.mts +28 -0
  29. package/dist/react.d.ts +28 -0
  30. package/dist/react.js +1389 -0
  31. package/dist/react.js.map +1 -0
  32. package/dist/react.mjs +1386 -0
  33. package/dist/react.mjs.map +1 -0
  34. package/dist/runtime/nuxt.plugin.client.d.mts +43 -0
  35. package/dist/runtime/nuxt.plugin.client.d.ts +43 -0
  36. package/dist/runtime/nuxt.plugin.client.js +1137 -0
  37. package/dist/runtime/nuxt.plugin.client.js.map +1 -0
  38. package/dist/runtime/nuxt.plugin.client.mjs +1135 -0
  39. package/dist/runtime/nuxt.plugin.client.mjs.map +1 -0
  40. package/dist/runtime/nuxt.types.d.ts +15 -0
  41. package/dist/svelte.d.mts +48 -0
  42. package/dist/svelte.d.ts +48 -0
  43. package/dist/svelte.js +1398 -0
  44. package/dist/svelte.js.map +1 -0
  45. package/dist/svelte.mjs +1391 -0
  46. package/dist/svelte.mjs.map +1 -0
  47. package/dist/vite.d.mts +37 -0
  48. package/dist/vite.d.ts +37 -0
  49. package/dist/vite.js +346 -0
  50. package/dist/vite.js.map +1 -0
  51. package/dist/vite.mjs +341 -0
  52. package/dist/vite.mjs.map +1 -0
  53. package/dist/vue.d.mts +49 -0
  54. package/dist/vue.d.ts +49 -0
  55. package/dist/vue.js +1388 -0
  56. package/dist/vue.js.map +1 -0
  57. package/dist/vue.mjs +1385 -0
  58. package/dist/vue.mjs.map +1 -0
  59. package/package.json +121 -0
package/dist/vue.js ADDED
@@ -0,0 +1,1388 @@
1
+ 'use strict';
2
+
3
+ var vue = require('vue');
4
+ var sqliteProxy = require('drizzle-orm/sqlite-proxy');
5
+
6
+ // src/vue.ts
7
+
8
+ // src/polyfills/localStorage.ts
9
+ function installLocalStoragePolyfill() {
10
+ if (typeof window === "undefined") {
11
+ return;
12
+ }
13
+ console.log("[HaexHub] Storage Polyfill loading immediately");
14
+ let localStorageWorks = false;
15
+ try {
16
+ const testKey = "__ls_test__";
17
+ localStorage.setItem(testKey, testKey);
18
+ localStorage.removeItem(testKey);
19
+ localStorageWorks = true;
20
+ } catch (e) {
21
+ console.warn("[HaexHub] localStorage blocked \u2013 using in-memory fallback");
22
+ }
23
+ if (!localStorageWorks) {
24
+ const lsStorage = /* @__PURE__ */ new Map();
25
+ const localStoragePoly = {
26
+ getItem(key) {
27
+ return lsStorage.get(key) || null;
28
+ },
29
+ setItem(key, value) {
30
+ lsStorage.set(key, String(value));
31
+ },
32
+ removeItem(key) {
33
+ lsStorage.delete(key);
34
+ },
35
+ clear() {
36
+ lsStorage.clear();
37
+ },
38
+ get length() {
39
+ return lsStorage.size;
40
+ },
41
+ key(index) {
42
+ return Array.from(lsStorage.keys())[index] || null;
43
+ }
44
+ };
45
+ try {
46
+ Object.defineProperty(window, "localStorage", {
47
+ value: localStoragePoly,
48
+ writable: true,
49
+ configurable: true
50
+ });
51
+ } catch (e) {
52
+ window.localStorage = localStoragePoly;
53
+ }
54
+ console.log("[HaexHub] localStorage replaced with in-memory polyfill");
55
+ }
56
+ }
57
+ function installSessionStoragePolyfill() {
58
+ if (typeof window === "undefined") {
59
+ return;
60
+ }
61
+ try {
62
+ const sessionStoragePoly = {
63
+ getItem() {
64
+ return null;
65
+ },
66
+ setItem() {
67
+ },
68
+ removeItem() {
69
+ },
70
+ clear() {
71
+ },
72
+ get length() {
73
+ return 0;
74
+ },
75
+ key() {
76
+ return null;
77
+ }
78
+ };
79
+ Object.defineProperty(window, "sessionStorage", {
80
+ value: sessionStoragePoly,
81
+ writable: true,
82
+ configurable: true
83
+ });
84
+ } catch (e) {
85
+ window.sessionStorage = {
86
+ getItem: () => null,
87
+ setItem: () => {
88
+ },
89
+ removeItem: () => {
90
+ },
91
+ clear: () => {
92
+ },
93
+ get length() {
94
+ return 0;
95
+ },
96
+ key: () => null
97
+ };
98
+ }
99
+ console.log("[HaexHub] sessionStorage polyfill installed");
100
+ }
101
+
102
+ // src/polyfills/cookies.ts
103
+ function installCookiePolyfill() {
104
+ if (typeof window === "undefined" || typeof document === "undefined") {
105
+ return;
106
+ }
107
+ let cookiesWork = false;
108
+ try {
109
+ document.cookie = "__cookie_test__=1";
110
+ cookiesWork = document.cookie.indexOf("__cookie_test__") !== -1;
111
+ } catch (e) {
112
+ console.warn("[HaexHub] Cookies blocked \u2013 using in-memory fallback");
113
+ }
114
+ if (!cookiesWork) {
115
+ const cookieStore = /* @__PURE__ */ new Map();
116
+ Object.defineProperty(document, "cookie", {
117
+ get() {
118
+ const cookies = [];
119
+ cookieStore.forEach((value, key) => {
120
+ cookies.push(`${key}=${value}`);
121
+ });
122
+ return cookies.join("; ");
123
+ },
124
+ set(cookieString) {
125
+ const parts = cookieString.split(";").map((p) => p.trim());
126
+ const [keyValue] = parts;
127
+ if (!keyValue) return;
128
+ const [key, value] = keyValue.split("=");
129
+ if (!key) return;
130
+ const options = {};
131
+ for (let i = 1; i < parts.length; i++) {
132
+ const part = parts[i];
133
+ if (!part) continue;
134
+ const parts_split = part.split("=");
135
+ const optKey = parts_split[0];
136
+ const optValue = parts_split[1];
137
+ if (optKey) {
138
+ options[optKey.toLowerCase()] = optValue || true;
139
+ }
140
+ }
141
+ const expiresValue = options.expires;
142
+ if (expiresValue && typeof expiresValue === "string") {
143
+ const expiresDate = new Date(expiresValue);
144
+ if (expiresDate < /* @__PURE__ */ new Date()) {
145
+ cookieStore.delete(key);
146
+ return;
147
+ }
148
+ }
149
+ const maxAgeValue = options["max-age"];
150
+ if (typeof maxAgeValue === "string" && maxAgeValue === "0") {
151
+ cookieStore.delete(key);
152
+ return;
153
+ }
154
+ cookieStore.set(key, value || "");
155
+ },
156
+ configurable: true
157
+ });
158
+ console.log("[HaexHub] Cookie polyfill installed");
159
+ }
160
+ }
161
+
162
+ // src/polyfills/history.ts
163
+ function installHistoryPolyfill() {
164
+ if (typeof window === "undefined" || typeof history === "undefined") {
165
+ return;
166
+ }
167
+ const install = () => {
168
+ console.log("[HaexHub] History Patch loading");
169
+ const originalPushState = history.pushState;
170
+ const originalReplaceState = history.replaceState;
171
+ let skipNextPush = false;
172
+ let skipNextReplace = false;
173
+ history.pushState = function(state, title, url) {
174
+ console.log("[HaexHub] pushState called:", url, "skip:", skipNextPush);
175
+ if (skipNextPush) {
176
+ skipNextPush = false;
177
+ console.log("[HaexHub] pushState skipped");
178
+ return;
179
+ }
180
+ try {
181
+ return originalPushState.call(this, state, title, url);
182
+ } catch (e) {
183
+ if (e.name === "SecurityError" && url) {
184
+ const urlString = url.toString();
185
+ let hashUrl = urlString.replace(/^\/#/, "");
186
+ hashUrl = hashUrl.startsWith("#") ? hashUrl : "#" + hashUrl;
187
+ console.log("[HaexHub] SecurityError - setting hash to:", hashUrl);
188
+ skipNextPush = true;
189
+ window.location.hash = hashUrl.replace(/^#/, "");
190
+ return;
191
+ }
192
+ throw e;
193
+ }
194
+ };
195
+ history.replaceState = function(state, title, url) {
196
+ console.log("[HaexHub] replaceState called:", url, "skip:", skipNextReplace);
197
+ if (skipNextReplace) {
198
+ skipNextReplace = false;
199
+ console.log("[HaexHub] replaceState skipped");
200
+ return;
201
+ }
202
+ try {
203
+ return originalReplaceState.call(this, state, title, url);
204
+ } catch (e) {
205
+ if (e.name === "SecurityError" && url) {
206
+ const urlString = url.toString();
207
+ let hashUrl = urlString.replace(/^\/#/, "");
208
+ hashUrl = hashUrl.startsWith("#") ? hashUrl : "#" + hashUrl;
209
+ console.log("[HaexHub] SecurityError - setting hash to:", hashUrl);
210
+ skipNextReplace = true;
211
+ window.location.hash = hashUrl.replace(/^#/, "");
212
+ return;
213
+ }
214
+ throw e;
215
+ }
216
+ };
217
+ console.log("[HaexHub] History API patched");
218
+ };
219
+ if (document.readyState === "loading") {
220
+ document.addEventListener("DOMContentLoaded", install, { once: true });
221
+ } else {
222
+ install();
223
+ }
224
+ }
225
+
226
+ // src/polyfills/debug.ts
227
+ function installDebugDiagnostics() {
228
+ if (typeof window === "undefined") {
229
+ return;
230
+ }
231
+ const hasParent = window.parent && window.parent !== window;
232
+ console.log("[HaexHub] hasParent:", hasParent);
233
+ if (hasParent) {
234
+ console.log("[HaexHub] Attempting to send debug message to parent...");
235
+ window.parent.postMessage({
236
+ type: "haexhub:debug",
237
+ data: `[Polyfills] window.parent test: exists=${!!window.parent}, different=${hasParent}, selfIsTop=${window.self === window.top}`
238
+ }, "*");
239
+ console.log("[HaexHub] Debug message sent!");
240
+ } else {
241
+ console.log("[HaexHub] No parent window or parent === window");
242
+ }
243
+ }
244
+
245
+ // src/polyfills/consoleForwarding.ts
246
+ var originalConsole = {
247
+ log: console.log,
248
+ info: console.info,
249
+ warn: console.warn,
250
+ error: console.error,
251
+ debug: console.debug
252
+ };
253
+ function serializeArgs(args) {
254
+ return args.map((arg) => {
255
+ if (arg === null) return "null";
256
+ if (arg === void 0) return "undefined";
257
+ if (typeof arg === "object") {
258
+ try {
259
+ return JSON.stringify(arg, null, 2);
260
+ } catch {
261
+ return String(arg);
262
+ }
263
+ }
264
+ return String(arg);
265
+ }).join(" ");
266
+ }
267
+ function interceptConsole(level) {
268
+ console[level] = function(...args) {
269
+ originalConsole[level].apply(console, args);
270
+ if (window.self !== window.top && window.parent) {
271
+ try {
272
+ const message = serializeArgs(args);
273
+ const timestamp = (/* @__PURE__ */ new Date()).toLocaleTimeString();
274
+ window.parent.postMessage(
275
+ {
276
+ type: "console.forward",
277
+ data: {
278
+ timestamp,
279
+ level,
280
+ message
281
+ },
282
+ timestamp: Date.now()
283
+ },
284
+ "*"
285
+ );
286
+ } catch (error) {
287
+ originalConsole.error("[HaexHub] Failed to forward console message:", error);
288
+ }
289
+ }
290
+ };
291
+ }
292
+ function installConsoleForwarding(debug = false) {
293
+ if (typeof window === "undefined") {
294
+ return;
295
+ }
296
+ if (window.self === window.top) {
297
+ return;
298
+ }
299
+ if (!debug) {
300
+ console.log("[HaexHub] Console forwarding disabled (not in debug mode)");
301
+ return;
302
+ }
303
+ interceptConsole("log");
304
+ interceptConsole("info");
305
+ interceptConsole("warn");
306
+ interceptConsole("error");
307
+ interceptConsole("debug");
308
+ console.log("[HaexHub] Console forwarding installed");
309
+ }
310
+
311
+ // src/polyfills/index.ts
312
+ function installPolyfills() {
313
+ if (typeof window === "undefined") {
314
+ return;
315
+ }
316
+ installLocalStoragePolyfill();
317
+ installSessionStoragePolyfill();
318
+ installCookiePolyfill();
319
+ installHistoryPolyfill();
320
+ console.log("[HaexHub] All polyfills loaded successfully");
321
+ installDebugDiagnostics();
322
+ }
323
+ if (typeof window !== "undefined") {
324
+ installPolyfills();
325
+ }
326
+
327
+ // src/events.ts
328
+ var HAEXTENSION_EVENTS = {
329
+ /** Context (theme, locale, platform) has changed */
330
+ CONTEXT_CHANGED: "haextension:context:changed",
331
+ /** Search request from HaexHub */
332
+ SEARCH_REQUEST: "haextension:search:request"
333
+ };
334
+
335
+ // src/methods.ts
336
+ var HAEXTENSION_METHODS = {
337
+ context: {
338
+ get: "haextension:context:get"
339
+ },
340
+ database: {
341
+ query: "haextension:database:query",
342
+ execute: "haextension:database:execute",
343
+ transaction: "haextension:database:transaction",
344
+ registerMigrations: "haextension:database:register-migrations"
345
+ },
346
+ filesystem: {
347
+ saveFile: "haextension:filesystem:save-file",
348
+ openFile: "haextension:filesystem:open-file",
349
+ showImage: "haextension:filesystem:show-image"
350
+ },
351
+ storage: {
352
+ getItem: "haextension:storage:get-item",
353
+ setItem: "haextension:storage:set-item",
354
+ removeItem: "haextension:storage:remove-item",
355
+ clear: "haextension:storage:clear",
356
+ keys: "haextension:storage:keys"
357
+ },
358
+ web: {
359
+ fetch: "haextension:web:fetch"
360
+ },
361
+ application: {
362
+ open: "haextension:application:open"
363
+ }
364
+ };
365
+
366
+ // src/types.ts
367
+ var DEFAULT_TIMEOUT = 3e4;
368
+ var TABLE_SEPARATOR = "__";
369
+ var HaexHubError = class extends Error {
370
+ constructor(code, messageKey, details) {
371
+ super(messageKey);
372
+ this.code = code;
373
+ this.messageKey = messageKey;
374
+ this.details = details;
375
+ this.name = "HaexHubError";
376
+ }
377
+ /**
378
+ * Get localized error message
379
+ * @param locale - Locale code (e.g., 'en', 'de')
380
+ * @param translations - Translation object
381
+ */
382
+ getLocalizedMessage(locale = "en", translations) {
383
+ if (!translations || !translations[locale]) {
384
+ return this.messageKey;
385
+ }
386
+ let message = translations[locale][this.messageKey] || this.messageKey;
387
+ if (this.details) {
388
+ Object.entries(this.details).forEach(([key, value]) => {
389
+ message = message.replace(`{${key}}`, String(value));
390
+ });
391
+ }
392
+ return message;
393
+ }
394
+ toJSON() {
395
+ return {
396
+ code: this.code,
397
+ message: this.messageKey,
398
+ details: this.details
399
+ };
400
+ }
401
+ };
402
+
403
+ // src/api/storage.ts
404
+ var StorageAPI = class {
405
+ constructor(client) {
406
+ this.client = client;
407
+ }
408
+ async getItem(key) {
409
+ return this.client.request(HAEXTENSION_METHODS.storage.getItem, { key });
410
+ }
411
+ async setItem(key, value) {
412
+ await this.client.request(HAEXTENSION_METHODS.storage.setItem, { key, value });
413
+ }
414
+ async removeItem(key) {
415
+ await this.client.request(HAEXTENSION_METHODS.storage.removeItem, { key });
416
+ }
417
+ async clear() {
418
+ await this.client.request(HAEXTENSION_METHODS.storage.clear);
419
+ }
420
+ async keys() {
421
+ return this.client.request(HAEXTENSION_METHODS.storage.keys);
422
+ }
423
+ };
424
+
425
+ // src/api/database.ts
426
+ var DatabaseAPI = class {
427
+ constructor(client) {
428
+ this.client = client;
429
+ }
430
+ async query(query, params) {
431
+ const result = await this.client.request(
432
+ HAEXTENSION_METHODS.database.query,
433
+ {
434
+ query,
435
+ params: params || []
436
+ }
437
+ );
438
+ return result.rows;
439
+ }
440
+ async queryOne(query, params) {
441
+ const rows = await this.query(query, params);
442
+ return rows.length > 0 ? rows[0] ?? null : null;
443
+ }
444
+ async execute(query, params) {
445
+ return this.client.request(HAEXTENSION_METHODS.database.execute, {
446
+ query,
447
+ params: params || []
448
+ });
449
+ }
450
+ async transaction(statements) {
451
+ await this.client.request(HAEXTENSION_METHODS.database.transaction, {
452
+ statements
453
+ });
454
+ }
455
+ async createTable(tableName, columns) {
456
+ const query = `CREATE TABLE IF NOT EXISTS ${tableName} (${columns})`;
457
+ await this.execute(query);
458
+ }
459
+ async dropTable(tableName) {
460
+ const query = `DROP TABLE IF EXISTS ${tableName}`;
461
+ await this.execute(query);
462
+ }
463
+ /**
464
+ * Registers extension migrations with HaexVault for CRDT synchronization
465
+ * HaexVault will validate and execute these migrations, ensuring only
466
+ * tables with the correct prefix are manipulated
467
+ * @param extensionVersion - The version of the extension
468
+ * @param migrations - Array of migration objects with name and SQL content
469
+ * @returns Promise that resolves when migrations are registered
470
+ */
471
+ async registerMigrationsAsync(extensionVersion, migrations) {
472
+ await this.client.request(HAEXTENSION_METHODS.database.registerMigrations, {
473
+ extensionVersion,
474
+ migrations
475
+ });
476
+ }
477
+ async insert(tableName, data) {
478
+ const keys = Object.keys(data);
479
+ const values = Object.values(data);
480
+ const placeholders = keys.map(() => "?").join(", ");
481
+ const query = `INSERT INTO ${tableName} (${keys.join(
482
+ ", "
483
+ )}) VALUES (${placeholders})`;
484
+ const result = await this.execute(query, values);
485
+ return result.lastInsertId ?? -1;
486
+ }
487
+ async update(tableName, data, where, whereParams) {
488
+ const keys = Object.keys(data);
489
+ const values = Object.values(data);
490
+ const setClause = keys.map((key) => `${key} = ?`).join(", ");
491
+ const query = `UPDATE ${tableName} SET ${setClause} WHERE ${where}`;
492
+ const result = await this.execute(query, [
493
+ ...values,
494
+ ...whereParams || []
495
+ ]);
496
+ return result.rowsAffected;
497
+ }
498
+ async delete(tableName, where, whereParams) {
499
+ const query = `DELETE FROM ${tableName} WHERE ${where}`;
500
+ const result = await this.execute(query, whereParams);
501
+ return result.rowsAffected;
502
+ }
503
+ async count(tableName, where, whereParams) {
504
+ const query = where ? `SELECT COUNT(*) as count FROM ${tableName} WHERE ${where}` : `SELECT COUNT(*) as count FROM ${tableName}`;
505
+ const result = await this.queryOne(query, whereParams);
506
+ return result?.count ?? 0;
507
+ }
508
+ };
509
+
510
+ // src/api/filesystem.ts
511
+ var FilesystemAPI = class {
512
+ constructor(client) {
513
+ this.client = client;
514
+ }
515
+ /**
516
+ * Opens a save file dialog and saves the provided data to the selected location
517
+ * @param data The file data as Uint8Array
518
+ * @param options Options for the save dialog
519
+ * @returns The path where the file was saved, or null if cancelled
520
+ */
521
+ async saveFileAsync(data, options = {}) {
522
+ const result = await this.client.request(
523
+ HAEXTENSION_METHODS.filesystem.saveFile,
524
+ {
525
+ data: Array.from(data),
526
+ // Convert Uint8Array to regular array for postMessage
527
+ defaultPath: options.defaultPath,
528
+ title: options.title,
529
+ filters: options.filters
530
+ }
531
+ );
532
+ return result;
533
+ }
534
+ /**
535
+ * Opens a file with the system's default viewer
536
+ * @param data The file data as Uint8Array
537
+ * @param options Options for opening the file
538
+ * @returns The result of the operation
539
+ */
540
+ async openFileAsync(data, options) {
541
+ const result = await this.client.request(
542
+ HAEXTENSION_METHODS.filesystem.openFile,
543
+ {
544
+ data: Array.from(data),
545
+ // Convert Uint8Array to regular array for postMessage
546
+ fileName: options.fileName,
547
+ mimeType: options.mimeType
548
+ }
549
+ );
550
+ return result;
551
+ }
552
+ /**
553
+ * Shows an image using a data URL (safe, read-only viewing)
554
+ * This is safe to use without special permissions as it only displays images
555
+ * and doesn't execute any code or open files with external applications
556
+ * @param options Options containing the data URL
557
+ * @returns The result of the operation
558
+ */
559
+ async showImageAsync(options) {
560
+ const result = await this.client.request(
561
+ HAEXTENSION_METHODS.filesystem.showImage,
562
+ {
563
+ dataUrl: options.dataUrl
564
+ }
565
+ );
566
+ return result;
567
+ }
568
+ };
569
+
570
+ // src/api/web.ts
571
+ var WebAPI = class {
572
+ constructor(client) {
573
+ this.client = client;
574
+ }
575
+ /**
576
+ * Performs a web request through the HaexHub host application
577
+ * @param url The URL to fetch
578
+ * @param options Request options (method, headers, body, timeout)
579
+ * @returns Promise resolving to the web response
580
+ */
581
+ async fetchAsync(url, options = {}) {
582
+ let bodyParam;
583
+ if (options.body) {
584
+ if (options.body instanceof ArrayBuffer) {
585
+ bodyParam = this.arrayBufferToBase64(options.body);
586
+ } else if (options.body instanceof Blob) {
587
+ bodyParam = await this.blobToBase64(options.body);
588
+ } else {
589
+ bodyParam = options.body;
590
+ }
591
+ }
592
+ const response = await this.client.request(HAEXTENSION_METHODS.web.fetch, {
593
+ url,
594
+ method: options.method || "GET",
595
+ headers: options.headers,
596
+ body: bodyParam,
597
+ timeout: options.timeout
598
+ });
599
+ const bodyBuffer = this.base64ToArrayBuffer(response.body);
600
+ return {
601
+ status: response.status,
602
+ statusText: response.statusText,
603
+ headers: response.headers,
604
+ body: bodyBuffer,
605
+ url: response.url
606
+ };
607
+ }
608
+ /**
609
+ * Convenience method for JSON requests
610
+ */
611
+ async fetchJsonAsync(url, options = {}) {
612
+ const response = await this.fetchAsync(url, options);
613
+ const text = new TextDecoder().decode(response.body);
614
+ return JSON.parse(text);
615
+ }
616
+ /**
617
+ * Convenience method for text requests
618
+ */
619
+ async fetchTextAsync(url, options = {}) {
620
+ const response = await this.fetchAsync(url, options);
621
+ return new TextDecoder().decode(response.body);
622
+ }
623
+ /**
624
+ * Convenience method for blob requests
625
+ */
626
+ async fetchBlobAsync(url, options = {}) {
627
+ const response = await this.fetchAsync(url, options);
628
+ return new Blob([response.body]);
629
+ }
630
+ /**
631
+ * Opens a URL in the user's default browser
632
+ * @param url The URL to open
633
+ */
634
+ async openAsync(url) {
635
+ await this.client.request(HAEXTENSION_METHODS.application.open, {
636
+ application: "browser",
637
+ url
638
+ });
639
+ }
640
+ arrayBufferToBase64(buffer) {
641
+ const bytes = new Uint8Array(buffer);
642
+ let binary = "";
643
+ for (let i = 0; i < bytes.byteLength; i++) {
644
+ const byte = bytes[i];
645
+ if (byte === void 0) {
646
+ throw new Error("Invalid byte at index " + i);
647
+ }
648
+ binary += String.fromCharCode(byte);
649
+ }
650
+ return btoa(binary);
651
+ }
652
+ async blobToBase64(blob) {
653
+ return new Promise((resolve, reject) => {
654
+ const reader = new FileReader();
655
+ reader.onloadend = () => {
656
+ const result = reader.result;
657
+ if (typeof result !== "string") {
658
+ reject(new Error("Failed to read blob as data URL"));
659
+ return;
660
+ }
661
+ const parts = result.split(",");
662
+ const base64 = parts[1];
663
+ if (!base64) {
664
+ reject(new Error("Failed to extract base64 from data URL"));
665
+ return;
666
+ }
667
+ resolve(base64);
668
+ };
669
+ reader.onerror = reject;
670
+ reader.readAsDataURL(blob);
671
+ });
672
+ }
673
+ base64ToArrayBuffer(base64) {
674
+ const binaryString = atob(base64);
675
+ const bytes = new Uint8Array(binaryString.length);
676
+ for (let i = 0; i < binaryString.length; i++) {
677
+ bytes[i] = binaryString.charCodeAt(i);
678
+ }
679
+ return bytes.buffer;
680
+ }
681
+ };
682
+
683
+ // src/api/permissions.ts
684
+ var PermissionsAPI = class {
685
+ constructor(client) {
686
+ this.client = client;
687
+ }
688
+ /**
689
+ * Checks if the extension has permission for a database operation
690
+ * @param resource The database resource (table name or "*" for all tables)
691
+ * @param operation The operation type ("read" or "write")
692
+ * @returns Promise<boolean> indicating if permission is granted
693
+ */
694
+ async checkDatabaseAsync(resource, operation) {
695
+ const response = await this.client.request(
696
+ "permissions.database.check",
697
+ {
698
+ resource,
699
+ operation
700
+ }
701
+ );
702
+ return response.status === "granted";
703
+ }
704
+ /**
705
+ * Checks if the extension has permission for a web request
706
+ * @param url The URL to check (e.g., "https://example.com/path")
707
+ * @returns Promise<boolean> indicating if permission is granted
708
+ * @note Method/operation is not checked - permissions apply to all HTTP methods
709
+ */
710
+ async checkWebAsync(url) {
711
+ const response = await this.client.request(
712
+ "permissions.web.check",
713
+ {
714
+ url
715
+ }
716
+ );
717
+ return response.status === "granted";
718
+ }
719
+ /**
720
+ * Checks if the extension has permission for a filesystem operation
721
+ * @param path The file or directory path
722
+ * @param operation The operation type ("read" or "write")
723
+ * @returns Promise<boolean> indicating if permission is granted
724
+ */
725
+ async checkFilesystemAsync(path, operation) {
726
+ const response = await this.client.request(
727
+ "permissions.filesystem.check",
728
+ {
729
+ path,
730
+ operation
731
+ }
732
+ );
733
+ return response.status === "granted";
734
+ }
735
+ };
736
+ var HaexVaultClient = class {
737
+ constructor(config = {}) {
738
+ this.pendingRequests = /* @__PURE__ */ new Map();
739
+ this.eventListeners = /* @__PURE__ */ new Map();
740
+ this.messageHandler = null;
741
+ this.initialized = false;
742
+ this.requestCounter = 0;
743
+ this._extensionInfo = null;
744
+ this._context = null;
745
+ this.reactiveSubscribers = /* @__PURE__ */ new Set();
746
+ this.isNativeWindow = false;
747
+ // Wird im Konstruktor initialisiert
748
+ this.setupPromise = null;
749
+ this.setupHook = null;
750
+ this._setupCompleted = false;
751
+ this.orm = null;
752
+ this.config = {
753
+ debug: config.debug ?? false,
754
+ timeout: config.timeout ?? DEFAULT_TIMEOUT,
755
+ manifest: config.manifest
756
+ };
757
+ this.storage = new StorageAPI(this);
758
+ this.database = new DatabaseAPI(this);
759
+ this.filesystem = new FilesystemAPI(this);
760
+ this.web = new WebAPI(this);
761
+ this.permissions = new PermissionsAPI(this);
762
+ installConsoleForwarding(this.config.debug);
763
+ this.readyPromise = new Promise((resolve) => {
764
+ this.resolveReady = resolve;
765
+ });
766
+ this.init();
767
+ }
768
+ /**
769
+ * Gibt ein Promise zurück, das aufgelöst wird, sobald der Client
770
+ * initialisiert ist und Extension-Infos empfangen hat.
771
+ */
772
+ async ready() {
773
+ return this.readyPromise;
774
+ }
775
+ /**
776
+ * Gibt zurück, ob das Setup bereits abgeschlossen wurde.
777
+ */
778
+ get setupCompleted() {
779
+ return this._setupCompleted;
780
+ }
781
+ /**
782
+ * Registriert eine Setup-Funktion, die nach der Initialisierung ausgeführt wird.
783
+ * Diese Funktion sollte für Aufgaben wie Tabellenerstellung, Migrationen, etc. verwendet werden.
784
+ * @param setupFn Die Setup-Funktion, die ausgeführt werden soll
785
+ */
786
+ onSetup(setupFn) {
787
+ if (this.setupHook) {
788
+ throw new Error("Setup hook already registered");
789
+ }
790
+ this.setupHook = setupFn;
791
+ }
792
+ /**
793
+ * Gibt ein Promise zurück, das aufgelöst wird, sobald der Client vollständig eingerichtet ist.
794
+ * Dies umfasst die Initialisierung UND das Setup (z.B. Tabellenerstellung).
795
+ * Falls kein Setup-Hook registriert wurde, entspricht dies ready().
796
+ */
797
+ async setupComplete() {
798
+ await this.readyPromise;
799
+ if (!this.setupHook || this.setupCompleted) {
800
+ return;
801
+ }
802
+ if (!this.setupPromise) {
803
+ this.setupPromise = this.runSetupAsync();
804
+ }
805
+ return this.setupPromise;
806
+ }
807
+ async runSetupAsync() {
808
+ if (!this.setupHook) return;
809
+ try {
810
+ this.log("[HaexHub] Running setup hook...");
811
+ await this.setupHook();
812
+ this._setupCompleted = true;
813
+ this.log("[HaexHub] Setup completed successfully");
814
+ this.notifySubscribers();
815
+ } catch (error) {
816
+ this.log("[HaexHub] Setup failed:", error);
817
+ throw error;
818
+ }
819
+ }
820
+ /**
821
+ * Initialisiert die Drizzle-Datenbankinstanz.
822
+ * Muss nach der Definition des Schemas aufgerufen werden.
823
+ * @param schema Das Drizzle-Schemaobjekt (mit bereits geprefixten Tabellennamen).
824
+ * @returns Die typsichere Drizzle-Datenbankinstanz.
825
+ */
826
+ initializeDatabase(schema) {
827
+ if (!this._extensionInfo) {
828
+ throw new HaexHubError(
829
+ "EXTENSION_INFO_UNAVAILABLE" /* EXTENSION_INFO_UNAVAILABLE */,
830
+ "errors.client_not_ready"
831
+ );
832
+ }
833
+ const dbInstance = sqliteProxy.drizzle(
834
+ async (sql, params, method) => {
835
+ try {
836
+ if (method === "run" || method === "all") {
837
+ const result2 = await this.request(
838
+ HAEXTENSION_METHODS.database.execute,
839
+ {
840
+ query: sql,
841
+ params
842
+ }
843
+ );
844
+ if (method === "all") {
845
+ return { rows: result2.rows || [] };
846
+ }
847
+ if (result2.rows && Array.isArray(result2.rows) && result2.rows.length > 0) {
848
+ return { rows: result2.rows };
849
+ }
850
+ return result2;
851
+ }
852
+ const result = await this.request(HAEXTENSION_METHODS.database.query, {
853
+ query: sql,
854
+ params
855
+ });
856
+ const rows = result.rows;
857
+ if (method === "get") {
858
+ return { rows: rows.length > 0 ? rows.at(0) : void 0 };
859
+ }
860
+ return { rows };
861
+ } catch (error) {
862
+ this.log("Database operation failed:", error);
863
+ throw error;
864
+ }
865
+ },
866
+ {
867
+ schema,
868
+ logger: false
869
+ }
870
+ );
871
+ this.orm = dbInstance;
872
+ return dbInstance;
873
+ }
874
+ get extensionInfo() {
875
+ return this._extensionInfo;
876
+ }
877
+ get context() {
878
+ return this._context;
879
+ }
880
+ subscribe(callback) {
881
+ this.reactiveSubscribers.add(callback);
882
+ return () => {
883
+ this.reactiveSubscribers.delete(callback);
884
+ };
885
+ }
886
+ notifySubscribers() {
887
+ this.reactiveSubscribers.forEach((callback) => callback());
888
+ }
889
+ async getDependencies() {
890
+ return this.request("extensions.getDependencies");
891
+ }
892
+ getTableName(tableName) {
893
+ if (!this._extensionInfo) {
894
+ throw new HaexHubError(
895
+ "EXTENSION_INFO_UNAVAILABLE" /* EXTENSION_INFO_UNAVAILABLE */,
896
+ "errors.extension_info_unavailable"
897
+ );
898
+ }
899
+ this.validateTableName(tableName);
900
+ const { publicKey, name } = this._extensionInfo;
901
+ const extensionName = name;
902
+ return `"${publicKey}${TABLE_SEPARATOR}${extensionName}${TABLE_SEPARATOR}${tableName}"`;
903
+ }
904
+ getDependencyTableName(publicKey, extensionName, tableName) {
905
+ this.validatePublicKey(publicKey);
906
+ this.validateExtensionName(extensionName);
907
+ this.validateTableName(tableName);
908
+ return `"${publicKey}${TABLE_SEPARATOR}${extensionName}${TABLE_SEPARATOR}${tableName}"`;
909
+ }
910
+ parseTableName(fullTableName) {
911
+ let cleanTableName = fullTableName;
912
+ if (cleanTableName.startsWith('"') && cleanTableName.endsWith('"')) {
913
+ cleanTableName = cleanTableName.slice(1, -1);
914
+ }
915
+ const parts = cleanTableName.split(TABLE_SEPARATOR);
916
+ if (parts.length !== 3) {
917
+ return null;
918
+ }
919
+ const [publicKey, extensionName, tableName] = parts;
920
+ if (!publicKey || !extensionName || !tableName) {
921
+ return null;
922
+ }
923
+ return {
924
+ publicKey,
925
+ extensionName,
926
+ tableName
927
+ };
928
+ }
929
+ /**
930
+ * Execute a raw SQL query (SELECT)
931
+ * Returns rows as an array of objects
932
+ */
933
+ async query(sql, params = []) {
934
+ const result = await this.request(
935
+ HAEXTENSION_METHODS.database.query,
936
+ { query: sql, params }
937
+ );
938
+ if (this.config.debug) {
939
+ console.log("[SDK query()] Raw result:", JSON.stringify(result, null, 2));
940
+ }
941
+ return result.rows;
942
+ }
943
+ /**
944
+ * Alias for query() - more intuitive for SELECT statements
945
+ */
946
+ async select(sql, params = []) {
947
+ return this.query(sql, params);
948
+ }
949
+ /**
950
+ * Execute a raw SQL statement (INSERT, UPDATE, DELETE, CREATE, etc.)
951
+ * Returns rowsAffected and lastInsertId
952
+ */
953
+ async execute(sql, params = []) {
954
+ const result = await this.request(
955
+ HAEXTENSION_METHODS.database.execute,
956
+ { query: sql, params }
957
+ );
958
+ return {
959
+ rowsAffected: result.rowsAffected,
960
+ lastInsertId: result.lastInsertId
961
+ };
962
+ }
963
+ /**
964
+ * Registers extension migrations with HaexVault for CRDT synchronization
965
+ * HaexVault will validate and execute these migrations
966
+ * @param extensionVersion - The version of the extension
967
+ * @param migrations - Array of migration objects with name and SQL content
968
+ * @returns Promise that resolves when migrations are registered
969
+ */
970
+ async registerMigrationsAsync(extensionVersion, migrations) {
971
+ return this.database.registerMigrationsAsync(extensionVersion, migrations);
972
+ }
973
+ async requestDatabasePermission(request) {
974
+ return this.request("permissions.database.request", {
975
+ resource: request.resource,
976
+ operation: request.operation,
977
+ reason: request.reason
978
+ });
979
+ }
980
+ async checkDatabasePermission(resource, operation) {
981
+ const response = await this.request(
982
+ "permissions.database.check",
983
+ {
984
+ resource,
985
+ operation
986
+ }
987
+ );
988
+ return response.status === "granted";
989
+ }
990
+ async respondToSearch(requestId, results) {
991
+ await this.request("search.respond", {
992
+ requestId,
993
+ results
994
+ });
995
+ }
996
+ async request(method, params = {}) {
997
+ if (this.isNativeWindow && typeof window.__TAURI__ !== "undefined") {
998
+ return this.invoke(method, params);
999
+ }
1000
+ return this.postMessage(method, params);
1001
+ }
1002
+ async postMessage(method, params) {
1003
+ const requestId = this.generateRequestId();
1004
+ const request = {
1005
+ method,
1006
+ params,
1007
+ timestamp: Date.now()
1008
+ };
1009
+ return new Promise((resolve, reject) => {
1010
+ const timeout = setTimeout(() => {
1011
+ this.pendingRequests.delete(requestId);
1012
+ reject(
1013
+ new HaexHubError("TIMEOUT" /* TIMEOUT */, "errors.timeout", {
1014
+ timeout: this.config.timeout
1015
+ })
1016
+ );
1017
+ }, this.config.timeout);
1018
+ this.pendingRequests.set(requestId, { resolve, reject, timeout });
1019
+ const targetOrigin = "*";
1020
+ if (this.config.debug) {
1021
+ console.log("[SDK Debug] ========== Sending Request ==========");
1022
+ console.log("[SDK Debug] Request ID:", requestId);
1023
+ console.log("[SDK Debug] Method:", request.method);
1024
+ console.log("[SDK Debug] Params:", request.params);
1025
+ console.log("[SDK Debug] Target origin:", targetOrigin);
1026
+ console.log("[SDK Debug] Extension info:", this._extensionInfo);
1027
+ console.log("[SDK Debug] ========================================");
1028
+ }
1029
+ window.parent.postMessage({ id: requestId, ...request }, targetOrigin);
1030
+ });
1031
+ }
1032
+ async invoke(method, params) {
1033
+ const { invoke } = window.__TAURI__.core;
1034
+ if (this.config.debug) {
1035
+ console.log("[SDK Debug] ========== Invoke Request ==========");
1036
+ console.log("[SDK Debug] Method:", method);
1037
+ console.log("[SDK Debug] Params:", params);
1038
+ console.log("[SDK Debug] =======================================");
1039
+ }
1040
+ switch (method) {
1041
+ case HAEXTENSION_METHODS.database.query:
1042
+ return invoke("webview_extension_db_query", {
1043
+ query: params.query,
1044
+ params: params.params || []
1045
+ });
1046
+ case HAEXTENSION_METHODS.database.execute:
1047
+ return invoke("webview_extension_db_execute", {
1048
+ query: params.query,
1049
+ params: params.params || []
1050
+ });
1051
+ case "permissions.web.check":
1052
+ return invoke("webview_extension_check_web_permission", {
1053
+ url: params.url
1054
+ });
1055
+ case "permissions.database.check":
1056
+ return invoke("webview_extension_check_database_permission", {
1057
+ resource: params.resource,
1058
+ operation: params.operation
1059
+ });
1060
+ case "permissions.filesystem.check":
1061
+ return invoke("webview_extension_check_filesystem_permission", {
1062
+ path: params.path,
1063
+ actionStr: params.action
1064
+ });
1065
+ case HAEXTENSION_METHODS.application.open:
1066
+ return invoke("webview_extension_web_open", {
1067
+ url: params.url
1068
+ });
1069
+ case HAEXTENSION_METHODS.web.fetch:
1070
+ return invoke("webview_extension_web_request", {
1071
+ url: params.url,
1072
+ method: params.method,
1073
+ headers: params.headers,
1074
+ body: params.body
1075
+ });
1076
+ case HAEXTENSION_METHODS.filesystem.saveFile:
1077
+ return invoke("webview_extension_fs_save_file", {
1078
+ data: params.data,
1079
+ defaultPath: params.defaultPath,
1080
+ title: params.title,
1081
+ filters: params.filters
1082
+ });
1083
+ case HAEXTENSION_METHODS.filesystem.openFile:
1084
+ return invoke("webview_extension_fs_open_file", {
1085
+ data: params.data,
1086
+ fileName: params.fileName
1087
+ });
1088
+ default:
1089
+ throw new HaexHubError(
1090
+ "METHOD_NOT_FOUND" /* METHOD_NOT_FOUND */,
1091
+ "errors.method_not_found",
1092
+ { method }
1093
+ );
1094
+ }
1095
+ }
1096
+ on(eventType, callback) {
1097
+ if (!this.eventListeners.has(eventType)) {
1098
+ this.eventListeners.set(eventType, /* @__PURE__ */ new Set());
1099
+ }
1100
+ this.eventListeners.get(eventType).add(callback);
1101
+ }
1102
+ off(eventType, callback) {
1103
+ const listeners = this.eventListeners.get(eventType);
1104
+ if (listeners) {
1105
+ listeners.delete(callback);
1106
+ }
1107
+ }
1108
+ destroy() {
1109
+ if (this.messageHandler) {
1110
+ window.removeEventListener("message", this.messageHandler);
1111
+ }
1112
+ this.pendingRequests.forEach(({ timeout }) => clearTimeout(timeout));
1113
+ this.pendingRequests.clear();
1114
+ this.eventListeners.clear();
1115
+ this.initialized = false;
1116
+ this.log("HaexHub SDK destroyed");
1117
+ }
1118
+ async init() {
1119
+ if (this.initialized) return;
1120
+ const isInIframe = window.self !== window.top;
1121
+ if (!isInIframe) {
1122
+ try {
1123
+ if (typeof window.__TAURI__ !== "undefined") {
1124
+ const { invoke } = window.__TAURI__.core;
1125
+ this._extensionInfo = await invoke("webview_extension_get_info");
1126
+ this._context = await invoke("webview_extension_context_get");
1127
+ this.isNativeWindow = true;
1128
+ this.initialized = true;
1129
+ this.log("HaexHub SDK initialized in native WebViewWindow mode");
1130
+ this.log("Extension info:", this._extensionInfo);
1131
+ this.log("Application context:", this._context);
1132
+ this.notifySubscribers();
1133
+ const { listen } = window.__TAURI__.event;
1134
+ console.log("[HaexHub SDK] Setting up Tauri event listener for:", HAEXTENSION_EVENTS.CONTEXT_CHANGED);
1135
+ try {
1136
+ await listen(HAEXTENSION_EVENTS.CONTEXT_CHANGED, (event) => {
1137
+ console.log("[HaexHub SDK] Received Tauri event:", HAEXTENSION_EVENTS.CONTEXT_CHANGED, event);
1138
+ this.log("Received context change event:", event);
1139
+ if (event.payload?.context) {
1140
+ this._context = event.payload.context;
1141
+ console.log("[HaexHub SDK] Updated context to:", this._context);
1142
+ this.handleEvent({
1143
+ type: HAEXTENSION_EVENTS.CONTEXT_CHANGED,
1144
+ data: { context: this._context },
1145
+ timestamp: Date.now()
1146
+ });
1147
+ } else {
1148
+ console.warn("[HaexHub SDK] Event received but no context in payload:", event);
1149
+ }
1150
+ });
1151
+ console.log("[HaexHub SDK] Context change listener registered successfully");
1152
+ } catch (error) {
1153
+ console.error("[HaexHub SDK] Failed to setup context change listener:", error);
1154
+ this.log("Failed to setup context change listener:", error);
1155
+ }
1156
+ this.resolveReady();
1157
+ return;
1158
+ }
1159
+ } catch (error) {
1160
+ this.log("Tauri commands failed, falling back to iframe mode", error);
1161
+ }
1162
+ }
1163
+ if (window.self === window.top) {
1164
+ throw new HaexHubError("NOT_IN_IFRAME" /* NOT_IN_IFRAME */, "errors.not_in_iframe");
1165
+ }
1166
+ this.messageHandler = this.handleMessage.bind(this);
1167
+ window.addEventListener("message", this.messageHandler);
1168
+ this.isNativeWindow = false;
1169
+ this.initialized = true;
1170
+ this.log("HaexHub SDK initialized in iframe mode");
1171
+ try {
1172
+ if (this.config.manifest) {
1173
+ this._extensionInfo = {
1174
+ publicKey: this.config.manifest.publicKey,
1175
+ name: this.config.manifest.name,
1176
+ version: this.config.manifest.version,
1177
+ displayName: this.config.manifest.name
1178
+ };
1179
+ this.log("Extension info loaded from manifest:", this._extensionInfo);
1180
+ this.notifySubscribers();
1181
+ }
1182
+ if (typeof window !== "undefined" && window.parent) {
1183
+ const debugInfo = `SDK Debug:
1184
+ window.parent exists: ${!!window.parent}
1185
+ window.parent === window: ${window.parent === window}
1186
+ window.self === window.top: ${window.self === window.top}`;
1187
+ try {
1188
+ window.parent.postMessage({
1189
+ type: "haexhub:debug",
1190
+ data: debugInfo
1191
+ }, "*");
1192
+ } catch (e) {
1193
+ alert(debugInfo + `
1194
+ postMessage error: ${e}`);
1195
+ }
1196
+ }
1197
+ this._context = await this.request(HAEXTENSION_METHODS.context.get);
1198
+ this.log("Application context received:", this._context);
1199
+ this.notifySubscribers();
1200
+ this.resolveReady();
1201
+ } catch (error) {
1202
+ this.log("Failed to load extension info or context:", error);
1203
+ throw error;
1204
+ }
1205
+ }
1206
+ handleMessage(event) {
1207
+ if (this.config.debug) {
1208
+ console.log("[SDK Debug] ========== Message Received ==========");
1209
+ console.log("[SDK Debug] Event origin:", event.origin);
1210
+ console.log(
1211
+ "[SDK Debug] Event source:",
1212
+ event.source === window.parent ? "parent window" : "unknown"
1213
+ );
1214
+ console.log("[SDK Debug] Event data:", event.data);
1215
+ console.log("[SDK Debug] Extension info loaded:", !!this._extensionInfo);
1216
+ console.log(
1217
+ "[SDK Debug] Pending requests count:",
1218
+ this.pendingRequests.size
1219
+ );
1220
+ }
1221
+ if (event.source !== window.parent) {
1222
+ if (this.config.debug) {
1223
+ console.error("[SDK Debug] \u274C REJECTED: Message not from parent window!");
1224
+ }
1225
+ return;
1226
+ }
1227
+ const data = event.data;
1228
+ if ("id" in data && this.pendingRequests.has(data.id)) {
1229
+ if (this.config.debug) {
1230
+ console.log("[SDK Debug] \u2705 Found pending request for ID:", data.id);
1231
+ }
1232
+ const pending = this.pendingRequests.get(data.id);
1233
+ clearTimeout(pending.timeout);
1234
+ this.pendingRequests.delete(data.id);
1235
+ if (data.error) {
1236
+ if (this.config.debug) {
1237
+ console.error("[SDK Debug] \u274C Request failed:", data.error);
1238
+ }
1239
+ pending.reject(data.error);
1240
+ } else {
1241
+ if (this.config.debug) {
1242
+ console.log("[SDK Debug] \u2705 Request succeeded:", data.result);
1243
+ }
1244
+ pending.resolve(data.result);
1245
+ }
1246
+ return;
1247
+ }
1248
+ if ("id" in data && !this.pendingRequests.has(data.id)) {
1249
+ if (this.config.debug) {
1250
+ console.warn(
1251
+ "[SDK Debug] \u26A0\uFE0F Received response for unknown request ID:",
1252
+ data.id
1253
+ );
1254
+ console.warn(
1255
+ "[SDK Debug] Known IDs:",
1256
+ Array.from(this.pendingRequests.keys())
1257
+ );
1258
+ }
1259
+ }
1260
+ if ("type" in data && data.type) {
1261
+ if (this.config.debug) {
1262
+ console.log("[SDK Debug] Event received:", data.type);
1263
+ }
1264
+ this.handleEvent(data);
1265
+ }
1266
+ if (this.config.debug) {
1267
+ console.log("[SDK Debug] ========== End Message ==========");
1268
+ }
1269
+ }
1270
+ handleEvent(event) {
1271
+ if (event.type === HAEXTENSION_EVENTS.CONTEXT_CHANGED) {
1272
+ const contextEvent = event;
1273
+ this._context = contextEvent.data.context;
1274
+ this.log("Context updated:", this._context);
1275
+ this.notifySubscribers();
1276
+ }
1277
+ this.emitEvent(event);
1278
+ }
1279
+ emitEvent(event) {
1280
+ this.log("Event received:", event);
1281
+ const listeners = this.eventListeners.get(event.type);
1282
+ if (listeners) {
1283
+ listeners.forEach((callback) => callback(event));
1284
+ }
1285
+ }
1286
+ generateRequestId() {
1287
+ return `req_${++this.requestCounter}`;
1288
+ }
1289
+ validatePublicKey(publicKey) {
1290
+ if (!publicKey || typeof publicKey !== "string" || publicKey.trim() === "") {
1291
+ throw new HaexHubError(
1292
+ "INVALID_PUBLIC_KEY" /* INVALID_PUBLIC_KEY */,
1293
+ "errors.invalid_public_key",
1294
+ { publicKey }
1295
+ );
1296
+ }
1297
+ }
1298
+ validateExtensionName(extensionName) {
1299
+ if (!extensionName || !/^[a-z][a-z0-9-]*$/i.test(extensionName)) {
1300
+ throw new HaexHubError(
1301
+ "INVALID_EXTENSION_NAME" /* INVALID_EXTENSION_NAME */,
1302
+ "errors.invalid_extension_name",
1303
+ { extensionName }
1304
+ );
1305
+ }
1306
+ if (extensionName.includes(TABLE_SEPARATOR)) {
1307
+ throw new HaexHubError(
1308
+ "INVALID_EXTENSION_NAME" /* INVALID_EXTENSION_NAME */,
1309
+ "errors.extension_name_contains_separator",
1310
+ { extensionName, separator: TABLE_SEPARATOR }
1311
+ );
1312
+ }
1313
+ }
1314
+ validateTableName(tableName) {
1315
+ if (!tableName || typeof tableName !== "string") {
1316
+ throw new HaexHubError(
1317
+ "INVALID_TABLE_NAME" /* INVALID_TABLE_NAME */,
1318
+ "errors.table_name_empty"
1319
+ );
1320
+ }
1321
+ if (tableName.includes(TABLE_SEPARATOR)) {
1322
+ throw new HaexHubError(
1323
+ "INVALID_TABLE_NAME" /* INVALID_TABLE_NAME */,
1324
+ "errors.table_name_contains_separator",
1325
+ { tableName, separator: TABLE_SEPARATOR }
1326
+ );
1327
+ }
1328
+ if (!/^[a-z][a-z0-9-_]*$/i.test(tableName)) {
1329
+ throw new HaexHubError(
1330
+ "INVALID_TABLE_NAME" /* INVALID_TABLE_NAME */,
1331
+ "errors.table_name_format",
1332
+ { tableName }
1333
+ );
1334
+ }
1335
+ }
1336
+ log(...args) {
1337
+ if (this.config.debug) {
1338
+ console.log("[HaexHub SDK]", ...args);
1339
+ }
1340
+ }
1341
+ };
1342
+
1343
+ // src/index.ts
1344
+ function createHaexVaultClient(config = {}) {
1345
+ return new HaexVaultClient(config);
1346
+ }
1347
+
1348
+ // src/vue.ts
1349
+ var clientInstance = null;
1350
+ var extensionInfo = null;
1351
+ var context = null;
1352
+ var isSetupComplete = null;
1353
+ function useHaexHub(config = {}) {
1354
+ if (!clientInstance) {
1355
+ clientInstance = createHaexVaultClient(config);
1356
+ extensionInfo = vue.ref(clientInstance.extensionInfo);
1357
+ context = vue.ref(clientInstance.context);
1358
+ isSetupComplete = vue.ref(false);
1359
+ clientInstance.subscribe(() => {
1360
+ if (extensionInfo) {
1361
+ extensionInfo.value = clientInstance.extensionInfo;
1362
+ }
1363
+ if (context) {
1364
+ context.value = clientInstance.context;
1365
+ }
1366
+ if (isSetupComplete) {
1367
+ isSetupComplete.value = clientInstance.setupCompleted;
1368
+ }
1369
+ });
1370
+ }
1371
+ return {
1372
+ client: clientInstance,
1373
+ extensionInfo: vue.readonly(extensionInfo),
1374
+ context: vue.readonly(context),
1375
+ isSetupComplete: vue.readonly(isSetupComplete),
1376
+ db: clientInstance.orm,
1377
+ storage: clientInstance.storage,
1378
+ getTableName: clientInstance.getTableName.bind(clientInstance)
1379
+ };
1380
+ }
1381
+ function getHaexVaultClient() {
1382
+ return clientInstance;
1383
+ }
1384
+
1385
+ exports.getHaexVaultClient = getHaexVaultClient;
1386
+ exports.useHaexHub = useHaexHub;
1387
+ //# sourceMappingURL=vue.js.map
1388
+ //# sourceMappingURL=vue.js.map