@metamask-previews/ai-controllers 0.8.0-preview-4f4c98e → 0.8.0-preview-eb263b0ee
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/CHANGELOG.md +0 -1
- package/dist/AiDigestController-method-action-types.cjs +7 -0
- package/dist/AiDigestController-method-action-types.cjs.map +1 -0
- package/dist/{AiDigestController-method-action-types.d.ts → AiDigestController-method-action-types.d.cts} +2 -2
- package/dist/AiDigestController-method-action-types.d.cts.map +1 -0
- package/dist/AiDigestController-method-action-types.d.mts +49 -0
- package/dist/AiDigestController-method-action-types.d.mts.map +1 -0
- package/dist/{AiDigestController-method-action-types.js → AiDigestController-method-action-types.mjs} +1 -1
- package/dist/AiDigestController-method-action-types.mjs.map +1 -0
- package/dist/AiDigestController.cjs +173 -0
- package/dist/AiDigestController.cjs.map +1 -0
- package/dist/{AiDigestController.d.ts → AiDigestController.d.cts} +7 -7
- package/dist/AiDigestController.d.cts.map +1 -0
- package/dist/AiDigestController.d.mts +52 -0
- package/dist/AiDigestController.d.mts.map +1 -0
- package/dist/{AiDigestController.js → AiDigestController.mjs} +3 -3
- package/dist/AiDigestController.mjs.map +1 -0
- package/dist/AiDigestService.cjs +217 -0
- package/dist/AiDigestService.cjs.map +1 -0
- package/dist/{AiDigestService.d.ts → AiDigestService.d.cts} +2 -2
- package/dist/AiDigestService.d.cts.map +1 -0
- package/dist/AiDigestService.d.mts +40 -0
- package/dist/AiDigestService.d.mts.map +1 -0
- package/dist/{AiDigestService.js → AiDigestService.mjs} +3 -3
- package/dist/AiDigestService.mjs.map +1 -0
- package/dist/ai-digest-constants.cjs +13 -0
- package/dist/ai-digest-constants.cjs.map +1 -0
- package/dist/ai-digest-constants.d.cts +10 -0
- package/dist/ai-digest-constants.d.cts.map +1 -0
- package/dist/ai-digest-constants.d.mts +10 -0
- package/dist/ai-digest-constants.d.mts.map +1 -0
- package/dist/{ai-digest-constants.js → ai-digest-constants.mjs} +1 -1
- package/dist/ai-digest-constants.mjs.map +1 -0
- package/dist/ai-digest-types.cjs +6 -0
- package/dist/ai-digest-types.cjs.map +1 -0
- package/dist/{ai-digest-types.d.ts → ai-digest-types.d.cts} +1 -1
- package/dist/ai-digest-types.d.cts.map +1 -0
- package/dist/ai-digest-types.d.mts +214 -0
- package/dist/ai-digest-types.d.mts.map +1 -0
- package/dist/{ai-digest-types.js → ai-digest-types.mjs} +1 -1
- package/dist/ai-digest-types.mjs.map +1 -0
- package/dist/index.cjs +14 -0
- package/dist/index.cjs.map +1 -0
- package/dist/{index.d.ts → index.d.cts} +8 -8
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +8 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +4 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +16 -12
- package/dist/AiDigestController-method-action-types.d.ts.map +0 -1
- package/dist/AiDigestController-method-action-types.js.map +0 -1
- package/dist/AiDigestController.d.ts.map +0 -1
- package/dist/AiDigestController.js.map +0 -1
- package/dist/AiDigestService.d.ts.map +0 -1
- package/dist/AiDigestService.js.map +0 -1
- package/dist/ai-digest-constants.d.ts +0 -10
- package/dist/ai-digest-constants.d.ts.map +0 -1
- package/dist/ai-digest-constants.js.map +0 -1
- package/dist/ai-digest-types.d.ts.map +0 -1
- package/dist/ai-digest-types.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -4
- package/dist/index.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,7 +9,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
### Changed
|
|
11
11
|
|
|
12
|
-
- **BREAKING:** Bump minimum Node.js version to 22 ([#9168](https://github.com/MetaMask/core/pull/9168))
|
|
13
12
|
- Bump `@metamask/superstruct` from `^3.1.0` to `^3.4.1` ([#9754](https://github.com/MetaMask/core/pull/9754))
|
|
14
13
|
|
|
15
14
|
## [0.8.0]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AiDigestController-method-action-types.cjs","sourceRoot":"","sources":["../src/AiDigestController-method-action-types.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { AiDigestController } from './AiDigestController.js';\n\n/**\n * Fetches market insights for a given asset identifier.\n * Returns cached data if still fresh, otherwise calls the service.\n *\n * Accepts either a CAIP-19 asset type (e.g. `eip155:1/slip44:60`) or a perps\n * market symbol (e.g. `ETH`). The service handles choosing the correct API\n * query parameter automatically.\n *\n * @param assetIdentifier - The asset identifier (CAIP-19 ID or perps market symbol).\n * @returns The market insights report, or `null` if none exists.\n */\nexport type AiDigestControllerFetchMarketInsightsAction = {\n type: `AiDigestController:fetchMarketInsights`;\n handler: AiDigestController['fetchMarketInsights'];\n};\n\n/**\n * Fetches the market overview report.\n * Returns cached data if still fresh, otherwise calls the service.\n *\n * @returns The market overview report, or `null` if none exists.\n */\nexport type AiDigestControllerFetchMarketOverviewAction = {\n type: `AiDigestController:fetchMarketOverview`;\n handler: AiDigestController['fetchMarketOverview'];\n};\n\n/**\n * Fetches a single market overview front page by id.\n *\n * Unlike the market overview report (which only returns the latest items),\n * this resolves an older item that has since dropped out of the report, so\n * clients can render it directly (e.g. from a deep link).\n *\n * @param id - The front-page identifier (UUID).\n * @returns The market overview front page, or `null` if none exists.\n */\nexport type AiDigestControllerFetchFrontPageItemAction = {\n type: `AiDigestController:fetchFrontPageItem`;\n handler: AiDigestController['fetchFrontPageItem'];\n};\n\n/**\n * Union of all AiDigestController action types.\n */\nexport type AiDigestControllerMethodActions =\n | AiDigestControllerFetchMarketInsightsAction\n | AiDigestControllerFetchMarketOverviewAction\n | AiDigestControllerFetchFrontPageItemAction;\n"]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* This file is auto generated.
|
|
3
3
|
* Do not edit manually.
|
|
4
4
|
*/
|
|
5
|
-
import type { AiDigestController } from
|
|
5
|
+
import type { AiDigestController } from "./AiDigestController.cjs";
|
|
6
6
|
/**
|
|
7
7
|
* Fetches market insights for a given asset identifier.
|
|
8
8
|
* Returns cached data if still fresh, otherwise calls the service.
|
|
@@ -46,4 +46,4 @@ export type AiDigestControllerFetchFrontPageItemAction = {
|
|
|
46
46
|
* Union of all AiDigestController action types.
|
|
47
47
|
*/
|
|
48
48
|
export type AiDigestControllerMethodActions = AiDigestControllerFetchMarketInsightsAction | AiDigestControllerFetchMarketOverviewAction | AiDigestControllerFetchFrontPageItemAction;
|
|
49
|
-
//# sourceMappingURL=AiDigestController-method-action-types.d.
|
|
49
|
+
//# sourceMappingURL=AiDigestController-method-action-types.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AiDigestController-method-action-types.d.cts","sourceRoot":"","sources":["../src/AiDigestController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,iCAAgC;AAElE;;;;;;;;;;GAUG;AACH,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,wCAAwC,CAAC;IAC/C,OAAO,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;CACpD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,wCAAwC,CAAC;IAC/C,OAAO,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;CACpD,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,MAAM,0CAA0C,GAAG;IACvD,IAAI,EAAE,uCAAuC,CAAC;IAC9C,OAAO,EAAE,kBAAkB,CAAC,oBAAoB,CAAC,CAAC;CACnD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,+BAA+B,GACvC,2CAA2C,GAC3C,2CAA2C,GAC3C,0CAA0C,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is auto generated.
|
|
3
|
+
* Do not edit manually.
|
|
4
|
+
*/
|
|
5
|
+
import type { AiDigestController } from "./AiDigestController.mjs";
|
|
6
|
+
/**
|
|
7
|
+
* Fetches market insights for a given asset identifier.
|
|
8
|
+
* Returns cached data if still fresh, otherwise calls the service.
|
|
9
|
+
*
|
|
10
|
+
* Accepts either a CAIP-19 asset type (e.g. `eip155:1/slip44:60`) or a perps
|
|
11
|
+
* market symbol (e.g. `ETH`). The service handles choosing the correct API
|
|
12
|
+
* query parameter automatically.
|
|
13
|
+
*
|
|
14
|
+
* @param assetIdentifier - The asset identifier (CAIP-19 ID or perps market symbol).
|
|
15
|
+
* @returns The market insights report, or `null` if none exists.
|
|
16
|
+
*/
|
|
17
|
+
export type AiDigestControllerFetchMarketInsightsAction = {
|
|
18
|
+
type: `AiDigestController:fetchMarketInsights`;
|
|
19
|
+
handler: AiDigestController['fetchMarketInsights'];
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Fetches the market overview report.
|
|
23
|
+
* Returns cached data if still fresh, otherwise calls the service.
|
|
24
|
+
*
|
|
25
|
+
* @returns The market overview report, or `null` if none exists.
|
|
26
|
+
*/
|
|
27
|
+
export type AiDigestControllerFetchMarketOverviewAction = {
|
|
28
|
+
type: `AiDigestController:fetchMarketOverview`;
|
|
29
|
+
handler: AiDigestController['fetchMarketOverview'];
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Fetches a single market overview front page by id.
|
|
33
|
+
*
|
|
34
|
+
* Unlike the market overview report (which only returns the latest items),
|
|
35
|
+
* this resolves an older item that has since dropped out of the report, so
|
|
36
|
+
* clients can render it directly (e.g. from a deep link).
|
|
37
|
+
*
|
|
38
|
+
* @param id - The front-page identifier (UUID).
|
|
39
|
+
* @returns The market overview front page, or `null` if none exists.
|
|
40
|
+
*/
|
|
41
|
+
export type AiDigestControllerFetchFrontPageItemAction = {
|
|
42
|
+
type: `AiDigestController:fetchFrontPageItem`;
|
|
43
|
+
handler: AiDigestController['fetchFrontPageItem'];
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Union of all AiDigestController action types.
|
|
47
|
+
*/
|
|
48
|
+
export type AiDigestControllerMethodActions = AiDigestControllerFetchMarketInsightsAction | AiDigestControllerFetchMarketOverviewAction | AiDigestControllerFetchFrontPageItemAction;
|
|
49
|
+
//# sourceMappingURL=AiDigestController-method-action-types.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AiDigestController-method-action-types.d.mts","sourceRoot":"","sources":["../src/AiDigestController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,iCAAgC;AAElE;;;;;;;;;;GAUG;AACH,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,wCAAwC,CAAC;IAC/C,OAAO,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;CACpD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,wCAAwC,CAAC;IAC/C,OAAO,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;CACpD,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,MAAM,0CAA0C,GAAG;IACvD,IAAI,EAAE,uCAAuC,CAAC;IAC9C,OAAO,EAAE,kBAAkB,CAAC,oBAAoB,CAAC,CAAC;CACnD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,+BAA+B,GACvC,2CAA2C,GAC3C,2CAA2C,GAC3C,0CAA0C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AiDigestController-method-action-types.mjs","sourceRoot":"","sources":["../src/AiDigestController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { AiDigestController } from './AiDigestController.js';\n\n/**\n * Fetches market insights for a given asset identifier.\n * Returns cached data if still fresh, otherwise calls the service.\n *\n * Accepts either a CAIP-19 asset type (e.g. `eip155:1/slip44:60`) or a perps\n * market symbol (e.g. `ETH`). The service handles choosing the correct API\n * query parameter automatically.\n *\n * @param assetIdentifier - The asset identifier (CAIP-19 ID or perps market symbol).\n * @returns The market insights report, or `null` if none exists.\n */\nexport type AiDigestControllerFetchMarketInsightsAction = {\n type: `AiDigestController:fetchMarketInsights`;\n handler: AiDigestController['fetchMarketInsights'];\n};\n\n/**\n * Fetches the market overview report.\n * Returns cached data if still fresh, otherwise calls the service.\n *\n * @returns The market overview report, or `null` if none exists.\n */\nexport type AiDigestControllerFetchMarketOverviewAction = {\n type: `AiDigestController:fetchMarketOverview`;\n handler: AiDigestController['fetchMarketOverview'];\n};\n\n/**\n * Fetches a single market overview front page by id.\n *\n * Unlike the market overview report (which only returns the latest items),\n * this resolves an older item that has since dropped out of the report, so\n * clients can render it directly (e.g. from a deep link).\n *\n * @param id - The front-page identifier (UUID).\n * @returns The market overview front page, or `null` if none exists.\n */\nexport type AiDigestControllerFetchFrontPageItemAction = {\n type: `AiDigestController:fetchFrontPageItem`;\n handler: AiDigestController['fetchFrontPageItem'];\n};\n\n/**\n * Union of all AiDigestController action types.\n */\nexport type AiDigestControllerMethodActions =\n | AiDigestControllerFetchMarketInsightsAction\n | AiDigestControllerFetchMarketOverviewAction\n | AiDigestControllerFetchFrontPageItemAction;\n"]}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
+
};
|
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
+
};
|
|
13
|
+
var _AiDigestController_instances, _AiDigestController_digestService, _AiDigestController_evictStaleCachedEntries;
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.AiDigestController = exports.getDefaultAiDigestControllerState = void 0;
|
|
16
|
+
const base_controller_1 = require("@metamask/base-controller");
|
|
17
|
+
const ai_digest_constants_js_1 = require("./ai-digest-constants.cjs");
|
|
18
|
+
function getDefaultAiDigestControllerState() {
|
|
19
|
+
return {
|
|
20
|
+
marketInsights: {},
|
|
21
|
+
marketOverview: null,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
exports.getDefaultAiDigestControllerState = getDefaultAiDigestControllerState;
|
|
25
|
+
const aiDigestControllerMetadata = {
|
|
26
|
+
marketInsights: {
|
|
27
|
+
persist: true,
|
|
28
|
+
includeInDebugSnapshot: true,
|
|
29
|
+
includeInStateLogs: true,
|
|
30
|
+
usedInUi: true,
|
|
31
|
+
},
|
|
32
|
+
marketOverview: {
|
|
33
|
+
persist: true,
|
|
34
|
+
includeInDebugSnapshot: true,
|
|
35
|
+
includeInStateLogs: true,
|
|
36
|
+
usedInUi: true,
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
const MESSENGER_EXPOSED_METHODS = [
|
|
40
|
+
'fetchMarketInsights',
|
|
41
|
+
'fetchMarketOverview',
|
|
42
|
+
'fetchFrontPageItem',
|
|
43
|
+
];
|
|
44
|
+
class AiDigestController extends base_controller_1.BaseController {
|
|
45
|
+
constructor({ messenger, state, digestService }) {
|
|
46
|
+
super({
|
|
47
|
+
name: ai_digest_constants_js_1.controllerName,
|
|
48
|
+
metadata: aiDigestControllerMetadata,
|
|
49
|
+
state: {
|
|
50
|
+
...getDefaultAiDigestControllerState(),
|
|
51
|
+
...state,
|
|
52
|
+
},
|
|
53
|
+
messenger,
|
|
54
|
+
});
|
|
55
|
+
_AiDigestController_instances.add(this);
|
|
56
|
+
_AiDigestController_digestService.set(this, void 0);
|
|
57
|
+
__classPrivateFieldSet(this, _AiDigestController_digestService, digestService, "f");
|
|
58
|
+
this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Fetches market insights for a given asset identifier.
|
|
62
|
+
* Returns cached data if still fresh, otherwise calls the service.
|
|
63
|
+
*
|
|
64
|
+
* Accepts either a CAIP-19 asset type (e.g. `eip155:1/slip44:60`) or a perps
|
|
65
|
+
* market symbol (e.g. `ETH`). The service handles choosing the correct API
|
|
66
|
+
* query parameter automatically.
|
|
67
|
+
*
|
|
68
|
+
* @param assetIdentifier - The asset identifier (CAIP-19 ID or perps market symbol).
|
|
69
|
+
* @returns The market insights report, or `null` if none exists.
|
|
70
|
+
*/
|
|
71
|
+
async fetchMarketInsights(assetIdentifier) {
|
|
72
|
+
if (!assetIdentifier) {
|
|
73
|
+
throw new Error(ai_digest_constants_js_1.AiDigestControllerErrorMessage.INVALID_ASSET_IDENTIFIER);
|
|
74
|
+
}
|
|
75
|
+
const existing = this.state.marketInsights[assetIdentifier];
|
|
76
|
+
if (existing) {
|
|
77
|
+
const age = Date.now() - existing.fetchedAt;
|
|
78
|
+
if (age < ai_digest_constants_js_1.CACHE_DURATION_MS) {
|
|
79
|
+
return existing.data;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const data = await __classPrivateFieldGet(this, _AiDigestController_digestService, "f").searchDigest(assetIdentifier);
|
|
83
|
+
if (data === null) {
|
|
84
|
+
// No insights available for this asset — clear any stale cache entry
|
|
85
|
+
this.update((state) => {
|
|
86
|
+
delete state.marketInsights[assetIdentifier];
|
|
87
|
+
});
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
const entry = {
|
|
91
|
+
assetIdentifier,
|
|
92
|
+
fetchedAt: Date.now(),
|
|
93
|
+
data,
|
|
94
|
+
};
|
|
95
|
+
this.update((state) => {
|
|
96
|
+
state.marketInsights[assetIdentifier] = entry;
|
|
97
|
+
__classPrivateFieldGet(this, _AiDigestController_instances, "m", _AiDigestController_evictStaleCachedEntries).call(this, state.marketInsights);
|
|
98
|
+
});
|
|
99
|
+
return data;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Fetches the market overview report.
|
|
103
|
+
* Returns cached data if still fresh, otherwise calls the service.
|
|
104
|
+
*
|
|
105
|
+
* @returns The market overview report, or `null` if none exists.
|
|
106
|
+
*/
|
|
107
|
+
async fetchMarketOverview() {
|
|
108
|
+
const existing = this.state.marketOverview;
|
|
109
|
+
if (existing) {
|
|
110
|
+
const age = Date.now() - existing.fetchedAt;
|
|
111
|
+
if (age < ai_digest_constants_js_1.CACHE_DURATION_MS) {
|
|
112
|
+
return existing.data;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const data = await __classPrivateFieldGet(this, _AiDigestController_digestService, "f").fetchMarketOverview();
|
|
116
|
+
if (data === null) {
|
|
117
|
+
this.update((state) => {
|
|
118
|
+
state.marketOverview = null;
|
|
119
|
+
});
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
const entry = {
|
|
123
|
+
fetchedAt: Date.now(),
|
|
124
|
+
data,
|
|
125
|
+
};
|
|
126
|
+
this.update((state) => {
|
|
127
|
+
state.marketOverview = entry;
|
|
128
|
+
});
|
|
129
|
+
return data;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Fetches a single market overview front page by id.
|
|
133
|
+
*
|
|
134
|
+
* Unlike the market overview report (which only returns the latest items),
|
|
135
|
+
* this resolves an older item that has since dropped out of the report, so
|
|
136
|
+
* clients can render it directly (e.g. from a deep link).
|
|
137
|
+
*
|
|
138
|
+
* @param id - The front-page identifier (UUID).
|
|
139
|
+
* @returns The market overview front page, or `null` if none exists.
|
|
140
|
+
*/
|
|
141
|
+
async fetchFrontPageItem(id) {
|
|
142
|
+
if (!id) {
|
|
143
|
+
throw new Error(ai_digest_constants_js_1.AiDigestControllerErrorMessage.INVALID_FRONT_PAGE_ID);
|
|
144
|
+
}
|
|
145
|
+
return __classPrivateFieldGet(this, _AiDigestController_digestService, "f").fetchFrontPageItem(id);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
exports.AiDigestController = AiDigestController;
|
|
149
|
+
_AiDigestController_digestService = new WeakMap(), _AiDigestController_instances = new WeakSet(), _AiDigestController_evictStaleCachedEntries = function _AiDigestController_evictStaleCachedEntries(cache) {
|
|
150
|
+
const now = Date.now();
|
|
151
|
+
const entries = Object.entries(cache);
|
|
152
|
+
const keysToDelete = [];
|
|
153
|
+
const freshEntries = [];
|
|
154
|
+
for (const [key, entry] of entries) {
|
|
155
|
+
if (now - entry.fetchedAt >= ai_digest_constants_js_1.CACHE_DURATION_MS) {
|
|
156
|
+
keysToDelete.push(key);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
freshEntries.push([key, entry]);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (freshEntries.length > ai_digest_constants_js_1.MAX_CACHE_ENTRIES) {
|
|
163
|
+
freshEntries.sort((a, b) => a[1].fetchedAt - b[1].fetchedAt);
|
|
164
|
+
const entriesToRemove = freshEntries.length - ai_digest_constants_js_1.MAX_CACHE_ENTRIES;
|
|
165
|
+
for (let i = 0; i < entriesToRemove; i++) {
|
|
166
|
+
keysToDelete.push(freshEntries[i][0]);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
for (const key of keysToDelete) {
|
|
170
|
+
delete cache[key];
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
//# sourceMappingURL=AiDigestController.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AiDigestController.cjs","sourceRoot":"","sources":["../src/AiDigestController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n StateMetadata,\n ControllerStateChangeEvent,\n ControllerGetStateAction,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\n\nimport {\n AiDigestControllerErrorMessage,\n controllerName,\n CACHE_DURATION_MS,\n MAX_CACHE_ENTRIES,\n} from './ai-digest-constants.js';\nimport type {\n AiDigestControllerState,\n DigestService,\n MarketInsightsReport,\n MarketInsightsEntry,\n MarketOverview,\n MarketOverviewEntry,\n MarketOverviewFrontPage,\n} from './ai-digest-types.js';\nimport type { AiDigestControllerMethodActions } from './AiDigestController-method-action-types.js';\n\nexport type AiDigestControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AiDigestControllerState\n>;\n\nexport type AiDigestControllerActions =\n | AiDigestControllerGetStateAction\n | AiDigestControllerMethodActions;\n\nexport type AiDigestControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n AiDigestControllerState\n>;\n\nexport type AiDigestControllerEvents = AiDigestControllerStateChangeEvent;\n\nexport type AiDigestControllerMessenger = Messenger<\n typeof controllerName,\n AiDigestControllerActions,\n AiDigestControllerEvents\n>;\n\nexport type AiDigestControllerOptions = {\n messenger: AiDigestControllerMessenger;\n state?: Partial<AiDigestControllerState>;\n digestService: DigestService;\n};\n\nexport function getDefaultAiDigestControllerState(): AiDigestControllerState {\n return {\n marketInsights: {},\n marketOverview: null,\n };\n}\n\nconst aiDigestControllerMetadata: StateMetadata<AiDigestControllerState> = {\n marketInsights: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n marketOverview: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n};\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'fetchMarketInsights',\n 'fetchMarketOverview',\n 'fetchFrontPageItem',\n] as const;\n\nexport class AiDigestController extends BaseController<\n typeof controllerName,\n AiDigestControllerState,\n AiDigestControllerMessenger\n> {\n readonly #digestService: DigestService;\n\n constructor({ messenger, state, digestService }: AiDigestControllerOptions) {\n super({\n name: controllerName,\n metadata: aiDigestControllerMetadata,\n state: {\n ...getDefaultAiDigestControllerState(),\n ...state,\n },\n messenger,\n });\n\n this.#digestService = digestService;\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Fetches market insights for a given asset identifier.\n * Returns cached data if still fresh, otherwise calls the service.\n *\n * Accepts either a CAIP-19 asset type (e.g. `eip155:1/slip44:60`) or a perps\n * market symbol (e.g. `ETH`). The service handles choosing the correct API\n * query parameter automatically.\n *\n * @param assetIdentifier - The asset identifier (CAIP-19 ID or perps market symbol).\n * @returns The market insights report, or `null` if none exists.\n */\n async fetchMarketInsights(\n assetIdentifier: string,\n ): Promise<MarketInsightsReport | null> {\n if (!assetIdentifier) {\n throw new Error(AiDigestControllerErrorMessage.INVALID_ASSET_IDENTIFIER);\n }\n\n const existing = this.state.marketInsights[assetIdentifier];\n if (existing) {\n const age = Date.now() - existing.fetchedAt;\n if (age < CACHE_DURATION_MS) {\n return existing.data;\n }\n }\n\n const data = await this.#digestService.searchDigest(assetIdentifier);\n\n if (data === null) {\n // No insights available for this asset — clear any stale cache entry\n this.update((state) => {\n delete state.marketInsights[assetIdentifier];\n });\n return null;\n }\n\n const entry: MarketInsightsEntry = {\n assetIdentifier,\n fetchedAt: Date.now(),\n data,\n };\n\n this.update((state) => {\n state.marketInsights[assetIdentifier] = entry;\n this.#evictStaleCachedEntries(state.marketInsights);\n });\n\n return data;\n }\n\n /**\n * Fetches the market overview report.\n * Returns cached data if still fresh, otherwise calls the service.\n *\n * @returns The market overview report, or `null` if none exists.\n */\n async fetchMarketOverview(): Promise<MarketOverview | null> {\n const existing = this.state.marketOverview;\n if (existing) {\n const age = Date.now() - existing.fetchedAt;\n if (age < CACHE_DURATION_MS) {\n return existing.data;\n }\n }\n\n const data = await this.#digestService.fetchMarketOverview();\n\n if (data === null) {\n this.update((state) => {\n state.marketOverview = null;\n });\n return null;\n }\n\n const entry: MarketOverviewEntry = {\n fetchedAt: Date.now(),\n data,\n };\n\n this.update((state) => {\n state.marketOverview = entry;\n });\n\n return data;\n }\n\n /**\n * Fetches a single market overview front page by id.\n *\n * Unlike the market overview report (which only returns the latest items),\n * this resolves an older item that has since dropped out of the report, so\n * clients can render it directly (e.g. from a deep link).\n *\n * @param id - The front-page identifier (UUID).\n * @returns The market overview front page, or `null` if none exists.\n */\n async fetchFrontPageItem(\n id: string,\n ): Promise<MarketOverviewFrontPage | null> {\n if (!id) {\n throw new Error(AiDigestControllerErrorMessage.INVALID_FRONT_PAGE_ID);\n }\n\n return this.#digestService.fetchFrontPageItem(id);\n }\n\n /**\n * Evicts stale (TTL expired) and oldest entries (FIFO) if cache exceeds max size.\n *\n * @param cache - The cache record to evict entries from.\n */\n #evictStaleCachedEntries<EntryType extends { fetchedAt: number }>(\n cache: Record<string, EntryType>,\n ): void {\n const now = Date.now();\n const entries = Object.entries(cache);\n const keysToDelete: string[] = [];\n const freshEntries: [string, EntryType][] = [];\n\n for (const [key, entry] of entries) {\n if (now - entry.fetchedAt >= CACHE_DURATION_MS) {\n keysToDelete.push(key);\n } else {\n freshEntries.push([key, entry]);\n }\n }\n\n if (freshEntries.length > MAX_CACHE_ENTRIES) {\n freshEntries.sort((a, b) => a[1].fetchedAt - b[1].fetchedAt);\n const entriesToRemove = freshEntries.length - MAX_CACHE_ENTRIES;\n for (let i = 0; i < entriesToRemove; i++) {\n keysToDelete.push(freshEntries[i][0]);\n }\n }\n\n for (const key of keysToDelete) {\n delete cache[key];\n }\n }\n}\n"]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { ControllerStateChangeEvent, ControllerGetStateAction } from
|
|
2
|
-
import { BaseController } from
|
|
3
|
-
import type { Messenger } from
|
|
4
|
-
import { controllerName } from
|
|
5
|
-
import type { AiDigestControllerState, DigestService, MarketInsightsReport, MarketOverview, MarketOverviewFrontPage } from
|
|
6
|
-
import type { AiDigestControllerMethodActions } from
|
|
1
|
+
import type { ControllerStateChangeEvent, ControllerGetStateAction } from "@metamask/base-controller";
|
|
2
|
+
import { BaseController } from "@metamask/base-controller";
|
|
3
|
+
import type { Messenger } from "@metamask/messenger";
|
|
4
|
+
import { controllerName } from "./ai-digest-constants.cjs";
|
|
5
|
+
import type { AiDigestControllerState, DigestService, MarketInsightsReport, MarketOverview, MarketOverviewFrontPage } from "./ai-digest-types.cjs";
|
|
6
|
+
import type { AiDigestControllerMethodActions } from "./AiDigestController-method-action-types.cjs";
|
|
7
7
|
export type AiDigestControllerGetStateAction = ControllerGetStateAction<typeof controllerName, AiDigestControllerState>;
|
|
8
8
|
export type AiDigestControllerActions = AiDigestControllerGetStateAction | AiDigestControllerMethodActions;
|
|
9
9
|
export type AiDigestControllerStateChangeEvent = ControllerStateChangeEvent<typeof controllerName, AiDigestControllerState>;
|
|
@@ -49,4 +49,4 @@ export declare class AiDigestController extends BaseController<typeof controller
|
|
|
49
49
|
*/
|
|
50
50
|
fetchFrontPageItem(id: string): Promise<MarketOverviewFrontPage | null>;
|
|
51
51
|
}
|
|
52
|
-
//# sourceMappingURL=AiDigestController.d.
|
|
52
|
+
//# sourceMappingURL=AiDigestController.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AiDigestController.d.cts","sourceRoot":"","sources":["../src/AiDigestController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,0BAA0B,EAC1B,wBAAwB,EACzB,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAErD,OAAO,EAEL,cAAc,EAGf,kCAAiC;AAClC,OAAO,KAAK,EACV,uBAAuB,EACvB,aAAa,EACb,oBAAoB,EAEpB,cAAc,EAEd,uBAAuB,EACxB,8BAA6B;AAC9B,OAAO,KAAK,EAAE,+BAA+B,EAAE,qDAAoD;AAEnG,MAAM,MAAM,gCAAgC,GAAG,wBAAwB,CACrE,OAAO,cAAc,EACrB,uBAAuB,CACxB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GACjC,gCAAgC,GAChC,+BAA+B,CAAC;AAEpC,MAAM,MAAM,kCAAkC,GAAG,0BAA0B,CACzE,OAAO,cAAc,EACrB,uBAAuB,CACxB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,kCAAkC,CAAC;AAE1E,MAAM,MAAM,2BAA2B,GAAG,SAAS,CACjD,OAAO,cAAc,EACrB,yBAAyB,EACzB,wBAAwB,CACzB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,SAAS,EAAE,2BAA2B,CAAC;IACvC,KAAK,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAC;IACzC,aAAa,EAAE,aAAa,CAAC;CAC9B,CAAC;AAEF,wBAAgB,iCAAiC,IAAI,uBAAuB,CAK3E;AAuBD,qBAAa,kBAAmB,SAAQ,cAAc,CACpD,OAAO,cAAc,EACrB,uBAAuB,EACvB,2BAA2B,CAC5B;;gBAGa,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,yBAAyB;IAkB1E;;;;;;;;;;OAUG;IACG,mBAAmB,CACvB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAqCvC;;;;;OAKG;IACG,mBAAmB,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IA8B3D;;;;;;;;;OASG;IACG,kBAAkB,CACtB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC;CAyC3C"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { ControllerStateChangeEvent, ControllerGetStateAction } from "@metamask/base-controller";
|
|
2
|
+
import { BaseController } from "@metamask/base-controller";
|
|
3
|
+
import type { Messenger } from "@metamask/messenger";
|
|
4
|
+
import { controllerName } from "./ai-digest-constants.mjs";
|
|
5
|
+
import type { AiDigestControllerState, DigestService, MarketInsightsReport, MarketOverview, MarketOverviewFrontPage } from "./ai-digest-types.mjs";
|
|
6
|
+
import type { AiDigestControllerMethodActions } from "./AiDigestController-method-action-types.mjs";
|
|
7
|
+
export type AiDigestControllerGetStateAction = ControllerGetStateAction<typeof controllerName, AiDigestControllerState>;
|
|
8
|
+
export type AiDigestControllerActions = AiDigestControllerGetStateAction | AiDigestControllerMethodActions;
|
|
9
|
+
export type AiDigestControllerStateChangeEvent = ControllerStateChangeEvent<typeof controllerName, AiDigestControllerState>;
|
|
10
|
+
export type AiDigestControllerEvents = AiDigestControllerStateChangeEvent;
|
|
11
|
+
export type AiDigestControllerMessenger = Messenger<typeof controllerName, AiDigestControllerActions, AiDigestControllerEvents>;
|
|
12
|
+
export type AiDigestControllerOptions = {
|
|
13
|
+
messenger: AiDigestControllerMessenger;
|
|
14
|
+
state?: Partial<AiDigestControllerState>;
|
|
15
|
+
digestService: DigestService;
|
|
16
|
+
};
|
|
17
|
+
export declare function getDefaultAiDigestControllerState(): AiDigestControllerState;
|
|
18
|
+
export declare class AiDigestController extends BaseController<typeof controllerName, AiDigestControllerState, AiDigestControllerMessenger> {
|
|
19
|
+
#private;
|
|
20
|
+
constructor({ messenger, state, digestService }: AiDigestControllerOptions);
|
|
21
|
+
/**
|
|
22
|
+
* Fetches market insights for a given asset identifier.
|
|
23
|
+
* Returns cached data if still fresh, otherwise calls the service.
|
|
24
|
+
*
|
|
25
|
+
* Accepts either a CAIP-19 asset type (e.g. `eip155:1/slip44:60`) or a perps
|
|
26
|
+
* market symbol (e.g. `ETH`). The service handles choosing the correct API
|
|
27
|
+
* query parameter automatically.
|
|
28
|
+
*
|
|
29
|
+
* @param assetIdentifier - The asset identifier (CAIP-19 ID or perps market symbol).
|
|
30
|
+
* @returns The market insights report, or `null` if none exists.
|
|
31
|
+
*/
|
|
32
|
+
fetchMarketInsights(assetIdentifier: string): Promise<MarketInsightsReport | null>;
|
|
33
|
+
/**
|
|
34
|
+
* Fetches the market overview report.
|
|
35
|
+
* Returns cached data if still fresh, otherwise calls the service.
|
|
36
|
+
*
|
|
37
|
+
* @returns The market overview report, or `null` if none exists.
|
|
38
|
+
*/
|
|
39
|
+
fetchMarketOverview(): Promise<MarketOverview | null>;
|
|
40
|
+
/**
|
|
41
|
+
* Fetches a single market overview front page by id.
|
|
42
|
+
*
|
|
43
|
+
* Unlike the market overview report (which only returns the latest items),
|
|
44
|
+
* this resolves an older item that has since dropped out of the report, so
|
|
45
|
+
* clients can render it directly (e.g. from a deep link).
|
|
46
|
+
*
|
|
47
|
+
* @param id - The front-page identifier (UUID).
|
|
48
|
+
* @returns The market overview front page, or `null` if none exists.
|
|
49
|
+
*/
|
|
50
|
+
fetchFrontPageItem(id: string): Promise<MarketOverviewFrontPage | null>;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=AiDigestController.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AiDigestController.d.mts","sourceRoot":"","sources":["../src/AiDigestController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,0BAA0B,EAC1B,wBAAwB,EACzB,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAErD,OAAO,EAEL,cAAc,EAGf,kCAAiC;AAClC,OAAO,KAAK,EACV,uBAAuB,EACvB,aAAa,EACb,oBAAoB,EAEpB,cAAc,EAEd,uBAAuB,EACxB,8BAA6B;AAC9B,OAAO,KAAK,EAAE,+BAA+B,EAAE,qDAAoD;AAEnG,MAAM,MAAM,gCAAgC,GAAG,wBAAwB,CACrE,OAAO,cAAc,EACrB,uBAAuB,CACxB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GACjC,gCAAgC,GAChC,+BAA+B,CAAC;AAEpC,MAAM,MAAM,kCAAkC,GAAG,0BAA0B,CACzE,OAAO,cAAc,EACrB,uBAAuB,CACxB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,kCAAkC,CAAC;AAE1E,MAAM,MAAM,2BAA2B,GAAG,SAAS,CACjD,OAAO,cAAc,EACrB,yBAAyB,EACzB,wBAAwB,CACzB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,SAAS,EAAE,2BAA2B,CAAC;IACvC,KAAK,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAC;IACzC,aAAa,EAAE,aAAa,CAAC;CAC9B,CAAC;AAEF,wBAAgB,iCAAiC,IAAI,uBAAuB,CAK3E;AAuBD,qBAAa,kBAAmB,SAAQ,cAAc,CACpD,OAAO,cAAc,EACrB,uBAAuB,EACvB,2BAA2B,CAC5B;;gBAGa,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,yBAAyB;IAkB1E;;;;;;;;;;OAUG;IACG,mBAAmB,CACvB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAqCvC;;;;;OAKG;IACG,mBAAmB,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IA8B3D;;;;;;;;;OASG;IACG,kBAAkB,CACtB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC;CAyC3C"}
|
|
@@ -10,8 +10,8 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
12
|
var _AiDigestController_instances, _AiDigestController_digestService, _AiDigestController_evictStaleCachedEntries;
|
|
13
|
-
import { BaseController } from
|
|
14
|
-
import { AiDigestControllerErrorMessage, controllerName, CACHE_DURATION_MS, MAX_CACHE_ENTRIES
|
|
13
|
+
import { BaseController } from "@metamask/base-controller";
|
|
14
|
+
import { AiDigestControllerErrorMessage, controllerName, CACHE_DURATION_MS, MAX_CACHE_ENTRIES } from "./ai-digest-constants.mjs";
|
|
15
15
|
export function getDefaultAiDigestControllerState() {
|
|
16
16
|
return {
|
|
17
17
|
marketInsights: {},
|
|
@@ -165,4 +165,4 @@ _AiDigestController_digestService = new WeakMap(), _AiDigestController_instances
|
|
|
165
165
|
delete cache[key];
|
|
166
166
|
}
|
|
167
167
|
};
|
|
168
|
-
//# sourceMappingURL=AiDigestController.
|
|
168
|
+
//# sourceMappingURL=AiDigestController.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AiDigestController.mjs","sourceRoot":"","sources":["../src/AiDigestController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n StateMetadata,\n ControllerStateChangeEvent,\n ControllerGetStateAction,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\n\nimport {\n AiDigestControllerErrorMessage,\n controllerName,\n CACHE_DURATION_MS,\n MAX_CACHE_ENTRIES,\n} from './ai-digest-constants.js';\nimport type {\n AiDigestControllerState,\n DigestService,\n MarketInsightsReport,\n MarketInsightsEntry,\n MarketOverview,\n MarketOverviewEntry,\n MarketOverviewFrontPage,\n} from './ai-digest-types.js';\nimport type { AiDigestControllerMethodActions } from './AiDigestController-method-action-types.js';\n\nexport type AiDigestControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AiDigestControllerState\n>;\n\nexport type AiDigestControllerActions =\n | AiDigestControllerGetStateAction\n | AiDigestControllerMethodActions;\n\nexport type AiDigestControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n AiDigestControllerState\n>;\n\nexport type AiDigestControllerEvents = AiDigestControllerStateChangeEvent;\n\nexport type AiDigestControllerMessenger = Messenger<\n typeof controllerName,\n AiDigestControllerActions,\n AiDigestControllerEvents\n>;\n\nexport type AiDigestControllerOptions = {\n messenger: AiDigestControllerMessenger;\n state?: Partial<AiDigestControllerState>;\n digestService: DigestService;\n};\n\nexport function getDefaultAiDigestControllerState(): AiDigestControllerState {\n return {\n marketInsights: {},\n marketOverview: null,\n };\n}\n\nconst aiDigestControllerMetadata: StateMetadata<AiDigestControllerState> = {\n marketInsights: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n marketOverview: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n};\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'fetchMarketInsights',\n 'fetchMarketOverview',\n 'fetchFrontPageItem',\n] as const;\n\nexport class AiDigestController extends BaseController<\n typeof controllerName,\n AiDigestControllerState,\n AiDigestControllerMessenger\n> {\n readonly #digestService: DigestService;\n\n constructor({ messenger, state, digestService }: AiDigestControllerOptions) {\n super({\n name: controllerName,\n metadata: aiDigestControllerMetadata,\n state: {\n ...getDefaultAiDigestControllerState(),\n ...state,\n },\n messenger,\n });\n\n this.#digestService = digestService;\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Fetches market insights for a given asset identifier.\n * Returns cached data if still fresh, otherwise calls the service.\n *\n * Accepts either a CAIP-19 asset type (e.g. `eip155:1/slip44:60`) or a perps\n * market symbol (e.g. `ETH`). The service handles choosing the correct API\n * query parameter automatically.\n *\n * @param assetIdentifier - The asset identifier (CAIP-19 ID or perps market symbol).\n * @returns The market insights report, or `null` if none exists.\n */\n async fetchMarketInsights(\n assetIdentifier: string,\n ): Promise<MarketInsightsReport | null> {\n if (!assetIdentifier) {\n throw new Error(AiDigestControllerErrorMessage.INVALID_ASSET_IDENTIFIER);\n }\n\n const existing = this.state.marketInsights[assetIdentifier];\n if (existing) {\n const age = Date.now() - existing.fetchedAt;\n if (age < CACHE_DURATION_MS) {\n return existing.data;\n }\n }\n\n const data = await this.#digestService.searchDigest(assetIdentifier);\n\n if (data === null) {\n // No insights available for this asset — clear any stale cache entry\n this.update((state) => {\n delete state.marketInsights[assetIdentifier];\n });\n return null;\n }\n\n const entry: MarketInsightsEntry = {\n assetIdentifier,\n fetchedAt: Date.now(),\n data,\n };\n\n this.update((state) => {\n state.marketInsights[assetIdentifier] = entry;\n this.#evictStaleCachedEntries(state.marketInsights);\n });\n\n return data;\n }\n\n /**\n * Fetches the market overview report.\n * Returns cached data if still fresh, otherwise calls the service.\n *\n * @returns The market overview report, or `null` if none exists.\n */\n async fetchMarketOverview(): Promise<MarketOverview | null> {\n const existing = this.state.marketOverview;\n if (existing) {\n const age = Date.now() - existing.fetchedAt;\n if (age < CACHE_DURATION_MS) {\n return existing.data;\n }\n }\n\n const data = await this.#digestService.fetchMarketOverview();\n\n if (data === null) {\n this.update((state) => {\n state.marketOverview = null;\n });\n return null;\n }\n\n const entry: MarketOverviewEntry = {\n fetchedAt: Date.now(),\n data,\n };\n\n this.update((state) => {\n state.marketOverview = entry;\n });\n\n return data;\n }\n\n /**\n * Fetches a single market overview front page by id.\n *\n * Unlike the market overview report (which only returns the latest items),\n * this resolves an older item that has since dropped out of the report, so\n * clients can render it directly (e.g. from a deep link).\n *\n * @param id - The front-page identifier (UUID).\n * @returns The market overview front page, or `null` if none exists.\n */\n async fetchFrontPageItem(\n id: string,\n ): Promise<MarketOverviewFrontPage | null> {\n if (!id) {\n throw new Error(AiDigestControllerErrorMessage.INVALID_FRONT_PAGE_ID);\n }\n\n return this.#digestService.fetchFrontPageItem(id);\n }\n\n /**\n * Evicts stale (TTL expired) and oldest entries (FIFO) if cache exceeds max size.\n *\n * @param cache - The cache record to evict entries from.\n */\n #evictStaleCachedEntries<EntryType extends { fetchedAt: number }>(\n cache: Record<string, EntryType>,\n ): void {\n const now = Date.now();\n const entries = Object.entries(cache);\n const keysToDelete: string[] = [];\n const freshEntries: [string, EntryType][] = [];\n\n for (const [key, entry] of entries) {\n if (now - entry.fetchedAt >= CACHE_DURATION_MS) {\n keysToDelete.push(key);\n } else {\n freshEntries.push([key, entry]);\n }\n }\n\n if (freshEntries.length > MAX_CACHE_ENTRIES) {\n freshEntries.sort((a, b) => a[1].fetchedAt - b[1].fetchedAt);\n const entriesToRemove = freshEntries.length - MAX_CACHE_ENTRIES;\n for (let i = 0; i < entriesToRemove; i++) {\n keysToDelete.push(freshEntries[i][0]);\n }\n }\n\n for (const key of keysToDelete) {\n delete cache[key];\n }\n }\n}\n"]}
|