@trops/dash-core 0.1.15 → 0.1.17
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/electron/index.js +220 -2
- package/dist/electron/index.js.map +1 -1
- package/dist/index.esm.js +30 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/electron/index.js
CHANGED
|
@@ -4135,7 +4135,7 @@ const {
|
|
|
4135
4135
|
const appName$2 = "Dashboard";
|
|
4136
4136
|
const configFilename$2 = "providers.json";
|
|
4137
4137
|
|
|
4138
|
-
const providerController$
|
|
4138
|
+
const providerController$2 = {
|
|
4139
4139
|
/**
|
|
4140
4140
|
* saveProvider
|
|
4141
4141
|
* Save a new provider with encrypted credentials
|
|
@@ -4395,7 +4395,7 @@ const providerController$1 = {
|
|
|
4395
4395
|
},
|
|
4396
4396
|
};
|
|
4397
4397
|
|
|
4398
|
-
var providerController_1 = providerController$
|
|
4398
|
+
var providerController_1 = providerController$2;
|
|
4399
4399
|
|
|
4400
4400
|
const { app: app$2 } = require$$0;
|
|
4401
4401
|
const path$7 = require$$1$1;
|
|
@@ -5954,6 +5954,216 @@ const pluginController$1 = {
|
|
|
5954
5954
|
|
|
5955
5955
|
var pluginController_1 = pluginController$1;
|
|
5956
5956
|
|
|
5957
|
+
/**
|
|
5958
|
+
* clientCache
|
|
5959
|
+
*
|
|
5960
|
+
* Generic provider client cache for the main process.
|
|
5961
|
+
* Caches API clients (e.g., algoliasearch, Stripe) by provider hash.
|
|
5962
|
+
* Factories are registered per provider type; credentials are resolved
|
|
5963
|
+
* from the encrypted store — renderer never sends credential fields.
|
|
5964
|
+
*/
|
|
5965
|
+
|
|
5966
|
+
const providerController$1 = providerController_1;
|
|
5967
|
+
|
|
5968
|
+
const clients = new Map(); // hash → client
|
|
5969
|
+
const factories = new Map(); // providerType → factoryFn(credentials)
|
|
5970
|
+
const pendingClients = new Map(); // hash → Promise (dedup in-flight)
|
|
5971
|
+
const providerLookup = new Map(); // "appId:providerName" → hash (reverse lookup)
|
|
5972
|
+
|
|
5973
|
+
const clientCache$1 = {
|
|
5974
|
+
registerFactory(providerType, factoryFn) {
|
|
5975
|
+
factories.set(providerType, factoryFn);
|
|
5976
|
+
},
|
|
5977
|
+
|
|
5978
|
+
async getClient(providerHash, appId, providerName) {
|
|
5979
|
+
// Cache hit
|
|
5980
|
+
if (clients.has(providerHash)) {
|
|
5981
|
+
return clients.get(providerHash);
|
|
5982
|
+
}
|
|
5983
|
+
|
|
5984
|
+
// Dedup in-flight (same pattern as mcpController.pendingStarts)
|
|
5985
|
+
if (pendingClients.has(providerHash)) {
|
|
5986
|
+
return pendingClients.get(providerHash);
|
|
5987
|
+
}
|
|
5988
|
+
|
|
5989
|
+
const promise = this._resolve(providerHash, appId, providerName);
|
|
5990
|
+
pendingClients.set(providerHash, promise);
|
|
5991
|
+
try {
|
|
5992
|
+
return await promise;
|
|
5993
|
+
} finally {
|
|
5994
|
+
pendingClients.delete(providerHash);
|
|
5995
|
+
}
|
|
5996
|
+
},
|
|
5997
|
+
|
|
5998
|
+
async _resolve(providerHash, appId, providerName) {
|
|
5999
|
+
const result = providerController$1.getProvider(null, appId, providerName);
|
|
6000
|
+
if (result.error) throw new Error(result.message);
|
|
6001
|
+
|
|
6002
|
+
const { provider } = result;
|
|
6003
|
+
const factory = factories.get(provider.type);
|
|
6004
|
+
if (!factory) {
|
|
6005
|
+
throw new Error(`No client factory for type: ${provider.type}`);
|
|
6006
|
+
}
|
|
6007
|
+
|
|
6008
|
+
const client = factory(provider.credentials);
|
|
6009
|
+
clients.set(providerHash, client);
|
|
6010
|
+
providerLookup.set(`${appId}:${providerName}`, providerHash);
|
|
6011
|
+
console.log(
|
|
6012
|
+
`[clientCache] Created ${provider.type} client (hash: ${providerHash.slice(0, 8)}...)`
|
|
6013
|
+
);
|
|
6014
|
+
return client;
|
|
6015
|
+
},
|
|
6016
|
+
|
|
6017
|
+
invalidate(appId, providerName) {
|
|
6018
|
+
const lookupKey = `${appId}:${providerName}`;
|
|
6019
|
+
const hash = providerLookup.get(lookupKey);
|
|
6020
|
+
if (hash) {
|
|
6021
|
+
clients.delete(hash);
|
|
6022
|
+
providerLookup.delete(lookupKey);
|
|
6023
|
+
console.log(
|
|
6024
|
+
`[clientCache] Invalidated ${providerName} (hash: ${hash.slice(0, 8)}...)`
|
|
6025
|
+
);
|
|
6026
|
+
}
|
|
6027
|
+
},
|
|
6028
|
+
|
|
6029
|
+
invalidateAll() {
|
|
6030
|
+
const count = clients.size;
|
|
6031
|
+
clients.clear();
|
|
6032
|
+
providerLookup.clear();
|
|
6033
|
+
pendingClients.clear();
|
|
6034
|
+
console.log(
|
|
6035
|
+
`[clientCache] Invalidated all (${count} clients cleared)`
|
|
6036
|
+
);
|
|
6037
|
+
},
|
|
6038
|
+
|
|
6039
|
+
clear() {
|
|
6040
|
+
clients.clear();
|
|
6041
|
+
providerLookup.clear();
|
|
6042
|
+
pendingClients.clear();
|
|
6043
|
+
},
|
|
6044
|
+
};
|
|
6045
|
+
|
|
6046
|
+
var clientCache_1 = clientCache$1;
|
|
6047
|
+
|
|
6048
|
+
/**
|
|
6049
|
+
* responseCache.js
|
|
6050
|
+
*
|
|
6051
|
+
* TTL-based API response cache with in-flight deduplication.
|
|
6052
|
+
* Renderer-driven: widget developer includes { cache: true } or { cache: { ttl: N } }
|
|
6053
|
+
* in IPC messages to opt-in to caching per call.
|
|
6054
|
+
*
|
|
6055
|
+
* Usage:
|
|
6056
|
+
* // Wrap a handler:
|
|
6057
|
+
* ipcMain.handle("my-channel", responseCache.cachedHandler("my-channel", handler));
|
|
6058
|
+
*
|
|
6059
|
+
* // Widget-side (renderer):
|
|
6060
|
+
* window.mainApi.myService.getData({ ...pc, cache: true }); // 30s default
|
|
6061
|
+
* window.mainApi.myService.getData({ ...pc, cache: 60000 }); // 60s
|
|
6062
|
+
* window.mainApi.myService.getData({ ...pc, cache: { ttl: 120000 } }); // 120s
|
|
6063
|
+
* window.mainApi.myService.getData({ ...pc, cache: true, forceRefresh: true }); // bypass
|
|
6064
|
+
*/
|
|
6065
|
+
|
|
6066
|
+
const cache = new Map(); // key → { data, timestamp, ttl }
|
|
6067
|
+
const inflight = new Map(); // key → Promise
|
|
6068
|
+
|
|
6069
|
+
function stableHash(obj) {
|
|
6070
|
+
const str = JSON.stringify(obj, Object.keys(obj).sort());
|
|
6071
|
+
let hash = 5381;
|
|
6072
|
+
for (let i = 0; i < str.length; i++) {
|
|
6073
|
+
hash = ((hash << 5) + hash + str.charCodeAt(i)) & 0xffffffff;
|
|
6074
|
+
}
|
|
6075
|
+
return hash.toString(36);
|
|
6076
|
+
}
|
|
6077
|
+
|
|
6078
|
+
const responseCache$1 = {
|
|
6079
|
+
async get(key, fetcher, options = {}) {
|
|
6080
|
+
const { ttl = 30000, forceRefresh = false } = options;
|
|
6081
|
+
|
|
6082
|
+
if (!forceRefresh && cache.has(key)) {
|
|
6083
|
+
const entry = cache.get(key);
|
|
6084
|
+
if (Date.now() - entry.timestamp < entry.ttl) {
|
|
6085
|
+
console.log(`[responseCache] HIT ${key}`);
|
|
6086
|
+
return entry.data;
|
|
6087
|
+
}
|
|
6088
|
+
cache.delete(key);
|
|
6089
|
+
}
|
|
6090
|
+
|
|
6091
|
+
if (!forceRefresh && inflight.has(key)) {
|
|
6092
|
+
console.log(`[responseCache] DEDUP ${key}`);
|
|
6093
|
+
return inflight.get(key);
|
|
6094
|
+
}
|
|
6095
|
+
|
|
6096
|
+
console.log(`[responseCache] MISS ${key}`);
|
|
6097
|
+
const promise = fetcher();
|
|
6098
|
+
inflight.set(key, promise);
|
|
6099
|
+
try {
|
|
6100
|
+
const data = await promise;
|
|
6101
|
+
if (data && !data.error) {
|
|
6102
|
+
cache.set(key, { data, timestamp: Date.now(), ttl });
|
|
6103
|
+
}
|
|
6104
|
+
return data;
|
|
6105
|
+
} finally {
|
|
6106
|
+
inflight.delete(key);
|
|
6107
|
+
}
|
|
6108
|
+
},
|
|
6109
|
+
|
|
6110
|
+
/**
|
|
6111
|
+
* Wrap an ipcMain.handle handler with renderer-driven caching.
|
|
6112
|
+
* If the incoming message has a `cache` property, the response is cached.
|
|
6113
|
+
* If the message has `forceRefresh: true`, the cache is bypassed.
|
|
6114
|
+
*
|
|
6115
|
+
* The `cache` and `forceRefresh` properties are stripped from the message
|
|
6116
|
+
* before passing to the handler, so handlers receive clean params.
|
|
6117
|
+
*
|
|
6118
|
+
* Cache parameter forms:
|
|
6119
|
+
* cache: true → 30s default TTL
|
|
6120
|
+
* cache: 60000 → 60s (number shorthand)
|
|
6121
|
+
* cache: { ttl: N } → explicit TTL in ms
|
|
6122
|
+
*/
|
|
6123
|
+
cachedHandler(channelName, handler) {
|
|
6124
|
+
return async (e, msg) => {
|
|
6125
|
+
const { cache: cacheOpt, forceRefresh, ...params } = msg || {};
|
|
6126
|
+
if (cacheOpt) {
|
|
6127
|
+
const ttl =
|
|
6128
|
+
typeof cacheOpt === "number"
|
|
6129
|
+
? cacheOpt
|
|
6130
|
+
: cacheOpt?.ttl || 30000;
|
|
6131
|
+
const key = `${channelName}:${stableHash(params)}`;
|
|
6132
|
+
return this.get(key, () => handler(e, params), {
|
|
6133
|
+
ttl,
|
|
6134
|
+
forceRefresh,
|
|
6135
|
+
});
|
|
6136
|
+
}
|
|
6137
|
+
return handler(e, msg);
|
|
6138
|
+
};
|
|
6139
|
+
},
|
|
6140
|
+
|
|
6141
|
+
invalidate(key) {
|
|
6142
|
+
cache.delete(key);
|
|
6143
|
+
},
|
|
6144
|
+
|
|
6145
|
+
invalidatePrefix(prefix) {
|
|
6146
|
+
for (const k of cache.keys()) {
|
|
6147
|
+
if (k.startsWith(prefix)) cache.delete(k);
|
|
6148
|
+
}
|
|
6149
|
+
},
|
|
6150
|
+
|
|
6151
|
+
clear() {
|
|
6152
|
+
cache.clear();
|
|
6153
|
+
inflight.clear();
|
|
6154
|
+
},
|
|
6155
|
+
|
|
6156
|
+
stats() {
|
|
6157
|
+
return {
|
|
6158
|
+
entries: cache.size,
|
|
6159
|
+
inflight: inflight.size,
|
|
6160
|
+
keys: [...cache.keys()],
|
|
6161
|
+
};
|
|
6162
|
+
},
|
|
6163
|
+
};
|
|
6164
|
+
|
|
6165
|
+
var responseCache_1 = responseCache$1;
|
|
6166
|
+
|
|
5957
6167
|
/**
|
|
5958
6168
|
* Controller exports.
|
|
5959
6169
|
*/
|
|
@@ -8634,6 +8844,10 @@ const openaiController = openaiController_1;
|
|
|
8634
8844
|
const menuItemsController = menuItemsController_1;
|
|
8635
8845
|
const pluginController = pluginController_1;
|
|
8636
8846
|
|
|
8847
|
+
// --- Utils ---
|
|
8848
|
+
const clientCache = clientCache_1;
|
|
8849
|
+
const responseCache = responseCache_1;
|
|
8850
|
+
|
|
8637
8851
|
// --- Controller functions (flat, for convenient destructuring) ---
|
|
8638
8852
|
const controllers = controller;
|
|
8639
8853
|
|
|
@@ -8713,6 +8927,10 @@ var electron = {
|
|
|
8713
8927
|
// Factory
|
|
8714
8928
|
createMainApi,
|
|
8715
8929
|
defaultMainApi,
|
|
8930
|
+
|
|
8931
|
+
// Utils
|
|
8932
|
+
clientCache,
|
|
8933
|
+
responseCache,
|
|
8716
8934
|
};
|
|
8717
8935
|
|
|
8718
8936
|
var index = /*@__PURE__*/getDefaultExportFromCjs(electron);
|