@metamask-previews/ai-controllers 0.0.0-preview-e4aa1532 → 0.0.0-preview-6dfa4aeba
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 +1 -0
- package/dist/AiDigestController.cjs +109 -0
- package/dist/AiDigestController.cjs.map +1 -0
- package/dist/AiDigestController.d.cts +36 -0
- package/dist/AiDigestController.d.cts.map +1 -0
- package/dist/AiDigestController.d.mts +36 -0
- package/dist/AiDigestController.d.mts.map +1 -0
- package/dist/AiDigestController.mjs +104 -0
- package/dist/AiDigestController.mjs.map +1 -0
- package/dist/AiDigestService.cjs +36 -0
- package/dist/AiDigestService.cjs.map +1 -0
- package/dist/AiDigestService.d.cts +10 -0
- package/dist/AiDigestService.d.cts.map +1 -0
- package/dist/AiDigestService.d.mts +10 -0
- package/dist/AiDigestService.d.mts.map +1 -0
- package/dist/AiDigestService.mjs +32 -0
- package/dist/AiDigestService.mjs.map +1 -0
- package/dist/ai-digest-constants.cjs +11 -0
- package/dist/ai-digest-constants.cjs.map +1 -0
- package/dist/ai-digest-constants.d.cts +8 -0
- package/dist/ai-digest-constants.d.cts.map +1 -0
- package/dist/ai-digest-constants.d.mts +8 -0
- package/dist/ai-digest-constants.d.mts.map +1 -0
- package/dist/ai-digest-constants.mjs +8 -0
- package/dist/ai-digest-constants.mjs.map +1 -0
- package/dist/ai-digest-types.cjs +3 -0
- package/dist/ai-digest-types.cjs.map +1 -0
- package/dist/ai-digest-types.d.cts +30 -0
- package/dist/ai-digest-types.d.cts.map +1 -0
- package/dist/ai-digest-types.d.mts +30 -0
- package/dist/ai-digest-types.d.mts.map +1 -0
- package/dist/ai-digest-types.mjs +2 -0
- package/dist/ai-digest-types.mjs.map +1 -0
- package/dist/index.cjs +11 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -7
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +6 -7
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +3 -9
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -3
package/CHANGELOG.md
CHANGED
|
@@ -10,5 +10,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
10
10
|
### Added
|
|
11
11
|
|
|
12
12
|
- Initial release ([#7693](https://github.com/MetaMask/core/pull/7693))
|
|
13
|
+
- Add `AiDigestController` for fetching and caching AI-generated asset digests ([#7746](https://github.com/MetaMask/core/pull/7746))
|
|
13
14
|
|
|
14
15
|
[Unreleased]: https://github.com/MetaMask/core/
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
+
};
|
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
+
};
|
|
13
|
+
var _AiDigestController_instances, _AiDigestController_digestService, _AiDigestController_registerMessageHandlers, _AiDigestController_evictStaleEntries;
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.AiDigestController = exports.getDefaultAiDigestControllerState = void 0;
|
|
16
|
+
const base_controller_1 = require("@metamask/base-controller");
|
|
17
|
+
const ai_digest_constants_1 = require("./ai-digest-constants.cjs");
|
|
18
|
+
function getDefaultAiDigestControllerState() {
|
|
19
|
+
return {
|
|
20
|
+
digests: {},
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
exports.getDefaultAiDigestControllerState = getDefaultAiDigestControllerState;
|
|
24
|
+
const aiDigestControllerMetadata = {
|
|
25
|
+
digests: {
|
|
26
|
+
persist: true,
|
|
27
|
+
includeInDebugSnapshot: true,
|
|
28
|
+
includeInStateLogs: true,
|
|
29
|
+
usedInUi: true,
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
class AiDigestController extends base_controller_1.BaseController {
|
|
33
|
+
constructor({ messenger, state, digestService }) {
|
|
34
|
+
super({
|
|
35
|
+
name: ai_digest_constants_1.controllerName,
|
|
36
|
+
metadata: aiDigestControllerMetadata,
|
|
37
|
+
state: {
|
|
38
|
+
...getDefaultAiDigestControllerState(),
|
|
39
|
+
...state,
|
|
40
|
+
},
|
|
41
|
+
messenger,
|
|
42
|
+
});
|
|
43
|
+
_AiDigestController_instances.add(this);
|
|
44
|
+
_AiDigestController_digestService.set(this, void 0);
|
|
45
|
+
__classPrivateFieldSet(this, _AiDigestController_digestService, digestService, "f");
|
|
46
|
+
__classPrivateFieldGet(this, _AiDigestController_instances, "m", _AiDigestController_registerMessageHandlers).call(this);
|
|
47
|
+
}
|
|
48
|
+
async fetchDigest(assetId) {
|
|
49
|
+
const existingDigest = this.state.digests[assetId];
|
|
50
|
+
if (existingDigest) {
|
|
51
|
+
const age = Date.now() - existingDigest.fetchedAt;
|
|
52
|
+
if (age < ai_digest_constants_1.CACHE_DURATION_MS) {
|
|
53
|
+
return existingDigest.data;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const data = await __classPrivateFieldGet(this, _AiDigestController_digestService, "f").fetchDigest(assetId);
|
|
57
|
+
const entry = {
|
|
58
|
+
asset: assetId,
|
|
59
|
+
fetchedAt: Date.now(),
|
|
60
|
+
data,
|
|
61
|
+
};
|
|
62
|
+
this.update((state) => {
|
|
63
|
+
state.digests[assetId] = entry;
|
|
64
|
+
__classPrivateFieldGet(this, _AiDigestController_instances, "m", _AiDigestController_evictStaleEntries).call(this, state);
|
|
65
|
+
});
|
|
66
|
+
return data;
|
|
67
|
+
}
|
|
68
|
+
clearDigest(assetId) {
|
|
69
|
+
this.update((state) => {
|
|
70
|
+
delete state.digests[assetId];
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
clearAllDigests() {
|
|
74
|
+
this.update((state) => {
|
|
75
|
+
state.digests = {};
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
exports.AiDigestController = AiDigestController;
|
|
80
|
+
_AiDigestController_digestService = new WeakMap(), _AiDigestController_instances = new WeakSet(), _AiDigestController_registerMessageHandlers = function _AiDigestController_registerMessageHandlers() {
|
|
81
|
+
this.messenger.registerActionHandler(`${ai_digest_constants_1.controllerName}:fetchDigest`, this.fetchDigest.bind(this));
|
|
82
|
+
this.messenger.registerActionHandler(`${ai_digest_constants_1.controllerName}:clearDigest`, this.clearDigest.bind(this));
|
|
83
|
+
this.messenger.registerActionHandler(`${ai_digest_constants_1.controllerName}:clearAllDigests`, this.clearAllDigests.bind(this));
|
|
84
|
+
}, _AiDigestController_evictStaleEntries = function _AiDigestController_evictStaleEntries(state) {
|
|
85
|
+
const now = Date.now();
|
|
86
|
+
const entries = Object.entries(state.digests);
|
|
87
|
+
const keysToDelete = [];
|
|
88
|
+
const freshEntries = [];
|
|
89
|
+
for (const [key, entry] of entries) {
|
|
90
|
+
if (now - entry.fetchedAt >= ai_digest_constants_1.CACHE_DURATION_MS) {
|
|
91
|
+
keysToDelete.push(key);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
freshEntries.push([key, entry]);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Evict oldest entries if over max cache size
|
|
98
|
+
if (freshEntries.length > ai_digest_constants_1.MAX_CACHE_ENTRIES) {
|
|
99
|
+
freshEntries.sort((a, b) => a[1].fetchedAt - b[1].fetchedAt);
|
|
100
|
+
const entriesToRemove = freshEntries.length - ai_digest_constants_1.MAX_CACHE_ENTRIES;
|
|
101
|
+
for (let i = 0; i < entriesToRemove; i++) {
|
|
102
|
+
keysToDelete.push(freshEntries[i][0]);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
for (const key of keysToDelete) {
|
|
106
|
+
delete state.digests[key];
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
//# sourceMappingURL=AiDigestController.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AiDigestController.cjs","sourceRoot":"","sources":["../src/AiDigestController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n StateMetadata,\n ControllerStateChangeEvent,\n ControllerGetStateAction,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\n\nimport {\n 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"]}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ControllerStateChangeEvent, ControllerGetStateAction } from "@metamask/base-controller";
|
|
2
|
+
import { BaseController } from "@metamask/base-controller";
|
|
3
|
+
import type { Messenger } from "@metamask/messenger";
|
|
4
|
+
import { controllerName } from "./ai-digest-constants.cjs";
|
|
5
|
+
import type { AiDigestControllerState, DigestService, DigestData } from "./ai-digest-types.cjs";
|
|
6
|
+
export type AiDigestControllerFetchDigestAction = {
|
|
7
|
+
type: `${typeof controllerName}:fetchDigest`;
|
|
8
|
+
handler: AiDigestController['fetchDigest'];
|
|
9
|
+
};
|
|
10
|
+
export type AiDigestControllerClearDigestAction = {
|
|
11
|
+
type: `${typeof controllerName}:clearDigest`;
|
|
12
|
+
handler: AiDigestController['clearDigest'];
|
|
13
|
+
};
|
|
14
|
+
export type AiDigestControllerClearAllDigestsAction = {
|
|
15
|
+
type: `${typeof controllerName}:clearAllDigests`;
|
|
16
|
+
handler: AiDigestController['clearAllDigests'];
|
|
17
|
+
};
|
|
18
|
+
export type AiDigestControllerGetStateAction = ControllerGetStateAction<typeof controllerName, AiDigestControllerState>;
|
|
19
|
+
export type AiDigestControllerActions = AiDigestControllerFetchDigestAction | AiDigestControllerClearDigestAction | AiDigestControllerClearAllDigestsAction | AiDigestControllerGetStateAction;
|
|
20
|
+
export type AiDigestControllerStateChangeEvent = ControllerStateChangeEvent<typeof controllerName, AiDigestControllerState>;
|
|
21
|
+
export type AiDigestControllerEvents = AiDigestControllerStateChangeEvent;
|
|
22
|
+
export type AiDigestControllerMessenger = Messenger<typeof controllerName, AiDigestControllerActions, AiDigestControllerEvents>;
|
|
23
|
+
export type AiDigestControllerOptions = {
|
|
24
|
+
messenger: AiDigestControllerMessenger;
|
|
25
|
+
state?: Partial<AiDigestControllerState>;
|
|
26
|
+
digestService: DigestService;
|
|
27
|
+
};
|
|
28
|
+
export declare function getDefaultAiDigestControllerState(): AiDigestControllerState;
|
|
29
|
+
export declare class AiDigestController extends BaseController<typeof controllerName, AiDigestControllerState, AiDigestControllerMessenger> {
|
|
30
|
+
#private;
|
|
31
|
+
constructor({ messenger, state, digestService }: AiDigestControllerOptions);
|
|
32
|
+
fetchDigest(assetId: string): Promise<DigestData>;
|
|
33
|
+
clearDigest(assetId: string): void;
|
|
34
|
+
clearAllDigests(): void;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=AiDigestController.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AiDigestController.d.cts","sourceRoot":"","sources":["../src/AiDigestController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,0BAA0B,EAC1B,wBAAwB,EACzB,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAErD,OAAO,EACL,cAAc,EAGf,kCAA8B;AAC/B,OAAO,KAAK,EACV,uBAAuB,EAEvB,aAAa,EACb,UAAU,EACX,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,gCAAgC,GAAG,wBAAwB,CACrE,OAAO,cAAc,EACrB,uBAAuB,CACxB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GACjC,mCAAmC,GACnC,mCAAmC,GACnC,uCAAuC,GACvC,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,CAI3E;AAWD,qBAAa,kBAAmB,SAAQ,cAAc,CACpD,OAAO,cAAc,EACrB,uBAAuB,EACvB,2BAA2B,CAC5B;;gBAGa,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,yBAAyB;IA8BpE,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAyBvD,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAMlC,eAAe,IAAI,IAAI;CAsCxB"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ControllerStateChangeEvent, ControllerGetStateAction } from "@metamask/base-controller";
|
|
2
|
+
import { BaseController } from "@metamask/base-controller";
|
|
3
|
+
import type { Messenger } from "@metamask/messenger";
|
|
4
|
+
import { controllerName } from "./ai-digest-constants.mjs";
|
|
5
|
+
import type { AiDigestControllerState, DigestService, DigestData } from "./ai-digest-types.mjs";
|
|
6
|
+
export type AiDigestControllerFetchDigestAction = {
|
|
7
|
+
type: `${typeof controllerName}:fetchDigest`;
|
|
8
|
+
handler: AiDigestController['fetchDigest'];
|
|
9
|
+
};
|
|
10
|
+
export type AiDigestControllerClearDigestAction = {
|
|
11
|
+
type: `${typeof controllerName}:clearDigest`;
|
|
12
|
+
handler: AiDigestController['clearDigest'];
|
|
13
|
+
};
|
|
14
|
+
export type AiDigestControllerClearAllDigestsAction = {
|
|
15
|
+
type: `${typeof controllerName}:clearAllDigests`;
|
|
16
|
+
handler: AiDigestController['clearAllDigests'];
|
|
17
|
+
};
|
|
18
|
+
export type AiDigestControllerGetStateAction = ControllerGetStateAction<typeof controllerName, AiDigestControllerState>;
|
|
19
|
+
export type AiDigestControllerActions = AiDigestControllerFetchDigestAction | AiDigestControllerClearDigestAction | AiDigestControllerClearAllDigestsAction | AiDigestControllerGetStateAction;
|
|
20
|
+
export type AiDigestControllerStateChangeEvent = ControllerStateChangeEvent<typeof controllerName, AiDigestControllerState>;
|
|
21
|
+
export type AiDigestControllerEvents = AiDigestControllerStateChangeEvent;
|
|
22
|
+
export type AiDigestControllerMessenger = Messenger<typeof controllerName, AiDigestControllerActions, AiDigestControllerEvents>;
|
|
23
|
+
export type AiDigestControllerOptions = {
|
|
24
|
+
messenger: AiDigestControllerMessenger;
|
|
25
|
+
state?: Partial<AiDigestControllerState>;
|
|
26
|
+
digestService: DigestService;
|
|
27
|
+
};
|
|
28
|
+
export declare function getDefaultAiDigestControllerState(): AiDigestControllerState;
|
|
29
|
+
export declare class AiDigestController extends BaseController<typeof controllerName, AiDigestControllerState, AiDigestControllerMessenger> {
|
|
30
|
+
#private;
|
|
31
|
+
constructor({ messenger, state, digestService }: AiDigestControllerOptions);
|
|
32
|
+
fetchDigest(assetId: string): Promise<DigestData>;
|
|
33
|
+
clearDigest(assetId: string): void;
|
|
34
|
+
clearAllDigests(): void;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=AiDigestController.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AiDigestController.d.mts","sourceRoot":"","sources":["../src/AiDigestController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,0BAA0B,EAC1B,wBAAwB,EACzB,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAErD,OAAO,EACL,cAAc,EAGf,kCAA8B;AAC/B,OAAO,KAAK,EACV,uBAAuB,EAEvB,aAAa,EACb,UAAU,EACX,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,gCAAgC,GAAG,wBAAwB,CACrE,OAAO,cAAc,EACrB,uBAAuB,CACxB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GACjC,mCAAmC,GACnC,mCAAmC,GACnC,uCAAuC,GACvC,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,CAI3E;AAWD,qBAAa,kBAAmB,SAAQ,cAAc,CACpD,OAAO,cAAc,EACrB,uBAAuB,EACvB,2BAA2B,CAC5B;;gBAGa,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,yBAAyB;IA8BpE,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAyBvD,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAMlC,eAAe,IAAI,IAAI;CAsCxB"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
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
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _AiDigestController_instances, _AiDigestController_digestService, _AiDigestController_registerMessageHandlers, _AiDigestController_evictStaleEntries;
|
|
13
|
+
import { BaseController } from "@metamask/base-controller";
|
|
14
|
+
import { controllerName, CACHE_DURATION_MS, MAX_CACHE_ENTRIES } from "./ai-digest-constants.mjs";
|
|
15
|
+
export function getDefaultAiDigestControllerState() {
|
|
16
|
+
return {
|
|
17
|
+
digests: {},
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
const aiDigestControllerMetadata = {
|
|
21
|
+
digests: {
|
|
22
|
+
persist: true,
|
|
23
|
+
includeInDebugSnapshot: true,
|
|
24
|
+
includeInStateLogs: true,
|
|
25
|
+
usedInUi: true,
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
export class AiDigestController extends BaseController {
|
|
29
|
+
constructor({ messenger, state, digestService }) {
|
|
30
|
+
super({
|
|
31
|
+
name: controllerName,
|
|
32
|
+
metadata: aiDigestControllerMetadata,
|
|
33
|
+
state: {
|
|
34
|
+
...getDefaultAiDigestControllerState(),
|
|
35
|
+
...state,
|
|
36
|
+
},
|
|
37
|
+
messenger,
|
|
38
|
+
});
|
|
39
|
+
_AiDigestController_instances.add(this);
|
|
40
|
+
_AiDigestController_digestService.set(this, void 0);
|
|
41
|
+
__classPrivateFieldSet(this, _AiDigestController_digestService, digestService, "f");
|
|
42
|
+
__classPrivateFieldGet(this, _AiDigestController_instances, "m", _AiDigestController_registerMessageHandlers).call(this);
|
|
43
|
+
}
|
|
44
|
+
async fetchDigest(assetId) {
|
|
45
|
+
const existingDigest = this.state.digests[assetId];
|
|
46
|
+
if (existingDigest) {
|
|
47
|
+
const age = Date.now() - existingDigest.fetchedAt;
|
|
48
|
+
if (age < CACHE_DURATION_MS) {
|
|
49
|
+
return existingDigest.data;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const data = await __classPrivateFieldGet(this, _AiDigestController_digestService, "f").fetchDigest(assetId);
|
|
53
|
+
const entry = {
|
|
54
|
+
asset: assetId,
|
|
55
|
+
fetchedAt: Date.now(),
|
|
56
|
+
data,
|
|
57
|
+
};
|
|
58
|
+
this.update((state) => {
|
|
59
|
+
state.digests[assetId] = entry;
|
|
60
|
+
__classPrivateFieldGet(this, _AiDigestController_instances, "m", _AiDigestController_evictStaleEntries).call(this, state);
|
|
61
|
+
});
|
|
62
|
+
return data;
|
|
63
|
+
}
|
|
64
|
+
clearDigest(assetId) {
|
|
65
|
+
this.update((state) => {
|
|
66
|
+
delete state.digests[assetId];
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
clearAllDigests() {
|
|
70
|
+
this.update((state) => {
|
|
71
|
+
state.digests = {};
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
_AiDigestController_digestService = new WeakMap(), _AiDigestController_instances = new WeakSet(), _AiDigestController_registerMessageHandlers = function _AiDigestController_registerMessageHandlers() {
|
|
76
|
+
this.messenger.registerActionHandler(`${controllerName}:fetchDigest`, this.fetchDigest.bind(this));
|
|
77
|
+
this.messenger.registerActionHandler(`${controllerName}:clearDigest`, this.clearDigest.bind(this));
|
|
78
|
+
this.messenger.registerActionHandler(`${controllerName}:clearAllDigests`, this.clearAllDigests.bind(this));
|
|
79
|
+
}, _AiDigestController_evictStaleEntries = function _AiDigestController_evictStaleEntries(state) {
|
|
80
|
+
const now = Date.now();
|
|
81
|
+
const entries = Object.entries(state.digests);
|
|
82
|
+
const keysToDelete = [];
|
|
83
|
+
const freshEntries = [];
|
|
84
|
+
for (const [key, entry] of entries) {
|
|
85
|
+
if (now - entry.fetchedAt >= CACHE_DURATION_MS) {
|
|
86
|
+
keysToDelete.push(key);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
freshEntries.push([key, entry]);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Evict oldest entries if over max cache size
|
|
93
|
+
if (freshEntries.length > MAX_CACHE_ENTRIES) {
|
|
94
|
+
freshEntries.sort((a, b) => a[1].fetchedAt - b[1].fetchedAt);
|
|
95
|
+
const entriesToRemove = freshEntries.length - MAX_CACHE_ENTRIES;
|
|
96
|
+
for (let i = 0; i < entriesToRemove; i++) {
|
|
97
|
+
keysToDelete.push(freshEntries[i][0]);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
for (const key of keysToDelete) {
|
|
101
|
+
delete state.digests[key];
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
//# sourceMappingURL=AiDigestController.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AiDigestController.mjs","sourceRoot":"","sources":["../src/AiDigestController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n StateMetadata,\n ControllerStateChangeEvent,\n ControllerGetStateAction,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\n\nimport {\n 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"]}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
+
};
|
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
+
};
|
|
13
|
+
var _AiDigestService_baseUrl;
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.AiDigestService = void 0;
|
|
16
|
+
const ai_digest_constants_1 = require("./ai-digest-constants.cjs");
|
|
17
|
+
class AiDigestService {
|
|
18
|
+
constructor(config) {
|
|
19
|
+
_AiDigestService_baseUrl.set(this, void 0);
|
|
20
|
+
__classPrivateFieldSet(this, _AiDigestService_baseUrl, config.baseUrl, "f");
|
|
21
|
+
}
|
|
22
|
+
async fetchDigest(assetId) {
|
|
23
|
+
const response = await fetch(`${__classPrivateFieldGet(this, _AiDigestService_baseUrl, "f")}/digests/assets/${encodeURIComponent(assetId)}/latest`);
|
|
24
|
+
if (!response.ok) {
|
|
25
|
+
throw new Error(`${ai_digest_constants_1.AiDigestControllerErrorMessage.API_REQUEST_FAILED}: ${response.status}`);
|
|
26
|
+
}
|
|
27
|
+
const data = await response.json();
|
|
28
|
+
if (!data.success) {
|
|
29
|
+
throw new Error(data.error ?? ai_digest_constants_1.AiDigestControllerErrorMessage.API_RETURNED_ERROR);
|
|
30
|
+
}
|
|
31
|
+
return data;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
exports.AiDigestService = AiDigestService;
|
|
35
|
+
_AiDigestService_baseUrl = new WeakMap();
|
|
36
|
+
//# sourceMappingURL=AiDigestService.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AiDigestService.cjs","sourceRoot":"","sources":["../src/AiDigestService.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,mEAAuE;AAOvE,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;CACF;AA5BD,0CA4BC","sourcesContent":["import { AiDigestControllerErrorMessage } from './ai-digest-constants';\nimport type { DigestService, DigestData } 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"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { DigestService, DigestData } from "./ai-digest-types.cjs";
|
|
2
|
+
export type AiDigestServiceConfig = {
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
};
|
|
5
|
+
export declare class AiDigestService implements DigestService {
|
|
6
|
+
#private;
|
|
7
|
+
constructor(config: AiDigestServiceConfig);
|
|
8
|
+
fetchDigest(assetId: string): Promise<DigestData>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=AiDigestService.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AiDigestService.d.cts","sourceRoot":"","sources":["../src/AiDigestService.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,8BAA0B;AAEnE,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;CAqBxD"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { DigestService, DigestData } from "./ai-digest-types.mjs";
|
|
2
|
+
export type AiDigestServiceConfig = {
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
};
|
|
5
|
+
export declare class AiDigestService implements DigestService {
|
|
6
|
+
#private;
|
|
7
|
+
constructor(config: AiDigestServiceConfig);
|
|
8
|
+
fetchDigest(assetId: string): Promise<DigestData>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=AiDigestService.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AiDigestService.d.mts","sourceRoot":"","sources":["../src/AiDigestService.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,8BAA0B;AAEnE,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;CAqBxD"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
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
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _AiDigestService_baseUrl;
|
|
13
|
+
import { AiDigestControllerErrorMessage } from "./ai-digest-constants.mjs";
|
|
14
|
+
export class AiDigestService {
|
|
15
|
+
constructor(config) {
|
|
16
|
+
_AiDigestService_baseUrl.set(this, void 0);
|
|
17
|
+
__classPrivateFieldSet(this, _AiDigestService_baseUrl, config.baseUrl, "f");
|
|
18
|
+
}
|
|
19
|
+
async fetchDigest(assetId) {
|
|
20
|
+
const response = await fetch(`${__classPrivateFieldGet(this, _AiDigestService_baseUrl, "f")}/digests/assets/${encodeURIComponent(assetId)}/latest`);
|
|
21
|
+
if (!response.ok) {
|
|
22
|
+
throw new Error(`${AiDigestControllerErrorMessage.API_REQUEST_FAILED}: ${response.status}`);
|
|
23
|
+
}
|
|
24
|
+
const data = await response.json();
|
|
25
|
+
if (!data.success) {
|
|
26
|
+
throw new Error(data.error ?? AiDigestControllerErrorMessage.API_RETURNED_ERROR);
|
|
27
|
+
}
|
|
28
|
+
return data;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
_AiDigestService_baseUrl = new WeakMap();
|
|
32
|
+
//# sourceMappingURL=AiDigestService.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AiDigestService.mjs","sourceRoot":"","sources":["../src/AiDigestService.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,8BAA8B,EAAE,kCAA8B;AAOvE,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;CACF","sourcesContent":["import { AiDigestControllerErrorMessage } from './ai-digest-constants';\nimport type { DigestService, DigestData } 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"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AiDigestControllerErrorMessage = exports.MAX_CACHE_ENTRIES = exports.CACHE_DURATION_MS = exports.controllerName = void 0;
|
|
4
|
+
exports.controllerName = 'AiDigestController';
|
|
5
|
+
exports.CACHE_DURATION_MS = 10 * 60 * 1000; // 10 minutes
|
|
6
|
+
exports.MAX_CACHE_ENTRIES = 50;
|
|
7
|
+
exports.AiDigestControllerErrorMessage = {
|
|
8
|
+
API_REQUEST_FAILED: 'API request failed',
|
|
9
|
+
API_RETURNED_ERROR: 'API returned error',
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=ai-digest-constants.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-digest-constants.cjs","sourceRoot":"","sources":["../src/ai-digest-constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,cAAc,GAAG,oBAAoB,CAAC;AAEtC,QAAA,iBAAiB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;AAEjD,QAAA,iBAAiB,GAAG,EAAE,CAAC;AAEvB,QAAA,8BAA8B,GAAG;IAC5C,kBAAkB,EAAE,oBAAoB;IACxC,kBAAkB,EAAE,oBAAoB;CAChC,CAAC","sourcesContent":["export const controllerName = 'AiDigestController';\n\nexport const CACHE_DURATION_MS = 10 * 60 * 1000; // 10 minutes\n\nexport const MAX_CACHE_ENTRIES = 50;\n\nexport const AiDigestControllerErrorMessage = {\n API_REQUEST_FAILED: 'API request failed',\n API_RETURNED_ERROR: 'API returned error',\n} as const;\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const controllerName = "AiDigestController";
|
|
2
|
+
export declare const CACHE_DURATION_MS: number;
|
|
3
|
+
export declare const MAX_CACHE_ENTRIES = 50;
|
|
4
|
+
export declare const AiDigestControllerErrorMessage: {
|
|
5
|
+
readonly API_REQUEST_FAILED: "API request failed";
|
|
6
|
+
readonly API_RETURNED_ERROR: "API returned error";
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=ai-digest-constants.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-digest-constants.d.cts","sourceRoot":"","sources":["../src/ai-digest-constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,uBAAuB,CAAC;AAEnD,eAAO,MAAM,iBAAiB,QAAiB,CAAC;AAEhD,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAEpC,eAAO,MAAM,8BAA8B;;;CAGjC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const controllerName = "AiDigestController";
|
|
2
|
+
export declare const CACHE_DURATION_MS: number;
|
|
3
|
+
export declare const MAX_CACHE_ENTRIES = 50;
|
|
4
|
+
export declare const AiDigestControllerErrorMessage: {
|
|
5
|
+
readonly API_REQUEST_FAILED: "API request failed";
|
|
6
|
+
readonly API_RETURNED_ERROR: "API returned error";
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=ai-digest-constants.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-digest-constants.d.mts","sourceRoot":"","sources":["../src/ai-digest-constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,uBAAuB,CAAC;AAEnD,eAAO,MAAM,iBAAiB,QAAiB,CAAC;AAEhD,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAEpC,eAAO,MAAM,8BAA8B;;;CAGjC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const controllerName = 'AiDigestController';
|
|
2
|
+
export const CACHE_DURATION_MS = 10 * 60 * 1000; // 10 minutes
|
|
3
|
+
export const MAX_CACHE_ENTRIES = 50;
|
|
4
|
+
export const AiDigestControllerErrorMessage = {
|
|
5
|
+
API_REQUEST_FAILED: 'API request failed',
|
|
6
|
+
API_RETURNED_ERROR: 'API returned error',
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=ai-digest-constants.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-digest-constants.mjs","sourceRoot":"","sources":["../src/ai-digest-constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG,oBAAoB,CAAC;AAEnD,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;AAE9D,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAEpC,MAAM,CAAC,MAAM,8BAA8B,GAAG;IAC5C,kBAAkB,EAAE,oBAAoB;IACxC,kBAAkB,EAAE,oBAAoB;CAChC,CAAC","sourcesContent":["export const controllerName = 'AiDigestController';\n\nexport const CACHE_DURATION_MS = 10 * 60 * 1000; // 10 minutes\n\nexport const MAX_CACHE_ENTRIES = 50;\n\nexport const AiDigestControllerErrorMessage = {\n API_REQUEST_FAILED: 'API request failed',\n API_RETURNED_ERROR: 'API returned error',\n} as const;\n"]}
|
|
@@ -0,0 +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"]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Response from the digest API.
|
|
3
|
+
*/
|
|
4
|
+
export type DigestData = {
|
|
5
|
+
id: string;
|
|
6
|
+
assetId: string;
|
|
7
|
+
assetSymbol?: string;
|
|
8
|
+
digest: string;
|
|
9
|
+
generatedAt: string;
|
|
10
|
+
processingTime: number;
|
|
11
|
+
success: boolean;
|
|
12
|
+
error?: string;
|
|
13
|
+
createdAt: string;
|
|
14
|
+
updatedAt: string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* A cached digest entry. Only successful fetches are stored.
|
|
18
|
+
*/
|
|
19
|
+
export type DigestEntry = {
|
|
20
|
+
asset: string;
|
|
21
|
+
fetchedAt: number;
|
|
22
|
+
data: DigestData;
|
|
23
|
+
};
|
|
24
|
+
export type AiDigestControllerState = {
|
|
25
|
+
digests: Record<string, DigestEntry>;
|
|
26
|
+
};
|
|
27
|
+
export type DigestService = {
|
|
28
|
+
fetchDigest(assetId: string): Promise<DigestData>;
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=ai-digest-types.d.cts.map
|
|
@@ -0,0 +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,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACnD,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Response from the digest API.
|
|
3
|
+
*/
|
|
4
|
+
export type DigestData = {
|
|
5
|
+
id: string;
|
|
6
|
+
assetId: string;
|
|
7
|
+
assetSymbol?: string;
|
|
8
|
+
digest: string;
|
|
9
|
+
generatedAt: string;
|
|
10
|
+
processingTime: number;
|
|
11
|
+
success: boolean;
|
|
12
|
+
error?: string;
|
|
13
|
+
createdAt: string;
|
|
14
|
+
updatedAt: string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* A cached digest entry. Only successful fetches are stored.
|
|
18
|
+
*/
|
|
19
|
+
export type DigestEntry = {
|
|
20
|
+
asset: string;
|
|
21
|
+
fetchedAt: number;
|
|
22
|
+
data: DigestData;
|
|
23
|
+
};
|
|
24
|
+
export type AiDigestControllerState = {
|
|
25
|
+
digests: Record<string, DigestEntry>;
|
|
26
|
+
};
|
|
27
|
+
export type DigestService = {
|
|
28
|
+
fetchDigest(assetId: string): Promise<DigestData>;
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=ai-digest-types.d.mts.map
|
|
@@ -0,0 +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,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACnD,CAAC"}
|
|
@@ -0,0 +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"]}
|
package/dist/index.cjs
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
exports.
|
|
3
|
+
exports.AiDigestControllerErrorMessage = exports.MAX_CACHE_ENTRIES = exports.CACHE_DURATION_MS = exports.aiDigestControllerName = exports.AiDigestService = exports.getDefaultAiDigestControllerState = exports.AiDigestController = void 0;
|
|
4
|
+
var AiDigestController_1 = require("./AiDigestController.cjs");
|
|
5
|
+
Object.defineProperty(exports, "AiDigestController", { enumerable: true, get: function () { return AiDigestController_1.AiDigestController; } });
|
|
6
|
+
Object.defineProperty(exports, "getDefaultAiDigestControllerState", { enumerable: true, get: function () { return AiDigestController_1.getDefaultAiDigestControllerState; } });
|
|
7
|
+
var AiDigestService_1 = require("./AiDigestService.cjs");
|
|
8
|
+
Object.defineProperty(exports, "AiDigestService", { enumerable: true, get: function () { return AiDigestService_1.AiDigestService; } });
|
|
9
|
+
var ai_digest_constants_1 = require("./ai-digest-constants.cjs");
|
|
10
|
+
Object.defineProperty(exports, "aiDigestControllerName", { enumerable: true, get: function () { return ai_digest_constants_1.controllerName; } });
|
|
11
|
+
Object.defineProperty(exports, "CACHE_DURATION_MS", { enumerable: true, get: function () { return ai_digest_constants_1.CACHE_DURATION_MS; } });
|
|
12
|
+
Object.defineProperty(exports, "MAX_CACHE_ENTRIES", { enumerable: true, get: function () { return ai_digest_constants_1.MAX_CACHE_ENTRIES; } });
|
|
13
|
+
Object.defineProperty(exports, "AiDigestControllerErrorMessage", { enumerable: true, get: function () { return ai_digest_constants_1.AiDigestControllerErrorMessage; } });
|
|
13
14
|
//# sourceMappingURL=index.cjs.map
|
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":";;;AAWA,+DAG8B;AAF5B,wHAAA,kBAAkB,OAAA;AAClB,uIAAA,iCAAiC,OAAA;AAInC,yDAAoD;AAA3C,kHAAA,eAAe,OAAA;AASxB,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 AiDigestControllerEvents,\n AiDigestControllerFetchDigestAction,\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} 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,8 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export default function greeter(name: string): string;
|
|
1
|
+
export type { AiDigestControllerActions, AiDigestControllerClearAllDigestsAction, AiDigestControllerClearDigestAction, AiDigestControllerEvents, AiDigestControllerFetchDigestAction, AiDigestControllerGetStateAction, AiDigestControllerMessenger, AiDigestControllerOptions, AiDigestControllerStateChangeEvent, } from "./AiDigestController.cjs";
|
|
2
|
+
export { AiDigestController, getDefaultAiDigestControllerState, } from "./AiDigestController.cjs";
|
|
3
|
+
export type { AiDigestServiceConfig } from "./AiDigestService.cjs";
|
|
4
|
+
export { AiDigestService } from "./AiDigestService.cjs";
|
|
5
|
+
export type { AiDigestControllerState, DigestData, DigestEntry, DigestService, } from "./ai-digest-types.cjs";
|
|
6
|
+
export { controllerName as aiDigestControllerName, CACHE_DURATION_MS, MAX_CACHE_ENTRIES, AiDigestControllerErrorMessage, } from "./ai-digest-constants.cjs";
|
|
8
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
|
|
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,GACd,8BAA0B;AAE3B,OAAO,EACL,cAAc,IAAI,sBAAsB,EACxC,iBAAiB,EACjB,iBAAiB,EACjB,8BAA8B,GAC/B,kCAA8B"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export default function greeter(name: string): string;
|
|
1
|
+
export type { AiDigestControllerActions, AiDigestControllerClearAllDigestsAction, AiDigestControllerClearDigestAction, AiDigestControllerEvents, AiDigestControllerFetchDigestAction, AiDigestControllerGetStateAction, AiDigestControllerMessenger, AiDigestControllerOptions, AiDigestControllerStateChangeEvent, } from "./AiDigestController.mjs";
|
|
2
|
+
export { AiDigestController, getDefaultAiDigestControllerState, } from "./AiDigestController.mjs";
|
|
3
|
+
export type { AiDigestServiceConfig } from "./AiDigestService.mjs";
|
|
4
|
+
export { AiDigestService } from "./AiDigestService.mjs";
|
|
5
|
+
export type { AiDigestControllerState, DigestData, DigestEntry, DigestService, } from "./ai-digest-types.mjs";
|
|
6
|
+
export { controllerName as aiDigestControllerName, CACHE_DURATION_MS, MAX_CACHE_ENTRIES, AiDigestControllerErrorMessage, } from "./ai-digest-constants.mjs";
|
|
8
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
|
|
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,GACd,8BAA0B;AAE3B,OAAO,EACL,cAAc,IAAI,sBAAsB,EACxC,iBAAiB,EACjB,iBAAiB,EACjB,8BAA8B,GAC/B,kCAA8B"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* @param name - The name to greet.
|
|
5
|
-
* @returns The greeting.
|
|
6
|
-
*/
|
|
7
|
-
export default function greeter(name) {
|
|
8
|
-
return `Hello, ${name}!`;
|
|
9
|
-
}
|
|
1
|
+
export { AiDigestController, getDefaultAiDigestControllerState } from "./AiDigestController.mjs";
|
|
2
|
+
export { AiDigestService } from "./AiDigestService.mjs";
|
|
3
|
+
export { controllerName as aiDigestControllerName, CACHE_DURATION_MS, MAX_CACHE_ENTRIES, AiDigestControllerErrorMessage } from "./ai-digest-constants.mjs";
|
|
10
4
|
//# sourceMappingURL=index.mjs.map
|
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":"AAWA,OAAO,EACL,kBAAkB,EAClB,iCAAiC,EAClC,iCAA6B;AAG9B,OAAO,EAAE,eAAe,EAAE,8BAA0B;AASpD,OAAO,EACL,cAAc,IAAI,sBAAsB,EACxC,iBAAiB,EACjB,iBAAiB,EACjB,8BAA8B,EAC/B,kCAA8B","sourcesContent":["export type {\n AiDigestControllerActions,\n AiDigestControllerClearAllDigestsAction,\n AiDigestControllerClearDigestAction,\n AiDigestControllerEvents,\n AiDigestControllerFetchDigestAction,\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} 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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask-previews/ai-controllers",
|
|
3
|
-
"version": "0.0.0-preview-
|
|
3
|
+
"version": "0.0.0-preview-6dfa4aeba",
|
|
4
4
|
"description": "A collection of AI-related controllers",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"MetaMask",
|
|
@@ -47,13 +47,17 @@
|
|
|
47
47
|
"test:verbose": "NODE_OPTIONS=--experimental-vm-modules jest --verbose",
|
|
48
48
|
"test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch"
|
|
49
49
|
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"@metamask/base-controller": "^9.0.0",
|
|
52
|
+
"@metamask/messenger": "^0.3.0"
|
|
53
|
+
},
|
|
50
54
|
"devDependencies": {
|
|
51
55
|
"@metamask/auto-changelog": "^3.4.4",
|
|
52
56
|
"@ts-bridge/cli": "^0.6.4",
|
|
53
|
-
"@types/jest": "^27.
|
|
57
|
+
"@types/jest": "^27.5.2",
|
|
54
58
|
"deepmerge": "^4.2.2",
|
|
55
59
|
"jest": "^27.5.1",
|
|
56
|
-
"ts-jest": "^27.1.
|
|
60
|
+
"ts-jest": "^27.1.5",
|
|
57
61
|
"typedoc": "^0.24.8",
|
|
58
62
|
"typedoc-plugin-missing-exports": "^2.0.0",
|
|
59
63
|
"typescript": "~5.3.3"
|