@studiocms/cfetch 0.1.6 → 0.2.1
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/README.md +268 -25
- package/dist/cache.d.ts +78 -0
- package/dist/cache.js +89 -0
- package/dist/consts.d.ts +4 -8
- package/dist/consts.js +7 -2
- package/dist/index.d.ts +47 -20
- package/dist/index.js +7 -1
- package/dist/stub.js +145 -68
- package/dist/types.d.ts +26 -41
- package/dist/wrappers.d.ts +241 -11
- package/dist/wrappers.js +79 -39
- package/package.json +9 -7
- package/dist/utils/isOlderThan.d.ts +0 -13
- package/dist/utils/isOlderThan.js +0 -13
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ This is an [Astro integration](https://docs.astro.build/en/guides/integrations-g
|
|
|
17
17
|
|
|
18
18
|
### Installation
|
|
19
19
|
|
|
20
|
-
Install the integration **automatically** using the Astro CLI:
|
|
20
|
+
1. Install the integration **automatically** using the Astro CLI:
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
23
|
pnpm astro add @studiocms/cfetch
|
|
@@ -47,7 +47,23 @@ npm install @studiocms/cfetch
|
|
|
47
47
|
yarn add @studiocms/cfetch
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
2.
|
|
50
|
+
2. Install peer dependencies
|
|
51
|
+
|
|
52
|
+
If your package manager does not automatically install peer dependencies, you will need to ensure `Effect` is installed.
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pnpm add effect
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npm install effect
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
yarn add effect
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
3. Add the integration to your astro config
|
|
51
67
|
|
|
52
68
|
```diff
|
|
53
69
|
+import cFetch from "@studiocms/cfetch";
|
|
@@ -61,39 +77,266 @@ export default defineConfig({
|
|
|
61
77
|
|
|
62
78
|
### Usage
|
|
63
79
|
|
|
64
|
-
|
|
80
|
+
This integration includes various versions of cached fetch functions and [Effects](https://effect.website) to allow full control of how you work with your data.
|
|
81
|
+
|
|
82
|
+
#### Effects
|
|
83
|
+
|
|
84
|
+
All Effects have the following return pattern or derivatives there of
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
Effect.Effect<CachedResponse<T>, FetchError, never>;
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
##### `CachedResponse<T>` type
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
interface CachedResponse<T> {
|
|
94
|
+
data: T;
|
|
95
|
+
ok: boolean;
|
|
96
|
+
status: number;
|
|
97
|
+
statusText: string;
|
|
98
|
+
headers: Record<string, string>;
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
##### `CFetchConfig` type
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
interface CFetchConfig {
|
|
106
|
+
ttl?: Duration.DurationInput;
|
|
107
|
+
tags?: string[];
|
|
108
|
+
key?: string;
|
|
109
|
+
verbose?: boolean;
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
##### `cFetchEffect`
|
|
114
|
+
|
|
115
|
+
###### Interface
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
const cFetchEffect: <T>(
|
|
119
|
+
url: string | URL,
|
|
120
|
+
parser: (response: Response) => Promise<T>,
|
|
121
|
+
options?: RequestInit | undefined,
|
|
122
|
+
cacheConfig?: CFetchConfig | undefined
|
|
123
|
+
) => Effect.Effect<CachedResponse<T>, FetchError, never>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
###### Example Usage
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
import { cFetchEffect, Duration } from "c:fetch"
|
|
130
|
+
|
|
131
|
+
const effect = cFetchEffect<{ foo: string; bar: number; }>(
|
|
132
|
+
'https://api.example.com/data',
|
|
133
|
+
(res) => res.json(),
|
|
134
|
+
{ method: "GET" },
|
|
135
|
+
{ ttl?: Duration.hours(1), tags?: ['example'], key?: "api-data-fetch", verbose?: false }
|
|
136
|
+
);
|
|
137
|
+
/*
|
|
138
|
+
Return type:
|
|
139
|
+
Effect.Effect<CachedResponse<{ foo: string; bar: number; }>, FetchError, never>
|
|
140
|
+
*/
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
##### `cFetchEffectJson`
|
|
144
|
+
|
|
145
|
+
###### Interface
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
const cFetchEffectJson: <T>(
|
|
149
|
+
url: string | URL,
|
|
150
|
+
options?: RequestInit | undefined,
|
|
151
|
+
cacheConfig?: CFetchConfig | undefined
|
|
152
|
+
) => Effect.Effect<CachedResponse<T>, FetchError, never>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
###### Example Usage
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
import { cFetchEffectJson } from "c:fetch"
|
|
159
|
+
|
|
160
|
+
const effect = cFetchEffectJson<{ foo: string; bar: number; }>(
|
|
161
|
+
'https://api.example.com/data',
|
|
162
|
+
{ method: "GET" }
|
|
163
|
+
);
|
|
164
|
+
/*
|
|
165
|
+
Return type:
|
|
166
|
+
Effect.Effect<CachedResponse<{ foo: string; bar: number; }>, FetchError, never>
|
|
167
|
+
*/
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
##### `cFetchEffectText`
|
|
171
|
+
|
|
172
|
+
###### Interface
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
const cFetchEffectText: (
|
|
176
|
+
url: string | URL,
|
|
177
|
+
options?: RequestInit | undefined,
|
|
178
|
+
cacheConfig?: CFetchConfig | undefined
|
|
179
|
+
) => Effect.Effect<CachedResponse<string>, FetchError, never>
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
###### Example Usage
|
|
65
183
|
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
import { cFetch } from 'c:fetch';
|
|
184
|
+
```ts
|
|
185
|
+
import { cFetchEffectText } from "c:fetch"
|
|
69
186
|
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
{ lifetime: "1h" }, // Optional, allows changing the default lifetime of the cache
|
|
74
|
-
'json', // Optional, allows changing the type of response object to be cached. 'json' (default) or 'text'
|
|
187
|
+
const effect = cFetchEffectText(
|
|
188
|
+
'https://example.com',
|
|
189
|
+
{ method: "GET" }
|
|
75
190
|
);
|
|
191
|
+
/*
|
|
192
|
+
Return type:
|
|
193
|
+
Effect.Effect<CachedResponse<string>, FetchError, never>
|
|
194
|
+
*/
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
##### `cFetchEffectBlob`
|
|
198
|
+
|
|
199
|
+
###### Interface
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
const cFetchEffectBlob: (
|
|
203
|
+
url: string | URL,
|
|
204
|
+
options?: RequestInit | undefined,
|
|
205
|
+
cacheConfig?: CFetchConfig | undefined
|
|
206
|
+
) => Effect.Effect<CachedResponse<Blob>, FetchError, never>
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
###### Example Usage
|
|
210
|
+
|
|
211
|
+
```ts
|
|
212
|
+
import { cFetchEffectBlob } from "c:fetch"
|
|
213
|
+
|
|
214
|
+
const effect = cFetchEffectBlob(
|
|
215
|
+
'https://example.com/image.png',
|
|
216
|
+
{ method: "GET" }
|
|
217
|
+
);
|
|
218
|
+
/*
|
|
219
|
+
Return type:
|
|
220
|
+
Effect.Effect<CachedResponse<Blob>, FetchError, never>
|
|
221
|
+
*/
|
|
222
|
+
```
|
|
76
223
|
|
|
77
|
-
|
|
78
|
-
|
|
224
|
+
#### Functions
|
|
225
|
+
|
|
226
|
+
All Functions have the following return pattern or derivatives there of
|
|
227
|
+
|
|
228
|
+
```ts
|
|
229
|
+
CachedResponse<T>;
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
##### `cFetch`
|
|
233
|
+
|
|
234
|
+
###### Interface
|
|
235
|
+
|
|
236
|
+
```ts
|
|
237
|
+
const cFetch: <T>(
|
|
238
|
+
url: string | URL,
|
|
239
|
+
parser: (response: Response) => Promise<T>,
|
|
240
|
+
options?: RequestInit | undefined,
|
|
241
|
+
cacheConfig?: CFetchConfig | undefined
|
|
242
|
+
) => Promise<CachedResponse<T>>
|
|
79
243
|
```
|
|
80
244
|
|
|
81
|
-
|
|
245
|
+
###### Example Usage
|
|
82
246
|
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
import { cFetch } from 'c:fetch';
|
|
247
|
+
```ts
|
|
248
|
+
import { cFetch } from "c:fetch"
|
|
86
249
|
|
|
87
|
-
const {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
'json',
|
|
92
|
-
true // Changes the the output to include the lastCheck value
|
|
250
|
+
const effect = await cFetch<{ foo: string; bar: number; }>(
|
|
251
|
+
'https://api.example.com/data',
|
|
252
|
+
(res) => res.json(),
|
|
253
|
+
{ method: "GET" }
|
|
93
254
|
);
|
|
255
|
+
/*
|
|
256
|
+
Return type:
|
|
257
|
+
CachedResponse<{ foo: string; bar: number; }>
|
|
258
|
+
*/
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
##### `cFetchJson`
|
|
262
|
+
|
|
263
|
+
###### Interface
|
|
264
|
+
|
|
265
|
+
```ts
|
|
266
|
+
const cFetchJson: <T>(
|
|
267
|
+
url: string | URL,
|
|
268
|
+
options?: RequestInit | undefined,
|
|
269
|
+
cacheConfig?: CFetchConfig | undefined
|
|
270
|
+
) => Promise<CachedResponse<T>>
|
|
271
|
+
```
|
|
94
272
|
|
|
95
|
-
|
|
96
|
-
|
|
273
|
+
###### Example Usage
|
|
274
|
+
|
|
275
|
+
```ts
|
|
276
|
+
import { cFetchJson } from "c:fetch"
|
|
277
|
+
|
|
278
|
+
const effect = await cFetchJson<{ foo: string; bar: number; }>(
|
|
279
|
+
'https://api.example.com/data',
|
|
280
|
+
{ method: "GET" }
|
|
281
|
+
);
|
|
282
|
+
/*
|
|
283
|
+
Return type:
|
|
284
|
+
CachedResponse<{ foo: string; bar: number; }>
|
|
285
|
+
*/
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
##### `cFetchText`
|
|
289
|
+
|
|
290
|
+
###### Interface
|
|
291
|
+
|
|
292
|
+
```ts
|
|
293
|
+
const cFetchText: (
|
|
294
|
+
url: string | URL,
|
|
295
|
+
options?: RequestInit | undefined,
|
|
296
|
+
cacheConfig?: CFetchConfig | undefined
|
|
297
|
+
) => Promise<CachedResponse<string>>
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
###### Example Usage
|
|
301
|
+
|
|
302
|
+
```ts
|
|
303
|
+
import { cFetchText } from "c:fetch"
|
|
304
|
+
|
|
305
|
+
const effect = await cFetchText(
|
|
306
|
+
'https://example.com',
|
|
307
|
+
{ method: "GET" }
|
|
308
|
+
);
|
|
309
|
+
/*
|
|
310
|
+
Return type:
|
|
311
|
+
CachedResponse<string>
|
|
312
|
+
*/
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
##### `cFetchBlob`
|
|
316
|
+
|
|
317
|
+
###### Interface
|
|
318
|
+
|
|
319
|
+
```ts
|
|
320
|
+
const cFetchBlob: (
|
|
321
|
+
url: string | URL,
|
|
322
|
+
options?: RequestInit | undefined,
|
|
323
|
+
cacheConfig?: CFetchConfig | undefined
|
|
324
|
+
) => Promise<CachedResponse<Blob>>
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
###### Example Usage
|
|
328
|
+
|
|
329
|
+
```ts
|
|
330
|
+
import { cFetchBlob } from "c:fetch"
|
|
331
|
+
|
|
332
|
+
const effect = await cFetchBlob(
|
|
333
|
+
'https://example.com/image.png',
|
|
334
|
+
{ method: "GET" }
|
|
335
|
+
);
|
|
336
|
+
/*
|
|
337
|
+
Return type:
|
|
338
|
+
CachedResponse<Blob>
|
|
339
|
+
*/
|
|
97
340
|
```
|
|
98
341
|
|
|
99
342
|
## Licensing
|
package/dist/cache.d.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module cfetch/cache
|
|
3
|
+
* Cache service implementation using Effect-TS.
|
|
4
|
+
*/
|
|
5
|
+
import { Context, Duration, Effect } from 'effect';
|
|
6
|
+
/**
|
|
7
|
+
* Represents a cache entry with its value, expiration time, last updated time, and tags.
|
|
8
|
+
*/
|
|
9
|
+
export interface CacheEntry<A> {
|
|
10
|
+
value: A;
|
|
11
|
+
expiresAt: number;
|
|
12
|
+
lastUpdatedAt: number;
|
|
13
|
+
tags: Set<string>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Represents the status of a cache entry, including expiration and tags.
|
|
17
|
+
*/
|
|
18
|
+
export interface CacheEntryStatus {
|
|
19
|
+
expiresAt: Date;
|
|
20
|
+
lastUpdatedAt: Date;
|
|
21
|
+
tags: Set<string>;
|
|
22
|
+
}
|
|
23
|
+
declare const CacheMaps_base: Context.TagClass<CacheMaps, "@studiocms/cfetch/CacheMaps", {
|
|
24
|
+
store: Map<string, CacheEntry<unknown>>;
|
|
25
|
+
tagIndex: Map<string, Set<string>>;
|
|
26
|
+
}>;
|
|
27
|
+
/**
|
|
28
|
+
* Tag to hold the in-memory cache maps.
|
|
29
|
+
*
|
|
30
|
+
* This tag provides access to the main cache store and the tag index for invalidation.
|
|
31
|
+
*/
|
|
32
|
+
export declare class CacheMaps extends CacheMaps_base {
|
|
33
|
+
}
|
|
34
|
+
declare const CacheService_base: Effect.Service.Class<CacheService, "@studiocms/cfetch/CacheService", {
|
|
35
|
+
readonly effect: Effect.Effect<{
|
|
36
|
+
get: <A>(key: string) => Effect.Effect<A | null, never, never>;
|
|
37
|
+
set: <A>(key: string, value: A, options?: {
|
|
38
|
+
ttl?: Duration.DurationInput;
|
|
39
|
+
tags?: string[];
|
|
40
|
+
}) => Effect.Effect<void, never, never>;
|
|
41
|
+
delete: (key: string) => Effect.Effect<void, never, never>;
|
|
42
|
+
invalidateTags: (tags: string[]) => Effect.Effect<void, never, never>;
|
|
43
|
+
clear: () => Effect.Effect<void, never, never>;
|
|
44
|
+
}, never, CacheMaps>;
|
|
45
|
+
}>;
|
|
46
|
+
/**
|
|
47
|
+
* A service for managing cached data with TTL (time-to-live) and tag-based invalidation.
|
|
48
|
+
*
|
|
49
|
+
* @remarks
|
|
50
|
+
* This service provides an in-memory cache with the following features:
|
|
51
|
+
* - Automatic expiration based on TTL
|
|
52
|
+
* - Tag-based organization for batch invalidation
|
|
53
|
+
* - Effect-based API for safe side-effect management
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```typescript
|
|
57
|
+
* const program = Effect.gen(function* () {
|
|
58
|
+
* const cache = yield* CacheService;
|
|
59
|
+
*
|
|
60
|
+
* // Set a value with custom TTL and tags
|
|
61
|
+
* yield* cache.set('user:123', userData, {
|
|
62
|
+
* ttl: Duration.minutes(5),
|
|
63
|
+
* tags: ['user', 'profile']
|
|
64
|
+
* });
|
|
65
|
+
*
|
|
66
|
+
* // Get a value
|
|
67
|
+
* const result = yield* cache.get('user:123');
|
|
68
|
+
*
|
|
69
|
+
* // Invalidate all entries with specific tags
|
|
70
|
+
* yield* cache.invalidateTags(['user']);
|
|
71
|
+
* });
|
|
72
|
+
* ```
|
|
73
|
+
*
|
|
74
|
+
* @public
|
|
75
|
+
*/
|
|
76
|
+
export declare class CacheService extends CacheService_base {
|
|
77
|
+
}
|
|
78
|
+
export {};
|
package/dist/cache.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Clock, Context, Duration, Effect } from "effect";
|
|
2
|
+
import { defaultConfigLive } from "./consts";
|
|
3
|
+
class CacheMaps extends Context.Tag("@studiocms/cfetch/CacheMaps")() {
|
|
4
|
+
}
|
|
5
|
+
class ConfigFetchError {
|
|
6
|
+
_tag = "ConfigFetchError";
|
|
7
|
+
}
|
|
8
|
+
const getConfig = async () => {
|
|
9
|
+
try {
|
|
10
|
+
const config = await import("virtual:cfetch/config");
|
|
11
|
+
return config.default;
|
|
12
|
+
} catch (error) {
|
|
13
|
+
console.warn("Could not load virtual:cfetch/config, using default config.");
|
|
14
|
+
return defaultConfigLive;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
class CacheService extends Effect.Service()("@studiocms/cfetch/CacheService", {
|
|
18
|
+
effect: Effect.gen(function* () {
|
|
19
|
+
const { store, tagIndex } = yield* CacheMaps;
|
|
20
|
+
const config = yield* Effect.tryPromise({
|
|
21
|
+
try: () => getConfig(),
|
|
22
|
+
catch: () => new ConfigFetchError()
|
|
23
|
+
}).pipe(Effect.catchTag("ConfigFetchError", () => Effect.succeed(defaultConfigLive)));
|
|
24
|
+
const get = (key) => Effect.gen(function* () {
|
|
25
|
+
const now = yield* Clock.currentTimeMillis;
|
|
26
|
+
const entry = store.get(key);
|
|
27
|
+
if (!entry) return null;
|
|
28
|
+
if (entry.expiresAt < now) {
|
|
29
|
+
yield* deleteKey(key);
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
return entry.value;
|
|
33
|
+
});
|
|
34
|
+
const set = (key, value, options) => Effect.gen(function* () {
|
|
35
|
+
const now = yield* Clock.currentTimeMillis;
|
|
36
|
+
const ttl = options?.ttl ?? Duration.millis(config.lifetime);
|
|
37
|
+
const tags = new Set(options?.tags ?? []);
|
|
38
|
+
const expiresAt = now + Duration.toMillis(ttl);
|
|
39
|
+
store.set(key, { value, expiresAt, lastUpdatedAt: now, tags });
|
|
40
|
+
for (const tag of tags) {
|
|
41
|
+
if (!tagIndex.has(tag)) {
|
|
42
|
+
tagIndex.set(tag, /* @__PURE__ */ new Set());
|
|
43
|
+
}
|
|
44
|
+
tagIndex.get(tag)?.add(key);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
const deleteKey = (key) => Effect.sync(() => {
|
|
48
|
+
const entry = store.get(key);
|
|
49
|
+
if (entry) {
|
|
50
|
+
for (const tag of entry.tags) {
|
|
51
|
+
const keys = tagIndex.get(tag);
|
|
52
|
+
if (keys) {
|
|
53
|
+
keys.delete(key);
|
|
54
|
+
if (keys.size === 0) {
|
|
55
|
+
tagIndex.delete(tag);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
store.delete(key);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
const invalidateTags = (tags) => Effect.gen(function* () {
|
|
63
|
+
for (const tag of tags) {
|
|
64
|
+
const keys = tagIndex.get(tag);
|
|
65
|
+
if (keys) {
|
|
66
|
+
for (const key of [...keys]) {
|
|
67
|
+
yield* deleteKey(key);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
const clear = () => Effect.sync(() => {
|
|
73
|
+
store.clear();
|
|
74
|
+
tagIndex.clear();
|
|
75
|
+
});
|
|
76
|
+
return {
|
|
77
|
+
get,
|
|
78
|
+
set,
|
|
79
|
+
delete: deleteKey,
|
|
80
|
+
invalidateTags,
|
|
81
|
+
clear
|
|
82
|
+
};
|
|
83
|
+
})
|
|
84
|
+
}) {
|
|
85
|
+
}
|
|
86
|
+
export {
|
|
87
|
+
CacheMaps,
|
|
88
|
+
CacheService
|
|
89
|
+
};
|
package/dist/consts.d.ts
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* @module
|
|
4
|
-
*/
|
|
5
|
-
import type { CacheConfig } from './types.js';
|
|
6
|
-
/**
|
|
7
|
-
* Default cache configuration object.
|
|
2
|
+
* @module cfetch/consts
|
|
8
3
|
*
|
|
9
|
-
*
|
|
10
|
-
* Accepts a string representation of time, e.g., '1h' for 1 hour.
|
|
4
|
+
* Constant values used throughout the cfetch package.
|
|
11
5
|
*/
|
|
6
|
+
import type { CacheConfig, CacheConfigLive } from './types.js';
|
|
12
7
|
export declare const defaultConfig: CacheConfig;
|
|
8
|
+
export declare const defaultConfigLive: CacheConfigLive;
|
package/dist/consts.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
import { Duration } from "effect";
|
|
1
2
|
const defaultConfig = {
|
|
2
|
-
lifetime:
|
|
3
|
+
lifetime: Duration.hours(1)
|
|
4
|
+
};
|
|
5
|
+
const defaultConfigLive = {
|
|
6
|
+
lifetime: Duration.toMillis(Duration.hours(1))
|
|
3
7
|
};
|
|
4
8
|
export {
|
|
5
|
-
defaultConfig
|
|
9
|
+
defaultConfig,
|
|
10
|
+
defaultConfigLive
|
|
6
11
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,38 +1,65 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* @module
|
|
4
|
-
*/
|
|
5
|
-
import type { AstroIntegration } from 'astro';
|
|
6
|
-
import type { CacheConfig } from './types.js';
|
|
7
|
-
/**
|
|
8
|
-
* Astro integration that allows you to have a cached fetch function in your Astro SSR project.
|
|
2
|
+
* @module @studiocms/cfetch
|
|
9
3
|
*
|
|
10
|
-
*
|
|
4
|
+
* An Astro integration that provides a caching fetch utility using Effect.
|
|
11
5
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
6
|
+
* This module exports the `cFetch` function, which can be used to create an Astro
|
|
7
|
+
* integration that adds virtual modules for cached fetching capabilities. It also
|
|
8
|
+
* exports the `Duration` type from Effect for specifying cache lifetimes.
|
|
9
|
+
*
|
|
10
|
+
* The `cFetch` integration injects virtual modules:
|
|
11
|
+
* - `virtual:cfetch/config`: Exports the default cache configuration.
|
|
12
|
+
* - `c:fetch`: Exports various cached fetch functions and types.
|
|
13
|
+
*
|
|
14
|
+
* Example usage:
|
|
15
|
+
*
|
|
16
|
+
* ```ts
|
|
17
|
+
* import cFetch, { Duration } from '@studiocms/cfetch';
|
|
16
18
|
* import { defineConfig } from 'astro/config';
|
|
17
|
-
* import cFetch from '@studiocms/cfetch';
|
|
18
19
|
*
|
|
19
20
|
* export default defineConfig({
|
|
20
21
|
* integrations: [
|
|
21
22
|
* cFetch({
|
|
22
|
-
*
|
|
23
|
-
* })
|
|
23
|
+
* lifetime: Duration.minutes(5), // Set cache lifetime to 5 minutes (default is 1 hour)
|
|
24
|
+
* }),
|
|
24
25
|
* ],
|
|
25
26
|
* });
|
|
26
27
|
* ```
|
|
27
28
|
*
|
|
28
|
-
* then in your components
|
|
29
|
+
* You can then use the cached fetch functions in your Astro components or pages:
|
|
29
30
|
*
|
|
30
|
-
* ```
|
|
31
|
+
* ```ts
|
|
31
32
|
* import { cFetch } from 'c:fetch';
|
|
32
33
|
*
|
|
33
|
-
* const response = await cFetch('https://example.com/
|
|
34
|
-
*
|
|
35
|
-
*
|
|
34
|
+
* const response = await cFetch('https://api.example.com/data', (res) => res.json());
|
|
35
|
+
* console.log(response.data);
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
import type { AstroIntegration } from 'astro';
|
|
39
|
+
import type { CacheConfig } from './types.js';
|
|
40
|
+
export { Duration } from 'effect';
|
|
41
|
+
/**
|
|
42
|
+
* Creates a caching fetch integration for Astro.
|
|
43
|
+
*
|
|
44
|
+
* This integration provides a cached fetch implementation that can be configured
|
|
45
|
+
* with custom cache lifetime and other options. It sets up virtual module imports
|
|
46
|
+
* and injects TypeScript type definitions for the cached fetch functionality.
|
|
47
|
+
*
|
|
48
|
+
* @param opts - Optional cache configuration options to customize the caching behavior
|
|
49
|
+
* @returns An Astro integration object with hooks for configuration setup and completion
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* // astro.config.mjs
|
|
54
|
+
* import cFetch, { Duration } from '@studiocms/cfetch';
|
|
55
|
+
*
|
|
56
|
+
* export default defineConfig({
|
|
57
|
+
* integrations: [
|
|
58
|
+
* cFetch({
|
|
59
|
+
* lifetime: Duration.minutes(10), // Cache entries live for 10 minutes (default is 1 hour)
|
|
60
|
+
* })
|
|
61
|
+
* ]
|
|
62
|
+
* });
|
|
36
63
|
* ```
|
|
37
64
|
*/
|
|
38
65
|
export declare function cFetch(opts?: CacheConfig): AstroIntegration;
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { Duration } from "effect";
|
|
1
2
|
import { defaultConfig } from "./consts.js";
|
|
2
3
|
import stub from "./stub.js";
|
|
3
4
|
import { addVirtualImports, createResolver } from "./utils/integration.js";
|
|
5
|
+
import { Duration as Duration2 } from "effect";
|
|
4
6
|
function cFetch(opts) {
|
|
5
7
|
const name = "@studiocms/cfetch";
|
|
6
8
|
const { resolve } = createResolver(import.meta.url);
|
|
@@ -15,7 +17,10 @@ function cFetch(opts) {
|
|
|
15
17
|
addVirtualImports(params, {
|
|
16
18
|
name,
|
|
17
19
|
imports: {
|
|
18
|
-
"virtual:cfetch/config": `export default ${JSON.stringify(
|
|
20
|
+
"virtual:cfetch/config": `export default ${JSON.stringify({
|
|
21
|
+
// Convert Duration.DurationInput to milliseconds number (required to preserve value through JSON.stringify)
|
|
22
|
+
lifetime: Duration.toMillis(options.lifetime)
|
|
23
|
+
})}`,
|
|
19
24
|
"c:fetch": `export * from '${resolve("./wrappers.js")}';`
|
|
20
25
|
}
|
|
21
26
|
});
|
|
@@ -31,6 +36,7 @@ function cFetch(opts) {
|
|
|
31
36
|
}
|
|
32
37
|
var index_default = cFetch;
|
|
33
38
|
export {
|
|
39
|
+
Duration2 as Duration,
|
|
34
40
|
cFetch,
|
|
35
41
|
index_default as default
|
|
36
42
|
};
|