@metamask-previews/base-data-service 0.0.0-preview-a0caca0c0 → 0.1.0-preview-afe010990

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 CHANGED
@@ -7,4 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
- [Unreleased]: https://github.com/MetaMask/core/
10
+ ## [0.1.0]
11
+
12
+ ### Added
13
+
14
+ - Initial release ([#8039](https://github.com/MetaMask/core/pull/8039), [#8292](https://github.com/MetaMask/core/pull/8292))
15
+
16
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/base-data-service@0.1.0...HEAD
17
+ [0.1.0]: https://github.com/MetaMask/core/releases/tag/@metamask/base-data-service@0.1.0
@@ -0,0 +1,150 @@
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 __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ var _BaseDataService_instances, _BaseDataService_messenger, _BaseDataService_policy, _BaseDataService_queryClient, _BaseDataService_queryCacheUnsubscribe, _BaseDataService_publishCacheUpdate;
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.BaseDataService = void 0;
19
+ const controller_utils_1 = require("@metamask/controller-utils");
20
+ const messenger_1 = require("@metamask/messenger");
21
+ const utils_1 = require("@metamask/utils");
22
+ const query_core_1 = require("@tanstack/query-core");
23
+ const fast_deep_equal_1 = __importDefault(require("fast-deep-equal"));
24
+ // Defaults to apply to all data service queries if no default option specified
25
+ const QUERY_CLIENT_DEFAULTS = {
26
+ queries: {
27
+ retry: false,
28
+ staleTime: (0, utils_1.inMilliseconds)(1, utils_1.Duration.Minute),
29
+ },
30
+ };
31
+ class BaseDataService {
32
+ constructor({ name, messenger, queryClientConfig = {}, policyOptions, }) {
33
+ _BaseDataService_instances.add(this);
34
+ _BaseDataService_messenger.set(this, void 0);
35
+ _BaseDataService_policy.set(this, void 0);
36
+ _BaseDataService_queryClient.set(this, void 0);
37
+ _BaseDataService_queryCacheUnsubscribe.set(this, void 0);
38
+ this.name = name;
39
+ // We are storing a separately typed messenger for known actions and events provided by data services
40
+ // and a generic public one that is typed using the generic parameters and accessible to implementations.
41
+ __classPrivateFieldSet(this, _BaseDataService_messenger, messenger, "f");
42
+ this.messenger = messenger;
43
+ __classPrivateFieldSet(this, _BaseDataService_queryClient, new query_core_1.QueryClient({
44
+ ...queryClientConfig,
45
+ defaultOptions: {
46
+ queries: {
47
+ ...QUERY_CLIENT_DEFAULTS.queries,
48
+ ...queryClientConfig.defaultOptions?.queries,
49
+ },
50
+ mutations: queryClientConfig.defaultOptions?.mutations,
51
+ },
52
+ }), "f");
53
+ __classPrivateFieldSet(this, _BaseDataService_policy, (0, controller_utils_1.createServicePolicy)(policyOptions), "f");
54
+ __classPrivateFieldSet(this, _BaseDataService_queryCacheUnsubscribe, __classPrivateFieldGet(this, _BaseDataService_queryClient, "f")
55
+ .getQueryCache()
56
+ .subscribe((event) => {
57
+ if (['added', 'updated', 'removed'].includes(event.type)) {
58
+ __classPrivateFieldGet(this, _BaseDataService_instances, "m", _BaseDataService_publishCacheUpdate).call(this, event.query.queryHash, event.type);
59
+ }
60
+ }), "f");
61
+ __classPrivateFieldGet(this, _BaseDataService_messenger, "f").registerActionHandler(`${this.name}:invalidateQueries`, this.invalidateQueries.bind(this));
62
+ }
63
+ /**
64
+ * Fetch a query.
65
+ *
66
+ * @param options - The options defining the query. Keep in mind that `queryKey` and `queryFn` are required when using data services.
67
+ * Additionally `retry` and `retryDelay` are not available, retries can be customized using the `servicePolicyOptions`.
68
+ * @returns The query results.
69
+ */
70
+ async fetchQuery(options) {
71
+ return __classPrivateFieldGet(this, _BaseDataService_queryClient, "f").fetchQuery({
72
+ ...options,
73
+ queryFn: (context) => __classPrivateFieldGet(this, _BaseDataService_policy, "f").execute(() => options.queryFn(context)),
74
+ });
75
+ }
76
+ /**
77
+ * Fetch a paginated query.
78
+ *
79
+ * @param options - The options defining the query. Keep in mind that `queryKey` and `queryFn` are required when using data services.
80
+ * Additionally `retry` and `retryDelay` are not available, retries can be customized using the `servicePolicyOptions`.
81
+ * @param pageParam - An optional page parameter.
82
+ * @returns The query result, exclusively the requested page is returned.
83
+ */
84
+ async fetchInfiniteQuery(options, pageParam) {
85
+ const cache = __classPrivateFieldGet(this, _BaseDataService_queryClient, "f").getQueryCache();
86
+ const query = cache.find({
87
+ queryKey: options.queryKey,
88
+ });
89
+ if (!query?.state.data || pageParam === undefined) {
90
+ const result = await __classPrivateFieldGet(this, _BaseDataService_queryClient, "f").fetchInfiniteQuery({
91
+ ...options,
92
+ queryFn: (context) => __classPrivateFieldGet(this, _BaseDataService_policy, "f").execute(() => options.queryFn({
93
+ ...context,
94
+ pageParam: context.pageParam ?? pageParam,
95
+ })),
96
+ });
97
+ return result.pages[0];
98
+ }
99
+ const { pages } = query.state.data;
100
+ const previous = options.getPreviousPageParam?.(pages[0], pages);
101
+ const direction = (0, fast_deep_equal_1.default)(pageParam, previous) ? 'backward' : 'forward';
102
+ const result = await query.fetch(undefined, {
103
+ meta: {
104
+ fetchMore: {
105
+ direction,
106
+ pageParam,
107
+ },
108
+ },
109
+ });
110
+ const pageIndex = result.pageParams.findIndex((param) => (0, fast_deep_equal_1.default)(param, pageParam));
111
+ return result.pages[pageIndex];
112
+ }
113
+ /**
114
+ * Invalidate queries serviced by this data service.
115
+ *
116
+ * @param filters - Optional filter for selecting specific queries.
117
+ * @param options - Additional optional options for query invalidations.
118
+ * @returns Nothing.
119
+ */
120
+ async invalidateQueries(filters, options) {
121
+ return __classPrivateFieldGet(this, _BaseDataService_queryClient, "f").invalidateQueries(filters, options);
122
+ }
123
+ /**
124
+ * Prepares the service for garbage collection. This should be extended
125
+ * by any subclasses to clean up any additional connections or events.
126
+ */
127
+ destroy() {
128
+ __classPrivateFieldGet(this, _BaseDataService_queryCacheUnsubscribe, "f").call(this);
129
+ this.messenger.clearSubscriptions();
130
+ this.messenger.clearActions();
131
+ }
132
+ }
133
+ exports.BaseDataService = BaseDataService;
134
+ _BaseDataService_messenger = new WeakMap(), _BaseDataService_policy = new WeakMap(), _BaseDataService_queryClient = new WeakMap(), _BaseDataService_queryCacheUnsubscribe = new WeakMap(), _BaseDataService_instances = new WeakSet(), _BaseDataService_publishCacheUpdate = function _BaseDataService_publishCacheUpdate(hash, type) {
135
+ const state = type === 'added' || type === 'updated'
136
+ ? (0, query_core_1.dehydrate)(__classPrivateFieldGet(this, _BaseDataService_queryClient, "f"), {
137
+ shouldDehydrateQuery: (query) => query.queryHash === hash,
138
+ })
139
+ : null;
140
+ __classPrivateFieldGet(this, _BaseDataService_messenger, "f").publish(`${this.name}:cacheUpdated`, {
141
+ type,
142
+ hash,
143
+ state,
144
+ });
145
+ __classPrivateFieldGet(this, _BaseDataService_messenger, "f").publish(`${this.name}:cacheUpdated:${hash}`, {
146
+ type,
147
+ state,
148
+ });
149
+ };
150
+ //# sourceMappingURL=BaseDataService.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseDataService.cjs","sourceRoot":"","sources":["../src/BaseDataService.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createServicePolicy,\n CreateServicePolicyOptions,\n ServicePolicy,\n} from '@metamask/controller-utils';\nimport {\n Messenger,\n ActionConstraint,\n EventConstraint,\n} from '@metamask/messenger';\nimport { Duration, inMilliseconds } from '@metamask/utils';\nimport type { Json } from '@metamask/utils';\nimport {\n DefaultOptions,\n DehydratedState,\n FetchInfiniteQueryOptions,\n FetchQueryOptions,\n InfiniteData,\n InvalidateOptions,\n InvalidateQueryFilters,\n OmitKeyof,\n QueryClient,\n QueryClientConfig,\n WithRequired,\n dehydrate,\n} from '@tanstack/query-core';\nimport deepEqual from 'fast-deep-equal';\n\n// Data service queries use the following format: ['ServiceActionName', ...params]\nexport type QueryKey = [string, ...Json[]];\n\nexport type DataServiceGranularCacheUpdatedPayload =\n | { type: 'added' | 'updated'; state: DehydratedState }\n | {\n type: 'removed';\n state: null;\n };\n\nexport type DataServiceCacheUpdatedPayload =\n DataServiceGranularCacheUpdatedPayload & {\n hash: string;\n };\n\ntype CacheUpdatedType = DataServiceCacheUpdatedPayload['type'];\n\nexport type DataServiceInvalidateQueriesAction<ServiceName extends string> = {\n type: `${ServiceName}:invalidateQueries`;\n handler: (\n filters?: InvalidateQueryFilters<Json>,\n options?: InvalidateOptions,\n ) => Promise<void>;\n};\n\ntype DataServiceActions<ServiceName extends string> =\n DataServiceInvalidateQueriesAction<ServiceName>;\n\nexport type DataServiceCacheUpdatedEvent<ServiceName extends string> = {\n type: `${ServiceName}:cacheUpdated`;\n payload: [DataServiceCacheUpdatedPayload];\n};\n\nexport type DataServiceGranularCacheUpdatedEvent<ServiceName extends string> = {\n type: `${ServiceName}:cacheUpdated:${string}`;\n payload: [DataServiceGranularCacheUpdatedPayload];\n};\n\ntype DataServiceEvents<ServiceName extends string> =\n | DataServiceCacheUpdatedEvent<ServiceName>\n | DataServiceGranularCacheUpdatedEvent<ServiceName>;\n\n// Defaults to apply to all data service queries if no default option specified\nconst QUERY_CLIENT_DEFAULTS: DefaultOptions = {\n queries: {\n retry: false,\n staleTime: inMilliseconds(1, Duration.Minute),\n },\n};\n\nexport class BaseDataService<\n ServiceName extends string,\n ServiceMessenger extends Messenger<\n ServiceName,\n ActionConstraint,\n EventConstraint,\n // Use `any` to allow any parent to be set. `any` is harmless in a type constraint anyway,\n // it's the one totally safe place to use it.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any\n >,\n> {\n public readonly name: ServiceName;\n\n readonly #messenger: Messenger<\n ServiceName,\n DataServiceActions<ServiceName>,\n DataServiceEvents<ServiceName>\n >;\n\n protected messenger: ServiceMessenger;\n\n readonly #policy: ServicePolicy;\n\n readonly #queryClient: QueryClient;\n\n readonly #queryCacheUnsubscribe: () => void;\n\n constructor({\n name,\n messenger,\n queryClientConfig = {},\n policyOptions,\n }: {\n name: ServiceName;\n messenger: ServiceMessenger;\n queryClientConfig?: QueryClientConfig;\n policyOptions?: CreateServicePolicyOptions;\n }) {\n this.name = name;\n\n // We are storing a separately typed messenger for known actions and events provided by data services\n // and a generic public one that is typed using the generic parameters and accessible to implementations.\n this.#messenger = messenger as unknown as Messenger<\n ServiceName,\n DataServiceActions<ServiceName>,\n DataServiceEvents<ServiceName>\n >;\n this.messenger = messenger;\n\n this.#queryClient = new QueryClient({\n ...queryClientConfig,\n defaultOptions: {\n queries: {\n ...QUERY_CLIENT_DEFAULTS.queries,\n ...queryClientConfig.defaultOptions?.queries,\n },\n mutations: queryClientConfig.defaultOptions?.mutations,\n },\n });\n\n this.#policy = createServicePolicy(policyOptions);\n\n this.#queryCacheUnsubscribe = this.#queryClient\n .getQueryCache()\n .subscribe((event) => {\n if (['added', 'updated', 'removed'].includes(event.type)) {\n this.#publishCacheUpdate(\n event.query.queryHash,\n event.type as CacheUpdatedType,\n );\n }\n });\n\n this.#messenger.registerActionHandler(\n `${this.name}:invalidateQueries`,\n this.invalidateQueries.bind(this),\n );\n }\n\n /**\n * Fetch a query.\n *\n * @param options - The options defining the query. Keep in mind that `queryKey` and `queryFn` are required when using data services.\n * Additionally `retry` and `retryDelay` are not available, retries can be customized using the `servicePolicyOptions`.\n * @returns The query results.\n */\n protected async fetchQuery<\n TQueryFnData extends Json,\n TError = unknown,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n >(\n options: WithRequired<\n OmitKeyof<\n FetchQueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n 'retry' | 'retryDelay'\n >,\n 'queryKey' | 'queryFn'\n >,\n ): Promise<TData> {\n return this.#queryClient.fetchQuery({\n ...options,\n queryFn: (context) =>\n this.#policy.execute(() => options.queryFn(context)),\n });\n }\n\n /**\n * Fetch a paginated query.\n *\n * @param options - The options defining the query. Keep in mind that `queryKey` and `queryFn` are required when using data services.\n * Additionally `retry` and `retryDelay` are not available, retries can be customized using the `servicePolicyOptions`.\n * @param pageParam - An optional page parameter.\n * @returns The query result, exclusively the requested page is returned.\n */\n protected async fetchInfiniteQuery<\n TQueryFnData extends Json,\n TError = unknown,\n TData extends TQueryFnData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam extends Json = Json,\n >(\n options: WithRequired<\n OmitKeyof<\n FetchInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n 'retry' | 'retryDelay'\n >,\n 'queryKey' | 'queryFn'\n >,\n pageParam?: TPageParam,\n ): Promise<TData> {\n const cache = this.#queryClient.getQueryCache();\n\n const query = cache.find<TQueryFnData, TError, InfiniteData<TData>>({\n queryKey: options.queryKey,\n });\n\n if (!query?.state.data || pageParam === undefined) {\n const result = await this.#queryClient.fetchInfiniteQuery({\n ...options,\n queryFn: (context) =>\n this.#policy.execute(() =>\n options.queryFn({\n ...context,\n pageParam: context.pageParam ?? pageParam,\n }),\n ),\n });\n\n return result.pages[0];\n }\n\n const { pages } = query.state.data;\n const previous = options.getPreviousPageParam?.(pages[0], pages);\n\n const direction = deepEqual(pageParam, previous) ? 'backward' : 'forward';\n\n const result = await query.fetch(undefined, {\n meta: {\n fetchMore: {\n direction,\n pageParam,\n },\n },\n });\n\n const pageIndex = result.pageParams.findIndex((param) =>\n deepEqual(param, pageParam),\n );\n\n return result.pages[pageIndex];\n }\n\n /**\n * Invalidate queries serviced by this data service.\n *\n * @param filters - Optional filter for selecting specific queries.\n * @param options - Additional optional options for query invalidations.\n * @returns Nothing.\n */\n async invalidateQueries<TPageData extends Json>(\n filters?: InvalidateQueryFilters<TPageData>,\n options?: InvalidateOptions,\n ): Promise<void> {\n return this.#queryClient.invalidateQueries(filters, options);\n }\n\n /**\n * Prepares the service for garbage collection. This should be extended\n * by any subclasses to clean up any additional connections or events.\n */\n destroy(): void {\n this.#queryCacheUnsubscribe();\n this.messenger.clearSubscriptions();\n this.messenger.clearActions();\n }\n\n /**\n * Publish `cacheUpdated` events when a given query changes.\n *\n * @param hash The hash of the query.\n * @param type The type of cache update.\n */\n #publishCacheUpdate(hash: string, type: CacheUpdatedType): void {\n const state =\n type === 'added' || type === 'updated'\n ? dehydrate(this.#queryClient, {\n shouldDehydrateQuery: (query) => query.queryHash === hash,\n })\n : null;\n\n this.#messenger.publish(\n `${this.name}:cacheUpdated` as const,\n {\n type,\n hash,\n state,\n } as DataServiceCacheUpdatedPayload,\n );\n\n this.#messenger.publish(\n `${this.name}:cacheUpdated:${hash}` as const,\n {\n type,\n state,\n } as DataServiceGranularCacheUpdatedPayload,\n );\n }\n}\n"]}
@@ -0,0 +1,69 @@
1
+ import { CreateServicePolicyOptions } from "@metamask/controller-utils";
2
+ import { Messenger, ActionConstraint, EventConstraint } from "@metamask/messenger";
3
+ import type { Json } from "@metamask/utils";
4
+ import { DehydratedState, FetchInfiniteQueryOptions, FetchQueryOptions, InvalidateOptions, InvalidateQueryFilters, OmitKeyof, QueryClientConfig, WithRequired } from "@tanstack/query-core";
5
+ export type QueryKey = [string, ...Json[]];
6
+ export type DataServiceGranularCacheUpdatedPayload = {
7
+ type: 'added' | 'updated';
8
+ state: DehydratedState;
9
+ } | {
10
+ type: 'removed';
11
+ state: null;
12
+ };
13
+ export type DataServiceCacheUpdatedPayload = DataServiceGranularCacheUpdatedPayload & {
14
+ hash: string;
15
+ };
16
+ export type DataServiceInvalidateQueriesAction<ServiceName extends string> = {
17
+ type: `${ServiceName}:invalidateQueries`;
18
+ handler: (filters?: InvalidateQueryFilters<Json>, options?: InvalidateOptions) => Promise<void>;
19
+ };
20
+ export type DataServiceCacheUpdatedEvent<ServiceName extends string> = {
21
+ type: `${ServiceName}:cacheUpdated`;
22
+ payload: [DataServiceCacheUpdatedPayload];
23
+ };
24
+ export type DataServiceGranularCacheUpdatedEvent<ServiceName extends string> = {
25
+ type: `${ServiceName}:cacheUpdated:${string}`;
26
+ payload: [DataServiceGranularCacheUpdatedPayload];
27
+ };
28
+ export declare class BaseDataService<ServiceName extends string, ServiceMessenger extends Messenger<ServiceName, ActionConstraint, EventConstraint, any>> {
29
+ #private;
30
+ readonly name: ServiceName;
31
+ protected messenger: ServiceMessenger;
32
+ constructor({ name, messenger, queryClientConfig, policyOptions, }: {
33
+ name: ServiceName;
34
+ messenger: ServiceMessenger;
35
+ queryClientConfig?: QueryClientConfig;
36
+ policyOptions?: CreateServicePolicyOptions;
37
+ });
38
+ /**
39
+ * Fetch a query.
40
+ *
41
+ * @param options - The options defining the query. Keep in mind that `queryKey` and `queryFn` are required when using data services.
42
+ * Additionally `retry` and `retryDelay` are not available, retries can be customized using the `servicePolicyOptions`.
43
+ * @returns The query results.
44
+ */
45
+ protected fetchQuery<TQueryFnData extends Json, TError = unknown, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(options: WithRequired<OmitKeyof<FetchQueryOptions<TQueryFnData, TError, TData, TQueryKey>, 'retry' | 'retryDelay'>, 'queryKey' | 'queryFn'>): Promise<TData>;
46
+ /**
47
+ * Fetch a paginated query.
48
+ *
49
+ * @param options - The options defining the query. Keep in mind that `queryKey` and `queryFn` are required when using data services.
50
+ * Additionally `retry` and `retryDelay` are not available, retries can be customized using the `servicePolicyOptions`.
51
+ * @param pageParam - An optional page parameter.
52
+ * @returns The query result, exclusively the requested page is returned.
53
+ */
54
+ protected fetchInfiniteQuery<TQueryFnData extends Json, TError = unknown, TData extends TQueryFnData = TQueryFnData, TQueryKey extends QueryKey = QueryKey, TPageParam extends Json = Json>(options: WithRequired<OmitKeyof<FetchInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey>, 'retry' | 'retryDelay'>, 'queryKey' | 'queryFn'>, pageParam?: TPageParam): Promise<TData>;
55
+ /**
56
+ * Invalidate queries serviced by this data service.
57
+ *
58
+ * @param filters - Optional filter for selecting specific queries.
59
+ * @param options - Additional optional options for query invalidations.
60
+ * @returns Nothing.
61
+ */
62
+ invalidateQueries<TPageData extends Json>(filters?: InvalidateQueryFilters<TPageData>, options?: InvalidateOptions): Promise<void>;
63
+ /**
64
+ * Prepares the service for garbage collection. This should be extended
65
+ * by any subclasses to clean up any additional connections or events.
66
+ */
67
+ destroy(): void;
68
+ }
69
+ //# sourceMappingURL=BaseDataService.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseDataService.d.cts","sourceRoot":"","sources":["../src/BaseDataService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ import { CreateServicePolicyOptions } from "@metamask/controller-utils";
2
+ import { Messenger, ActionConstraint, EventConstraint } from "@metamask/messenger";
3
+ import type { Json } from "@metamask/utils";
4
+ import { DehydratedState, FetchInfiniteQueryOptions, FetchQueryOptions, InvalidateOptions, InvalidateQueryFilters, OmitKeyof, QueryClientConfig, WithRequired } from "@tanstack/query-core";
5
+ export type QueryKey = [string, ...Json[]];
6
+ export type DataServiceGranularCacheUpdatedPayload = {
7
+ type: 'added' | 'updated';
8
+ state: DehydratedState;
9
+ } | {
10
+ type: 'removed';
11
+ state: null;
12
+ };
13
+ export type DataServiceCacheUpdatedPayload = DataServiceGranularCacheUpdatedPayload & {
14
+ hash: string;
15
+ };
16
+ export type DataServiceInvalidateQueriesAction<ServiceName extends string> = {
17
+ type: `${ServiceName}:invalidateQueries`;
18
+ handler: (filters?: InvalidateQueryFilters<Json>, options?: InvalidateOptions) => Promise<void>;
19
+ };
20
+ export type DataServiceCacheUpdatedEvent<ServiceName extends string> = {
21
+ type: `${ServiceName}:cacheUpdated`;
22
+ payload: [DataServiceCacheUpdatedPayload];
23
+ };
24
+ export type DataServiceGranularCacheUpdatedEvent<ServiceName extends string> = {
25
+ type: `${ServiceName}:cacheUpdated:${string}`;
26
+ payload: [DataServiceGranularCacheUpdatedPayload];
27
+ };
28
+ export declare class BaseDataService<ServiceName extends string, ServiceMessenger extends Messenger<ServiceName, ActionConstraint, EventConstraint, any>> {
29
+ #private;
30
+ readonly name: ServiceName;
31
+ protected messenger: ServiceMessenger;
32
+ constructor({ name, messenger, queryClientConfig, policyOptions, }: {
33
+ name: ServiceName;
34
+ messenger: ServiceMessenger;
35
+ queryClientConfig?: QueryClientConfig;
36
+ policyOptions?: CreateServicePolicyOptions;
37
+ });
38
+ /**
39
+ * Fetch a query.
40
+ *
41
+ * @param options - The options defining the query. Keep in mind that `queryKey` and `queryFn` are required when using data services.
42
+ * Additionally `retry` and `retryDelay` are not available, retries can be customized using the `servicePolicyOptions`.
43
+ * @returns The query results.
44
+ */
45
+ protected fetchQuery<TQueryFnData extends Json, TError = unknown, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(options: WithRequired<OmitKeyof<FetchQueryOptions<TQueryFnData, TError, TData, TQueryKey>, 'retry' | 'retryDelay'>, 'queryKey' | 'queryFn'>): Promise<TData>;
46
+ /**
47
+ * Fetch a paginated query.
48
+ *
49
+ * @param options - The options defining the query. Keep in mind that `queryKey` and `queryFn` are required when using data services.
50
+ * Additionally `retry` and `retryDelay` are not available, retries can be customized using the `servicePolicyOptions`.
51
+ * @param pageParam - An optional page parameter.
52
+ * @returns The query result, exclusively the requested page is returned.
53
+ */
54
+ protected fetchInfiniteQuery<TQueryFnData extends Json, TError = unknown, TData extends TQueryFnData = TQueryFnData, TQueryKey extends QueryKey = QueryKey, TPageParam extends Json = Json>(options: WithRequired<OmitKeyof<FetchInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey>, 'retry' | 'retryDelay'>, 'queryKey' | 'queryFn'>, pageParam?: TPageParam): Promise<TData>;
55
+ /**
56
+ * Invalidate queries serviced by this data service.
57
+ *
58
+ * @param filters - Optional filter for selecting specific queries.
59
+ * @param options - Additional optional options for query invalidations.
60
+ * @returns Nothing.
61
+ */
62
+ invalidateQueries<TPageData extends Json>(filters?: InvalidateQueryFilters<TPageData>, options?: InvalidateOptions): Promise<void>;
63
+ /**
64
+ * Prepares the service for garbage collection. This should be extended
65
+ * by any subclasses to clean up any additional connections or events.
66
+ */
67
+ destroy(): void;
68
+ }
69
+ //# sourceMappingURL=BaseDataService.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseDataService.d.mts","sourceRoot":"","sources":["../src/BaseDataService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,150 @@
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 _BaseDataService_instances, _BaseDataService_messenger, _BaseDataService_policy, _BaseDataService_queryClient, _BaseDataService_queryCacheUnsubscribe, _BaseDataService_publishCacheUpdate;
13
+ function $importDefault(module) {
14
+ if (module?.__esModule) {
15
+ return module.default;
16
+ }
17
+ return module;
18
+ }
19
+ import { createServicePolicy } from "@metamask/controller-utils";
20
+ import { Messenger } from "@metamask/messenger";
21
+ import { Duration, inMilliseconds } from "@metamask/utils";
22
+ import { QueryClient, dehydrate } from "@tanstack/query-core";
23
+ import $deepEqual from "fast-deep-equal";
24
+ const deepEqual = $importDefault($deepEqual);
25
+ // Defaults to apply to all data service queries if no default option specified
26
+ const QUERY_CLIENT_DEFAULTS = {
27
+ queries: {
28
+ retry: false,
29
+ staleTime: inMilliseconds(1, Duration.Minute),
30
+ },
31
+ };
32
+ export class BaseDataService {
33
+ constructor({ name, messenger, queryClientConfig = {}, policyOptions, }) {
34
+ _BaseDataService_instances.add(this);
35
+ _BaseDataService_messenger.set(this, void 0);
36
+ _BaseDataService_policy.set(this, void 0);
37
+ _BaseDataService_queryClient.set(this, void 0);
38
+ _BaseDataService_queryCacheUnsubscribe.set(this, void 0);
39
+ this.name = name;
40
+ // We are storing a separately typed messenger for known actions and events provided by data services
41
+ // and a generic public one that is typed using the generic parameters and accessible to implementations.
42
+ __classPrivateFieldSet(this, _BaseDataService_messenger, messenger, "f");
43
+ this.messenger = messenger;
44
+ __classPrivateFieldSet(this, _BaseDataService_queryClient, new QueryClient({
45
+ ...queryClientConfig,
46
+ defaultOptions: {
47
+ queries: {
48
+ ...QUERY_CLIENT_DEFAULTS.queries,
49
+ ...queryClientConfig.defaultOptions?.queries,
50
+ },
51
+ mutations: queryClientConfig.defaultOptions?.mutations,
52
+ },
53
+ }), "f");
54
+ __classPrivateFieldSet(this, _BaseDataService_policy, createServicePolicy(policyOptions), "f");
55
+ __classPrivateFieldSet(this, _BaseDataService_queryCacheUnsubscribe, __classPrivateFieldGet(this, _BaseDataService_queryClient, "f")
56
+ .getQueryCache()
57
+ .subscribe((event) => {
58
+ if (['added', 'updated', 'removed'].includes(event.type)) {
59
+ __classPrivateFieldGet(this, _BaseDataService_instances, "m", _BaseDataService_publishCacheUpdate).call(this, event.query.queryHash, event.type);
60
+ }
61
+ }), "f");
62
+ __classPrivateFieldGet(this, _BaseDataService_messenger, "f").registerActionHandler(`${this.name}:invalidateQueries`, this.invalidateQueries.bind(this));
63
+ }
64
+ /**
65
+ * Fetch a query.
66
+ *
67
+ * @param options - The options defining the query. Keep in mind that `queryKey` and `queryFn` are required when using data services.
68
+ * Additionally `retry` and `retryDelay` are not available, retries can be customized using the `servicePolicyOptions`.
69
+ * @returns The query results.
70
+ */
71
+ async fetchQuery(options) {
72
+ return __classPrivateFieldGet(this, _BaseDataService_queryClient, "f").fetchQuery({
73
+ ...options,
74
+ queryFn: (context) => __classPrivateFieldGet(this, _BaseDataService_policy, "f").execute(() => options.queryFn(context)),
75
+ });
76
+ }
77
+ /**
78
+ * Fetch a paginated query.
79
+ *
80
+ * @param options - The options defining the query. Keep in mind that `queryKey` and `queryFn` are required when using data services.
81
+ * Additionally `retry` and `retryDelay` are not available, retries can be customized using the `servicePolicyOptions`.
82
+ * @param pageParam - An optional page parameter.
83
+ * @returns The query result, exclusively the requested page is returned.
84
+ */
85
+ async fetchInfiniteQuery(options, pageParam) {
86
+ const cache = __classPrivateFieldGet(this, _BaseDataService_queryClient, "f").getQueryCache();
87
+ const query = cache.find({
88
+ queryKey: options.queryKey,
89
+ });
90
+ if (!query?.state.data || pageParam === undefined) {
91
+ const result = await __classPrivateFieldGet(this, _BaseDataService_queryClient, "f").fetchInfiniteQuery({
92
+ ...options,
93
+ queryFn: (context) => __classPrivateFieldGet(this, _BaseDataService_policy, "f").execute(() => options.queryFn({
94
+ ...context,
95
+ pageParam: context.pageParam ?? pageParam,
96
+ })),
97
+ });
98
+ return result.pages[0];
99
+ }
100
+ const { pages } = query.state.data;
101
+ const previous = options.getPreviousPageParam?.(pages[0], pages);
102
+ const direction = deepEqual(pageParam, previous) ? 'backward' : 'forward';
103
+ const result = await query.fetch(undefined, {
104
+ meta: {
105
+ fetchMore: {
106
+ direction,
107
+ pageParam,
108
+ },
109
+ },
110
+ });
111
+ const pageIndex = result.pageParams.findIndex((param) => deepEqual(param, pageParam));
112
+ return result.pages[pageIndex];
113
+ }
114
+ /**
115
+ * Invalidate queries serviced by this data service.
116
+ *
117
+ * @param filters - Optional filter for selecting specific queries.
118
+ * @param options - Additional optional options for query invalidations.
119
+ * @returns Nothing.
120
+ */
121
+ async invalidateQueries(filters, options) {
122
+ return __classPrivateFieldGet(this, _BaseDataService_queryClient, "f").invalidateQueries(filters, options);
123
+ }
124
+ /**
125
+ * Prepares the service for garbage collection. This should be extended
126
+ * by any subclasses to clean up any additional connections or events.
127
+ */
128
+ destroy() {
129
+ __classPrivateFieldGet(this, _BaseDataService_queryCacheUnsubscribe, "f").call(this);
130
+ this.messenger.clearSubscriptions();
131
+ this.messenger.clearActions();
132
+ }
133
+ }
134
+ _BaseDataService_messenger = new WeakMap(), _BaseDataService_policy = new WeakMap(), _BaseDataService_queryClient = new WeakMap(), _BaseDataService_queryCacheUnsubscribe = new WeakMap(), _BaseDataService_instances = new WeakSet(), _BaseDataService_publishCacheUpdate = function _BaseDataService_publishCacheUpdate(hash, type) {
135
+ const state = type === 'added' || type === 'updated'
136
+ ? dehydrate(__classPrivateFieldGet(this, _BaseDataService_queryClient, "f"), {
137
+ shouldDehydrateQuery: (query) => query.queryHash === hash,
138
+ })
139
+ : null;
140
+ __classPrivateFieldGet(this, _BaseDataService_messenger, "f").publish(`${this.name}:cacheUpdated`, {
141
+ type,
142
+ hash,
143
+ state,
144
+ });
145
+ __classPrivateFieldGet(this, _BaseDataService_messenger, "f").publish(`${this.name}:cacheUpdated:${hash}`, {
146
+ type,
147
+ state,
148
+ });
149
+ };
150
+ //# sourceMappingURL=BaseDataService.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseDataService.mjs","sourceRoot":"","sources":["../src/BaseDataService.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createServicePolicy,\n CreateServicePolicyOptions,\n ServicePolicy,\n} from '@metamask/controller-utils';\nimport {\n Messenger,\n ActionConstraint,\n EventConstraint,\n} from '@metamask/messenger';\nimport { Duration, inMilliseconds } from '@metamask/utils';\nimport type { Json } from '@metamask/utils';\nimport {\n DefaultOptions,\n DehydratedState,\n FetchInfiniteQueryOptions,\n FetchQueryOptions,\n InfiniteData,\n InvalidateOptions,\n InvalidateQueryFilters,\n OmitKeyof,\n QueryClient,\n QueryClientConfig,\n WithRequired,\n dehydrate,\n} from '@tanstack/query-core';\nimport deepEqual from 'fast-deep-equal';\n\n// Data service queries use the following format: ['ServiceActionName', ...params]\nexport type QueryKey = [string, ...Json[]];\n\nexport type DataServiceGranularCacheUpdatedPayload =\n | { type: 'added' | 'updated'; state: DehydratedState }\n | {\n type: 'removed';\n state: null;\n };\n\nexport type DataServiceCacheUpdatedPayload =\n DataServiceGranularCacheUpdatedPayload & {\n hash: string;\n };\n\ntype CacheUpdatedType = DataServiceCacheUpdatedPayload['type'];\n\nexport type DataServiceInvalidateQueriesAction<ServiceName extends string> = {\n type: `${ServiceName}:invalidateQueries`;\n handler: (\n filters?: InvalidateQueryFilters<Json>,\n options?: InvalidateOptions,\n ) => Promise<void>;\n};\n\ntype DataServiceActions<ServiceName extends string> =\n DataServiceInvalidateQueriesAction<ServiceName>;\n\nexport type DataServiceCacheUpdatedEvent<ServiceName extends string> = {\n type: `${ServiceName}:cacheUpdated`;\n payload: [DataServiceCacheUpdatedPayload];\n};\n\nexport type DataServiceGranularCacheUpdatedEvent<ServiceName extends string> = {\n type: `${ServiceName}:cacheUpdated:${string}`;\n payload: [DataServiceGranularCacheUpdatedPayload];\n};\n\ntype DataServiceEvents<ServiceName extends string> =\n | DataServiceCacheUpdatedEvent<ServiceName>\n | DataServiceGranularCacheUpdatedEvent<ServiceName>;\n\n// Defaults to apply to all data service queries if no default option specified\nconst QUERY_CLIENT_DEFAULTS: DefaultOptions = {\n queries: {\n retry: false,\n staleTime: inMilliseconds(1, Duration.Minute),\n },\n};\n\nexport class BaseDataService<\n ServiceName extends string,\n ServiceMessenger extends Messenger<\n ServiceName,\n ActionConstraint,\n EventConstraint,\n // Use `any` to allow any parent to be set. `any` is harmless in a type constraint anyway,\n // it's the one totally safe place to use it.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any\n >,\n> {\n public readonly name: ServiceName;\n\n readonly #messenger: Messenger<\n ServiceName,\n DataServiceActions<ServiceName>,\n DataServiceEvents<ServiceName>\n >;\n\n protected messenger: ServiceMessenger;\n\n readonly #policy: ServicePolicy;\n\n readonly #queryClient: QueryClient;\n\n readonly #queryCacheUnsubscribe: () => void;\n\n constructor({\n name,\n messenger,\n queryClientConfig = {},\n policyOptions,\n }: {\n name: ServiceName;\n messenger: ServiceMessenger;\n queryClientConfig?: QueryClientConfig;\n policyOptions?: CreateServicePolicyOptions;\n }) {\n this.name = name;\n\n // We are storing a separately typed messenger for known actions and events provided by data services\n // and a generic public one that is typed using the generic parameters and accessible to implementations.\n this.#messenger = messenger as unknown as Messenger<\n ServiceName,\n DataServiceActions<ServiceName>,\n DataServiceEvents<ServiceName>\n >;\n this.messenger = messenger;\n\n this.#queryClient = new QueryClient({\n ...queryClientConfig,\n defaultOptions: {\n queries: {\n ...QUERY_CLIENT_DEFAULTS.queries,\n ...queryClientConfig.defaultOptions?.queries,\n },\n mutations: queryClientConfig.defaultOptions?.mutations,\n },\n });\n\n this.#policy = createServicePolicy(policyOptions);\n\n this.#queryCacheUnsubscribe = this.#queryClient\n .getQueryCache()\n .subscribe((event) => {\n if (['added', 'updated', 'removed'].includes(event.type)) {\n this.#publishCacheUpdate(\n event.query.queryHash,\n event.type as CacheUpdatedType,\n );\n }\n });\n\n this.#messenger.registerActionHandler(\n `${this.name}:invalidateQueries`,\n this.invalidateQueries.bind(this),\n );\n }\n\n /**\n * Fetch a query.\n *\n * @param options - The options defining the query. Keep in mind that `queryKey` and `queryFn` are required when using data services.\n * Additionally `retry` and `retryDelay` are not available, retries can be customized using the `servicePolicyOptions`.\n * @returns The query results.\n */\n protected async fetchQuery<\n TQueryFnData extends Json,\n TError = unknown,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n >(\n options: WithRequired<\n OmitKeyof<\n FetchQueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n 'retry' | 'retryDelay'\n >,\n 'queryKey' | 'queryFn'\n >,\n ): Promise<TData> {\n return this.#queryClient.fetchQuery({\n ...options,\n queryFn: (context) =>\n this.#policy.execute(() => options.queryFn(context)),\n });\n }\n\n /**\n * Fetch a paginated query.\n *\n * @param options - The options defining the query. Keep in mind that `queryKey` and `queryFn` are required when using data services.\n * Additionally `retry` and `retryDelay` are not available, retries can be customized using the `servicePolicyOptions`.\n * @param pageParam - An optional page parameter.\n * @returns The query result, exclusively the requested page is returned.\n */\n protected async fetchInfiniteQuery<\n TQueryFnData extends Json,\n TError = unknown,\n TData extends TQueryFnData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam extends Json = Json,\n >(\n options: WithRequired<\n OmitKeyof<\n FetchInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n 'retry' | 'retryDelay'\n >,\n 'queryKey' | 'queryFn'\n >,\n pageParam?: TPageParam,\n ): Promise<TData> {\n const cache = this.#queryClient.getQueryCache();\n\n const query = cache.find<TQueryFnData, TError, InfiniteData<TData>>({\n queryKey: options.queryKey,\n });\n\n if (!query?.state.data || pageParam === undefined) {\n const result = await this.#queryClient.fetchInfiniteQuery({\n ...options,\n queryFn: (context) =>\n this.#policy.execute(() =>\n options.queryFn({\n ...context,\n pageParam: context.pageParam ?? pageParam,\n }),\n ),\n });\n\n return result.pages[0];\n }\n\n const { pages } = query.state.data;\n const previous = options.getPreviousPageParam?.(pages[0], pages);\n\n const direction = deepEqual(pageParam, previous) ? 'backward' : 'forward';\n\n const result = await query.fetch(undefined, {\n meta: {\n fetchMore: {\n direction,\n pageParam,\n },\n },\n });\n\n const pageIndex = result.pageParams.findIndex((param) =>\n deepEqual(param, pageParam),\n );\n\n return result.pages[pageIndex];\n }\n\n /**\n * Invalidate queries serviced by this data service.\n *\n * @param filters - Optional filter for selecting specific queries.\n * @param options - Additional optional options for query invalidations.\n * @returns Nothing.\n */\n async invalidateQueries<TPageData extends Json>(\n filters?: InvalidateQueryFilters<TPageData>,\n options?: InvalidateOptions,\n ): Promise<void> {\n return this.#queryClient.invalidateQueries(filters, options);\n }\n\n /**\n * Prepares the service for garbage collection. This should be extended\n * by any subclasses to clean up any additional connections or events.\n */\n destroy(): void {\n this.#queryCacheUnsubscribe();\n this.messenger.clearSubscriptions();\n this.messenger.clearActions();\n }\n\n /**\n * Publish `cacheUpdated` events when a given query changes.\n *\n * @param hash The hash of the query.\n * @param type The type of cache update.\n */\n #publishCacheUpdate(hash: string, type: CacheUpdatedType): void {\n const state =\n type === 'added' || type === 'updated'\n ? dehydrate(this.#queryClient, {\n shouldDehydrateQuery: (query) => query.queryHash === hash,\n })\n : null;\n\n this.#messenger.publish(\n `${this.name}:cacheUpdated` as const,\n {\n type,\n hash,\n state,\n } as DataServiceCacheUpdatedPayload,\n );\n\n this.#messenger.publish(\n `${this.name}:cacheUpdated:${hash}` as const,\n {\n type,\n state,\n } as DataServiceGranularCacheUpdatedPayload,\n );\n }\n}\n"]}
package/dist/index.cjs CHANGED
@@ -1,13 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- /**
4
- * Example function that returns a greeting for the given name.
5
- *
6
- * @param name - The name to greet.
7
- * @returns The greeting.
8
- */
9
- function greeter(name) {
10
- return `Hello, ${name}!`;
11
- }
12
- exports.default = greeter;
3
+ exports.BaseDataService = void 0;
4
+ var BaseDataService_1 = require("./BaseDataService.cjs");
5
+ Object.defineProperty(exports, "BaseDataService", { enumerable: true, get: function () { return BaseDataService_1.BaseDataService; } });
13
6
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA;;;;;GAKG;AACH,SAAwB,OAAO,CAAC,IAAY;IAC1C,OAAO,UAAU,IAAI,GAAG,CAAC;AAC3B,CAAC;AAFD,0BAEC","sourcesContent":["/**\n * Example function that returns a greeting for the given name.\n *\n * @param name - The name to greet.\n * @returns The greeting.\n */\nexport default function greeter(name: string): string {\n return `Hello, ${name}!`;\n}\n"]}
1
+ {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAQA,yDAAoD;AAA3C,kHAAA,eAAe,OAAA","sourcesContent":["export type {\n DataServiceCacheUpdatedPayload,\n DataServiceGranularCacheUpdatedPayload,\n DataServiceInvalidateQueriesAction,\n DataServiceCacheUpdatedEvent,\n DataServiceGranularCacheUpdatedEvent,\n QueryKey,\n} from './BaseDataService';\nexport { BaseDataService } from './BaseDataService';\n"]}
package/dist/index.d.cts CHANGED
@@ -1,8 +1,3 @@
1
- /**
2
- * Example function that returns a greeting for the given name.
3
- *
4
- * @param name - The name to greet.
5
- * @returns The greeting.
6
- */
7
- export default function greeter(name: string): string;
1
+ export type { DataServiceCacheUpdatedPayload, DataServiceGranularCacheUpdatedPayload, DataServiceInvalidateQueriesAction, DataServiceCacheUpdatedEvent, DataServiceGranularCacheUpdatedEvent, QueryKey, } from "./BaseDataService.cjs";
2
+ export { BaseDataService } from "./BaseDataService.cjs";
8
3
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,OAAO,UAAU,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD"}
1
+ {"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,8BAA8B,EAC9B,sCAAsC,EACtC,kCAAkC,EAClC,4BAA4B,EAC5B,oCAAoC,EACpC,QAAQ,GACT,8BAA0B;AAC3B,OAAO,EAAE,eAAe,EAAE,8BAA0B"}
package/dist/index.d.mts CHANGED
@@ -1,8 +1,3 @@
1
- /**
2
- * Example function that returns a greeting for the given name.
3
- *
4
- * @param name - The name to greet.
5
- * @returns The greeting.
6
- */
7
- export default function greeter(name: string): string;
1
+ export type { DataServiceCacheUpdatedPayload, DataServiceGranularCacheUpdatedPayload, DataServiceInvalidateQueriesAction, DataServiceCacheUpdatedEvent, DataServiceGranularCacheUpdatedEvent, QueryKey, } from "./BaseDataService.mjs";
2
+ export { BaseDataService } from "./BaseDataService.mjs";
8
3
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,OAAO,UAAU,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD"}
1
+ {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,8BAA8B,EAC9B,sCAAsC,EACtC,kCAAkC,EAClC,4BAA4B,EAC5B,oCAAoC,EACpC,QAAQ,GACT,8BAA0B;AAC3B,OAAO,EAAE,eAAe,EAAE,8BAA0B"}
package/dist/index.mjs CHANGED
@@ -1,10 +1,2 @@
1
- /**
2
- * Example function that returns a greeting for the given name.
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 { BaseDataService } from "./BaseDataService.mjs";
10
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,OAAO,UAAU,OAAO,CAAC,IAAY;IAC1C,OAAO,UAAU,IAAI,GAAG,CAAC;AAC3B,CAAC","sourcesContent":["/**\n * Example function that returns a greeting for the given name.\n *\n * @param name - The name to greet.\n * @returns The greeting.\n */\nexport default function greeter(name: string): string {\n return `Hello, ${name}!`;\n}\n"]}
1
+ {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,eAAe,EAAE,8BAA0B","sourcesContent":["export type {\n DataServiceCacheUpdatedPayload,\n DataServiceGranularCacheUpdatedPayload,\n DataServiceInvalidateQueriesAction,\n DataServiceCacheUpdatedEvent,\n DataServiceGranularCacheUpdatedEvent,\n QueryKey,\n} from './BaseDataService';\nexport { BaseDataService } from './BaseDataService';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/base-data-service",
3
- "version": "0.0.0-preview-a0caca0c0",
3
+ "version": "0.1.0-preview-afe010990",
4
4
  "description": "Provides utilities for building data services",
5
5
  "keywords": [
6
6
  "MetaMask",
@@ -47,12 +47,20 @@
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/controller-utils": "^11.19.0",
52
+ "@metamask/messenger": "^0.3.0",
53
+ "@metamask/utils": "^11.9.0",
54
+ "@tanstack/query-core": "^4.43.0",
55
+ "fast-deep-equal": "^3.1.3"
56
+ },
50
57
  "devDependencies": {
51
58
  "@metamask/auto-changelog": "^3.4.4",
52
59
  "@ts-bridge/cli": "^0.6.4",
53
60
  "@types/jest": "^29.5.14",
54
61
  "deepmerge": "^4.2.2",
55
62
  "jest": "^29.7.0",
63
+ "nock": "^13.3.1",
56
64
  "ts-jest": "^29.2.5",
57
65
  "typedoc": "^0.25.13",
58
66
  "typedoc-plugin-missing-exports": "^2.0.0",