@haex-space/vault-sdk 2.3.16 → 2.5.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.
- package/dist/{client-ChH7wiuU.d.ts → client-BNq2TcVs.d.ts} +25 -95
- package/dist/{client-8eGxojZ1.d.mts → client-DQ6VwHic.d.mts} +25 -95
- package/dist/index.d.mts +75 -5
- package/dist/index.d.ts +75 -5
- package/dist/index.js +1076 -680
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1074 -680
- package/dist/index.mjs.map +1 -1
- package/dist/node.d.mts +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/react.d.mts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +1025 -658
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +1025 -658
- package/dist/react.mjs.map +1 -1
- package/dist/runtime/nuxt.plugin.client.d.mts +2 -2
- package/dist/runtime/nuxt.plugin.client.d.ts +2 -2
- package/dist/runtime/nuxt.plugin.client.js +1034 -667
- package/dist/runtime/nuxt.plugin.client.js.map +1 -1
- package/dist/runtime/nuxt.plugin.client.mjs +1034 -667
- package/dist/runtime/nuxt.plugin.client.mjs.map +1 -1
- package/dist/svelte.d.mts +2 -2
- package/dist/svelte.d.ts +2 -2
- package/dist/svelte.js +1027 -660
- package/dist/svelte.js.map +1 -1
- package/dist/svelte.mjs +1027 -660
- package/dist/svelte.mjs.map +1 -1
- package/dist/{types-DBF83o_W.d.mts → types-Bw5uc1vm.d.mts} +70 -11
- package/dist/{types-DBF83o_W.d.ts → types-Bw5uc1vm.d.ts} +70 -11
- package/dist/vue.d.mts +2 -2
- package/dist/vue.d.ts +2 -2
- package/dist/vue.js +1025 -658
- package/dist/vue.js.map +1 -1
- package/dist/vue.mjs +1025 -658
- package/dist/vue.mjs.map +1 -1
- package/package.json +1 -1
package/dist/svelte.js
CHANGED
|
@@ -337,9 +337,47 @@ var HAEXTENSION_EVENTS = {
|
|
|
337
337
|
/** Context (theme, locale, platform) has changed */
|
|
338
338
|
CONTEXT_CHANGED: "haextension:context:changed",
|
|
339
339
|
/** Search request from HaexHub */
|
|
340
|
-
SEARCH_REQUEST: "haextension:search:request"
|
|
341
|
-
|
|
342
|
-
|
|
340
|
+
SEARCH_REQUEST: "haextension:search:request"
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
// src/types.ts
|
|
344
|
+
var DEFAULT_TIMEOUT = 3e4;
|
|
345
|
+
var TABLE_SEPARATOR = "__";
|
|
346
|
+
function getTableName(publicKey, extensionName, tableName) {
|
|
347
|
+
return `${publicKey}${TABLE_SEPARATOR}${extensionName}${TABLE_SEPARATOR}${tableName}`;
|
|
348
|
+
}
|
|
349
|
+
var HaexVaultSdkError = class extends Error {
|
|
350
|
+
constructor(code, messageKey, details) {
|
|
351
|
+
super(messageKey);
|
|
352
|
+
this.code = code;
|
|
353
|
+
this.messageKey = messageKey;
|
|
354
|
+
this.details = details;
|
|
355
|
+
this.name = "HaexVaultSdkError";
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Get localized error message
|
|
359
|
+
* @param locale - Locale code (e.g., 'en', 'de')
|
|
360
|
+
* @param translations - Translation object
|
|
361
|
+
*/
|
|
362
|
+
getLocalizedMessage(locale = "en", translations) {
|
|
363
|
+
if (!translations || !translations[locale]) {
|
|
364
|
+
return this.messageKey;
|
|
365
|
+
}
|
|
366
|
+
let message = translations[locale][this.messageKey] || this.messageKey;
|
|
367
|
+
if (this.details) {
|
|
368
|
+
Object.entries(this.details).forEach(([key, value]) => {
|
|
369
|
+
message = message.replace(`{${key}}`, String(value));
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
return message;
|
|
373
|
+
}
|
|
374
|
+
toJSON() {
|
|
375
|
+
return {
|
|
376
|
+
code: this.code,
|
|
377
|
+
message: this.messageKey,
|
|
378
|
+
details: this.details
|
|
379
|
+
};
|
|
380
|
+
}
|
|
343
381
|
};
|
|
344
382
|
|
|
345
383
|
// src/methods.ts
|
|
@@ -403,46 +441,6 @@ var HAEXTENSION_METHODS = {
|
|
|
403
441
|
}
|
|
404
442
|
};
|
|
405
443
|
|
|
406
|
-
// src/types.ts
|
|
407
|
-
var DEFAULT_TIMEOUT = 3e4;
|
|
408
|
-
var TABLE_SEPARATOR = "__";
|
|
409
|
-
function getTableName(publicKey, extensionName, tableName) {
|
|
410
|
-
return `${publicKey}${TABLE_SEPARATOR}${extensionName}${TABLE_SEPARATOR}${tableName}`;
|
|
411
|
-
}
|
|
412
|
-
var HaexHubError = class extends Error {
|
|
413
|
-
constructor(code, messageKey, details) {
|
|
414
|
-
super(messageKey);
|
|
415
|
-
this.code = code;
|
|
416
|
-
this.messageKey = messageKey;
|
|
417
|
-
this.details = details;
|
|
418
|
-
this.name = "HaexHubError";
|
|
419
|
-
}
|
|
420
|
-
/**
|
|
421
|
-
* Get localized error message
|
|
422
|
-
* @param locale - Locale code (e.g., 'en', 'de')
|
|
423
|
-
* @param translations - Translation object
|
|
424
|
-
*/
|
|
425
|
-
getLocalizedMessage(locale = "en", translations) {
|
|
426
|
-
if (!translations || !translations[locale]) {
|
|
427
|
-
return this.messageKey;
|
|
428
|
-
}
|
|
429
|
-
let message = translations[locale][this.messageKey] || this.messageKey;
|
|
430
|
-
if (this.details) {
|
|
431
|
-
Object.entries(this.details).forEach(([key, value]) => {
|
|
432
|
-
message = message.replace(`{${key}}`, String(value));
|
|
433
|
-
});
|
|
434
|
-
}
|
|
435
|
-
return message;
|
|
436
|
-
}
|
|
437
|
-
toJSON() {
|
|
438
|
-
return {
|
|
439
|
-
code: this.code,
|
|
440
|
-
message: this.messageKey,
|
|
441
|
-
details: this.details
|
|
442
|
-
};
|
|
443
|
-
}
|
|
444
|
-
};
|
|
445
|
-
|
|
446
444
|
// src/api/storage.ts
|
|
447
445
|
var StorageAPI = class {
|
|
448
446
|
constructor(client) {
|
|
@@ -985,548 +983,543 @@ var PermissionsAPI = class {
|
|
|
985
983
|
return response.status === "granted";
|
|
986
984
|
}
|
|
987
985
|
};
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
this._context = null;
|
|
998
|
-
this.reactiveSubscribers = /* @__PURE__ */ new Set();
|
|
999
|
-
this.isNativeWindow = false;
|
|
1000
|
-
// Wird im Konstruktor initialisiert
|
|
1001
|
-
this.setupPromise = null;
|
|
1002
|
-
this.setupHook = null;
|
|
1003
|
-
this._setupCompleted = false;
|
|
1004
|
-
this.orm = null;
|
|
1005
|
-
this.config = {
|
|
1006
|
-
debug: config.debug ?? false,
|
|
1007
|
-
timeout: config.timeout ?? DEFAULT_TIMEOUT,
|
|
1008
|
-
manifest: config.manifest
|
|
1009
|
-
};
|
|
1010
|
-
this.storage = new StorageAPI(this);
|
|
1011
|
-
this.database = new DatabaseAPI(this);
|
|
1012
|
-
this.filesystem = new FilesystemAPI(this);
|
|
1013
|
-
this.web = new WebAPI(this);
|
|
1014
|
-
this.permissions = new PermissionsAPI(this);
|
|
1015
|
-
installConsoleForwarding(this.config.debug);
|
|
1016
|
-
this.readyPromise = new Promise((resolve) => {
|
|
1017
|
-
this.resolveReady = resolve;
|
|
1018
|
-
});
|
|
1019
|
-
this.init();
|
|
986
|
+
|
|
987
|
+
// src/client/tableName.ts
|
|
988
|
+
function validatePublicKey(publicKey) {
|
|
989
|
+
if (!publicKey || typeof publicKey !== "string" || publicKey.trim() === "") {
|
|
990
|
+
throw new HaexVaultSdkError(
|
|
991
|
+
"INVALID_PUBLIC_KEY" /* INVALID_PUBLIC_KEY */,
|
|
992
|
+
"errors.invalid_public_key",
|
|
993
|
+
{ publicKey }
|
|
994
|
+
);
|
|
1020
995
|
}
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
996
|
+
}
|
|
997
|
+
function validateExtensionName(extensionName) {
|
|
998
|
+
if (!extensionName || !/^[a-z][a-z0-9-]*$/i.test(extensionName)) {
|
|
999
|
+
throw new HaexVaultSdkError(
|
|
1000
|
+
"INVALID_EXTENSION_NAME" /* INVALID_EXTENSION_NAME */,
|
|
1001
|
+
"errors.invalid_extension_name",
|
|
1002
|
+
{ extensionName }
|
|
1003
|
+
);
|
|
1027
1004
|
}
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1005
|
+
if (extensionName.includes(TABLE_SEPARATOR)) {
|
|
1006
|
+
throw new HaexVaultSdkError(
|
|
1007
|
+
"INVALID_EXTENSION_NAME" /* INVALID_EXTENSION_NAME */,
|
|
1008
|
+
"errors.extension_name_contains_separator",
|
|
1009
|
+
{ extensionName, separator: TABLE_SEPARATOR }
|
|
1010
|
+
);
|
|
1033
1011
|
}
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
throw new Error("Setup hook already registered");
|
|
1042
|
-
}
|
|
1043
|
-
this.setupHook = setupFn;
|
|
1012
|
+
}
|
|
1013
|
+
function validateTableName(tableName) {
|
|
1014
|
+
if (!tableName || typeof tableName !== "string") {
|
|
1015
|
+
throw new HaexVaultSdkError(
|
|
1016
|
+
"INVALID_TABLE_NAME" /* INVALID_TABLE_NAME */,
|
|
1017
|
+
"errors.table_name_empty"
|
|
1018
|
+
);
|
|
1044
1019
|
}
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
await this.readyPromise;
|
|
1052
|
-
if (!this.setupHook || this.setupCompleted) {
|
|
1053
|
-
return;
|
|
1054
|
-
}
|
|
1055
|
-
if (!this.setupPromise) {
|
|
1056
|
-
this.setupPromise = this.runSetupAsync();
|
|
1057
|
-
}
|
|
1058
|
-
return this.setupPromise;
|
|
1020
|
+
if (tableName.includes(TABLE_SEPARATOR)) {
|
|
1021
|
+
throw new HaexVaultSdkError(
|
|
1022
|
+
"INVALID_TABLE_NAME" /* INVALID_TABLE_NAME */,
|
|
1023
|
+
"errors.table_name_contains_separator",
|
|
1024
|
+
{ tableName, separator: TABLE_SEPARATOR }
|
|
1025
|
+
);
|
|
1059
1026
|
}
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
this.log("[HaexSpace] Setup completed successfully");
|
|
1067
|
-
this.notifySubscribers();
|
|
1068
|
-
} catch (error) {
|
|
1069
|
-
this.log("[HaexSpace] Setup failed:", error);
|
|
1070
|
-
throw error;
|
|
1071
|
-
}
|
|
1027
|
+
if (!/^[a-z][a-z0-9-_]*$/i.test(tableName)) {
|
|
1028
|
+
throw new HaexVaultSdkError(
|
|
1029
|
+
"INVALID_TABLE_NAME" /* INVALID_TABLE_NAME */,
|
|
1030
|
+
"errors.table_name_format",
|
|
1031
|
+
{ tableName }
|
|
1032
|
+
);
|
|
1072
1033
|
}
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
initializeDatabase(schema) {
|
|
1080
|
-
if (!this._extensionInfo) {
|
|
1081
|
-
throw new HaexHubError(
|
|
1082
|
-
"EXTENSION_INFO_UNAVAILABLE" /* EXTENSION_INFO_UNAVAILABLE */,
|
|
1083
|
-
"errors.client_not_ready"
|
|
1084
|
-
);
|
|
1085
|
-
}
|
|
1086
|
-
const dbInstance = sqliteProxy.drizzle(
|
|
1087
|
-
async (sql, params, method) => {
|
|
1088
|
-
try {
|
|
1089
|
-
if (method === "run" || method === "all") {
|
|
1090
|
-
const result2 = await this.request(
|
|
1091
|
-
HAEXTENSION_METHODS.database.execute,
|
|
1092
|
-
{
|
|
1093
|
-
query: sql,
|
|
1094
|
-
params
|
|
1095
|
-
}
|
|
1096
|
-
);
|
|
1097
|
-
if (method === "all") {
|
|
1098
|
-
return { rows: result2.rows || [] };
|
|
1099
|
-
}
|
|
1100
|
-
if (result2.rows && Array.isArray(result2.rows) && result2.rows.length > 0) {
|
|
1101
|
-
return { rows: result2.rows };
|
|
1102
|
-
}
|
|
1103
|
-
return result2;
|
|
1104
|
-
}
|
|
1105
|
-
const result = await this.request(HAEXTENSION_METHODS.database.query, {
|
|
1106
|
-
query: sql,
|
|
1107
|
-
params
|
|
1108
|
-
});
|
|
1109
|
-
const rows = result.rows;
|
|
1110
|
-
if (method === "get") {
|
|
1111
|
-
return { rows: rows.length > 0 ? rows.at(0) : void 0 };
|
|
1112
|
-
}
|
|
1113
|
-
return { rows };
|
|
1114
|
-
} catch (error) {
|
|
1115
|
-
this.log("Database operation failed:", error);
|
|
1116
|
-
throw error;
|
|
1117
|
-
}
|
|
1118
|
-
},
|
|
1119
|
-
{
|
|
1120
|
-
schema,
|
|
1121
|
-
logger: false
|
|
1122
|
-
}
|
|
1034
|
+
}
|
|
1035
|
+
function getExtensionTableName(extensionInfo2, tableName) {
|
|
1036
|
+
if (!extensionInfo2) {
|
|
1037
|
+
throw new HaexVaultSdkError(
|
|
1038
|
+
"EXTENSION_INFO_UNAVAILABLE" /* EXTENSION_INFO_UNAVAILABLE */,
|
|
1039
|
+
"errors.extension_info_unavailable"
|
|
1123
1040
|
);
|
|
1124
|
-
this.orm = dbInstance;
|
|
1125
|
-
return dbInstance;
|
|
1126
1041
|
}
|
|
1127
|
-
|
|
1128
|
-
|
|
1042
|
+
validateTableName(tableName);
|
|
1043
|
+
const { publicKey, name } = extensionInfo2;
|
|
1044
|
+
return `"${getTableName(publicKey, name, tableName)}"`;
|
|
1045
|
+
}
|
|
1046
|
+
function getDependencyTableName(publicKey, extensionName, tableName) {
|
|
1047
|
+
validatePublicKey(publicKey);
|
|
1048
|
+
validateExtensionName(extensionName);
|
|
1049
|
+
validateTableName(tableName);
|
|
1050
|
+
return `"${getTableName(publicKey, extensionName, tableName)}"`;
|
|
1051
|
+
}
|
|
1052
|
+
function parseTableName(fullTableName) {
|
|
1053
|
+
let cleanTableName = fullTableName;
|
|
1054
|
+
if (cleanTableName.startsWith('"') && cleanTableName.endsWith('"')) {
|
|
1055
|
+
cleanTableName = cleanTableName.slice(1, -1);
|
|
1056
|
+
}
|
|
1057
|
+
const parts = cleanTableName.split(TABLE_SEPARATOR);
|
|
1058
|
+
if (parts.length !== 3) {
|
|
1059
|
+
return null;
|
|
1060
|
+
}
|
|
1061
|
+
const [publicKey, extensionName, tableName] = parts;
|
|
1062
|
+
if (!publicKey || !extensionName || !tableName) {
|
|
1063
|
+
return null;
|
|
1064
|
+
}
|
|
1065
|
+
return {
|
|
1066
|
+
publicKey,
|
|
1067
|
+
extensionName,
|
|
1068
|
+
tableName
|
|
1069
|
+
};
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
// src/client/init.ts
|
|
1073
|
+
function isInIframe() {
|
|
1074
|
+
return window.self !== window.top;
|
|
1075
|
+
}
|
|
1076
|
+
function hasTauri() {
|
|
1077
|
+
return typeof window.__TAURI__ !== "undefined";
|
|
1078
|
+
}
|
|
1079
|
+
function getTauriCore() {
|
|
1080
|
+
return window.__TAURI__.core;
|
|
1081
|
+
}
|
|
1082
|
+
function getTauriEvent() {
|
|
1083
|
+
return window.__TAURI__.event;
|
|
1084
|
+
}
|
|
1085
|
+
async function initNativeMode(ctx, log, onEvent, onContextChange) {
|
|
1086
|
+
const { invoke } = getTauriCore();
|
|
1087
|
+
const extensionInfo2 = await invoke("webview_extension_get_info");
|
|
1088
|
+
const context2 = await invoke("webview_extension_context_get");
|
|
1089
|
+
ctx.state.isNativeWindow = true;
|
|
1090
|
+
ctx.state.initialized = true;
|
|
1091
|
+
ctx.state.extensionInfo = extensionInfo2;
|
|
1092
|
+
ctx.state.context = context2;
|
|
1093
|
+
log("HaexVault SDK initialized in native WebViewWindow mode");
|
|
1094
|
+
log("Extension info:", extensionInfo2);
|
|
1095
|
+
log("Application context:", context2);
|
|
1096
|
+
await setupTauriEventListeners(ctx, log, onEvent, onContextChange);
|
|
1097
|
+
return { extensionInfo: extensionInfo2, context: context2 };
|
|
1098
|
+
}
|
|
1099
|
+
async function setupTauriEventListeners(ctx, log, onEvent, onContextChange) {
|
|
1100
|
+
const { listen } = getTauriEvent();
|
|
1101
|
+
console.log("[HaexVault SDK] Setting up Tauri event listener for:", HAEXTENSION_EVENTS.CONTEXT_CHANGED);
|
|
1102
|
+
try {
|
|
1103
|
+
await listen(HAEXTENSION_EVENTS.CONTEXT_CHANGED, (event) => {
|
|
1104
|
+
console.log("[HaexVault SDK] Received Tauri event:", HAEXTENSION_EVENTS.CONTEXT_CHANGED, event);
|
|
1105
|
+
log("Received context change event:", event);
|
|
1106
|
+
const payload = event.payload;
|
|
1107
|
+
if (payload?.context) {
|
|
1108
|
+
ctx.state.context = payload.context;
|
|
1109
|
+
console.log("[HaexVault SDK] Updated context to:", ctx.state.context);
|
|
1110
|
+
onContextChange(payload.context);
|
|
1111
|
+
onEvent({
|
|
1112
|
+
type: HAEXTENSION_EVENTS.CONTEXT_CHANGED,
|
|
1113
|
+
data: { context: ctx.state.context },
|
|
1114
|
+
timestamp: Date.now()
|
|
1115
|
+
});
|
|
1116
|
+
} else {
|
|
1117
|
+
console.warn("[HaexVault SDK] Event received but no context in payload:", event);
|
|
1118
|
+
}
|
|
1119
|
+
});
|
|
1120
|
+
console.log("[HaexVault SDK] Context change listener registered successfully");
|
|
1121
|
+
} catch (error) {
|
|
1122
|
+
console.error("[HaexVault SDK] Failed to setup context change listener:", error);
|
|
1123
|
+
log("Failed to setup context change listener:", error);
|
|
1129
1124
|
}
|
|
1130
|
-
|
|
1131
|
-
|
|
1125
|
+
try {
|
|
1126
|
+
await listen(HAEXTENSION_EVENTS.EXTERNAL_REQUEST, (event) => {
|
|
1127
|
+
log("Received external request event:", event);
|
|
1128
|
+
if (event.payload) {
|
|
1129
|
+
onEvent({
|
|
1130
|
+
type: HAEXTENSION_EVENTS.EXTERNAL_REQUEST,
|
|
1131
|
+
data: event.payload,
|
|
1132
|
+
timestamp: Date.now()
|
|
1133
|
+
});
|
|
1134
|
+
}
|
|
1135
|
+
});
|
|
1136
|
+
console.log("[HaexVault SDK] External request listener registered successfully");
|
|
1137
|
+
} catch (error) {
|
|
1138
|
+
console.error("[HaexVault SDK] Failed to setup external request listener:", error);
|
|
1139
|
+
log("Failed to setup external request listener:", error);
|
|
1132
1140
|
}
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1141
|
+
}
|
|
1142
|
+
async function initIframeMode(ctx, log, messageHandler, request) {
|
|
1143
|
+
if (!isInIframe()) {
|
|
1144
|
+
throw new HaexVaultSdkError("NOT_IN_IFRAME" /* NOT_IN_IFRAME */, "errors.not_in_iframe");
|
|
1145
|
+
}
|
|
1146
|
+
ctx.handlers.messageHandler = messageHandler;
|
|
1147
|
+
window.addEventListener("message", messageHandler);
|
|
1148
|
+
ctx.state.isNativeWindow = false;
|
|
1149
|
+
ctx.state.initialized = true;
|
|
1150
|
+
log("HaexVault SDK initialized in iframe mode");
|
|
1151
|
+
if (ctx.config.manifest) {
|
|
1152
|
+
ctx.state.extensionInfo = {
|
|
1153
|
+
publicKey: ctx.config.manifest.publicKey,
|
|
1154
|
+
name: ctx.config.manifest.name,
|
|
1155
|
+
version: ctx.config.manifest.version,
|
|
1156
|
+
displayName: ctx.config.manifest.name
|
|
1137
1157
|
};
|
|
1158
|
+
log("Extension info loaded from manifest:", ctx.state.extensionInfo);
|
|
1138
1159
|
}
|
|
1139
|
-
|
|
1140
|
-
|
|
1160
|
+
sendDebugInfo(ctx.config);
|
|
1161
|
+
const context2 = await request(HAEXTENSION_METHODS.context.get);
|
|
1162
|
+
ctx.state.context = context2;
|
|
1163
|
+
log("Application context received:", context2);
|
|
1164
|
+
return { context: context2 };
|
|
1165
|
+
}
|
|
1166
|
+
function sendDebugInfo(config) {
|
|
1167
|
+
if (!config.debug) return;
|
|
1168
|
+
if (typeof window === "undefined" || !window.parent) return;
|
|
1169
|
+
const debugInfo = `SDK Debug:
|
|
1170
|
+
window.parent exists: ${!!window.parent}
|
|
1171
|
+
window.parent === window: ${window.parent === window}
|
|
1172
|
+
window.self === window.top: ${window.self === window.top}`;
|
|
1173
|
+
try {
|
|
1174
|
+
window.parent.postMessage({
|
|
1175
|
+
type: HAEXSPACE_MESSAGE_TYPES.DEBUG,
|
|
1176
|
+
data: debugInfo
|
|
1177
|
+
}, "*");
|
|
1178
|
+
} catch (e) {
|
|
1179
|
+
alert(debugInfo + `
|
|
1180
|
+
postMessage error: ${e}`);
|
|
1141
1181
|
}
|
|
1142
|
-
|
|
1143
|
-
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
// src/commands.ts
|
|
1185
|
+
var TAURI_COMMANDS = {
|
|
1186
|
+
database: {
|
|
1187
|
+
query: "webview_extension_db_query",
|
|
1188
|
+
execute: "webview_extension_db_execute",
|
|
1189
|
+
registerMigrations: "webview_extension_db_register_migrations"
|
|
1190
|
+
},
|
|
1191
|
+
permissions: {
|
|
1192
|
+
checkWeb: "webview_extension_check_web_permission",
|
|
1193
|
+
checkDatabase: "webview_extension_check_database_permission",
|
|
1194
|
+
checkFilesystem: "webview_extension_check_filesystem_permission"
|
|
1195
|
+
},
|
|
1196
|
+
web: {
|
|
1197
|
+
open: "webview_extension_web_open",
|
|
1198
|
+
fetch: "webview_extension_web_request"
|
|
1199
|
+
},
|
|
1200
|
+
filesystem: {
|
|
1201
|
+
saveFile: "webview_extension_fs_save_file",
|
|
1202
|
+
openFile: "webview_extension_fs_open_file",
|
|
1203
|
+
showImage: "webview_extension_fs_show_image"
|
|
1204
|
+
},
|
|
1205
|
+
external: {
|
|
1206
|
+
// Response handling (called by extensions)
|
|
1207
|
+
respond: "external_respond"},
|
|
1208
|
+
filesync: {
|
|
1209
|
+
// Spaces
|
|
1210
|
+
listSpaces: "filesync_list_spaces",
|
|
1211
|
+
createSpace: "filesync_create_space",
|
|
1212
|
+
deleteSpace: "filesync_delete_space",
|
|
1213
|
+
// Files
|
|
1214
|
+
listFiles: "filesync_list_files",
|
|
1215
|
+
getFile: "filesync_get_file",
|
|
1216
|
+
uploadFile: "filesync_upload_file",
|
|
1217
|
+
downloadFile: "filesync_download_file",
|
|
1218
|
+
deleteFile: "filesync_delete_file",
|
|
1219
|
+
// Backends
|
|
1220
|
+
listBackends: "filesync_list_backends",
|
|
1221
|
+
addBackend: "filesync_add_backend",
|
|
1222
|
+
removeBackend: "filesync_remove_backend",
|
|
1223
|
+
testBackend: "filesync_test_backend",
|
|
1224
|
+
// Sync Rules
|
|
1225
|
+
listSyncRules: "filesync_list_sync_rules",
|
|
1226
|
+
addSyncRule: "filesync_add_sync_rule",
|
|
1227
|
+
removeSyncRule: "filesync_remove_sync_rule",
|
|
1228
|
+
// Sync Operations
|
|
1229
|
+
getSyncStatus: "filesync_get_sync_status",
|
|
1230
|
+
triggerSync: "filesync_trigger_sync",
|
|
1231
|
+
pauseSync: "filesync_pause_sync",
|
|
1232
|
+
resumeSync: "filesync_resume_sync",
|
|
1233
|
+
// Conflict Resolution
|
|
1234
|
+
resolveConflict: "filesync_resolve_conflict",
|
|
1235
|
+
// UI Helpers
|
|
1236
|
+
selectFolder: "filesync_select_folder"
|
|
1144
1237
|
}
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1238
|
+
};
|
|
1239
|
+
|
|
1240
|
+
// src/transport/handlers/database.ts
|
|
1241
|
+
var databaseHandlers = {
|
|
1242
|
+
[HAEXTENSION_METHODS.database.query]: {
|
|
1243
|
+
command: TAURI_COMMANDS.database.query,
|
|
1244
|
+
args: (p) => ({
|
|
1245
|
+
query: p.query,
|
|
1246
|
+
params: p.params || []
|
|
1247
|
+
})
|
|
1248
|
+
},
|
|
1249
|
+
[HAEXTENSION_METHODS.database.execute]: {
|
|
1250
|
+
command: TAURI_COMMANDS.database.execute,
|
|
1251
|
+
args: (p) => ({
|
|
1252
|
+
query: p.query,
|
|
1253
|
+
params: p.params || []
|
|
1254
|
+
})
|
|
1255
|
+
},
|
|
1256
|
+
[HAEXTENSION_METHODS.database.registerMigrations]: {
|
|
1257
|
+
command: TAURI_COMMANDS.database.registerMigrations,
|
|
1258
|
+
args: (p) => ({
|
|
1259
|
+
extensionVersion: p.extensionVersion,
|
|
1260
|
+
migrations: p.migrations
|
|
1261
|
+
})
|
|
1155
1262
|
}
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1263
|
+
};
|
|
1264
|
+
|
|
1265
|
+
// src/transport/handlers/permissions.ts
|
|
1266
|
+
var permissionsHandlers = {
|
|
1267
|
+
"permissions.web.check": {
|
|
1268
|
+
command: TAURI_COMMANDS.permissions.checkWeb,
|
|
1269
|
+
args: (p) => ({
|
|
1270
|
+
url: p.url
|
|
1271
|
+
})
|
|
1272
|
+
},
|
|
1273
|
+
"permissions.database.check": {
|
|
1274
|
+
command: TAURI_COMMANDS.permissions.checkDatabase,
|
|
1275
|
+
args: (p) => ({
|
|
1276
|
+
resource: p.resource,
|
|
1277
|
+
operation: p.operation
|
|
1278
|
+
})
|
|
1279
|
+
},
|
|
1280
|
+
"permissions.filesystem.check": {
|
|
1281
|
+
command: TAURI_COMMANDS.permissions.checkFilesystem,
|
|
1282
|
+
args: (p) => ({
|
|
1283
|
+
path: p.path,
|
|
1284
|
+
actionStr: p.action
|
|
1285
|
+
})
|
|
1161
1286
|
}
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
}
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
}
|
|
1287
|
+
};
|
|
1288
|
+
|
|
1289
|
+
// src/transport/handlers/web.ts
|
|
1290
|
+
var webHandlers = {
|
|
1291
|
+
[HAEXTENSION_METHODS.application.open]: {
|
|
1292
|
+
command: TAURI_COMMANDS.web.open,
|
|
1293
|
+
args: (p) => ({
|
|
1294
|
+
url: p.url
|
|
1295
|
+
})
|
|
1296
|
+
},
|
|
1297
|
+
[HAEXTENSION_METHODS.web.fetch]: {
|
|
1298
|
+
command: TAURI_COMMANDS.web.fetch,
|
|
1299
|
+
args: (p) => ({
|
|
1300
|
+
url: p.url,
|
|
1301
|
+
method: p.method,
|
|
1302
|
+
headers: p.headers,
|
|
1303
|
+
body: p.body
|
|
1304
|
+
})
|
|
1180
1305
|
}
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
}
|
|
1193
|
-
|
|
1306
|
+
};
|
|
1307
|
+
|
|
1308
|
+
// src/transport/handlers/filesystem.ts
|
|
1309
|
+
var filesystemHandlers = {
|
|
1310
|
+
[HAEXTENSION_METHODS.filesystem.saveFile]: {
|
|
1311
|
+
command: TAURI_COMMANDS.filesystem.saveFile,
|
|
1312
|
+
args: (p) => ({
|
|
1313
|
+
data: p.data,
|
|
1314
|
+
defaultPath: p.defaultPath,
|
|
1315
|
+
title: p.title,
|
|
1316
|
+
filters: p.filters
|
|
1317
|
+
})
|
|
1318
|
+
},
|
|
1319
|
+
[HAEXTENSION_METHODS.filesystem.openFile]: {
|
|
1320
|
+
command: TAURI_COMMANDS.filesystem.openFile,
|
|
1321
|
+
args: (p) => ({
|
|
1322
|
+
data: p.data,
|
|
1323
|
+
fileName: p.fileName
|
|
1324
|
+
})
|
|
1325
|
+
},
|
|
1326
|
+
[HAEXTENSION_METHODS.filesystem.showImage]: {
|
|
1327
|
+
command: TAURI_COMMANDS.filesystem.showImage,
|
|
1328
|
+
args: (p) => ({
|
|
1329
|
+
dataUrl: p.dataUrl
|
|
1330
|
+
})
|
|
1194
1331
|
}
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1332
|
+
};
|
|
1333
|
+
|
|
1334
|
+
// src/transport/handlers/external.ts
|
|
1335
|
+
var externalHandlers = {
|
|
1336
|
+
"external.respond": {
|
|
1337
|
+
command: TAURI_COMMANDS.external.respond,
|
|
1338
|
+
args: (p) => ({
|
|
1339
|
+
requestId: p.requestId,
|
|
1340
|
+
success: p.success,
|
|
1341
|
+
data: p.data,
|
|
1342
|
+
error: p.error
|
|
1343
|
+
})
|
|
1200
1344
|
}
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
})
|
|
1238
|
-
}
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
}
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
})
|
|
1310
|
-
);
|
|
1311
|
-
}, this.config.timeout);
|
|
1312
|
-
this.pendingRequests.set(requestId, { resolve, reject, timeout });
|
|
1313
|
-
const targetOrigin = "*";
|
|
1314
|
-
if (this.config.debug) {
|
|
1315
|
-
console.log("[SDK Debug] ========== Sending Request ==========");
|
|
1316
|
-
console.log("[SDK Debug] Request ID:", requestId);
|
|
1317
|
-
console.log("[SDK Debug] Method:", request.method);
|
|
1318
|
-
console.log("[SDK Debug] Params:", request.params);
|
|
1319
|
-
console.log("[SDK Debug] Target origin:", targetOrigin);
|
|
1320
|
-
console.log("[SDK Debug] Extension info:", this._extensionInfo);
|
|
1321
|
-
console.log("[SDK Debug] ========================================");
|
|
1322
|
-
}
|
|
1323
|
-
window.parent.postMessage({ id: requestId, ...request }, targetOrigin);
|
|
1324
|
-
});
|
|
1325
|
-
}
|
|
1326
|
-
async invoke(method, params) {
|
|
1327
|
-
const { invoke } = window.__TAURI__.core;
|
|
1328
|
-
if (this.config.debug) {
|
|
1329
|
-
console.log("[SDK Debug] ========== Invoke Request ==========");
|
|
1330
|
-
console.log("[SDK Debug] Method:", method);
|
|
1331
|
-
console.log("[SDK Debug] Params:", params);
|
|
1332
|
-
console.log("[SDK Debug] =======================================");
|
|
1333
|
-
}
|
|
1334
|
-
switch (method) {
|
|
1335
|
-
case HAEXTENSION_METHODS.database.query:
|
|
1336
|
-
return invoke("webview_extension_db_query", {
|
|
1337
|
-
query: params.query,
|
|
1338
|
-
params: params.params || []
|
|
1339
|
-
});
|
|
1340
|
-
case HAEXTENSION_METHODS.database.execute:
|
|
1341
|
-
return invoke("webview_extension_db_execute", {
|
|
1342
|
-
query: params.query,
|
|
1343
|
-
params: params.params || []
|
|
1344
|
-
});
|
|
1345
|
-
case "permissions.web.check":
|
|
1346
|
-
return invoke("webview_extension_check_web_permission", {
|
|
1347
|
-
url: params.url
|
|
1348
|
-
});
|
|
1349
|
-
case "permissions.database.check":
|
|
1350
|
-
return invoke("webview_extension_check_database_permission", {
|
|
1351
|
-
resource: params.resource,
|
|
1352
|
-
operation: params.operation
|
|
1353
|
-
});
|
|
1354
|
-
case "permissions.filesystem.check":
|
|
1355
|
-
return invoke("webview_extension_check_filesystem_permission", {
|
|
1356
|
-
path: params.path,
|
|
1357
|
-
actionStr: params.action
|
|
1358
|
-
});
|
|
1359
|
-
case HAEXTENSION_METHODS.application.open:
|
|
1360
|
-
return invoke("webview_extension_web_open", {
|
|
1361
|
-
url: params.url
|
|
1362
|
-
});
|
|
1363
|
-
case HAEXTENSION_METHODS.web.fetch:
|
|
1364
|
-
return invoke("webview_extension_web_request", {
|
|
1365
|
-
url: params.url,
|
|
1366
|
-
method: params.method,
|
|
1367
|
-
headers: params.headers,
|
|
1368
|
-
body: params.body
|
|
1369
|
-
});
|
|
1370
|
-
case HAEXTENSION_METHODS.filesystem.saveFile:
|
|
1371
|
-
return invoke("webview_extension_fs_save_file", {
|
|
1372
|
-
data: params.data,
|
|
1373
|
-
defaultPath: params.defaultPath,
|
|
1374
|
-
title: params.title,
|
|
1375
|
-
filters: params.filters
|
|
1376
|
-
});
|
|
1377
|
-
case HAEXTENSION_METHODS.filesystem.openFile:
|
|
1378
|
-
return invoke("webview_extension_fs_open_file", {
|
|
1379
|
-
data: params.data,
|
|
1380
|
-
fileName: params.fileName
|
|
1381
|
-
});
|
|
1382
|
-
case HAEXTENSION_METHODS.database.registerMigrations:
|
|
1383
|
-
return invoke("webview_extension_db_register_migrations", {
|
|
1384
|
-
extensionVersion: params.extensionVersion,
|
|
1385
|
-
migrations: params.migrations
|
|
1386
|
-
});
|
|
1387
|
-
case "external.respond":
|
|
1388
|
-
return invoke("webview_extension_external_respond", {
|
|
1389
|
-
requestId: params.requestId,
|
|
1390
|
-
success: params.success,
|
|
1391
|
-
data: params.data,
|
|
1392
|
-
error: params.error
|
|
1393
|
-
});
|
|
1394
|
-
default:
|
|
1395
|
-
throw new HaexHubError(
|
|
1396
|
-
"METHOD_NOT_FOUND" /* METHOD_NOT_FOUND */,
|
|
1397
|
-
"errors.method_not_found",
|
|
1398
|
-
{ method }
|
|
1399
|
-
);
|
|
1400
|
-
}
|
|
1401
|
-
}
|
|
1402
|
-
on(eventType, callback) {
|
|
1403
|
-
if (!this.eventListeners.has(eventType)) {
|
|
1404
|
-
this.eventListeners.set(eventType, /* @__PURE__ */ new Set());
|
|
1405
|
-
}
|
|
1406
|
-
this.eventListeners.get(eventType).add(callback);
|
|
1407
|
-
}
|
|
1408
|
-
off(eventType, callback) {
|
|
1409
|
-
const listeners = this.eventListeners.get(eventType);
|
|
1410
|
-
if (listeners) {
|
|
1411
|
-
listeners.delete(callback);
|
|
1412
|
-
}
|
|
1413
|
-
}
|
|
1414
|
-
destroy() {
|
|
1415
|
-
if (this.messageHandler) {
|
|
1416
|
-
window.removeEventListener("message", this.messageHandler);
|
|
1417
|
-
}
|
|
1418
|
-
this.pendingRequests.forEach(({ timeout }) => clearTimeout(timeout));
|
|
1419
|
-
this.pendingRequests.clear();
|
|
1420
|
-
this.eventListeners.clear();
|
|
1421
|
-
this.initialized = false;
|
|
1422
|
-
this.log("HaexHub SDK destroyed");
|
|
1345
|
+
};
|
|
1346
|
+
|
|
1347
|
+
// src/transport/handlers/filesync.ts
|
|
1348
|
+
var filesyncHandlers = {
|
|
1349
|
+
// ==========================================================================
|
|
1350
|
+
// Spaces
|
|
1351
|
+
// ==========================================================================
|
|
1352
|
+
[HAEXTENSION_METHODS.filesystem.sync.listSpaces]: {
|
|
1353
|
+
command: TAURI_COMMANDS.filesync.listSpaces,
|
|
1354
|
+
args: () => ({})
|
|
1355
|
+
},
|
|
1356
|
+
[HAEXTENSION_METHODS.filesystem.sync.createSpace]: {
|
|
1357
|
+
command: TAURI_COMMANDS.filesync.createSpace,
|
|
1358
|
+
args: (p) => ({ request: p })
|
|
1359
|
+
},
|
|
1360
|
+
[HAEXTENSION_METHODS.filesystem.sync.deleteSpace]: {
|
|
1361
|
+
command: TAURI_COMMANDS.filesync.deleteSpace,
|
|
1362
|
+
args: (p) => ({ spaceId: p.spaceId })
|
|
1363
|
+
},
|
|
1364
|
+
// ==========================================================================
|
|
1365
|
+
// Files
|
|
1366
|
+
// ==========================================================================
|
|
1367
|
+
[HAEXTENSION_METHODS.filesystem.sync.listFiles]: {
|
|
1368
|
+
command: TAURI_COMMANDS.filesync.listFiles,
|
|
1369
|
+
args: (p) => ({ request: p })
|
|
1370
|
+
},
|
|
1371
|
+
[HAEXTENSION_METHODS.filesystem.sync.getFile]: {
|
|
1372
|
+
command: TAURI_COMMANDS.filesync.getFile,
|
|
1373
|
+
args: (p) => ({ fileId: p.fileId })
|
|
1374
|
+
},
|
|
1375
|
+
[HAEXTENSION_METHODS.filesystem.sync.uploadFile]: {
|
|
1376
|
+
command: TAURI_COMMANDS.filesync.uploadFile,
|
|
1377
|
+
args: (p) => ({ request: p })
|
|
1378
|
+
},
|
|
1379
|
+
[HAEXTENSION_METHODS.filesystem.sync.downloadFile]: {
|
|
1380
|
+
command: TAURI_COMMANDS.filesync.downloadFile,
|
|
1381
|
+
args: (p) => ({ request: p })
|
|
1382
|
+
},
|
|
1383
|
+
[HAEXTENSION_METHODS.filesystem.sync.deleteFile]: {
|
|
1384
|
+
command: TAURI_COMMANDS.filesync.deleteFile,
|
|
1385
|
+
args: (p) => ({ fileId: p.fileId })
|
|
1386
|
+
},
|
|
1387
|
+
// ==========================================================================
|
|
1388
|
+
// Backends
|
|
1389
|
+
// ==========================================================================
|
|
1390
|
+
[HAEXTENSION_METHODS.filesystem.sync.listBackends]: {
|
|
1391
|
+
command: TAURI_COMMANDS.filesync.listBackends,
|
|
1392
|
+
args: () => ({})
|
|
1393
|
+
},
|
|
1394
|
+
[HAEXTENSION_METHODS.filesystem.sync.addBackend]: {
|
|
1395
|
+
command: TAURI_COMMANDS.filesync.addBackend,
|
|
1396
|
+
args: (p) => ({ request: p })
|
|
1397
|
+
},
|
|
1398
|
+
[HAEXTENSION_METHODS.filesystem.sync.removeBackend]: {
|
|
1399
|
+
command: TAURI_COMMANDS.filesync.removeBackend,
|
|
1400
|
+
args: (p) => ({ backendId: p.backendId })
|
|
1401
|
+
},
|
|
1402
|
+
[HAEXTENSION_METHODS.filesystem.sync.testBackend]: {
|
|
1403
|
+
command: TAURI_COMMANDS.filesync.testBackend,
|
|
1404
|
+
args: (p) => ({ backendId: p.backendId })
|
|
1405
|
+
},
|
|
1406
|
+
// ==========================================================================
|
|
1407
|
+
// Sync Rules
|
|
1408
|
+
// ==========================================================================
|
|
1409
|
+
[HAEXTENSION_METHODS.filesystem.sync.listSyncRules]: {
|
|
1410
|
+
command: TAURI_COMMANDS.filesync.listSyncRules,
|
|
1411
|
+
args: () => ({})
|
|
1412
|
+
},
|
|
1413
|
+
[HAEXTENSION_METHODS.filesystem.sync.addSyncRule]: {
|
|
1414
|
+
command: TAURI_COMMANDS.filesync.addSyncRule,
|
|
1415
|
+
args: (p) => ({ request: p })
|
|
1416
|
+
},
|
|
1417
|
+
[HAEXTENSION_METHODS.filesystem.sync.removeSyncRule]: {
|
|
1418
|
+
command: TAURI_COMMANDS.filesync.removeSyncRule,
|
|
1419
|
+
args: (p) => ({ ruleId: p.ruleId })
|
|
1420
|
+
},
|
|
1421
|
+
// ==========================================================================
|
|
1422
|
+
// Sync Operations
|
|
1423
|
+
// ==========================================================================
|
|
1424
|
+
[HAEXTENSION_METHODS.filesystem.sync.getSyncStatus]: {
|
|
1425
|
+
command: TAURI_COMMANDS.filesync.getSyncStatus,
|
|
1426
|
+
args: () => ({})
|
|
1427
|
+
},
|
|
1428
|
+
[HAEXTENSION_METHODS.filesystem.sync.triggerSync]: {
|
|
1429
|
+
command: TAURI_COMMANDS.filesync.triggerSync,
|
|
1430
|
+
args: () => ({})
|
|
1431
|
+
},
|
|
1432
|
+
[HAEXTENSION_METHODS.filesystem.sync.pauseSync]: {
|
|
1433
|
+
command: TAURI_COMMANDS.filesync.pauseSync,
|
|
1434
|
+
args: () => ({})
|
|
1435
|
+
},
|
|
1436
|
+
[HAEXTENSION_METHODS.filesystem.sync.resumeSync]: {
|
|
1437
|
+
command: TAURI_COMMANDS.filesync.resumeSync,
|
|
1438
|
+
args: () => ({})
|
|
1439
|
+
},
|
|
1440
|
+
// ==========================================================================
|
|
1441
|
+
// Conflict Resolution
|
|
1442
|
+
// ==========================================================================
|
|
1443
|
+
[HAEXTENSION_METHODS.filesystem.sync.resolveConflict]: {
|
|
1444
|
+
command: TAURI_COMMANDS.filesync.resolveConflict,
|
|
1445
|
+
args: (p) => ({ request: p })
|
|
1446
|
+
},
|
|
1447
|
+
// ==========================================================================
|
|
1448
|
+
// UI Helpers
|
|
1449
|
+
// ==========================================================================
|
|
1450
|
+
[HAEXTENSION_METHODS.filesystem.sync.selectFolder]: {
|
|
1451
|
+
command: TAURI_COMMANDS.filesync.selectFolder,
|
|
1452
|
+
args: () => ({})
|
|
1423
1453
|
}
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
if (event.payload) {
|
|
1466
|
-
this.handleEvent({
|
|
1467
|
-
type: HAEXTENSION_EVENTS.EXTERNAL_REQUEST,
|
|
1468
|
-
data: event.payload,
|
|
1469
|
-
timestamp: Date.now()
|
|
1470
|
-
});
|
|
1471
|
-
}
|
|
1472
|
-
});
|
|
1473
|
-
console.log("[HaexSpace SDK] External request listener registered successfully");
|
|
1474
|
-
} catch (error) {
|
|
1475
|
-
console.error("[HaexSpace SDK] Failed to setup external request listener:", error);
|
|
1476
|
-
this.log("Failed to setup external request listener:", error);
|
|
1477
|
-
}
|
|
1478
|
-
this.resolveReady();
|
|
1479
|
-
return;
|
|
1480
|
-
}
|
|
1481
|
-
} catch (error) {
|
|
1482
|
-
this.log("Tauri commands failed, falling back to iframe mode", error);
|
|
1483
|
-
}
|
|
1484
|
-
}
|
|
1485
|
-
if (window.self === window.top) {
|
|
1486
|
-
throw new HaexHubError("NOT_IN_IFRAME" /* NOT_IN_IFRAME */, "errors.not_in_iframe");
|
|
1487
|
-
}
|
|
1488
|
-
this.messageHandler = this.handleMessage.bind(this);
|
|
1489
|
-
window.addEventListener("message", this.messageHandler);
|
|
1490
|
-
this.isNativeWindow = false;
|
|
1491
|
-
this.initialized = true;
|
|
1492
|
-
this.log("HaexSpace SDK initialized in iframe mode");
|
|
1493
|
-
try {
|
|
1494
|
-
if (this.config.manifest) {
|
|
1495
|
-
this._extensionInfo = {
|
|
1496
|
-
publicKey: this.config.manifest.publicKey,
|
|
1497
|
-
name: this.config.manifest.name,
|
|
1498
|
-
version: this.config.manifest.version,
|
|
1499
|
-
displayName: this.config.manifest.name
|
|
1500
|
-
};
|
|
1501
|
-
this.log("Extension info loaded from manifest:", this._extensionInfo);
|
|
1502
|
-
this.notifySubscribers();
|
|
1503
|
-
}
|
|
1504
|
-
if (typeof window !== "undefined" && window.parent) {
|
|
1505
|
-
const debugInfo = `SDK Debug:
|
|
1506
|
-
window.parent exists: ${!!window.parent}
|
|
1507
|
-
window.parent === window: ${window.parent === window}
|
|
1508
|
-
window.self === window.top: ${window.self === window.top}`;
|
|
1509
|
-
try {
|
|
1510
|
-
window.parent.postMessage({
|
|
1511
|
-
type: HAEXSPACE_MESSAGE_TYPES.DEBUG,
|
|
1512
|
-
data: debugInfo
|
|
1513
|
-
}, "*");
|
|
1514
|
-
} catch (e) {
|
|
1515
|
-
alert(debugInfo + `
|
|
1516
|
-
postMessage error: ${e}`);
|
|
1517
|
-
}
|
|
1518
|
-
}
|
|
1519
|
-
this._context = await this.request(HAEXTENSION_METHODS.context.get);
|
|
1520
|
-
this.log("Application context received:", this._context);
|
|
1521
|
-
this.notifySubscribers();
|
|
1522
|
-
this.resolveReady();
|
|
1523
|
-
} catch (error) {
|
|
1524
|
-
this.log("Failed to load extension info or context:", error);
|
|
1525
|
-
throw error;
|
|
1454
|
+
};
|
|
1455
|
+
|
|
1456
|
+
// src/transport/handlers/index.ts
|
|
1457
|
+
var allHandlers = {
|
|
1458
|
+
...databaseHandlers,
|
|
1459
|
+
...permissionsHandlers,
|
|
1460
|
+
...webHandlers,
|
|
1461
|
+
...filesystemHandlers,
|
|
1462
|
+
...externalHandlers,
|
|
1463
|
+
...filesyncHandlers
|
|
1464
|
+
};
|
|
1465
|
+
|
|
1466
|
+
// src/client/transport.ts
|
|
1467
|
+
function generateRequestId(counter) {
|
|
1468
|
+
return `req_${counter}`;
|
|
1469
|
+
}
|
|
1470
|
+
function sendPostMessage(method, params, requestId, config, extensionInfo2, pendingRequests) {
|
|
1471
|
+
const request = {
|
|
1472
|
+
method,
|
|
1473
|
+
params,
|
|
1474
|
+
timestamp: Date.now()
|
|
1475
|
+
};
|
|
1476
|
+
return new Promise((resolve, reject) => {
|
|
1477
|
+
const timeout = setTimeout(() => {
|
|
1478
|
+
pendingRequests.delete(requestId);
|
|
1479
|
+
reject(
|
|
1480
|
+
new HaexVaultSdkError("TIMEOUT" /* TIMEOUT */, "errors.timeout", {
|
|
1481
|
+
timeout: config.timeout
|
|
1482
|
+
})
|
|
1483
|
+
);
|
|
1484
|
+
}, config.timeout);
|
|
1485
|
+
pendingRequests.set(requestId, { resolve, reject, timeout });
|
|
1486
|
+
const targetOrigin = "*";
|
|
1487
|
+
if (config.debug) {
|
|
1488
|
+
console.log("[SDK Debug] ========== Sending Request ==========");
|
|
1489
|
+
console.log("[SDK Debug] Request ID:", requestId);
|
|
1490
|
+
console.log("[SDK Debug] Method:", request.method);
|
|
1491
|
+
console.log("[SDK Debug] Params:", request.params);
|
|
1492
|
+
console.log("[SDK Debug] Target origin:", targetOrigin);
|
|
1493
|
+
console.log("[SDK Debug] Extension info:", extensionInfo2);
|
|
1494
|
+
console.log("[SDK Debug] ========================================");
|
|
1526
1495
|
}
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1496
|
+
window.parent.postMessage({ id: requestId, ...request }, targetOrigin);
|
|
1497
|
+
});
|
|
1498
|
+
}
|
|
1499
|
+
async function sendInvoke(method, params, config, log) {
|
|
1500
|
+
const { invoke } = window.__TAURI__.core;
|
|
1501
|
+
if (config.debug) {
|
|
1502
|
+
console.log("[SDK Debug] ========== Invoke Request ==========");
|
|
1503
|
+
console.log("[SDK Debug] Method:", method);
|
|
1504
|
+
console.log("[SDK Debug] Params:", params);
|
|
1505
|
+
console.log("[SDK Debug] =======================================");
|
|
1506
|
+
}
|
|
1507
|
+
const handler = allHandlers[method];
|
|
1508
|
+
if (handler) {
|
|
1509
|
+
const args = handler.args(params);
|
|
1510
|
+
return invoke(handler.command, args);
|
|
1511
|
+
}
|
|
1512
|
+
throw new HaexVaultSdkError(
|
|
1513
|
+
"METHOD_NOT_FOUND" /* METHOD_NOT_FOUND */,
|
|
1514
|
+
"errors.method_not_found",
|
|
1515
|
+
{ method }
|
|
1516
|
+
);
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
// src/client/events.ts
|
|
1520
|
+
function createMessageHandler(config, pendingRequests, extensionInfo2, onEvent) {
|
|
1521
|
+
return (event) => {
|
|
1522
|
+
if (config.debug) {
|
|
1530
1523
|
console.log("[SDK Debug] ========== Message Received ==========");
|
|
1531
1524
|
console.log("[SDK Debug] Event origin:", event.origin);
|
|
1532
1525
|
console.log(
|
|
@@ -1534,160 +1527,534 @@ postMessage error: ${e}`);
|
|
|
1534
1527
|
event.source === window.parent ? "parent window" : "unknown"
|
|
1535
1528
|
);
|
|
1536
1529
|
console.log("[SDK Debug] Event data:", event.data);
|
|
1537
|
-
console.log("[SDK Debug] Extension info loaded:", !!
|
|
1530
|
+
console.log("[SDK Debug] Extension info loaded:", !!extensionInfo2());
|
|
1538
1531
|
console.log(
|
|
1539
1532
|
"[SDK Debug] Pending requests count:",
|
|
1540
|
-
|
|
1533
|
+
pendingRequests.size
|
|
1541
1534
|
);
|
|
1542
1535
|
}
|
|
1543
1536
|
if (event.source !== window.parent) {
|
|
1544
|
-
if (
|
|
1537
|
+
if (config.debug) {
|
|
1545
1538
|
console.error("[SDK Debug] \u274C REJECTED: Message not from parent window!");
|
|
1546
1539
|
}
|
|
1547
1540
|
return;
|
|
1548
1541
|
}
|
|
1549
1542
|
const data = event.data;
|
|
1550
|
-
if ("id" in data &&
|
|
1551
|
-
if (
|
|
1543
|
+
if ("id" in data && pendingRequests.has(data.id)) {
|
|
1544
|
+
if (config.debug) {
|
|
1552
1545
|
console.log("[SDK Debug] \u2705 Found pending request for ID:", data.id);
|
|
1553
1546
|
}
|
|
1554
|
-
const pending =
|
|
1547
|
+
const pending = pendingRequests.get(data.id);
|
|
1555
1548
|
clearTimeout(pending.timeout);
|
|
1556
|
-
|
|
1549
|
+
pendingRequests.delete(data.id);
|
|
1557
1550
|
if (data.error) {
|
|
1558
|
-
if (
|
|
1551
|
+
if (config.debug) {
|
|
1559
1552
|
console.error("[SDK Debug] \u274C Request failed:", data.error);
|
|
1560
1553
|
}
|
|
1561
1554
|
pending.reject(data.error);
|
|
1562
1555
|
} else {
|
|
1563
|
-
if (
|
|
1556
|
+
if (config.debug) {
|
|
1564
1557
|
console.log("[SDK Debug] \u2705 Request succeeded:", data.result);
|
|
1565
1558
|
}
|
|
1566
1559
|
pending.resolve(data.result);
|
|
1567
1560
|
}
|
|
1568
1561
|
return;
|
|
1569
1562
|
}
|
|
1570
|
-
if ("id" in data && !
|
|
1571
|
-
if (
|
|
1563
|
+
if ("id" in data && !pendingRequests.has(data.id)) {
|
|
1564
|
+
if (config.debug) {
|
|
1572
1565
|
console.warn(
|
|
1573
1566
|
"[SDK Debug] \u26A0\uFE0F Received response for unknown request ID:",
|
|
1574
1567
|
data.id
|
|
1575
1568
|
);
|
|
1576
1569
|
console.warn(
|
|
1577
1570
|
"[SDK Debug] Known IDs:",
|
|
1578
|
-
Array.from(
|
|
1571
|
+
Array.from(pendingRequests.keys())
|
|
1579
1572
|
);
|
|
1580
1573
|
}
|
|
1581
1574
|
}
|
|
1582
1575
|
if ("type" in data && data.type) {
|
|
1583
|
-
if (
|
|
1576
|
+
if (config.debug) {
|
|
1584
1577
|
console.log("[SDK Debug] Event received:", data.type);
|
|
1585
1578
|
}
|
|
1586
|
-
|
|
1579
|
+
onEvent(data);
|
|
1587
1580
|
}
|
|
1588
|
-
if (
|
|
1581
|
+
if (config.debug) {
|
|
1589
1582
|
console.log("[SDK Debug] ========== End Message ==========");
|
|
1590
1583
|
}
|
|
1584
|
+
};
|
|
1585
|
+
}
|
|
1586
|
+
function processEvent(event, log, eventListeners, onContextChanged, onExternalRequest) {
|
|
1587
|
+
if (event.type === HAEXTENSION_EVENTS.CONTEXT_CHANGED) {
|
|
1588
|
+
const contextEvent = event;
|
|
1589
|
+
onContextChanged(contextEvent.data.context);
|
|
1590
|
+
log("Context updated:", contextEvent.data.context);
|
|
1591
|
+
}
|
|
1592
|
+
if (event.type === HAEXTENSION_EVENTS.EXTERNAL_REQUEST) {
|
|
1593
|
+
const externalEvent = event;
|
|
1594
|
+
onExternalRequest(externalEvent);
|
|
1595
|
+
return;
|
|
1591
1596
|
}
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1597
|
+
emitEvent(event, log, eventListeners);
|
|
1598
|
+
}
|
|
1599
|
+
function emitEvent(event, log, eventListeners) {
|
|
1600
|
+
log("Event received:", event);
|
|
1601
|
+
const listeners = eventListeners.get(event.type);
|
|
1602
|
+
if (listeners) {
|
|
1603
|
+
listeners.forEach((callback) => callback(event));
|
|
1604
|
+
}
|
|
1605
|
+
}
|
|
1606
|
+
function addEventListener(eventType, callback, eventListeners) {
|
|
1607
|
+
if (!eventListeners.has(eventType)) {
|
|
1608
|
+
eventListeners.set(eventType, /* @__PURE__ */ new Set());
|
|
1609
|
+
}
|
|
1610
|
+
eventListeners.get(eventType).add(callback);
|
|
1611
|
+
}
|
|
1612
|
+
function removeEventListener(eventType, callback, eventListeners) {
|
|
1613
|
+
const listeners = eventListeners.get(eventType);
|
|
1614
|
+
if (listeners) {
|
|
1615
|
+
listeners.delete(callback);
|
|
1616
|
+
}
|
|
1617
|
+
}
|
|
1618
|
+
function notifySubscribers(subscribers) {
|
|
1619
|
+
subscribers.forEach((callback) => callback());
|
|
1620
|
+
}
|
|
1621
|
+
function createDrizzleInstance(schema, extensionInfo2, request, log) {
|
|
1622
|
+
if (!extensionInfo2) {
|
|
1623
|
+
throw new HaexVaultSdkError(
|
|
1624
|
+
"EXTENSION_INFO_UNAVAILABLE" /* EXTENSION_INFO_UNAVAILABLE */,
|
|
1625
|
+
"errors.client_not_ready"
|
|
1626
|
+
);
|
|
1627
|
+
}
|
|
1628
|
+
return sqliteProxy.drizzle(
|
|
1629
|
+
async (sql, params, method) => {
|
|
1630
|
+
try {
|
|
1631
|
+
if (method === "run" || method === "all") {
|
|
1632
|
+
const result2 = await request(
|
|
1633
|
+
HAEXTENSION_METHODS.database.execute,
|
|
1634
|
+
{
|
|
1635
|
+
query: sql,
|
|
1636
|
+
params
|
|
1637
|
+
}
|
|
1638
|
+
);
|
|
1639
|
+
if (method === "all") {
|
|
1640
|
+
return { rows: result2.rows || [] };
|
|
1641
|
+
}
|
|
1642
|
+
if (result2.rows && Array.isArray(result2.rows) && result2.rows.length > 0) {
|
|
1643
|
+
return { rows: result2.rows };
|
|
1644
|
+
}
|
|
1645
|
+
return result2;
|
|
1646
|
+
}
|
|
1647
|
+
const result = await request(HAEXTENSION_METHODS.database.query, {
|
|
1648
|
+
query: sql,
|
|
1649
|
+
params
|
|
1650
|
+
});
|
|
1651
|
+
const rows = result.rows;
|
|
1652
|
+
if (method === "get") {
|
|
1653
|
+
return { rows: rows.length > 0 ? rows.at(0) : void 0 };
|
|
1654
|
+
}
|
|
1655
|
+
return { rows };
|
|
1656
|
+
} catch (error) {
|
|
1657
|
+
log("Database operation failed:", error);
|
|
1658
|
+
throw error;
|
|
1659
|
+
}
|
|
1660
|
+
},
|
|
1661
|
+
{
|
|
1662
|
+
schema,
|
|
1663
|
+
logger: false
|
|
1598
1664
|
}
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1665
|
+
);
|
|
1666
|
+
}
|
|
1667
|
+
async function queryRaw(sql, params, request, debug) {
|
|
1668
|
+
const result = await request(
|
|
1669
|
+
HAEXTENSION_METHODS.database.query,
|
|
1670
|
+
{ query: sql, params }
|
|
1671
|
+
);
|
|
1672
|
+
if (debug) {
|
|
1673
|
+
console.log("[SDK query()] Raw result:", JSON.stringify(result, null, 2));
|
|
1674
|
+
}
|
|
1675
|
+
return result.rows;
|
|
1676
|
+
}
|
|
1677
|
+
async function executeRaw(sql, params, request) {
|
|
1678
|
+
const result = await request(
|
|
1679
|
+
HAEXTENSION_METHODS.database.execute,
|
|
1680
|
+
{ query: sql, params }
|
|
1681
|
+
);
|
|
1682
|
+
return {
|
|
1683
|
+
rowsAffected: result.rowsAffected,
|
|
1684
|
+
lastInsertId: result.lastInsertId
|
|
1685
|
+
};
|
|
1686
|
+
}
|
|
1687
|
+
|
|
1688
|
+
// src/client/external.ts
|
|
1689
|
+
function registerExternalHandler(action, handler, handlers, log) {
|
|
1690
|
+
handlers.set(action, handler);
|
|
1691
|
+
log(`[ExternalRequest] Registered handler for action: ${action}`);
|
|
1692
|
+
return () => {
|
|
1693
|
+
handlers.delete(action);
|
|
1694
|
+
log(`[ExternalRequest] Unregistered handler for action: ${action}`);
|
|
1695
|
+
};
|
|
1696
|
+
}
|
|
1697
|
+
async function handleExternalRequest(request, handlers, respond, log) {
|
|
1698
|
+
log(`[ExternalRequest] Received request: ${request.action} from ${request.publicKey.substring(0, 20)}...`);
|
|
1699
|
+
const handler = handlers.get(request.action);
|
|
1700
|
+
if (!handler) {
|
|
1701
|
+
log(`[ExternalRequest] No handler for action: ${request.action}`);
|
|
1702
|
+
await respond({
|
|
1703
|
+
requestId: request.requestId,
|
|
1704
|
+
success: false,
|
|
1705
|
+
error: `No handler registered for action: ${request.action}`
|
|
1706
|
+
});
|
|
1707
|
+
return;
|
|
1708
|
+
}
|
|
1709
|
+
try {
|
|
1710
|
+
const response = await handler(request);
|
|
1711
|
+
await respond(response);
|
|
1712
|
+
log(`[ExternalRequest] Response sent for: ${request.action}`);
|
|
1713
|
+
} catch (error) {
|
|
1714
|
+
log(`[ExternalRequest] Handler error:`, error);
|
|
1715
|
+
await respond({
|
|
1716
|
+
requestId: request.requestId,
|
|
1717
|
+
success: false,
|
|
1718
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1719
|
+
});
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
async function respondToExternalRequest(response, request) {
|
|
1723
|
+
await request("external.respond", response);
|
|
1724
|
+
}
|
|
1725
|
+
|
|
1726
|
+
// src/client.ts
|
|
1727
|
+
var HaexVaultClient = class {
|
|
1728
|
+
constructor(config = {}) {
|
|
1729
|
+
// State
|
|
1730
|
+
this.initialized = false;
|
|
1731
|
+
this.isNativeWindow = false;
|
|
1732
|
+
this.requestCounter = 0;
|
|
1733
|
+
this._extensionInfo = null;
|
|
1734
|
+
this._context = null;
|
|
1735
|
+
this._setupCompleted = false;
|
|
1736
|
+
// Collections
|
|
1737
|
+
this.pendingRequests = /* @__PURE__ */ new Map();
|
|
1738
|
+
this.eventListeners = /* @__PURE__ */ new Map();
|
|
1739
|
+
this.externalRequestHandlers = /* @__PURE__ */ new Map();
|
|
1740
|
+
this.reactiveSubscribers = /* @__PURE__ */ new Set();
|
|
1741
|
+
// Handlers
|
|
1742
|
+
this.messageHandler = null;
|
|
1743
|
+
this.setupPromise = null;
|
|
1744
|
+
this.setupHook = null;
|
|
1745
|
+
// Public APIs
|
|
1746
|
+
this.orm = null;
|
|
1747
|
+
this.config = {
|
|
1748
|
+
debug: config.debug ?? false,
|
|
1749
|
+
timeout: config.timeout ?? DEFAULT_TIMEOUT,
|
|
1750
|
+
manifest: config.manifest
|
|
1751
|
+
};
|
|
1752
|
+
this.storage = new StorageAPI(this);
|
|
1753
|
+
this.database = new DatabaseAPI(this);
|
|
1754
|
+
this.filesystem = new FilesystemAPI(this);
|
|
1755
|
+
this.web = new WebAPI(this);
|
|
1756
|
+
this.permissions = new PermissionsAPI(this);
|
|
1757
|
+
installConsoleForwarding(this.config.debug);
|
|
1758
|
+
this.readyPromise = new Promise((resolve) => {
|
|
1759
|
+
this.resolveReady = resolve;
|
|
1760
|
+
});
|
|
1761
|
+
this.init();
|
|
1762
|
+
}
|
|
1763
|
+
// ==========================================================================
|
|
1764
|
+
// Lifecycle
|
|
1765
|
+
// ==========================================================================
|
|
1766
|
+
async ready() {
|
|
1767
|
+
return this.readyPromise;
|
|
1768
|
+
}
|
|
1769
|
+
get setupCompleted() {
|
|
1770
|
+
return this._setupCompleted;
|
|
1771
|
+
}
|
|
1772
|
+
onSetup(setupFn) {
|
|
1773
|
+
if (this.setupHook) {
|
|
1774
|
+
throw new Error("Setup hook already registered");
|
|
1603
1775
|
}
|
|
1604
|
-
this.
|
|
1605
|
-
}
|
|
1606
|
-
async
|
|
1607
|
-
this.
|
|
1608
|
-
|
|
1609
|
-
if (!handler) {
|
|
1610
|
-
this.log(`[ExternalRequest] No handler for action: ${request.action}`);
|
|
1611
|
-
await this.respondToExternalRequest({
|
|
1612
|
-
requestId: request.requestId,
|
|
1613
|
-
success: false,
|
|
1614
|
-
error: `No handler registered for action: ${request.action}`
|
|
1615
|
-
});
|
|
1776
|
+
this.setupHook = setupFn;
|
|
1777
|
+
}
|
|
1778
|
+
async setupComplete() {
|
|
1779
|
+
await this.readyPromise;
|
|
1780
|
+
if (!this.setupHook || this.setupCompleted) {
|
|
1616
1781
|
return;
|
|
1617
1782
|
}
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
await this.respondToExternalRequest(response);
|
|
1621
|
-
this.log(`[ExternalRequest] Response sent for: ${request.action}`);
|
|
1622
|
-
} catch (error) {
|
|
1623
|
-
this.log(`[ExternalRequest] Handler error:`, error);
|
|
1624
|
-
await this.respondToExternalRequest({
|
|
1625
|
-
requestId: request.requestId,
|
|
1626
|
-
success: false,
|
|
1627
|
-
error: error instanceof Error ? error.message : String(error)
|
|
1628
|
-
});
|
|
1783
|
+
if (!this.setupPromise) {
|
|
1784
|
+
this.setupPromise = this.runSetupAsync();
|
|
1629
1785
|
}
|
|
1786
|
+
return this.setupPromise;
|
|
1630
1787
|
}
|
|
1631
|
-
|
|
1632
|
-
this.
|
|
1633
|
-
|
|
1634
|
-
if (listeners) {
|
|
1635
|
-
listeners.forEach((callback) => callback(event));
|
|
1788
|
+
destroy() {
|
|
1789
|
+
if (this.messageHandler) {
|
|
1790
|
+
window.removeEventListener("message", this.messageHandler);
|
|
1636
1791
|
}
|
|
1792
|
+
this.pendingRequests.forEach(({ timeout }) => clearTimeout(timeout));
|
|
1793
|
+
this.pendingRequests.clear();
|
|
1794
|
+
this.eventListeners.clear();
|
|
1795
|
+
this.initialized = false;
|
|
1796
|
+
this.log("HaexVault SDK destroyed");
|
|
1637
1797
|
}
|
|
1638
|
-
|
|
1639
|
-
|
|
1798
|
+
// ==========================================================================
|
|
1799
|
+
// Properties
|
|
1800
|
+
// ==========================================================================
|
|
1801
|
+
get extensionInfo() {
|
|
1802
|
+
return this._extensionInfo;
|
|
1640
1803
|
}
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
throw new HaexHubError(
|
|
1644
|
-
"INVALID_PUBLIC_KEY" /* INVALID_PUBLIC_KEY */,
|
|
1645
|
-
"errors.invalid_public_key",
|
|
1646
|
-
{ publicKey }
|
|
1647
|
-
);
|
|
1648
|
-
}
|
|
1804
|
+
get context() {
|
|
1805
|
+
return this._context;
|
|
1649
1806
|
}
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
);
|
|
1657
|
-
}
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1807
|
+
// ==========================================================================
|
|
1808
|
+
// Subscriptions
|
|
1809
|
+
// ==========================================================================
|
|
1810
|
+
subscribe(callback) {
|
|
1811
|
+
this.reactiveSubscribers.add(callback);
|
|
1812
|
+
return () => {
|
|
1813
|
+
this.reactiveSubscribers.delete(callback);
|
|
1814
|
+
};
|
|
1815
|
+
}
|
|
1816
|
+
// ==========================================================================
|
|
1817
|
+
// Table Name Utilities
|
|
1818
|
+
// ==========================================================================
|
|
1819
|
+
getTableName(tableName) {
|
|
1820
|
+
return getExtensionTableName(this._extensionInfo, tableName);
|
|
1821
|
+
}
|
|
1822
|
+
getDependencyTableName(publicKey, extensionName, tableName) {
|
|
1823
|
+
return getDependencyTableName(publicKey, extensionName, tableName);
|
|
1824
|
+
}
|
|
1825
|
+
parseTableName(fullTableName) {
|
|
1826
|
+
return parseTableName(fullTableName);
|
|
1827
|
+
}
|
|
1828
|
+
// ==========================================================================
|
|
1829
|
+
// Database
|
|
1830
|
+
// ==========================================================================
|
|
1831
|
+
initializeDatabase(schema) {
|
|
1832
|
+
const db = createDrizzleInstance(schema, this._extensionInfo, this.request.bind(this), this.log.bind(this));
|
|
1833
|
+
this.orm = db;
|
|
1834
|
+
return db;
|
|
1835
|
+
}
|
|
1836
|
+
async query(sql, params = []) {
|
|
1837
|
+
return queryRaw(sql, params, this.request.bind(this), this.config.debug);
|
|
1838
|
+
}
|
|
1839
|
+
async select(sql, params = []) {
|
|
1840
|
+
return this.query(sql, params);
|
|
1841
|
+
}
|
|
1842
|
+
async execute(sql, params = []) {
|
|
1843
|
+
return executeRaw(sql, params, this.request.bind(this));
|
|
1844
|
+
}
|
|
1845
|
+
async registerMigrationsAsync(extensionVersion, migrations) {
|
|
1846
|
+
return this.database.registerMigrationsAsync(extensionVersion, migrations);
|
|
1847
|
+
}
|
|
1848
|
+
// ==========================================================================
|
|
1849
|
+
// Dependencies
|
|
1850
|
+
// ==========================================================================
|
|
1851
|
+
async getDependencies() {
|
|
1852
|
+
return this.request("extensions.getDependencies");
|
|
1853
|
+
}
|
|
1854
|
+
// ==========================================================================
|
|
1855
|
+
// Permissions
|
|
1856
|
+
// ==========================================================================
|
|
1857
|
+
async requestDatabasePermission(request) {
|
|
1858
|
+
return this.request("permissions.database.request", {
|
|
1859
|
+
resource: request.resource,
|
|
1860
|
+
operation: request.operation,
|
|
1861
|
+
reason: request.reason
|
|
1862
|
+
});
|
|
1863
|
+
}
|
|
1864
|
+
async checkDatabasePermission(resource, operation) {
|
|
1865
|
+
const response = await this.request("permissions.database.check", { resource, operation });
|
|
1866
|
+
return response.status === "granted";
|
|
1867
|
+
}
|
|
1868
|
+
// ==========================================================================
|
|
1869
|
+
// Search
|
|
1870
|
+
// ==========================================================================
|
|
1871
|
+
async respondToSearch(requestId, results) {
|
|
1872
|
+
await this.request("search.respond", { requestId, results });
|
|
1873
|
+
}
|
|
1874
|
+
// ==========================================================================
|
|
1875
|
+
// External Requests
|
|
1876
|
+
// ==========================================================================
|
|
1877
|
+
onExternalRequest(action, handler) {
|
|
1878
|
+
return registerExternalHandler(action, handler, this.externalRequestHandlers, this.log.bind(this));
|
|
1879
|
+
}
|
|
1880
|
+
async respondToExternalRequest(response) {
|
|
1881
|
+
await respondToExternalRequest(response, this.request.bind(this));
|
|
1882
|
+
}
|
|
1883
|
+
// ==========================================================================
|
|
1884
|
+
// Events
|
|
1885
|
+
// ==========================================================================
|
|
1886
|
+
on(eventType, callback) {
|
|
1887
|
+
addEventListener(eventType, callback, this.eventListeners);
|
|
1888
|
+
}
|
|
1889
|
+
off(eventType, callback) {
|
|
1890
|
+
removeEventListener(eventType, callback, this.eventListeners);
|
|
1891
|
+
}
|
|
1892
|
+
// ==========================================================================
|
|
1893
|
+
// Communication
|
|
1894
|
+
// ==========================================================================
|
|
1895
|
+
async request(method, params) {
|
|
1896
|
+
const resolvedParams = params ?? {};
|
|
1897
|
+
if (this.isNativeWindow && hasTauri()) {
|
|
1898
|
+
return sendInvoke(method, resolvedParams, this.config, this.log.bind(this));
|
|
1664
1899
|
}
|
|
1900
|
+
const requestId = generateRequestId(++this.requestCounter);
|
|
1901
|
+
return sendPostMessage(method, resolvedParams, requestId, this.config, this._extensionInfo, this.pendingRequests);
|
|
1665
1902
|
}
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1903
|
+
// ==========================================================================
|
|
1904
|
+
// Private: Initialization
|
|
1905
|
+
// ==========================================================================
|
|
1906
|
+
async init() {
|
|
1907
|
+
if (this.initialized) return;
|
|
1908
|
+
if (!isInIframe() && hasTauri()) {
|
|
1909
|
+
try {
|
|
1910
|
+
await this.initNative();
|
|
1911
|
+
return;
|
|
1912
|
+
} catch (error) {
|
|
1913
|
+
this.log("Tauri commands failed, falling back to iframe mode", error);
|
|
1914
|
+
}
|
|
1672
1915
|
}
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1916
|
+
await this.initIframe();
|
|
1917
|
+
}
|
|
1918
|
+
async initNative() {
|
|
1919
|
+
const { extensionInfo: extensionInfo2, context: context2 } = await initNativeMode(
|
|
1920
|
+
{
|
|
1921
|
+
config: this.config,
|
|
1922
|
+
state: {
|
|
1923
|
+
initialized: this.initialized,
|
|
1924
|
+
isNativeWindow: this.isNativeWindow,
|
|
1925
|
+
requestCounter: this.requestCounter,
|
|
1926
|
+
setupCompleted: this._setupCompleted,
|
|
1927
|
+
extensionInfo: this._extensionInfo,
|
|
1928
|
+
context: this._context,
|
|
1929
|
+
orm: this.orm
|
|
1930
|
+
},
|
|
1931
|
+
collections: {
|
|
1932
|
+
pendingRequests: this.pendingRequests,
|
|
1933
|
+
eventListeners: this.eventListeners,
|
|
1934
|
+
externalRequestHandlers: this.externalRequestHandlers,
|
|
1935
|
+
reactiveSubscribers: this.reactiveSubscribers
|
|
1936
|
+
},
|
|
1937
|
+
promises: {
|
|
1938
|
+
readyPromise: this.readyPromise,
|
|
1939
|
+
resolveReady: this.resolveReady,
|
|
1940
|
+
setupPromise: this.setupPromise,
|
|
1941
|
+
setupHook: this.setupHook
|
|
1942
|
+
},
|
|
1943
|
+
handlers: {
|
|
1944
|
+
messageHandler: this.messageHandler
|
|
1945
|
+
}
|
|
1946
|
+
},
|
|
1947
|
+
this.log.bind(this),
|
|
1948
|
+
this.handleEvent.bind(this),
|
|
1949
|
+
(ctx) => {
|
|
1950
|
+
this._context = ctx;
|
|
1951
|
+
this.notifySubscribersInternal();
|
|
1952
|
+
}
|
|
1953
|
+
);
|
|
1954
|
+
this._extensionInfo = extensionInfo2;
|
|
1955
|
+
this._context = context2;
|
|
1956
|
+
this.isNativeWindow = true;
|
|
1957
|
+
this.initialized = true;
|
|
1958
|
+
this.notifySubscribersInternal();
|
|
1959
|
+
this.resolveReady();
|
|
1960
|
+
}
|
|
1961
|
+
async initIframe() {
|
|
1962
|
+
this.messageHandler = createMessageHandler(
|
|
1963
|
+
this.config,
|
|
1964
|
+
this.pendingRequests,
|
|
1965
|
+
() => this._extensionInfo,
|
|
1966
|
+
this.handleEvent.bind(this)
|
|
1967
|
+
);
|
|
1968
|
+
const { context: context2 } = await initIframeMode(
|
|
1969
|
+
{
|
|
1970
|
+
config: this.config,
|
|
1971
|
+
state: {
|
|
1972
|
+
initialized: this.initialized,
|
|
1973
|
+
isNativeWindow: this.isNativeWindow,
|
|
1974
|
+
requestCounter: this.requestCounter,
|
|
1975
|
+
setupCompleted: this._setupCompleted,
|
|
1976
|
+
extensionInfo: this._extensionInfo,
|
|
1977
|
+
context: this._context,
|
|
1978
|
+
orm: this.orm
|
|
1979
|
+
},
|
|
1980
|
+
collections: {
|
|
1981
|
+
pendingRequests: this.pendingRequests,
|
|
1982
|
+
eventListeners: this.eventListeners,
|
|
1983
|
+
externalRequestHandlers: this.externalRequestHandlers,
|
|
1984
|
+
reactiveSubscribers: this.reactiveSubscribers
|
|
1985
|
+
},
|
|
1986
|
+
promises: {
|
|
1987
|
+
readyPromise: this.readyPromise,
|
|
1988
|
+
resolveReady: this.resolveReady,
|
|
1989
|
+
setupPromise: this.setupPromise,
|
|
1990
|
+
setupHook: this.setupHook
|
|
1991
|
+
},
|
|
1992
|
+
handlers: {
|
|
1993
|
+
messageHandler: this.messageHandler
|
|
1994
|
+
}
|
|
1995
|
+
},
|
|
1996
|
+
this.log.bind(this),
|
|
1997
|
+
this.messageHandler,
|
|
1998
|
+
this.request.bind(this)
|
|
1999
|
+
);
|
|
2000
|
+
if (this.config.manifest) {
|
|
2001
|
+
this._extensionInfo = {
|
|
2002
|
+
publicKey: this.config.manifest.publicKey,
|
|
2003
|
+
name: this.config.manifest.name,
|
|
2004
|
+
version: this.config.manifest.version,
|
|
2005
|
+
displayName: this.config.manifest.name
|
|
2006
|
+
};
|
|
2007
|
+
this.notifySubscribersInternal();
|
|
1679
2008
|
}
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
2009
|
+
this._context = context2;
|
|
2010
|
+
this.isNativeWindow = false;
|
|
2011
|
+
this.initialized = true;
|
|
2012
|
+
this.notifySubscribersInternal();
|
|
2013
|
+
this.resolveReady();
|
|
2014
|
+
}
|
|
2015
|
+
// ==========================================================================
|
|
2016
|
+
// Private: Event Handling
|
|
2017
|
+
// ==========================================================================
|
|
2018
|
+
handleEvent(event) {
|
|
2019
|
+
processEvent(
|
|
2020
|
+
event,
|
|
2021
|
+
this.log.bind(this),
|
|
2022
|
+
this.eventListeners,
|
|
2023
|
+
(ctx) => {
|
|
2024
|
+
this._context = ctx;
|
|
2025
|
+
this.notifySubscribersInternal();
|
|
2026
|
+
},
|
|
2027
|
+
(extEvent) => this.handleExternalRequestInternal(extEvent.data)
|
|
2028
|
+
);
|
|
2029
|
+
}
|
|
2030
|
+
async handleExternalRequestInternal(request) {
|
|
2031
|
+
await handleExternalRequest(request, this.externalRequestHandlers, this.respondToExternalRequest.bind(this), this.log.bind(this));
|
|
2032
|
+
}
|
|
2033
|
+
// ==========================================================================
|
|
2034
|
+
// Private: Setup
|
|
2035
|
+
// ==========================================================================
|
|
2036
|
+
async runSetupAsync() {
|
|
2037
|
+
if (!this.setupHook) return;
|
|
2038
|
+
try {
|
|
2039
|
+
this.log("[HaexVault] Running setup hook...");
|
|
2040
|
+
await this.setupHook();
|
|
2041
|
+
this._setupCompleted = true;
|
|
2042
|
+
this.log("[HaexVault] Setup completed successfully");
|
|
2043
|
+
this.notifySubscribersInternal();
|
|
2044
|
+
} catch (error) {
|
|
2045
|
+
this.log("[HaexVault] Setup failed:", error);
|
|
2046
|
+
throw error;
|
|
1686
2047
|
}
|
|
1687
2048
|
}
|
|
2049
|
+
// ==========================================================================
|
|
2050
|
+
// Private: Utilities
|
|
2051
|
+
// ==========================================================================
|
|
2052
|
+
notifySubscribersInternal() {
|
|
2053
|
+
notifySubscribers(this.reactiveSubscribers);
|
|
2054
|
+
}
|
|
1688
2055
|
log(...args) {
|
|
1689
2056
|
if (this.config.debug) {
|
|
1690
|
-
console.log("[
|
|
2057
|
+
console.log("[HaexVault SDK]", ...args);
|
|
1691
2058
|
}
|
|
1692
2059
|
}
|
|
1693
2060
|
};
|