@metamask-previews/ai-controllers 0.0.0-preview-33dbba4f3 → 0.0.0-preview-a196307b6
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 +2 -0
- package/dist/AiDigestController.cjs +77 -1
- package/dist/AiDigestController.cjs.map +1 -1
- package/dist/AiDigestController.d.cts +24 -2
- package/dist/AiDigestController.d.cts.map +1 -1
- package/dist/AiDigestController.d.mts +24 -2
- package/dist/AiDigestController.d.mts.map +1 -1
- package/dist/AiDigestController.mjs +77 -1
- package/dist/AiDigestController.mjs.map +1 -1
- package/dist/AiDigestService.cjs +19 -0
- package/dist/AiDigestService.cjs.map +1 -1
- package/dist/AiDigestService.d.cts +10 -1
- package/dist/AiDigestService.d.cts.map +1 -1
- package/dist/AiDigestService.d.mts +10 -1
- package/dist/AiDigestService.d.mts.map +1 -1
- package/dist/AiDigestService.mjs +19 -0
- package/dist/AiDigestService.mjs.map +1 -1
- package/dist/ai-digest-types.cjs.map +1 -1
- package/dist/ai-digest-types.d.cts +94 -0
- package/dist/ai-digest-types.d.cts.map +1 -1
- package/dist/ai-digest-types.d.mts +94 -0
- package/dist/ai-digest-types.d.mts.map +1 -1
- package/dist/ai-digest-types.mjs.map +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -11,5 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
11
11
|
|
|
12
12
|
- Initial release ([#7693](https://github.com/MetaMask/core/pull/7693))
|
|
13
13
|
- Add `AiDigestController` for fetching and caching AI-generated asset digests ([#7746](https://github.com/MetaMask/core/pull/7746))
|
|
14
|
+
- Add Market Insights support to `AiDigestController` with `fetchMarketInsights` and `clearMarketInsights` actions ([#7930](https://github.com/MetaMask/core/pull/7930))
|
|
15
|
+
- Add `searchDigests` method to `AiDigestService` for calling the GET endpoint (currently mocked) ([#7930](https://github.com/MetaMask/core/pull/7930))
|
|
14
16
|
|
|
15
17
|
[Unreleased]: https://github.com/MetaMask/core/
|
|
@@ -10,7 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
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
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
12
|
};
|
|
13
|
-
var _AiDigestController_instances, _AiDigestController_digestService, _AiDigestController_registerMessageHandlers, _AiDigestController_evictStaleEntries;
|
|
13
|
+
var _AiDigestController_instances, _AiDigestController_digestService, _AiDigestController_registerMessageHandlers, _AiDigestController_evictStaleEntries, _AiDigestController_evictStaleMarketInsightsEntries;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.AiDigestController = exports.getDefaultAiDigestControllerState = void 0;
|
|
16
16
|
const base_controller_1 = require("@metamask/base-controller");
|
|
@@ -18,6 +18,7 @@ const ai_digest_constants_1 = require("./ai-digest-constants.cjs");
|
|
|
18
18
|
function getDefaultAiDigestControllerState() {
|
|
19
19
|
return {
|
|
20
20
|
digests: {},
|
|
21
|
+
marketInsights: {},
|
|
21
22
|
};
|
|
22
23
|
}
|
|
23
24
|
exports.getDefaultAiDigestControllerState = getDefaultAiDigestControllerState;
|
|
@@ -28,6 +29,12 @@ const aiDigestControllerMetadata = {
|
|
|
28
29
|
includeInStateLogs: true,
|
|
29
30
|
usedInUi: true,
|
|
30
31
|
},
|
|
32
|
+
marketInsights: {
|
|
33
|
+
persist: true,
|
|
34
|
+
includeInDebugSnapshot: true,
|
|
35
|
+
includeInStateLogs: true,
|
|
36
|
+
usedInUi: true,
|
|
37
|
+
},
|
|
31
38
|
};
|
|
32
39
|
class AiDigestController extends base_controller_1.BaseController {
|
|
33
40
|
constructor({ messenger, state, digestService }) {
|
|
@@ -75,12 +82,58 @@ class AiDigestController extends base_controller_1.BaseController {
|
|
|
75
82
|
state.digests = {};
|
|
76
83
|
});
|
|
77
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Fetches market insights for a given CAIP-19 asset identifier.
|
|
87
|
+
* Returns cached data if still fresh, otherwise calls the service.
|
|
88
|
+
*
|
|
89
|
+
* @param caip19Id - The CAIP-19 identifier of the asset.
|
|
90
|
+
* @returns The market insights report, or `null` if none exists.
|
|
91
|
+
*/
|
|
92
|
+
async fetchMarketInsights(caip19Id) {
|
|
93
|
+
const existing = this.state.marketInsights[caip19Id];
|
|
94
|
+
if (existing) {
|
|
95
|
+
const age = Date.now() - existing.fetchedAt;
|
|
96
|
+
if (age < ai_digest_constants_1.CACHE_DURATION_MS) {
|
|
97
|
+
return existing.data;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const data = await __classPrivateFieldGet(this, _AiDigestController_digestService, "f").searchDigests(caip19Id);
|
|
101
|
+
if (data === null) {
|
|
102
|
+
// No insights available for this asset — clear any stale cache entry
|
|
103
|
+
this.update((state) => {
|
|
104
|
+
delete state.marketInsights[caip19Id];
|
|
105
|
+
});
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
const entry = {
|
|
109
|
+
caip19Id,
|
|
110
|
+
fetchedAt: Date.now(),
|
|
111
|
+
data,
|
|
112
|
+
};
|
|
113
|
+
this.update((state) => {
|
|
114
|
+
state.marketInsights[caip19Id] = entry;
|
|
115
|
+
__classPrivateFieldGet(this, _AiDigestController_instances, "m", _AiDigestController_evictStaleMarketInsightsEntries).call(this, state);
|
|
116
|
+
});
|
|
117
|
+
return data;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Clears the cached market insights for a specific CAIP-19 asset.
|
|
121
|
+
*
|
|
122
|
+
* @param caip19Id - The CAIP-19 identifier.
|
|
123
|
+
*/
|
|
124
|
+
clearMarketInsights(caip19Id) {
|
|
125
|
+
this.update((state) => {
|
|
126
|
+
delete state.marketInsights[caip19Id];
|
|
127
|
+
});
|
|
128
|
+
}
|
|
78
129
|
}
|
|
79
130
|
exports.AiDigestController = AiDigestController;
|
|
80
131
|
_AiDigestController_digestService = new WeakMap(), _AiDigestController_instances = new WeakSet(), _AiDigestController_registerMessageHandlers = function _AiDigestController_registerMessageHandlers() {
|
|
81
132
|
this.messenger.registerActionHandler(`${ai_digest_constants_1.controllerName}:fetchDigest`, this.fetchDigest.bind(this));
|
|
82
133
|
this.messenger.registerActionHandler(`${ai_digest_constants_1.controllerName}:clearDigest`, this.clearDigest.bind(this));
|
|
83
134
|
this.messenger.registerActionHandler(`${ai_digest_constants_1.controllerName}:clearAllDigests`, this.clearAllDigests.bind(this));
|
|
135
|
+
this.messenger.registerActionHandler(`${ai_digest_constants_1.controllerName}:fetchMarketInsights`, this.fetchMarketInsights.bind(this));
|
|
136
|
+
this.messenger.registerActionHandler(`${ai_digest_constants_1.controllerName}:clearMarketInsights`, this.clearMarketInsights.bind(this));
|
|
84
137
|
}, _AiDigestController_evictStaleEntries = function _AiDigestController_evictStaleEntries(state) {
|
|
85
138
|
const now = Date.now();
|
|
86
139
|
const entries = Object.entries(state.digests);
|
|
@@ -105,5 +158,28 @@ _AiDigestController_digestService = new WeakMap(), _AiDigestController_instances
|
|
|
105
158
|
for (const key of keysToDelete) {
|
|
106
159
|
delete state.digests[key];
|
|
107
160
|
}
|
|
161
|
+
}, _AiDigestController_evictStaleMarketInsightsEntries = function _AiDigestController_evictStaleMarketInsightsEntries(state) {
|
|
162
|
+
const now = Date.now();
|
|
163
|
+
const entries = Object.entries(state.marketInsights);
|
|
164
|
+
const keysToDelete = [];
|
|
165
|
+
const freshEntries = [];
|
|
166
|
+
for (const [key, entry] of entries) {
|
|
167
|
+
if (now - entry.fetchedAt >= ai_digest_constants_1.CACHE_DURATION_MS) {
|
|
168
|
+
keysToDelete.push(key);
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
freshEntries.push([key, entry]);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
if (freshEntries.length > ai_digest_constants_1.MAX_CACHE_ENTRIES) {
|
|
175
|
+
freshEntries.sort((a, b) => a[1].fetchedAt - b[1].fetchedAt);
|
|
176
|
+
const entriesToRemove = freshEntries.length - ai_digest_constants_1.MAX_CACHE_ENTRIES;
|
|
177
|
+
for (let i = 0; i < entriesToRemove; i++) {
|
|
178
|
+
keysToDelete.push(freshEntries[i][0]);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
for (const key of keysToDelete) {
|
|
182
|
+
delete state.marketInsights[key];
|
|
183
|
+
}
|
|
108
184
|
};
|
|
109
185
|
//# sourceMappingURL=AiDigestController.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiDigestController.cjs","sourceRoot":"","sources":["../src/AiDigestController.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAKA,+DAA2D;AAG3D,mEAI+B;AAqD/B,SAAgB,iCAAiC;IAC/C,OAAO;QACL,OAAO,EAAE,EAAE;KACZ,CAAC;AACJ,CAAC;AAJD,8EAIC;AAED,MAAM,0BAA0B,GAA2C;IACzE,OAAO,EAAE;QACP,OAAO,EAAE,IAAI;QACb,sBAAsB,EAAE,IAAI;QAC5B,kBAAkB,EAAE,IAAI;QACxB,QAAQ,EAAE,IAAI;KACf;CACF,CAAC;AAEF,MAAa,kBAAmB,SAAQ,gCAIvC;IAGC,YAAY,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAA6B;QACxE,KAAK,CAAC;YACJ,IAAI,EAAE,oCAAc;YACpB,QAAQ,EAAE,0BAA0B;YACpC,KAAK,EAAE;gBACL,GAAG,iCAAiC,EAAE;gBACtC,GAAG,KAAK;aACT;YACD,SAAS;SACV,CAAC,CAAC;;QAXI,oDAA8B;QAarC,uBAAA,IAAI,qCAAkB,aAAa,MAAA,CAAC;QACpC,uBAAA,IAAI,kFAAyB,MAA7B,IAAI,CAA2B,CAAC;IAClC,CAAC;IAiBD,KAAK,CAAC,WAAW,CAAC,OAAe;QAC/B,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACnD,IAAI,cAAc,EAAE,CAAC;YACnB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,cAAc,CAAC,SAAS,CAAC;YAClD,IAAI,GAAG,GAAG,uCAAiB,EAAE,CAAC;gBAC5B,OAAO,cAAc,CAAC,IAAI,CAAC;YAC7B,CAAC;QACH,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,uBAAA,IAAI,yCAAe,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAE5D,MAAM,KAAK,GAAgB;YACzB,KAAK,EAAE,OAAO;YACd,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,IAAI;SACL,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC;YAC/B,uBAAA,IAAI,4EAAmB,MAAvB,IAAI,EAAoB,KAAK,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC;IACd,CAAC;IAED,WAAW,CAAC,OAAe;QACzB,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,OAAO,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,eAAe;QACb,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC;QACrB,CAAC,CAAC,CAAC;IACL,CAAC;CAkCF;AA1GD,gDA0GC;;IAnFG,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAClC,GAAG,oCAAc,cAAc,EAC/B,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAC5B,CAAC;IACF,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAClC,GAAG,oCAAc,cAAc,EAC/B,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAC5B,CAAC;IACF,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAClC,GAAG,oCAAc,kBAAkB,EACnC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAChC,CAAC;AACJ,CAAC,yFA4CkB,KAA8B;IAC/C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,YAAY,GAAa,EAAE,CAAC;IAClC,MAAM,YAAY,GAA4B,EAAE,CAAC;IAEjD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,OAAO,EAAE,CAAC;QACnC,IAAI,GAAG,GAAG,KAAK,CAAC,SAAS,IAAI,uCAAiB,EAAE,CAAC;YAC/C,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,YAAY,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,8CAA8C;IAC9C,IAAI,YAAY,CAAC,MAAM,GAAG,uCAAiB,EAAE,CAAC;QAC5C,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC7D,MAAM,eAAe,GAAG,YAAY,CAAC,MAAM,GAAG,uCAAiB,CAAC;QAChE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;AACH,CAAC","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 controllerName,\n CACHE_DURATION_MS,\n MAX_CACHE_ENTRIES,\n} from './ai-digest-constants';\nimport type {\n AiDigestControllerState,\n DigestEntry,\n DigestService,\n DigestData,\n} from './ai-digest-types';\n\nexport type AiDigestControllerFetchDigestAction = {\n type: `${typeof controllerName}:fetchDigest`;\n handler: AiDigestController['fetchDigest'];\n};\n\nexport type AiDigestControllerClearDigestAction = {\n type: `${typeof controllerName}:clearDigest`;\n handler: AiDigestController['clearDigest'];\n};\n\nexport type AiDigestControllerClearAllDigestsAction = {\n type: `${typeof controllerName}:clearAllDigests`;\n handler: AiDigestController['clearAllDigests'];\n};\n\nexport type AiDigestControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AiDigestControllerState\n>;\n\nexport type AiDigestControllerActions =\n | AiDigestControllerFetchDigestAction\n | AiDigestControllerClearDigestAction\n | AiDigestControllerClearAllDigestsAction\n | AiDigestControllerGetStateAction;\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 digests: {},\n };\n}\n\nconst aiDigestControllerMetadata: StateMetadata<AiDigestControllerState> = {\n digests: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n};\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.#registerMessageHandlers();\n }\n\n #registerMessageHandlers(): void {\n this.messenger.registerActionHandler(\n `${controllerName}:fetchDigest`,\n this.fetchDigest.bind(this),\n );\n this.messenger.registerActionHandler(\n `${controllerName}:clearDigest`,\n this.clearDigest.bind(this),\n );\n this.messenger.registerActionHandler(\n `${controllerName}:clearAllDigests`,\n this.clearAllDigests.bind(this),\n );\n }\n\n async fetchDigest(assetId: string): Promise<DigestData> {\n const existingDigest = this.state.digests[assetId];\n if (existingDigest) {\n const age = Date.now() - existingDigest.fetchedAt;\n if (age < CACHE_DURATION_MS) {\n return existingDigest.data;\n }\n }\n\n const data = await this.#digestService.fetchDigest(assetId);\n\n const entry: DigestEntry = {\n asset: assetId,\n fetchedAt: Date.now(),\n data,\n };\n\n this.update((state) => {\n state.digests[assetId] = entry;\n this.#evictStaleEntries(state);\n });\n\n return data;\n }\n\n clearDigest(assetId: string): void {\n this.update((state) => {\n delete state.digests[assetId];\n });\n }\n\n clearAllDigests(): void {\n this.update((state) => {\n state.digests = {};\n });\n }\n\n /**\n * Evicts stale (TTL expired) and oldest entries (FIFO) if cache exceeds max size.\n *\n * @param state - The current controller state to evict entries from.\n */\n #evictStaleEntries(state: AiDigestControllerState): void {\n const now = Date.now();\n const entries = Object.entries(state.digests);\n const keysToDelete: string[] = [];\n const freshEntries: [string, DigestEntry][] = [];\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 // Evict oldest entries if over max cache size\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 state.digests[key];\n }\n }\n}\n"]}
|
|
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 controllerName,\n CACHE_DURATION_MS,\n MAX_CACHE_ENTRIES,\n} from './ai-digest-constants';\nimport type {\n AiDigestControllerState,\n DigestEntry,\n DigestService,\n DigestData,\n MarketInsightsReport,\n MarketInsightsEntry,\n} from './ai-digest-types';\n\nexport type AiDigestControllerFetchDigestAction = {\n type: `${typeof controllerName}:fetchDigest`;\n handler: AiDigestController['fetchDigest'];\n};\n\nexport type AiDigestControllerClearDigestAction = {\n type: `${typeof controllerName}:clearDigest`;\n handler: AiDigestController['clearDigest'];\n};\n\nexport type AiDigestControllerClearAllDigestsAction = {\n type: `${typeof controllerName}:clearAllDigests`;\n handler: AiDigestController['clearAllDigests'];\n};\n\nexport type AiDigestControllerFetchMarketInsightsAction = {\n type: `${typeof controllerName}:fetchMarketInsights`;\n handler: AiDigestController['fetchMarketInsights'];\n};\n\nexport type AiDigestControllerClearMarketInsightsAction = {\n type: `${typeof controllerName}:clearMarketInsights`;\n handler: AiDigestController['clearMarketInsights'];\n};\n\nexport type AiDigestControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AiDigestControllerState\n>;\n\nexport type AiDigestControllerActions =\n | AiDigestControllerFetchDigestAction\n | AiDigestControllerClearDigestAction\n | AiDigestControllerClearAllDigestsAction\n | AiDigestControllerFetchMarketInsightsAction\n | AiDigestControllerClearMarketInsightsAction\n | AiDigestControllerGetStateAction;\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 digests: {},\n marketInsights: {},\n };\n}\n\nconst aiDigestControllerMetadata: StateMetadata<AiDigestControllerState> = {\n digests: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n marketInsights: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n};\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.#registerMessageHandlers();\n }\n\n #registerMessageHandlers(): void {\n this.messenger.registerActionHandler(\n `${controllerName}:fetchDigest`,\n this.fetchDigest.bind(this),\n );\n this.messenger.registerActionHandler(\n `${controllerName}:clearDigest`,\n this.clearDigest.bind(this),\n );\n this.messenger.registerActionHandler(\n `${controllerName}:clearAllDigests`,\n this.clearAllDigests.bind(this),\n );\n this.messenger.registerActionHandler(\n `${controllerName}:fetchMarketInsights`,\n this.fetchMarketInsights.bind(this),\n );\n this.messenger.registerActionHandler(\n `${controllerName}:clearMarketInsights`,\n this.clearMarketInsights.bind(this),\n );\n }\n\n async fetchDigest(assetId: string): Promise<DigestData> {\n const existingDigest = this.state.digests[assetId];\n if (existingDigest) {\n const age = Date.now() - existingDigest.fetchedAt;\n if (age < CACHE_DURATION_MS) {\n return existingDigest.data;\n }\n }\n\n const data = await this.#digestService.fetchDigest(assetId);\n\n const entry: DigestEntry = {\n asset: assetId,\n fetchedAt: Date.now(),\n data,\n };\n\n this.update((state) => {\n state.digests[assetId] = entry;\n this.#evictStaleEntries(state);\n });\n\n return data;\n }\n\n clearDigest(assetId: string): void {\n this.update((state) => {\n delete state.digests[assetId];\n });\n }\n\n clearAllDigests(): void {\n this.update((state) => {\n state.digests = {};\n });\n }\n\n /**\n * Fetches market insights for a given CAIP-19 asset identifier.\n * Returns cached data if still fresh, otherwise calls the service.\n *\n * @param caip19Id - The CAIP-19 identifier of the asset.\n * @returns The market insights report, or `null` if none exists.\n */\n async fetchMarketInsights(\n caip19Id: string,\n ): Promise<MarketInsightsReport | null> {\n const existing = this.state.marketInsights[caip19Id];\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.searchDigests(caip19Id);\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[caip19Id];\n });\n return null;\n }\n\n const entry: MarketInsightsEntry = {\n caip19Id,\n fetchedAt: Date.now(),\n data,\n };\n\n this.update((state) => {\n state.marketInsights[caip19Id] = entry;\n this.#evictStaleMarketInsightsEntries(state);\n });\n\n return data;\n }\n\n /**\n * Clears the cached market insights for a specific CAIP-19 asset.\n *\n * @param caip19Id - The CAIP-19 identifier.\n */\n clearMarketInsights(caip19Id: string): void {\n this.update((state) => {\n delete state.marketInsights[caip19Id];\n });\n }\n\n /**\n * Evicts stale (TTL expired) and oldest entries (FIFO) if cache exceeds max size.\n *\n * @param state - The current controller state to evict entries from.\n */\n #evictStaleEntries(state: AiDigestControllerState): void {\n const now = Date.now();\n const entries = Object.entries(state.digests);\n const keysToDelete: string[] = [];\n const freshEntries: [string, DigestEntry][] = [];\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 // Evict oldest entries if over max cache size\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 state.digests[key];\n }\n }\n\n /**\n * Evicts stale and oldest market insights entries if cache exceeds max size.\n *\n * @param state - The current controller state to evict entries from.\n */\n #evictStaleMarketInsightsEntries(state: AiDigestControllerState): void {\n const now = Date.now();\n const entries = Object.entries(state.marketInsights);\n const keysToDelete: string[] = [];\n const freshEntries: [string, MarketInsightsEntry][] = [];\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 state.marketInsights[key];\n }\n }\n}\n"]}
|
|
@@ -2,7 +2,7 @@ import type { ControllerStateChangeEvent, ControllerGetStateAction } from "@meta
|
|
|
2
2
|
import { BaseController } from "@metamask/base-controller";
|
|
3
3
|
import type { Messenger } from "@metamask/messenger";
|
|
4
4
|
import { controllerName } from "./ai-digest-constants.cjs";
|
|
5
|
-
import type { AiDigestControllerState, DigestService, DigestData } from "./ai-digest-types.cjs";
|
|
5
|
+
import type { AiDigestControllerState, DigestService, DigestData, MarketInsightsReport } from "./ai-digest-types.cjs";
|
|
6
6
|
export type AiDigestControllerFetchDigestAction = {
|
|
7
7
|
type: `${typeof controllerName}:fetchDigest`;
|
|
8
8
|
handler: AiDigestController['fetchDigest'];
|
|
@@ -15,8 +15,16 @@ export type AiDigestControllerClearAllDigestsAction = {
|
|
|
15
15
|
type: `${typeof controllerName}:clearAllDigests`;
|
|
16
16
|
handler: AiDigestController['clearAllDigests'];
|
|
17
17
|
};
|
|
18
|
+
export type AiDigestControllerFetchMarketInsightsAction = {
|
|
19
|
+
type: `${typeof controllerName}:fetchMarketInsights`;
|
|
20
|
+
handler: AiDigestController['fetchMarketInsights'];
|
|
21
|
+
};
|
|
22
|
+
export type AiDigestControllerClearMarketInsightsAction = {
|
|
23
|
+
type: `${typeof controllerName}:clearMarketInsights`;
|
|
24
|
+
handler: AiDigestController['clearMarketInsights'];
|
|
25
|
+
};
|
|
18
26
|
export type AiDigestControllerGetStateAction = ControllerGetStateAction<typeof controllerName, AiDigestControllerState>;
|
|
19
|
-
export type AiDigestControllerActions = AiDigestControllerFetchDigestAction | AiDigestControllerClearDigestAction | AiDigestControllerClearAllDigestsAction | AiDigestControllerGetStateAction;
|
|
27
|
+
export type AiDigestControllerActions = AiDigestControllerFetchDigestAction | AiDigestControllerClearDigestAction | AiDigestControllerClearAllDigestsAction | AiDigestControllerFetchMarketInsightsAction | AiDigestControllerClearMarketInsightsAction | AiDigestControllerGetStateAction;
|
|
20
28
|
export type AiDigestControllerStateChangeEvent = ControllerStateChangeEvent<typeof controllerName, AiDigestControllerState>;
|
|
21
29
|
export type AiDigestControllerEvents = AiDigestControllerStateChangeEvent;
|
|
22
30
|
export type AiDigestControllerMessenger = Messenger<typeof controllerName, AiDigestControllerActions, AiDigestControllerEvents>;
|
|
@@ -32,5 +40,19 @@ export declare class AiDigestController extends BaseController<typeof controller
|
|
|
32
40
|
fetchDigest(assetId: string): Promise<DigestData>;
|
|
33
41
|
clearDigest(assetId: string): void;
|
|
34
42
|
clearAllDigests(): void;
|
|
43
|
+
/**
|
|
44
|
+
* Fetches market insights for a given CAIP-19 asset identifier.
|
|
45
|
+
* Returns cached data if still fresh, otherwise calls the service.
|
|
46
|
+
*
|
|
47
|
+
* @param caip19Id - The CAIP-19 identifier of the asset.
|
|
48
|
+
* @returns The market insights report, or `null` if none exists.
|
|
49
|
+
*/
|
|
50
|
+
fetchMarketInsights(caip19Id: string): Promise<MarketInsightsReport | null>;
|
|
51
|
+
/**
|
|
52
|
+
* Clears the cached market insights for a specific CAIP-19 asset.
|
|
53
|
+
*
|
|
54
|
+
* @param caip19Id - The CAIP-19 identifier.
|
|
55
|
+
*/
|
|
56
|
+
clearMarketInsights(caip19Id: string): void;
|
|
35
57
|
}
|
|
36
58
|
//# sourceMappingURL=AiDigestController.d.cts.map
|
|
@@ -1 +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,EACL,cAAc,EAGf,kCAA8B;AAC/B,OAAO,KAAK,EACV,uBAAuB,EAEvB,aAAa,EACb,UAAU,
|
|
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,EACL,cAAc,EAGf,kCAA8B;AAC/B,OAAO,KAAK,EACV,uBAAuB,EAEvB,aAAa,EACb,UAAU,EACV,oBAAoB,EAErB,8BAA0B;AAE3B,MAAM,MAAM,mCAAmC,GAAG;IAChD,IAAI,EAAE,GAAG,OAAO,cAAc,cAAc,CAAC;IAC7C,OAAO,EAAE,kBAAkB,CAAC,aAAa,CAAC,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,mCAAmC,GAAG;IAChD,IAAI,EAAE,GAAG,OAAO,cAAc,cAAc,CAAC;IAC7C,OAAO,EAAE,kBAAkB,CAAC,aAAa,CAAC,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,uCAAuC,GAAG;IACpD,IAAI,EAAE,GAAG,OAAO,cAAc,kBAAkB,CAAC;IACjD,OAAO,EAAE,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;CAChD,CAAC;AAEF,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,GAAG,OAAO,cAAc,sBAAsB,CAAC;IACrD,OAAO,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,GAAG,OAAO,cAAc,sBAAsB,CAAC;IACrD,OAAO,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG,wBAAwB,CACrE,OAAO,cAAc,EACrB,uBAAuB,CACxB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GACjC,mCAAmC,GACnC,mCAAmC,GACnC,uCAAuC,GACvC,2CAA2C,GAC3C,2CAA2C,GAC3C,gCAAgC,CAAC;AAErC,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;AAiBD,qBAAa,kBAAmB,SAAQ,cAAc,CACpD,OAAO,cAAc,EACrB,uBAAuB,EACvB,2BAA2B,CAC5B;;gBAGa,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,yBAAyB;IAsCpE,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAyBvD,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAMlC,eAAe,IAAI,IAAI;IAMvB;;;;;;OAMG;IACG,mBAAmB,CACvB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAiCvC;;;;OAIG;IACH,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;CAsE5C"}
|
|
@@ -2,7 +2,7 @@ import type { ControllerStateChangeEvent, ControllerGetStateAction } from "@meta
|
|
|
2
2
|
import { BaseController } from "@metamask/base-controller";
|
|
3
3
|
import type { Messenger } from "@metamask/messenger";
|
|
4
4
|
import { controllerName } from "./ai-digest-constants.mjs";
|
|
5
|
-
import type { AiDigestControllerState, DigestService, DigestData } from "./ai-digest-types.mjs";
|
|
5
|
+
import type { AiDigestControllerState, DigestService, DigestData, MarketInsightsReport } from "./ai-digest-types.mjs";
|
|
6
6
|
export type AiDigestControllerFetchDigestAction = {
|
|
7
7
|
type: `${typeof controllerName}:fetchDigest`;
|
|
8
8
|
handler: AiDigestController['fetchDigest'];
|
|
@@ -15,8 +15,16 @@ export type AiDigestControllerClearAllDigestsAction = {
|
|
|
15
15
|
type: `${typeof controllerName}:clearAllDigests`;
|
|
16
16
|
handler: AiDigestController['clearAllDigests'];
|
|
17
17
|
};
|
|
18
|
+
export type AiDigestControllerFetchMarketInsightsAction = {
|
|
19
|
+
type: `${typeof controllerName}:fetchMarketInsights`;
|
|
20
|
+
handler: AiDigestController['fetchMarketInsights'];
|
|
21
|
+
};
|
|
22
|
+
export type AiDigestControllerClearMarketInsightsAction = {
|
|
23
|
+
type: `${typeof controllerName}:clearMarketInsights`;
|
|
24
|
+
handler: AiDigestController['clearMarketInsights'];
|
|
25
|
+
};
|
|
18
26
|
export type AiDigestControllerGetStateAction = ControllerGetStateAction<typeof controllerName, AiDigestControllerState>;
|
|
19
|
-
export type AiDigestControllerActions = AiDigestControllerFetchDigestAction | AiDigestControllerClearDigestAction | AiDigestControllerClearAllDigestsAction | AiDigestControllerGetStateAction;
|
|
27
|
+
export type AiDigestControllerActions = AiDigestControllerFetchDigestAction | AiDigestControllerClearDigestAction | AiDigestControllerClearAllDigestsAction | AiDigestControllerFetchMarketInsightsAction | AiDigestControllerClearMarketInsightsAction | AiDigestControllerGetStateAction;
|
|
20
28
|
export type AiDigestControllerStateChangeEvent = ControllerStateChangeEvent<typeof controllerName, AiDigestControllerState>;
|
|
21
29
|
export type AiDigestControllerEvents = AiDigestControllerStateChangeEvent;
|
|
22
30
|
export type AiDigestControllerMessenger = Messenger<typeof controllerName, AiDigestControllerActions, AiDigestControllerEvents>;
|
|
@@ -32,5 +40,19 @@ export declare class AiDigestController extends BaseController<typeof controller
|
|
|
32
40
|
fetchDigest(assetId: string): Promise<DigestData>;
|
|
33
41
|
clearDigest(assetId: string): void;
|
|
34
42
|
clearAllDigests(): void;
|
|
43
|
+
/**
|
|
44
|
+
* Fetches market insights for a given CAIP-19 asset identifier.
|
|
45
|
+
* Returns cached data if still fresh, otherwise calls the service.
|
|
46
|
+
*
|
|
47
|
+
* @param caip19Id - The CAIP-19 identifier of the asset.
|
|
48
|
+
* @returns The market insights report, or `null` if none exists.
|
|
49
|
+
*/
|
|
50
|
+
fetchMarketInsights(caip19Id: string): Promise<MarketInsightsReport | null>;
|
|
51
|
+
/**
|
|
52
|
+
* Clears the cached market insights for a specific CAIP-19 asset.
|
|
53
|
+
*
|
|
54
|
+
* @param caip19Id - The CAIP-19 identifier.
|
|
55
|
+
*/
|
|
56
|
+
clearMarketInsights(caip19Id: string): void;
|
|
35
57
|
}
|
|
36
58
|
//# sourceMappingURL=AiDigestController.d.mts.map
|
|
@@ -1 +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,EACL,cAAc,EAGf,kCAA8B;AAC/B,OAAO,KAAK,EACV,uBAAuB,EAEvB,aAAa,EACb,UAAU,
|
|
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,EACL,cAAc,EAGf,kCAA8B;AAC/B,OAAO,KAAK,EACV,uBAAuB,EAEvB,aAAa,EACb,UAAU,EACV,oBAAoB,EAErB,8BAA0B;AAE3B,MAAM,MAAM,mCAAmC,GAAG;IAChD,IAAI,EAAE,GAAG,OAAO,cAAc,cAAc,CAAC;IAC7C,OAAO,EAAE,kBAAkB,CAAC,aAAa,CAAC,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,mCAAmC,GAAG;IAChD,IAAI,EAAE,GAAG,OAAO,cAAc,cAAc,CAAC;IAC7C,OAAO,EAAE,kBAAkB,CAAC,aAAa,CAAC,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,uCAAuC,GAAG;IACpD,IAAI,EAAE,GAAG,OAAO,cAAc,kBAAkB,CAAC;IACjD,OAAO,EAAE,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;CAChD,CAAC;AAEF,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,GAAG,OAAO,cAAc,sBAAsB,CAAC;IACrD,OAAO,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,GAAG,OAAO,cAAc,sBAAsB,CAAC;IACrD,OAAO,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG,wBAAwB,CACrE,OAAO,cAAc,EACrB,uBAAuB,CACxB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GACjC,mCAAmC,GACnC,mCAAmC,GACnC,uCAAuC,GACvC,2CAA2C,GAC3C,2CAA2C,GAC3C,gCAAgC,CAAC;AAErC,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;AAiBD,qBAAa,kBAAmB,SAAQ,cAAc,CACpD,OAAO,cAAc,EACrB,uBAAuB,EACvB,2BAA2B,CAC5B;;gBAGa,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,yBAAyB;IAsCpE,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAyBvD,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAMlC,eAAe,IAAI,IAAI;IAMvB;;;;;;OAMG;IACG,mBAAmB,CACvB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAiCvC;;;;OAIG;IACH,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;CAsE5C"}
|
|
@@ -9,12 +9,13 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
9
9
|
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");
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
|
-
var _AiDigestController_instances, _AiDigestController_digestService, _AiDigestController_registerMessageHandlers, _AiDigestController_evictStaleEntries;
|
|
12
|
+
var _AiDigestController_instances, _AiDigestController_digestService, _AiDigestController_registerMessageHandlers, _AiDigestController_evictStaleEntries, _AiDigestController_evictStaleMarketInsightsEntries;
|
|
13
13
|
import { BaseController } from "@metamask/base-controller";
|
|
14
14
|
import { controllerName, CACHE_DURATION_MS, MAX_CACHE_ENTRIES } from "./ai-digest-constants.mjs";
|
|
15
15
|
export function getDefaultAiDigestControllerState() {
|
|
16
16
|
return {
|
|
17
17
|
digests: {},
|
|
18
|
+
marketInsights: {},
|
|
18
19
|
};
|
|
19
20
|
}
|
|
20
21
|
const aiDigestControllerMetadata = {
|
|
@@ -24,6 +25,12 @@ const aiDigestControllerMetadata = {
|
|
|
24
25
|
includeInStateLogs: true,
|
|
25
26
|
usedInUi: true,
|
|
26
27
|
},
|
|
28
|
+
marketInsights: {
|
|
29
|
+
persist: true,
|
|
30
|
+
includeInDebugSnapshot: true,
|
|
31
|
+
includeInStateLogs: true,
|
|
32
|
+
usedInUi: true,
|
|
33
|
+
},
|
|
27
34
|
};
|
|
28
35
|
export class AiDigestController extends BaseController {
|
|
29
36
|
constructor({ messenger, state, digestService }) {
|
|
@@ -71,11 +78,57 @@ export class AiDigestController extends BaseController {
|
|
|
71
78
|
state.digests = {};
|
|
72
79
|
});
|
|
73
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Fetches market insights for a given CAIP-19 asset identifier.
|
|
83
|
+
* Returns cached data if still fresh, otherwise calls the service.
|
|
84
|
+
*
|
|
85
|
+
* @param caip19Id - The CAIP-19 identifier of the asset.
|
|
86
|
+
* @returns The market insights report, or `null` if none exists.
|
|
87
|
+
*/
|
|
88
|
+
async fetchMarketInsights(caip19Id) {
|
|
89
|
+
const existing = this.state.marketInsights[caip19Id];
|
|
90
|
+
if (existing) {
|
|
91
|
+
const age = Date.now() - existing.fetchedAt;
|
|
92
|
+
if (age < CACHE_DURATION_MS) {
|
|
93
|
+
return existing.data;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const data = await __classPrivateFieldGet(this, _AiDigestController_digestService, "f").searchDigests(caip19Id);
|
|
97
|
+
if (data === null) {
|
|
98
|
+
// No insights available for this asset — clear any stale cache entry
|
|
99
|
+
this.update((state) => {
|
|
100
|
+
delete state.marketInsights[caip19Id];
|
|
101
|
+
});
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
const entry = {
|
|
105
|
+
caip19Id,
|
|
106
|
+
fetchedAt: Date.now(),
|
|
107
|
+
data,
|
|
108
|
+
};
|
|
109
|
+
this.update((state) => {
|
|
110
|
+
state.marketInsights[caip19Id] = entry;
|
|
111
|
+
__classPrivateFieldGet(this, _AiDigestController_instances, "m", _AiDigestController_evictStaleMarketInsightsEntries).call(this, state);
|
|
112
|
+
});
|
|
113
|
+
return data;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Clears the cached market insights for a specific CAIP-19 asset.
|
|
117
|
+
*
|
|
118
|
+
* @param caip19Id - The CAIP-19 identifier.
|
|
119
|
+
*/
|
|
120
|
+
clearMarketInsights(caip19Id) {
|
|
121
|
+
this.update((state) => {
|
|
122
|
+
delete state.marketInsights[caip19Id];
|
|
123
|
+
});
|
|
124
|
+
}
|
|
74
125
|
}
|
|
75
126
|
_AiDigestController_digestService = new WeakMap(), _AiDigestController_instances = new WeakSet(), _AiDigestController_registerMessageHandlers = function _AiDigestController_registerMessageHandlers() {
|
|
76
127
|
this.messenger.registerActionHandler(`${controllerName}:fetchDigest`, this.fetchDigest.bind(this));
|
|
77
128
|
this.messenger.registerActionHandler(`${controllerName}:clearDigest`, this.clearDigest.bind(this));
|
|
78
129
|
this.messenger.registerActionHandler(`${controllerName}:clearAllDigests`, this.clearAllDigests.bind(this));
|
|
130
|
+
this.messenger.registerActionHandler(`${controllerName}:fetchMarketInsights`, this.fetchMarketInsights.bind(this));
|
|
131
|
+
this.messenger.registerActionHandler(`${controllerName}:clearMarketInsights`, this.clearMarketInsights.bind(this));
|
|
79
132
|
}, _AiDigestController_evictStaleEntries = function _AiDigestController_evictStaleEntries(state) {
|
|
80
133
|
const now = Date.now();
|
|
81
134
|
const entries = Object.entries(state.digests);
|
|
@@ -100,5 +153,28 @@ _AiDigestController_digestService = new WeakMap(), _AiDigestController_instances
|
|
|
100
153
|
for (const key of keysToDelete) {
|
|
101
154
|
delete state.digests[key];
|
|
102
155
|
}
|
|
156
|
+
}, _AiDigestController_evictStaleMarketInsightsEntries = function _AiDigestController_evictStaleMarketInsightsEntries(state) {
|
|
157
|
+
const now = Date.now();
|
|
158
|
+
const entries = Object.entries(state.marketInsights);
|
|
159
|
+
const keysToDelete = [];
|
|
160
|
+
const freshEntries = [];
|
|
161
|
+
for (const [key, entry] of entries) {
|
|
162
|
+
if (now - entry.fetchedAt >= CACHE_DURATION_MS) {
|
|
163
|
+
keysToDelete.push(key);
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
freshEntries.push([key, entry]);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (freshEntries.length > MAX_CACHE_ENTRIES) {
|
|
170
|
+
freshEntries.sort((a, b) => a[1].fetchedAt - b[1].fetchedAt);
|
|
171
|
+
const entriesToRemove = freshEntries.length - MAX_CACHE_ENTRIES;
|
|
172
|
+
for (let i = 0; i < entriesToRemove; i++) {
|
|
173
|
+
keysToDelete.push(freshEntries[i][0]);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
for (const key of keysToDelete) {
|
|
177
|
+
delete state.marketInsights[key];
|
|
178
|
+
}
|
|
103
179
|
};
|
|
104
180
|
//# sourceMappingURL=AiDigestController.mjs.map
|
|
@@ -1 +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 controllerName,\n CACHE_DURATION_MS,\n MAX_CACHE_ENTRIES,\n} from './ai-digest-constants';\nimport type {\n AiDigestControllerState,\n DigestEntry,\n DigestService,\n DigestData,\n} from './ai-digest-types';\n\nexport type AiDigestControllerFetchDigestAction = {\n type: `${typeof controllerName}:fetchDigest`;\n handler: AiDigestController['fetchDigest'];\n};\n\nexport type AiDigestControllerClearDigestAction = {\n type: `${typeof controllerName}:clearDigest`;\n handler: AiDigestController['clearDigest'];\n};\n\nexport type AiDigestControllerClearAllDigestsAction = {\n type: `${typeof controllerName}:clearAllDigests`;\n handler: AiDigestController['clearAllDigests'];\n};\n\nexport type AiDigestControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AiDigestControllerState\n>;\n\nexport type AiDigestControllerActions =\n | AiDigestControllerFetchDigestAction\n | AiDigestControllerClearDigestAction\n | AiDigestControllerClearAllDigestsAction\n | AiDigestControllerGetStateAction;\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 digests: {},\n };\n}\n\nconst aiDigestControllerMetadata: StateMetadata<AiDigestControllerState> = {\n digests: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n};\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.#registerMessageHandlers();\n }\n\n #registerMessageHandlers(): void {\n this.messenger.registerActionHandler(\n `${controllerName}:fetchDigest`,\n this.fetchDigest.bind(this),\n );\n this.messenger.registerActionHandler(\n `${controllerName}:clearDigest`,\n this.clearDigest.bind(this),\n );\n this.messenger.registerActionHandler(\n `${controllerName}:clearAllDigests`,\n this.clearAllDigests.bind(this),\n );\n }\n\n async fetchDigest(assetId: string): Promise<DigestData> {\n const existingDigest = this.state.digests[assetId];\n if (existingDigest) {\n const age = Date.now() - existingDigest.fetchedAt;\n if (age < CACHE_DURATION_MS) {\n return existingDigest.data;\n }\n }\n\n const data = await this.#digestService.fetchDigest(assetId);\n\n const entry: DigestEntry = {\n asset: assetId,\n fetchedAt: Date.now(),\n data,\n };\n\n this.update((state) => {\n state.digests[assetId] = entry;\n this.#evictStaleEntries(state);\n });\n\n return data;\n }\n\n clearDigest(assetId: string): void {\n this.update((state) => {\n delete state.digests[assetId];\n });\n }\n\n clearAllDigests(): void {\n this.update((state) => {\n state.digests = {};\n });\n }\n\n /**\n * Evicts stale (TTL expired) and oldest entries (FIFO) if cache exceeds max size.\n *\n * @param state - The current controller state to evict entries from.\n */\n #evictStaleEntries(state: AiDigestControllerState): void {\n const now = Date.now();\n const entries = Object.entries(state.digests);\n const keysToDelete: string[] = [];\n const freshEntries: [string, DigestEntry][] = [];\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 // Evict oldest entries if over max cache size\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 state.digests[key];\n }\n }\n}\n"]}
|
|
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 controllerName,\n CACHE_DURATION_MS,\n MAX_CACHE_ENTRIES,\n} from './ai-digest-constants';\nimport type {\n AiDigestControllerState,\n DigestEntry,\n DigestService,\n DigestData,\n MarketInsightsReport,\n MarketInsightsEntry,\n} from './ai-digest-types';\n\nexport type AiDigestControllerFetchDigestAction = {\n type: `${typeof controllerName}:fetchDigest`;\n handler: AiDigestController['fetchDigest'];\n};\n\nexport type AiDigestControllerClearDigestAction = {\n type: `${typeof controllerName}:clearDigest`;\n handler: AiDigestController['clearDigest'];\n};\n\nexport type AiDigestControllerClearAllDigestsAction = {\n type: `${typeof controllerName}:clearAllDigests`;\n handler: AiDigestController['clearAllDigests'];\n};\n\nexport type AiDigestControllerFetchMarketInsightsAction = {\n type: `${typeof controllerName}:fetchMarketInsights`;\n handler: AiDigestController['fetchMarketInsights'];\n};\n\nexport type AiDigestControllerClearMarketInsightsAction = {\n type: `${typeof controllerName}:clearMarketInsights`;\n handler: AiDigestController['clearMarketInsights'];\n};\n\nexport type AiDigestControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AiDigestControllerState\n>;\n\nexport type AiDigestControllerActions =\n | AiDigestControllerFetchDigestAction\n | AiDigestControllerClearDigestAction\n | AiDigestControllerClearAllDigestsAction\n | AiDigestControllerFetchMarketInsightsAction\n | AiDigestControllerClearMarketInsightsAction\n | AiDigestControllerGetStateAction;\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 digests: {},\n marketInsights: {},\n };\n}\n\nconst aiDigestControllerMetadata: StateMetadata<AiDigestControllerState> = {\n digests: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n marketInsights: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n};\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.#registerMessageHandlers();\n }\n\n #registerMessageHandlers(): void {\n this.messenger.registerActionHandler(\n `${controllerName}:fetchDigest`,\n this.fetchDigest.bind(this),\n );\n this.messenger.registerActionHandler(\n `${controllerName}:clearDigest`,\n this.clearDigest.bind(this),\n );\n this.messenger.registerActionHandler(\n `${controllerName}:clearAllDigests`,\n this.clearAllDigests.bind(this),\n );\n this.messenger.registerActionHandler(\n `${controllerName}:fetchMarketInsights`,\n this.fetchMarketInsights.bind(this),\n );\n this.messenger.registerActionHandler(\n `${controllerName}:clearMarketInsights`,\n this.clearMarketInsights.bind(this),\n );\n }\n\n async fetchDigest(assetId: string): Promise<DigestData> {\n const existingDigest = this.state.digests[assetId];\n if (existingDigest) {\n const age = Date.now() - existingDigest.fetchedAt;\n if (age < CACHE_DURATION_MS) {\n return existingDigest.data;\n }\n }\n\n const data = await this.#digestService.fetchDigest(assetId);\n\n const entry: DigestEntry = {\n asset: assetId,\n fetchedAt: Date.now(),\n data,\n };\n\n this.update((state) => {\n state.digests[assetId] = entry;\n this.#evictStaleEntries(state);\n });\n\n return data;\n }\n\n clearDigest(assetId: string): void {\n this.update((state) => {\n delete state.digests[assetId];\n });\n }\n\n clearAllDigests(): void {\n this.update((state) => {\n state.digests = {};\n });\n }\n\n /**\n * Fetches market insights for a given CAIP-19 asset identifier.\n * Returns cached data if still fresh, otherwise calls the service.\n *\n * @param caip19Id - The CAIP-19 identifier of the asset.\n * @returns The market insights report, or `null` if none exists.\n */\n async fetchMarketInsights(\n caip19Id: string,\n ): Promise<MarketInsightsReport | null> {\n const existing = this.state.marketInsights[caip19Id];\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.searchDigests(caip19Id);\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[caip19Id];\n });\n return null;\n }\n\n const entry: MarketInsightsEntry = {\n caip19Id,\n fetchedAt: Date.now(),\n data,\n };\n\n this.update((state) => {\n state.marketInsights[caip19Id] = entry;\n this.#evictStaleMarketInsightsEntries(state);\n });\n\n return data;\n }\n\n /**\n * Clears the cached market insights for a specific CAIP-19 asset.\n *\n * @param caip19Id - The CAIP-19 identifier.\n */\n clearMarketInsights(caip19Id: string): void {\n this.update((state) => {\n delete state.marketInsights[caip19Id];\n });\n }\n\n /**\n * Evicts stale (TTL expired) and oldest entries (FIFO) if cache exceeds max size.\n *\n * @param state - The current controller state to evict entries from.\n */\n #evictStaleEntries(state: AiDigestControllerState): void {\n const now = Date.now();\n const entries = Object.entries(state.digests);\n const keysToDelete: string[] = [];\n const freshEntries: [string, DigestEntry][] = [];\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 // Evict oldest entries if over max cache size\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 state.digests[key];\n }\n }\n\n /**\n * Evicts stale and oldest market insights entries if cache exceeds max size.\n *\n * @param state - The current controller state to evict entries from.\n */\n #evictStaleMarketInsightsEntries(state: AiDigestControllerState): void {\n const now = Date.now();\n const entries = Object.entries(state.marketInsights);\n const keysToDelete: string[] = [];\n const freshEntries: [string, MarketInsightsEntry][] = [];\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 state.marketInsights[key];\n }\n }\n}\n"]}
|
package/dist/AiDigestService.cjs
CHANGED
|
@@ -30,6 +30,25 @@ class AiDigestService {
|
|
|
30
30
|
}
|
|
31
31
|
return data;
|
|
32
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Search for market insights by CAIP-19 asset identifier.
|
|
35
|
+
*
|
|
36
|
+
* Calls `GET ${this.#baseUrl}/digests?caipAssetType=${encodeURIComponent(caip19Id)}`.
|
|
37
|
+
*
|
|
38
|
+
* @param caip19Id - The CAIP-19 identifier of the asset.
|
|
39
|
+
* @returns The market insights report, or `null` if none exists (404).
|
|
40
|
+
*/
|
|
41
|
+
async searchDigests(caip19Id) {
|
|
42
|
+
const response = await fetch(`${__classPrivateFieldGet(this, _AiDigestService_baseUrl, "f")}/digests?caipAssetType=${encodeURIComponent(caip19Id)}`);
|
|
43
|
+
if (response.status === 404) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
throw new Error(`${ai_digest_constants_1.AiDigestControllerErrorMessage.API_REQUEST_FAILED}: ${response.status}`);
|
|
48
|
+
}
|
|
49
|
+
const data = await response.json();
|
|
50
|
+
return data;
|
|
51
|
+
}
|
|
33
52
|
}
|
|
34
53
|
exports.AiDigestService = AiDigestService;
|
|
35
54
|
_AiDigestService_baseUrl = new WeakMap();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiDigestService.cjs","sourceRoot":"","sources":["../src/AiDigestService.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,mEAAuE;
|
|
1
|
+
{"version":3,"file":"AiDigestService.cjs","sourceRoot":"","sources":["../src/AiDigestService.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,mEAAuE;AAWvE,MAAa,eAAe;IAG1B,YAAY,MAA6B;QAFhC,2CAAiB;QAGxB,uBAAA,IAAI,4BAAY,MAAM,CAAC,OAAO,MAAA,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAAe;QAC/B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAC1B,GAAG,uBAAA,IAAI,gCAAS,mBAAmB,kBAAkB,CAAC,OAAO,CAAC,SAAS,CACxE,CAAC;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CACb,GAAG,oDAA8B,CAAC,kBAAkB,KAAK,QAAQ,CAAC,MAAM,EAAE,CAC3E,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAe,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAE/C,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CACb,IAAI,CAAC,KAAK,IAAI,oDAA8B,CAAC,kBAAkB,CAChE,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,aAAa,CAAC,QAAgB;QAClC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAC1B,GAAG,uBAAA,IAAI,gCAAS,0BAA0B,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CACzE,CAAC;QAEF,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CACb,GAAG,oDAA8B,CAAC,kBAAkB,KAAK,QAAQ,CAAC,MAAM,EAAE,CAC3E,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAyB,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACzD,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAvDD,0CAuDC","sourcesContent":["import { AiDigestControllerErrorMessage } from './ai-digest-constants';\nimport type {\n DigestService,\n DigestData,\n MarketInsightsReport,\n} from './ai-digest-types';\n\nexport type AiDigestServiceConfig = {\n baseUrl: string;\n};\n\nexport class AiDigestService implements DigestService {\n readonly #baseUrl: string;\n\n constructor(config: AiDigestServiceConfig) {\n this.#baseUrl = config.baseUrl;\n }\n\n async fetchDigest(assetId: string): Promise<DigestData> {\n const response = await fetch(\n `${this.#baseUrl}/digests/assets/${encodeURIComponent(assetId)}/latest`,\n );\n\n if (!response.ok) {\n throw new Error(\n `${AiDigestControllerErrorMessage.API_REQUEST_FAILED}: ${response.status}`,\n );\n }\n\n const data: DigestData = await response.json();\n\n if (!data.success) {\n throw new Error(\n data.error ?? AiDigestControllerErrorMessage.API_RETURNED_ERROR,\n );\n }\n\n return data;\n }\n\n /**\n * Search for market insights by CAIP-19 asset identifier.\n *\n * Calls `GET ${this.#baseUrl}/digests?caipAssetType=${encodeURIComponent(caip19Id)}`.\n *\n * @param caip19Id - The CAIP-19 identifier of the asset.\n * @returns The market insights report, or `null` if none exists (404).\n */\n async searchDigests(caip19Id: string): Promise<MarketInsightsReport | null> {\n const response = await fetch(\n `${this.#baseUrl}/digests?caipAssetType=${encodeURIComponent(caip19Id)}`,\n );\n\n if (response.status === 404) {\n return null;\n }\n\n if (!response.ok) {\n throw new Error(\n `${AiDigestControllerErrorMessage.API_REQUEST_FAILED}: ${response.status}`,\n );\n }\n\n const data: MarketInsightsReport = await response.json();\n return data;\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DigestService, DigestData } from "./ai-digest-types.cjs";
|
|
1
|
+
import type { DigestService, DigestData, MarketInsightsReport } from "./ai-digest-types.cjs";
|
|
2
2
|
export type AiDigestServiceConfig = {
|
|
3
3
|
baseUrl: string;
|
|
4
4
|
};
|
|
@@ -6,5 +6,14 @@ export declare class AiDigestService implements DigestService {
|
|
|
6
6
|
#private;
|
|
7
7
|
constructor(config: AiDigestServiceConfig);
|
|
8
8
|
fetchDigest(assetId: string): Promise<DigestData>;
|
|
9
|
+
/**
|
|
10
|
+
* Search for market insights by CAIP-19 asset identifier.
|
|
11
|
+
*
|
|
12
|
+
* Calls `GET ${this.#baseUrl}/digests?caipAssetType=${encodeURIComponent(caip19Id)}`.
|
|
13
|
+
*
|
|
14
|
+
* @param caip19Id - The CAIP-19 identifier of the asset.
|
|
15
|
+
* @returns The market insights report, or `null` if none exists (404).
|
|
16
|
+
*/
|
|
17
|
+
searchDigests(caip19Id: string): Promise<MarketInsightsReport | null>;
|
|
9
18
|
}
|
|
10
19
|
//# sourceMappingURL=AiDigestService.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiDigestService.d.cts","sourceRoot":"","sources":["../src/AiDigestService.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"AiDigestService.d.cts","sourceRoot":"","sources":["../src/AiDigestService.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EACb,UAAU,EACV,oBAAoB,EACrB,8BAA0B;AAE3B,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,qBAAa,eAAgB,YAAW,aAAa;;gBAGvC,MAAM,EAAE,qBAAqB;IAInC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAsBvD;;;;;;;OAOG;IACG,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;CAkB5E"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DigestService, DigestData } from "./ai-digest-types.mjs";
|
|
1
|
+
import type { DigestService, DigestData, MarketInsightsReport } from "./ai-digest-types.mjs";
|
|
2
2
|
export type AiDigestServiceConfig = {
|
|
3
3
|
baseUrl: string;
|
|
4
4
|
};
|
|
@@ -6,5 +6,14 @@ export declare class AiDigestService implements DigestService {
|
|
|
6
6
|
#private;
|
|
7
7
|
constructor(config: AiDigestServiceConfig);
|
|
8
8
|
fetchDigest(assetId: string): Promise<DigestData>;
|
|
9
|
+
/**
|
|
10
|
+
* Search for market insights by CAIP-19 asset identifier.
|
|
11
|
+
*
|
|
12
|
+
* Calls `GET ${this.#baseUrl}/digests?caipAssetType=${encodeURIComponent(caip19Id)}`.
|
|
13
|
+
*
|
|
14
|
+
* @param caip19Id - The CAIP-19 identifier of the asset.
|
|
15
|
+
* @returns The market insights report, or `null` if none exists (404).
|
|
16
|
+
*/
|
|
17
|
+
searchDigests(caip19Id: string): Promise<MarketInsightsReport | null>;
|
|
9
18
|
}
|
|
10
19
|
//# sourceMappingURL=AiDigestService.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiDigestService.d.mts","sourceRoot":"","sources":["../src/AiDigestService.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"AiDigestService.d.mts","sourceRoot":"","sources":["../src/AiDigestService.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EACb,UAAU,EACV,oBAAoB,EACrB,8BAA0B;AAE3B,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,qBAAa,eAAgB,YAAW,aAAa;;gBAGvC,MAAM,EAAE,qBAAqB;IAInC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAsBvD;;;;;;;OAOG;IACG,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;CAkB5E"}
|
package/dist/AiDigestService.mjs
CHANGED
|
@@ -27,6 +27,25 @@ export class AiDigestService {
|
|
|
27
27
|
}
|
|
28
28
|
return data;
|
|
29
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Search for market insights by CAIP-19 asset identifier.
|
|
32
|
+
*
|
|
33
|
+
* Calls `GET ${this.#baseUrl}/digests?caipAssetType=${encodeURIComponent(caip19Id)}`.
|
|
34
|
+
*
|
|
35
|
+
* @param caip19Id - The CAIP-19 identifier of the asset.
|
|
36
|
+
* @returns The market insights report, or `null` if none exists (404).
|
|
37
|
+
*/
|
|
38
|
+
async searchDigests(caip19Id) {
|
|
39
|
+
const response = await fetch(`${__classPrivateFieldGet(this, _AiDigestService_baseUrl, "f")}/digests?caipAssetType=${encodeURIComponent(caip19Id)}`);
|
|
40
|
+
if (response.status === 404) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
if (!response.ok) {
|
|
44
|
+
throw new Error(`${AiDigestControllerErrorMessage.API_REQUEST_FAILED}: ${response.status}`);
|
|
45
|
+
}
|
|
46
|
+
const data = await response.json();
|
|
47
|
+
return data;
|
|
48
|
+
}
|
|
30
49
|
}
|
|
31
50
|
_AiDigestService_baseUrl = new WeakMap();
|
|
32
51
|
//# sourceMappingURL=AiDigestService.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiDigestService.mjs","sourceRoot":"","sources":["../src/AiDigestService.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,8BAA8B,EAAE,kCAA8B;
|
|
1
|
+
{"version":3,"file":"AiDigestService.mjs","sourceRoot":"","sources":["../src/AiDigestService.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,8BAA8B,EAAE,kCAA8B;AAWvE,MAAM,OAAO,eAAe;IAG1B,YAAY,MAA6B;QAFhC,2CAAiB;QAGxB,uBAAA,IAAI,4BAAY,MAAM,CAAC,OAAO,MAAA,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAAe;QAC/B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAC1B,GAAG,uBAAA,IAAI,gCAAS,mBAAmB,kBAAkB,CAAC,OAAO,CAAC,SAAS,CACxE,CAAC;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CACb,GAAG,8BAA8B,CAAC,kBAAkB,KAAK,QAAQ,CAAC,MAAM,EAAE,CAC3E,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAe,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAE/C,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CACb,IAAI,CAAC,KAAK,IAAI,8BAA8B,CAAC,kBAAkB,CAChE,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,aAAa,CAAC,QAAgB;QAClC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAC1B,GAAG,uBAAA,IAAI,gCAAS,0BAA0B,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CACzE,CAAC;QAEF,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CACb,GAAG,8BAA8B,CAAC,kBAAkB,KAAK,QAAQ,CAAC,MAAM,EAAE,CAC3E,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAyB,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACzD,OAAO,IAAI,CAAC;IACd,CAAC;CACF","sourcesContent":["import { AiDigestControllerErrorMessage } from './ai-digest-constants';\nimport type {\n DigestService,\n DigestData,\n MarketInsightsReport,\n} from './ai-digest-types';\n\nexport type AiDigestServiceConfig = {\n baseUrl: string;\n};\n\nexport class AiDigestService implements DigestService {\n readonly #baseUrl: string;\n\n constructor(config: AiDigestServiceConfig) {\n this.#baseUrl = config.baseUrl;\n }\n\n async fetchDigest(assetId: string): Promise<DigestData> {\n const response = await fetch(\n `${this.#baseUrl}/digests/assets/${encodeURIComponent(assetId)}/latest`,\n );\n\n if (!response.ok) {\n throw new Error(\n `${AiDigestControllerErrorMessage.API_REQUEST_FAILED}: ${response.status}`,\n );\n }\n\n const data: DigestData = await response.json();\n\n if (!data.success) {\n throw new Error(\n data.error ?? AiDigestControllerErrorMessage.API_RETURNED_ERROR,\n );\n }\n\n return data;\n }\n\n /**\n * Search for market insights by CAIP-19 asset identifier.\n *\n * Calls `GET ${this.#baseUrl}/digests?caipAssetType=${encodeURIComponent(caip19Id)}`.\n *\n * @param caip19Id - The CAIP-19 identifier of the asset.\n * @returns The market insights report, or `null` if none exists (404).\n */\n async searchDigests(caip19Id: string): Promise<MarketInsightsReport | null> {\n const response = await fetch(\n `${this.#baseUrl}/digests?caipAssetType=${encodeURIComponent(caip19Id)}`,\n );\n\n if (response.status === 404) {\n return null;\n }\n\n if (!response.ok) {\n throw new Error(\n `${AiDigestControllerErrorMessage.API_REQUEST_FAILED}: ${response.status}`,\n );\n }\n\n const data: MarketInsightsReport = await response.json();\n return data;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-digest-types.cjs","sourceRoot":"","sources":["../src/ai-digest-types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Response from the digest API.\n */\nexport type DigestData = {\n id: string;\n assetId: string;\n assetSymbol?: string;\n digest: string;\n generatedAt: string;\n processingTime: number;\n success: boolean;\n error?: string;\n createdAt: string;\n updatedAt: string;\n};\n\n/**\n * A cached digest entry. Only successful fetches are stored.\n */\nexport type DigestEntry = {\n asset: string;\n fetchedAt: number;\n data: DigestData;\n};\n\nexport type AiDigestControllerState = {\n digests: Record<string, DigestEntry>;\n};\n\nexport type DigestService = {\n fetchDigest(assetId: string): Promise<DigestData>;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"ai-digest-types.cjs","sourceRoot":"","sources":["../src/ai-digest-types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Response from the digest API.\n */\nexport type DigestData = {\n id: string;\n assetId: string;\n assetSymbol?: string;\n digest: string;\n generatedAt: string;\n processingTime: number;\n success: boolean;\n error?: string;\n createdAt: string;\n updatedAt: string;\n};\n\n/**\n * A cached digest entry. Only successful fetches are stored.\n */\nexport type DigestEntry = {\n asset: string;\n fetchedAt: number;\n data: DigestData;\n};\n\n// ---------------------------------------------------------------------------\n// Market Insights types\n// ---------------------------------------------------------------------------\n\n/**\n * A news article referenced by a market insight trend.\n */\nexport type MarketInsightsArticle = {\n /** Article title */\n title: string;\n /** Full URL to the article */\n url: string;\n /** Source domain name (e.g. \"coindesk.com\") */\n source: string;\n /** ISO date string */\n date: string;\n};\n\n/**\n * A social media post referenced by a market insight trend.\n */\nexport type MarketInsightsTweet = {\n /** Summary of the tweet content */\n contentSummary: string;\n /** Full URL to the tweet */\n url: string;\n /** Author handle (e.g. \"@saylordocs\") */\n author: string;\n /** ISO date string */\n date: string;\n};\n\n/**\n * A key market trend identified in the insights report.\n */\nexport type MarketInsightsTrend = {\n /** Trend title (e.g. \"Institutions Buying the Dip\") */\n title: string;\n /** Detailed description of the trend */\n description: string;\n /** Category of the trend */\n category: 'macro' | 'technical' | 'social' | string;\n /** Impact direction */\n impact: 'positive' | 'negative' | 'neutral' | string;\n /** Related news articles */\n articles: MarketInsightsArticle[];\n /** Related social media posts */\n tweets: MarketInsightsTweet[];\n};\n\n/**\n * A data source used to generate the market insights report.\n */\nexport type MarketInsightsSource = {\n /** Source name (e.g. \"CoinDesk\") */\n name: string;\n /** Source URL */\n url: string;\n /** Source type */\n type: 'news' | 'data' | 'social' | string;\n};\n\n/**\n * AI-generated market insights report for a crypto asset.\n * Returned by `GET /digests?caipAssetType=<caip19Id>`.\n */\nexport type MarketInsightsReport = {\n /** API version */\n version: string;\n /** Asset symbol (lowercase, e.g. \"btc\") */\n asset: string;\n /** ISO date string when the report was generated */\n generatedAt: string;\n /** Main headline */\n headline: string;\n /** Summary paragraph */\n summary: string;\n /** Key market trends */\n trends: MarketInsightsTrend[];\n /** Data sources used to generate the report */\n sources: MarketInsightsSource[];\n};\n\n/**\n * A cached market insights entry.\n */\nexport type MarketInsightsEntry = {\n /** CAIP-19 asset identifier */\n caip19Id: string;\n /** Timestamp when the entry was fetched */\n fetchedAt: number;\n /** The market insights report data */\n data: MarketInsightsReport;\n};\n\n// ---------------------------------------------------------------------------\n// Controller state\n// ---------------------------------------------------------------------------\n\nexport type AiDigestControllerState = {\n digests: Record<string, DigestEntry>;\n marketInsights: Record<string, MarketInsightsEntry>;\n};\n\n// ---------------------------------------------------------------------------\n// Service interface\n// ---------------------------------------------------------------------------\n\nexport type DigestService = {\n fetchDigest(assetId: string): Promise<DigestData>;\n /**\n * Search for market insights by CAIP-19 asset identifier.\n * Calls `GET /digests?caipAssetType=<caip19Id>`.\n *\n * @param caip19Id - The CAIP-19 identifier of the asset.\n * @returns The market insights report, or `null` if no insights exist (404).\n */\n searchDigests(caip19Id: string): Promise<MarketInsightsReport | null>;\n};\n"]}
|
|
@@ -21,10 +21,104 @@ export type DigestEntry = {
|
|
|
21
21
|
fetchedAt: number;
|
|
22
22
|
data: DigestData;
|
|
23
23
|
};
|
|
24
|
+
/**
|
|
25
|
+
* A news article referenced by a market insight trend.
|
|
26
|
+
*/
|
|
27
|
+
export type MarketInsightsArticle = {
|
|
28
|
+
/** Article title */
|
|
29
|
+
title: string;
|
|
30
|
+
/** Full URL to the article */
|
|
31
|
+
url: string;
|
|
32
|
+
/** Source domain name (e.g. "coindesk.com") */
|
|
33
|
+
source: string;
|
|
34
|
+
/** ISO date string */
|
|
35
|
+
date: string;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* A social media post referenced by a market insight trend.
|
|
39
|
+
*/
|
|
40
|
+
export type MarketInsightsTweet = {
|
|
41
|
+
/** Summary of the tweet content */
|
|
42
|
+
contentSummary: string;
|
|
43
|
+
/** Full URL to the tweet */
|
|
44
|
+
url: string;
|
|
45
|
+
/** Author handle (e.g. "@saylordocs") */
|
|
46
|
+
author: string;
|
|
47
|
+
/** ISO date string */
|
|
48
|
+
date: string;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* A key market trend identified in the insights report.
|
|
52
|
+
*/
|
|
53
|
+
export type MarketInsightsTrend = {
|
|
54
|
+
/** Trend title (e.g. "Institutions Buying the Dip") */
|
|
55
|
+
title: string;
|
|
56
|
+
/** Detailed description of the trend */
|
|
57
|
+
description: string;
|
|
58
|
+
/** Category of the trend */
|
|
59
|
+
category: 'macro' | 'technical' | 'social' | string;
|
|
60
|
+
/** Impact direction */
|
|
61
|
+
impact: 'positive' | 'negative' | 'neutral' | string;
|
|
62
|
+
/** Related news articles */
|
|
63
|
+
articles: MarketInsightsArticle[];
|
|
64
|
+
/** Related social media posts */
|
|
65
|
+
tweets: MarketInsightsTweet[];
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* A data source used to generate the market insights report.
|
|
69
|
+
*/
|
|
70
|
+
export type MarketInsightsSource = {
|
|
71
|
+
/** Source name (e.g. "CoinDesk") */
|
|
72
|
+
name: string;
|
|
73
|
+
/** Source URL */
|
|
74
|
+
url: string;
|
|
75
|
+
/** Source type */
|
|
76
|
+
type: 'news' | 'data' | 'social' | string;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* AI-generated market insights report for a crypto asset.
|
|
80
|
+
* Returned by `GET /digests?caipAssetType=<caip19Id>`.
|
|
81
|
+
*/
|
|
82
|
+
export type MarketInsightsReport = {
|
|
83
|
+
/** API version */
|
|
84
|
+
version: string;
|
|
85
|
+
/** Asset symbol (lowercase, e.g. "btc") */
|
|
86
|
+
asset: string;
|
|
87
|
+
/** ISO date string when the report was generated */
|
|
88
|
+
generatedAt: string;
|
|
89
|
+
/** Main headline */
|
|
90
|
+
headline: string;
|
|
91
|
+
/** Summary paragraph */
|
|
92
|
+
summary: string;
|
|
93
|
+
/** Key market trends */
|
|
94
|
+
trends: MarketInsightsTrend[];
|
|
95
|
+
/** Data sources used to generate the report */
|
|
96
|
+
sources: MarketInsightsSource[];
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* A cached market insights entry.
|
|
100
|
+
*/
|
|
101
|
+
export type MarketInsightsEntry = {
|
|
102
|
+
/** CAIP-19 asset identifier */
|
|
103
|
+
caip19Id: string;
|
|
104
|
+
/** Timestamp when the entry was fetched */
|
|
105
|
+
fetchedAt: number;
|
|
106
|
+
/** The market insights report data */
|
|
107
|
+
data: MarketInsightsReport;
|
|
108
|
+
};
|
|
24
109
|
export type AiDigestControllerState = {
|
|
25
110
|
digests: Record<string, DigestEntry>;
|
|
111
|
+
marketInsights: Record<string, MarketInsightsEntry>;
|
|
26
112
|
};
|
|
27
113
|
export type DigestService = {
|
|
28
114
|
fetchDigest(assetId: string): Promise<DigestData>;
|
|
115
|
+
/**
|
|
116
|
+
* Search for market insights by CAIP-19 asset identifier.
|
|
117
|
+
* Calls `GET /digests?caipAssetType=<caip19Id>`.
|
|
118
|
+
*
|
|
119
|
+
* @param caip19Id - The CAIP-19 identifier of the asset.
|
|
120
|
+
* @returns The market insights report, or `null` if no insights exist (404).
|
|
121
|
+
*/
|
|
122
|
+
searchDigests(caip19Id: string): Promise<MarketInsightsReport | null>;
|
|
29
123
|
};
|
|
30
124
|
//# sourceMappingURL=ai-digest-types.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-digest-types.d.cts","sourceRoot":"","sources":["../src/ai-digest-types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,UAAU,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,
|
|
1
|
+
{"version":3,"file":"ai-digest-types.d.cts","sourceRoot":"","sources":["../src/ai-digest-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,10 +21,104 @@ export type DigestEntry = {
|
|
|
21
21
|
fetchedAt: number;
|
|
22
22
|
data: DigestData;
|
|
23
23
|
};
|
|
24
|
+
/**
|
|
25
|
+
* A news article referenced by a market insight trend.
|
|
26
|
+
*/
|
|
27
|
+
export type MarketInsightsArticle = {
|
|
28
|
+
/** Article title */
|
|
29
|
+
title: string;
|
|
30
|
+
/** Full URL to the article */
|
|
31
|
+
url: string;
|
|
32
|
+
/** Source domain name (e.g. "coindesk.com") */
|
|
33
|
+
source: string;
|
|
34
|
+
/** ISO date string */
|
|
35
|
+
date: string;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* A social media post referenced by a market insight trend.
|
|
39
|
+
*/
|
|
40
|
+
export type MarketInsightsTweet = {
|
|
41
|
+
/** Summary of the tweet content */
|
|
42
|
+
contentSummary: string;
|
|
43
|
+
/** Full URL to the tweet */
|
|
44
|
+
url: string;
|
|
45
|
+
/** Author handle (e.g. "@saylordocs") */
|
|
46
|
+
author: string;
|
|
47
|
+
/** ISO date string */
|
|
48
|
+
date: string;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* A key market trend identified in the insights report.
|
|
52
|
+
*/
|
|
53
|
+
export type MarketInsightsTrend = {
|
|
54
|
+
/** Trend title (e.g. "Institutions Buying the Dip") */
|
|
55
|
+
title: string;
|
|
56
|
+
/** Detailed description of the trend */
|
|
57
|
+
description: string;
|
|
58
|
+
/** Category of the trend */
|
|
59
|
+
category: 'macro' | 'technical' | 'social' | string;
|
|
60
|
+
/** Impact direction */
|
|
61
|
+
impact: 'positive' | 'negative' | 'neutral' | string;
|
|
62
|
+
/** Related news articles */
|
|
63
|
+
articles: MarketInsightsArticle[];
|
|
64
|
+
/** Related social media posts */
|
|
65
|
+
tweets: MarketInsightsTweet[];
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* A data source used to generate the market insights report.
|
|
69
|
+
*/
|
|
70
|
+
export type MarketInsightsSource = {
|
|
71
|
+
/** Source name (e.g. "CoinDesk") */
|
|
72
|
+
name: string;
|
|
73
|
+
/** Source URL */
|
|
74
|
+
url: string;
|
|
75
|
+
/** Source type */
|
|
76
|
+
type: 'news' | 'data' | 'social' | string;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* AI-generated market insights report for a crypto asset.
|
|
80
|
+
* Returned by `GET /digests?caipAssetType=<caip19Id>`.
|
|
81
|
+
*/
|
|
82
|
+
export type MarketInsightsReport = {
|
|
83
|
+
/** API version */
|
|
84
|
+
version: string;
|
|
85
|
+
/** Asset symbol (lowercase, e.g. "btc") */
|
|
86
|
+
asset: string;
|
|
87
|
+
/** ISO date string when the report was generated */
|
|
88
|
+
generatedAt: string;
|
|
89
|
+
/** Main headline */
|
|
90
|
+
headline: string;
|
|
91
|
+
/** Summary paragraph */
|
|
92
|
+
summary: string;
|
|
93
|
+
/** Key market trends */
|
|
94
|
+
trends: MarketInsightsTrend[];
|
|
95
|
+
/** Data sources used to generate the report */
|
|
96
|
+
sources: MarketInsightsSource[];
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* A cached market insights entry.
|
|
100
|
+
*/
|
|
101
|
+
export type MarketInsightsEntry = {
|
|
102
|
+
/** CAIP-19 asset identifier */
|
|
103
|
+
caip19Id: string;
|
|
104
|
+
/** Timestamp when the entry was fetched */
|
|
105
|
+
fetchedAt: number;
|
|
106
|
+
/** The market insights report data */
|
|
107
|
+
data: MarketInsightsReport;
|
|
108
|
+
};
|
|
24
109
|
export type AiDigestControllerState = {
|
|
25
110
|
digests: Record<string, DigestEntry>;
|
|
111
|
+
marketInsights: Record<string, MarketInsightsEntry>;
|
|
26
112
|
};
|
|
27
113
|
export type DigestService = {
|
|
28
114
|
fetchDigest(assetId: string): Promise<DigestData>;
|
|
115
|
+
/**
|
|
116
|
+
* Search for market insights by CAIP-19 asset identifier.
|
|
117
|
+
* Calls `GET /digests?caipAssetType=<caip19Id>`.
|
|
118
|
+
*
|
|
119
|
+
* @param caip19Id - The CAIP-19 identifier of the asset.
|
|
120
|
+
* @returns The market insights report, or `null` if no insights exist (404).
|
|
121
|
+
*/
|
|
122
|
+
searchDigests(caip19Id: string): Promise<MarketInsightsReport | null>;
|
|
29
123
|
};
|
|
30
124
|
//# sourceMappingURL=ai-digest-types.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-digest-types.d.mts","sourceRoot":"","sources":["../src/ai-digest-types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,UAAU,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,
|
|
1
|
+
{"version":3,"file":"ai-digest-types.d.mts","sourceRoot":"","sources":["../src/ai-digest-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-digest-types.mjs","sourceRoot":"","sources":["../src/ai-digest-types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Response from the digest API.\n */\nexport type DigestData = {\n id: string;\n assetId: string;\n assetSymbol?: string;\n digest: string;\n generatedAt: string;\n processingTime: number;\n success: boolean;\n error?: string;\n createdAt: string;\n updatedAt: string;\n};\n\n/**\n * A cached digest entry. Only successful fetches are stored.\n */\nexport type DigestEntry = {\n asset: string;\n fetchedAt: number;\n data: DigestData;\n};\n\nexport type AiDigestControllerState = {\n digests: Record<string, DigestEntry>;\n};\n\nexport type DigestService = {\n fetchDigest(assetId: string): Promise<DigestData>;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"ai-digest-types.mjs","sourceRoot":"","sources":["../src/ai-digest-types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Response from the digest API.\n */\nexport type DigestData = {\n id: string;\n assetId: string;\n assetSymbol?: string;\n digest: string;\n generatedAt: string;\n processingTime: number;\n success: boolean;\n error?: string;\n createdAt: string;\n updatedAt: string;\n};\n\n/**\n * A cached digest entry. Only successful fetches are stored.\n */\nexport type DigestEntry = {\n asset: string;\n fetchedAt: number;\n data: DigestData;\n};\n\n// ---------------------------------------------------------------------------\n// Market Insights types\n// ---------------------------------------------------------------------------\n\n/**\n * A news article referenced by a market insight trend.\n */\nexport type MarketInsightsArticle = {\n /** Article title */\n title: string;\n /** Full URL to the article */\n url: string;\n /** Source domain name (e.g. \"coindesk.com\") */\n source: string;\n /** ISO date string */\n date: string;\n};\n\n/**\n * A social media post referenced by a market insight trend.\n */\nexport type MarketInsightsTweet = {\n /** Summary of the tweet content */\n contentSummary: string;\n /** Full URL to the tweet */\n url: string;\n /** Author handle (e.g. \"@saylordocs\") */\n author: string;\n /** ISO date string */\n date: string;\n};\n\n/**\n * A key market trend identified in the insights report.\n */\nexport type MarketInsightsTrend = {\n /** Trend title (e.g. \"Institutions Buying the Dip\") */\n title: string;\n /** Detailed description of the trend */\n description: string;\n /** Category of the trend */\n category: 'macro' | 'technical' | 'social' | string;\n /** Impact direction */\n impact: 'positive' | 'negative' | 'neutral' | string;\n /** Related news articles */\n articles: MarketInsightsArticle[];\n /** Related social media posts */\n tweets: MarketInsightsTweet[];\n};\n\n/**\n * A data source used to generate the market insights report.\n */\nexport type MarketInsightsSource = {\n /** Source name (e.g. \"CoinDesk\") */\n name: string;\n /** Source URL */\n url: string;\n /** Source type */\n type: 'news' | 'data' | 'social' | string;\n};\n\n/**\n * AI-generated market insights report for a crypto asset.\n * Returned by `GET /digests?caipAssetType=<caip19Id>`.\n */\nexport type MarketInsightsReport = {\n /** API version */\n version: string;\n /** Asset symbol (lowercase, e.g. \"btc\") */\n asset: string;\n /** ISO date string when the report was generated */\n generatedAt: string;\n /** Main headline */\n headline: string;\n /** Summary paragraph */\n summary: string;\n /** Key market trends */\n trends: MarketInsightsTrend[];\n /** Data sources used to generate the report */\n sources: MarketInsightsSource[];\n};\n\n/**\n * A cached market insights entry.\n */\nexport type MarketInsightsEntry = {\n /** CAIP-19 asset identifier */\n caip19Id: string;\n /** Timestamp when the entry was fetched */\n fetchedAt: number;\n /** The market insights report data */\n data: MarketInsightsReport;\n};\n\n// ---------------------------------------------------------------------------\n// Controller state\n// ---------------------------------------------------------------------------\n\nexport type AiDigestControllerState = {\n digests: Record<string, DigestEntry>;\n marketInsights: Record<string, MarketInsightsEntry>;\n};\n\n// ---------------------------------------------------------------------------\n// Service interface\n// ---------------------------------------------------------------------------\n\nexport type DigestService = {\n fetchDigest(assetId: string): Promise<DigestData>;\n /**\n * Search for market insights by CAIP-19 asset identifier.\n * Calls `GET /digests?caipAssetType=<caip19Id>`.\n *\n * @param caip19Id - The CAIP-19 identifier of the asset.\n * @returns The market insights report, or `null` if no insights exist (404).\n */\n searchDigests(caip19Id: string): Promise<MarketInsightsReport | null>;\n};\n"]}
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAaA,+DAG8B;AAF5B,wHAAA,kBAAkB,OAAA;AAClB,uIAAA,iCAAiC,OAAA;AAInC,yDAAoD;AAA3C,kHAAA,eAAe,OAAA;AAexB,iEAK+B;AAJ7B,6HAAA,cAAc,OAA0B;AACxC,wHAAA,iBAAiB,OAAA;AACjB,wHAAA,iBAAiB,OAAA;AACjB,qIAAA,8BAA8B,OAAA","sourcesContent":["export type {\n AiDigestControllerActions,\n AiDigestControllerClearAllDigestsAction,\n AiDigestControllerClearDigestAction,\n AiDigestControllerClearMarketInsightsAction,\n AiDigestControllerEvents,\n AiDigestControllerFetchDigestAction,\n AiDigestControllerFetchMarketInsightsAction,\n AiDigestControllerGetStateAction,\n AiDigestControllerMessenger,\n AiDigestControllerOptions,\n AiDigestControllerStateChangeEvent,\n} from './AiDigestController';\nexport {\n AiDigestController,\n getDefaultAiDigestControllerState,\n} from './AiDigestController';\n\nexport type { AiDigestServiceConfig } from './AiDigestService';\nexport { AiDigestService } from './AiDigestService';\n\nexport type {\n AiDigestControllerState,\n DigestData,\n DigestEntry,\n DigestService,\n MarketInsightsArticle,\n MarketInsightsTweet,\n MarketInsightsTrend,\n MarketInsightsSource,\n MarketInsightsReport,\n MarketInsightsEntry,\n} from './ai-digest-types';\n\nexport {\n controllerName as aiDigestControllerName,\n CACHE_DURATION_MS,\n MAX_CACHE_ENTRIES,\n AiDigestControllerErrorMessage,\n} from './ai-digest-constants';\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export type { AiDigestControllerActions, AiDigestControllerClearAllDigestsAction, AiDigestControllerClearDigestAction, AiDigestControllerEvents, AiDigestControllerFetchDigestAction, AiDigestControllerGetStateAction, AiDigestControllerMessenger, AiDigestControllerOptions, AiDigestControllerStateChangeEvent, } from "./AiDigestController.cjs";
|
|
1
|
+
export type { AiDigestControllerActions, AiDigestControllerClearAllDigestsAction, AiDigestControllerClearDigestAction, AiDigestControllerClearMarketInsightsAction, AiDigestControllerEvents, AiDigestControllerFetchDigestAction, AiDigestControllerFetchMarketInsightsAction, AiDigestControllerGetStateAction, AiDigestControllerMessenger, AiDigestControllerOptions, AiDigestControllerStateChangeEvent, } from "./AiDigestController.cjs";
|
|
2
2
|
export { AiDigestController, getDefaultAiDigestControllerState, } from "./AiDigestController.cjs";
|
|
3
3
|
export type { AiDigestServiceConfig } from "./AiDigestService.cjs";
|
|
4
4
|
export { AiDigestService } from "./AiDigestService.cjs";
|
|
5
|
-
export type { AiDigestControllerState, DigestData, DigestEntry, DigestService, } from "./ai-digest-types.cjs";
|
|
5
|
+
export type { AiDigestControllerState, DigestData, DigestEntry, DigestService, MarketInsightsArticle, MarketInsightsTweet, MarketInsightsTrend, MarketInsightsSource, MarketInsightsReport, MarketInsightsEntry, } from "./ai-digest-types.cjs";
|
|
6
6
|
export { controllerName as aiDigestControllerName, CACHE_DURATION_MS, MAX_CACHE_ENTRIES, AiDigestControllerErrorMessage, } from "./ai-digest-constants.cjs";
|
|
7
7
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,yBAAyB,EACzB,uCAAuC,EACvC,mCAAmC,EACnC,wBAAwB,EACxB,mCAAmC,EACnC,gCAAgC,EAChC,2BAA2B,EAC3B,yBAAyB,EACzB,kCAAkC,GACnC,iCAA6B;AAC9B,OAAO,EACL,kBAAkB,EAClB,iCAAiC,GAClC,iCAA6B;AAE9B,YAAY,EAAE,qBAAqB,EAAE,8BAA0B;AAC/D,OAAO,EAAE,eAAe,EAAE,8BAA0B;AAEpD,YAAY,EACV,uBAAuB,EACvB,UAAU,EACV,WAAW,EACX,aAAa,
|
|
1
|
+
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,yBAAyB,EACzB,uCAAuC,EACvC,mCAAmC,EACnC,2CAA2C,EAC3C,wBAAwB,EACxB,mCAAmC,EACnC,2CAA2C,EAC3C,gCAAgC,EAChC,2BAA2B,EAC3B,yBAAyB,EACzB,kCAAkC,GACnC,iCAA6B;AAC9B,OAAO,EACL,kBAAkB,EAClB,iCAAiC,GAClC,iCAA6B;AAE9B,YAAY,EAAE,qBAAqB,EAAE,8BAA0B;AAC/D,OAAO,EAAE,eAAe,EAAE,8BAA0B;AAEpD,YAAY,EACV,uBAAuB,EACvB,UAAU,EACV,WAAW,EACX,aAAa,EACb,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,GACpB,8BAA0B;AAE3B,OAAO,EACL,cAAc,IAAI,sBAAsB,EACxC,iBAAiB,EACjB,iBAAiB,EACjB,8BAA8B,GAC/B,kCAA8B"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export type { AiDigestControllerActions, AiDigestControllerClearAllDigestsAction, AiDigestControllerClearDigestAction, AiDigestControllerEvents, AiDigestControllerFetchDigestAction, AiDigestControllerGetStateAction, AiDigestControllerMessenger, AiDigestControllerOptions, AiDigestControllerStateChangeEvent, } from "./AiDigestController.mjs";
|
|
1
|
+
export type { AiDigestControllerActions, AiDigestControllerClearAllDigestsAction, AiDigestControllerClearDigestAction, AiDigestControllerClearMarketInsightsAction, AiDigestControllerEvents, AiDigestControllerFetchDigestAction, AiDigestControllerFetchMarketInsightsAction, AiDigestControllerGetStateAction, AiDigestControllerMessenger, AiDigestControllerOptions, AiDigestControllerStateChangeEvent, } from "./AiDigestController.mjs";
|
|
2
2
|
export { AiDigestController, getDefaultAiDigestControllerState, } from "./AiDigestController.mjs";
|
|
3
3
|
export type { AiDigestServiceConfig } from "./AiDigestService.mjs";
|
|
4
4
|
export { AiDigestService } from "./AiDigestService.mjs";
|
|
5
|
-
export type { AiDigestControllerState, DigestData, DigestEntry, DigestService, } from "./ai-digest-types.mjs";
|
|
5
|
+
export type { AiDigestControllerState, DigestData, DigestEntry, DigestService, MarketInsightsArticle, MarketInsightsTweet, MarketInsightsTrend, MarketInsightsSource, MarketInsightsReport, MarketInsightsEntry, } from "./ai-digest-types.mjs";
|
|
6
6
|
export { controllerName as aiDigestControllerName, CACHE_DURATION_MS, MAX_CACHE_ENTRIES, AiDigestControllerErrorMessage, } from "./ai-digest-constants.mjs";
|
|
7
7
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,yBAAyB,EACzB,uCAAuC,EACvC,mCAAmC,EACnC,wBAAwB,EACxB,mCAAmC,EACnC,gCAAgC,EAChC,2BAA2B,EAC3B,yBAAyB,EACzB,kCAAkC,GACnC,iCAA6B;AAC9B,OAAO,EACL,kBAAkB,EAClB,iCAAiC,GAClC,iCAA6B;AAE9B,YAAY,EAAE,qBAAqB,EAAE,8BAA0B;AAC/D,OAAO,EAAE,eAAe,EAAE,8BAA0B;AAEpD,YAAY,EACV,uBAAuB,EACvB,UAAU,EACV,WAAW,EACX,aAAa,
|
|
1
|
+
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,yBAAyB,EACzB,uCAAuC,EACvC,mCAAmC,EACnC,2CAA2C,EAC3C,wBAAwB,EACxB,mCAAmC,EACnC,2CAA2C,EAC3C,gCAAgC,EAChC,2BAA2B,EAC3B,yBAAyB,EACzB,kCAAkC,GACnC,iCAA6B;AAC9B,OAAO,EACL,kBAAkB,EAClB,iCAAiC,GAClC,iCAA6B;AAE9B,YAAY,EAAE,qBAAqB,EAAE,8BAA0B;AAC/D,OAAO,EAAE,eAAe,EAAE,8BAA0B;AAEpD,YAAY,EACV,uBAAuB,EACvB,UAAU,EACV,WAAW,EACX,aAAa,EACb,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,GACpB,8BAA0B;AAE3B,OAAO,EACL,cAAc,IAAI,sBAAsB,EACxC,iBAAiB,EACjB,iBAAiB,EACjB,8BAA8B,GAC/B,kCAA8B"}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,kBAAkB,EAClB,iCAAiC,EAClC,iCAA6B;AAG9B,OAAO,EAAE,eAAe,EAAE,8BAA0B;AAepD,OAAO,EACL,cAAc,IAAI,sBAAsB,EACxC,iBAAiB,EACjB,iBAAiB,EACjB,8BAA8B,EAC/B,kCAA8B","sourcesContent":["export type {\n AiDigestControllerActions,\n AiDigestControllerClearAllDigestsAction,\n AiDigestControllerClearDigestAction,\n AiDigestControllerClearMarketInsightsAction,\n AiDigestControllerEvents,\n AiDigestControllerFetchDigestAction,\n AiDigestControllerFetchMarketInsightsAction,\n AiDigestControllerGetStateAction,\n AiDigestControllerMessenger,\n AiDigestControllerOptions,\n AiDigestControllerStateChangeEvent,\n} from './AiDigestController';\nexport {\n AiDigestController,\n getDefaultAiDigestControllerState,\n} from './AiDigestController';\n\nexport type { AiDigestServiceConfig } from './AiDigestService';\nexport { AiDigestService } from './AiDigestService';\n\nexport type {\n AiDigestControllerState,\n DigestData,\n DigestEntry,\n DigestService,\n MarketInsightsArticle,\n MarketInsightsTweet,\n MarketInsightsTrend,\n MarketInsightsSource,\n MarketInsightsReport,\n MarketInsightsEntry,\n} from './ai-digest-types';\n\nexport {\n controllerName as aiDigestControllerName,\n CACHE_DURATION_MS,\n MAX_CACHE_ENTRIES,\n AiDigestControllerErrorMessage,\n} from './ai-digest-constants';\n"]}
|