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