@studiocms/cfetch 0.2.0 → 0.3.0
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 +59 -8
- package/dist/{cache.d.ts → cache.d.mts} +28 -31
- package/dist/cache.mjs +176 -0
- package/dist/consts.d.mts +17 -0
- package/dist/consts.mjs +23 -0
- package/dist/index.d.mts +32 -0
- package/dist/index.mjs +62 -0
- package/dist/stub.d.mts +22 -0
- package/dist/{stub.js → stub.mjs} +77 -19
- package/dist/{types.d.ts → types.d.mts} +9 -5
- package/dist/types.mjs +1 -0
- package/dist/utils/{integration.d.ts → integration.d.mts} +31 -32
- package/dist/utils/integration.mjs +276 -0
- package/dist/{wrappers.d.ts → wrappers.d.mts} +77 -40
- package/dist/wrappers.mjs +364 -0
- package/package.json +15 -12
- package/dist/cache.js +0 -89
- package/dist/consts.d.ts +0 -8
- package/dist/consts.js +0 -11
- package/dist/index.d.ts +0 -66
- package/dist/index.js +0 -42
- package/dist/stub.d.ts +0 -6
- package/dist/types.js +0 -0
- package/dist/utils/integration.js +0 -266
- package/dist/wrappers.js +0 -87
package/dist/cache.js
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
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
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module cfetch/consts
|
|
3
|
-
*
|
|
4
|
-
* Constant values used throughout the cfetch package.
|
|
5
|
-
*/
|
|
6
|
-
import type { CacheConfig, CacheConfigLive } from './types.js';
|
|
7
|
-
export declare const defaultConfig: CacheConfig;
|
|
8
|
-
export declare const defaultConfigLive: CacheConfigLive;
|
package/dist/consts.js
DELETED
package/dist/index.d.ts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module @studiocms/cfetch
|
|
3
|
-
*
|
|
4
|
-
* An Astro integration that provides a caching fetch utility using Effect.
|
|
5
|
-
*
|
|
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';
|
|
18
|
-
* import { defineConfig } from 'astro/config';
|
|
19
|
-
*
|
|
20
|
-
* export default defineConfig({
|
|
21
|
-
* integrations: [
|
|
22
|
-
* cFetch({
|
|
23
|
-
* lifetime: Duration.minutes(5), // Set cache lifetime to 5 minutes (default is 1 hour)
|
|
24
|
-
* }),
|
|
25
|
-
* ],
|
|
26
|
-
* });
|
|
27
|
-
* ```
|
|
28
|
-
*
|
|
29
|
-
* You can then use the cached fetch functions in your Astro components or pages:
|
|
30
|
-
*
|
|
31
|
-
* ```ts
|
|
32
|
-
* import { cFetch } from 'c:fetch';
|
|
33
|
-
*
|
|
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
|
-
* });
|
|
63
|
-
* ```
|
|
64
|
-
*/
|
|
65
|
-
export declare function cFetch(opts?: CacheConfig): AstroIntegration;
|
|
66
|
-
export default cFetch;
|
package/dist/index.js
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { Duration } from "effect";
|
|
2
|
-
import { defaultConfig } from "./consts.js";
|
|
3
|
-
import stub from "./stub.js";
|
|
4
|
-
import { addVirtualImports, createResolver } from "./utils/integration.js";
|
|
5
|
-
import { Duration as Duration2 } from "effect";
|
|
6
|
-
function cFetch(opts) {
|
|
7
|
-
const name = "@studiocms/cfetch";
|
|
8
|
-
const { resolve } = createResolver(import.meta.url);
|
|
9
|
-
const options = {
|
|
10
|
-
...defaultConfig,
|
|
11
|
-
...opts
|
|
12
|
-
};
|
|
13
|
-
return {
|
|
14
|
-
name,
|
|
15
|
-
hooks: {
|
|
16
|
-
"astro:config:setup": (params) => {
|
|
17
|
-
addVirtualImports(params, {
|
|
18
|
-
name,
|
|
19
|
-
imports: {
|
|
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
|
-
})}`,
|
|
24
|
-
"c:fetch": `export * from '${resolve("./wrappers.js")}';`
|
|
25
|
-
}
|
|
26
|
-
});
|
|
27
|
-
},
|
|
28
|
-
"astro:config:done": ({ injectTypes }) => {
|
|
29
|
-
injectTypes({
|
|
30
|
-
filename: "cfetch.d.ts",
|
|
31
|
-
content: stub
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
var index_default = cFetch;
|
|
38
|
-
export {
|
|
39
|
-
Duration2 as Duration,
|
|
40
|
-
cFetch,
|
|
41
|
-
index_default as default
|
|
42
|
-
};
|
package/dist/stub.d.ts
DELETED
package/dist/types.js
DELETED
|
File without changes
|
|
@@ -1,266 +0,0 @@
|
|
|
1
|
-
import { fileURLToPath } from "node:url";
|
|
2
|
-
const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/;
|
|
3
|
-
const _DRIVE_LETTER_RE = /^[A-Za-z]:$/;
|
|
4
|
-
const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
|
|
5
|
-
const isAbsolute = (p) => _IS_ABSOLUTE_RE.test(p);
|
|
6
|
-
const dirname = (p) => {
|
|
7
|
-
const segments = normalizeWindowsPath(p).replace(/\/$/, "").split("/").slice(0, -1);
|
|
8
|
-
if (segments.length === 1 && _DRIVE_LETTER_RE.test(segments[0])) {
|
|
9
|
-
segments[0] += "/";
|
|
10
|
-
}
|
|
11
|
-
return segments.join("/") || (isAbsolute(p) ? "/" : ".");
|
|
12
|
-
};
|
|
13
|
-
function cwd() {
|
|
14
|
-
if (typeof process !== "undefined" && typeof process.cwd === "function") {
|
|
15
|
-
return process.cwd().replace(/\\/g, "/");
|
|
16
|
-
}
|
|
17
|
-
return "/";
|
|
18
|
-
}
|
|
19
|
-
function normalizeString(path, allowAboveRoot) {
|
|
20
|
-
let res = "";
|
|
21
|
-
let lastSegmentLength = 0;
|
|
22
|
-
let lastSlash = -1;
|
|
23
|
-
let dots = 0;
|
|
24
|
-
let char = null;
|
|
25
|
-
for (let index = 0; index <= path.length; ++index) {
|
|
26
|
-
if (index < path.length) {
|
|
27
|
-
char = path[index];
|
|
28
|
-
} else if (char === "/") {
|
|
29
|
-
break;
|
|
30
|
-
} else {
|
|
31
|
-
char = "/";
|
|
32
|
-
}
|
|
33
|
-
if (char === "/") {
|
|
34
|
-
if (lastSlash === index - 1 || dots === 1) {
|
|
35
|
-
} else if (dots === 2) {
|
|
36
|
-
if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") {
|
|
37
|
-
if (res.length > 2) {
|
|
38
|
-
const lastSlashIndex = res.lastIndexOf("/");
|
|
39
|
-
if (lastSlashIndex === -1) {
|
|
40
|
-
res = "";
|
|
41
|
-
lastSegmentLength = 0;
|
|
42
|
-
} else {
|
|
43
|
-
res = res.slice(0, lastSlashIndex);
|
|
44
|
-
lastSegmentLength = res.length - 1 - res.lastIndexOf("/");
|
|
45
|
-
}
|
|
46
|
-
lastSlash = index;
|
|
47
|
-
dots = 0;
|
|
48
|
-
continue;
|
|
49
|
-
}
|
|
50
|
-
if (res.length > 0) {
|
|
51
|
-
res = "";
|
|
52
|
-
lastSegmentLength = 0;
|
|
53
|
-
lastSlash = index;
|
|
54
|
-
dots = 0;
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
if (allowAboveRoot) {
|
|
59
|
-
res += res.length > 0 ? "/.." : "..";
|
|
60
|
-
lastSegmentLength = 2;
|
|
61
|
-
}
|
|
62
|
-
} else {
|
|
63
|
-
if (res.length > 0) {
|
|
64
|
-
res += `/${path.slice(lastSlash + 1, index)}`;
|
|
65
|
-
} else {
|
|
66
|
-
res = path.slice(lastSlash + 1, index);
|
|
67
|
-
}
|
|
68
|
-
lastSegmentLength = index - lastSlash - 1;
|
|
69
|
-
}
|
|
70
|
-
lastSlash = index;
|
|
71
|
-
dots = 0;
|
|
72
|
-
} else if (char === "." && dots !== -1) {
|
|
73
|
-
++dots;
|
|
74
|
-
} else {
|
|
75
|
-
dots = -1;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
return res;
|
|
79
|
-
}
|
|
80
|
-
function normalizeWindowsPath(input = "") {
|
|
81
|
-
if (!input) {
|
|
82
|
-
return input;
|
|
83
|
-
}
|
|
84
|
-
return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase());
|
|
85
|
-
}
|
|
86
|
-
const resolve = (...arguments_) => {
|
|
87
|
-
arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument));
|
|
88
|
-
let resolvedPath = "";
|
|
89
|
-
let resolvedAbsolute = false;
|
|
90
|
-
for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) {
|
|
91
|
-
const path = index >= 0 ? arguments_[index] : cwd();
|
|
92
|
-
if (!path || path.length === 0) {
|
|
93
|
-
continue;
|
|
94
|
-
}
|
|
95
|
-
resolvedPath = `${path}/${resolvedPath}`;
|
|
96
|
-
resolvedAbsolute = isAbsolute(path);
|
|
97
|
-
}
|
|
98
|
-
resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute);
|
|
99
|
-
if (resolvedAbsolute && !isAbsolute(resolvedPath)) {
|
|
100
|
-
return `/${resolvedPath}`;
|
|
101
|
-
}
|
|
102
|
-
return resolvedPath.length > 0 ? resolvedPath : ".";
|
|
103
|
-
};
|
|
104
|
-
const createResolver = (_base) => {
|
|
105
|
-
let base = _base;
|
|
106
|
-
if (base.startsWith("file://")) {
|
|
107
|
-
base = dirname(fileURLToPath(base));
|
|
108
|
-
}
|
|
109
|
-
return {
|
|
110
|
-
resolve: (...path) => resolve(base, ...path)
|
|
111
|
-
};
|
|
112
|
-
};
|
|
113
|
-
const defineUtility = (_hook) => (
|
|
114
|
-
/**
|
|
115
|
-
* The function itself
|
|
116
|
-
* @param {Function} fn;
|
|
117
|
-
*/
|
|
118
|
-
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
119
|
-
(fn) => fn
|
|
120
|
-
);
|
|
121
|
-
function getPluginNames(plugins) {
|
|
122
|
-
const names = [];
|
|
123
|
-
if (plugins) {
|
|
124
|
-
for (const plugin of plugins) {
|
|
125
|
-
if (!plugin) continue;
|
|
126
|
-
if (Array.isArray(plugin)) {
|
|
127
|
-
names.push(...getPluginNames(plugin));
|
|
128
|
-
continue;
|
|
129
|
-
}
|
|
130
|
-
if (plugin instanceof Promise) {
|
|
131
|
-
continue;
|
|
132
|
-
}
|
|
133
|
-
names.push(plugin.name);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
return names;
|
|
137
|
-
}
|
|
138
|
-
const hasVitePlugin = defineUtility("astro:config:setup")(
|
|
139
|
-
({ config }, {
|
|
140
|
-
plugin
|
|
141
|
-
}) => {
|
|
142
|
-
if (!plugin || plugin instanceof Promise) return false;
|
|
143
|
-
const currentPlugins = new Set(getPluginNames(config?.vite?.plugins));
|
|
144
|
-
const plugins = /* @__PURE__ */ new Set();
|
|
145
|
-
if (typeof plugin === "string") {
|
|
146
|
-
plugins.add(plugin);
|
|
147
|
-
}
|
|
148
|
-
if (typeof plugin === "object") {
|
|
149
|
-
if (Array.isArray(plugin)) {
|
|
150
|
-
const names = new Set(
|
|
151
|
-
getPluginNames(plugin)
|
|
152
|
-
);
|
|
153
|
-
for (const name of names) plugins.add(name);
|
|
154
|
-
} else {
|
|
155
|
-
plugins.add(plugin.name);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
return [...plugins].some((name) => currentPlugins.has(name));
|
|
159
|
-
}
|
|
160
|
-
);
|
|
161
|
-
const addVitePlugin = defineUtility("astro:config:setup")(
|
|
162
|
-
(params, {
|
|
163
|
-
plugin,
|
|
164
|
-
warnDuplicated = true
|
|
165
|
-
}) => {
|
|
166
|
-
const { updateConfig, logger } = params;
|
|
167
|
-
if (warnDuplicated && hasVitePlugin(params, { plugin })) {
|
|
168
|
-
logger.warn(
|
|
169
|
-
`The Vite plugin "${plugin.name}" is already present in your Vite configuration, this plugin may not behave correctly.`
|
|
170
|
-
);
|
|
171
|
-
}
|
|
172
|
-
updateConfig({
|
|
173
|
-
vite: {
|
|
174
|
-
plugins: [plugin]
|
|
175
|
-
}
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
);
|
|
179
|
-
const incrementPluginName = (name) => {
|
|
180
|
-
let count = 1;
|
|
181
|
-
return `${name.replace(/-(\d+)$/, (_, c) => {
|
|
182
|
-
count = Number.parseInt(c) + 1;
|
|
183
|
-
return "";
|
|
184
|
-
})}-${count}`;
|
|
185
|
-
};
|
|
186
|
-
const resolveVirtualModuleId = (id) => {
|
|
187
|
-
return `\0${id}`;
|
|
188
|
-
};
|
|
189
|
-
const createVirtualModule = (name, _imports, bypassCoreValidation) => {
|
|
190
|
-
const imports = Array.isArray(_imports) ? _imports : Object.entries(_imports).map(([id, content]) => ({
|
|
191
|
-
id,
|
|
192
|
-
content,
|
|
193
|
-
context: void 0
|
|
194
|
-
}));
|
|
195
|
-
const duplicatedImports = {};
|
|
196
|
-
for (const { id, context } of imports) {
|
|
197
|
-
duplicatedImports[id] ??= [];
|
|
198
|
-
duplicatedImports[id]?.push(...context === void 0 ? ["server", "client"] : [context]);
|
|
199
|
-
}
|
|
200
|
-
for (const [id, contexts] of Object.entries(duplicatedImports)) {
|
|
201
|
-
if (contexts.length !== [...new Set(contexts)].length) {
|
|
202
|
-
throw new Error(
|
|
203
|
-
`Virtual import with id "${id}" has been registered several times with conflicting contexts.`
|
|
204
|
-
);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
const resolutionMap = Object.fromEntries(
|
|
208
|
-
imports.map(({ id }) => {
|
|
209
|
-
if (!bypassCoreValidation && id.startsWith("astro:")) {
|
|
210
|
-
throw new Error(
|
|
211
|
-
`Virtual import name prefix can't be "astro:" (for "${id}") because it's reserved for Astro core.`
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
return [resolveVirtualModuleId(id), id];
|
|
215
|
-
})
|
|
216
|
-
);
|
|
217
|
-
return {
|
|
218
|
-
name,
|
|
219
|
-
resolveId(id) {
|
|
220
|
-
if (imports.find((_import) => _import.id === id)) {
|
|
221
|
-
return resolveVirtualModuleId(id);
|
|
222
|
-
}
|
|
223
|
-
return;
|
|
224
|
-
},
|
|
225
|
-
load(id, options) {
|
|
226
|
-
const resolution = resolutionMap[id];
|
|
227
|
-
if (resolution) {
|
|
228
|
-
const context = options?.ssr ? "server" : "client";
|
|
229
|
-
const data = imports.find(
|
|
230
|
-
(_import) => _import.id === resolution && (_import.context === void 0 || _import.context === context)
|
|
231
|
-
);
|
|
232
|
-
if (data) {
|
|
233
|
-
return data.content;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
};
|
|
239
|
-
};
|
|
240
|
-
const addVirtualImports = defineUtility("astro:config:setup")(
|
|
241
|
-
(params, {
|
|
242
|
-
name,
|
|
243
|
-
imports,
|
|
244
|
-
__enableCorePowerDoNotUseOrYouWillBeFired = false
|
|
245
|
-
}) => {
|
|
246
|
-
let pluginName = `vite-plugin-${name}`;
|
|
247
|
-
while (hasVitePlugin(params, { plugin: pluginName }))
|
|
248
|
-
pluginName = incrementPluginName(pluginName);
|
|
249
|
-
addVitePlugin(params, {
|
|
250
|
-
warnDuplicated: false,
|
|
251
|
-
plugin: createVirtualModule(pluginName, imports, __enableCorePowerDoNotUseOrYouWillBeFired)
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
);
|
|
255
|
-
export {
|
|
256
|
-
addVirtualImports,
|
|
257
|
-
addVitePlugin,
|
|
258
|
-
createResolver,
|
|
259
|
-
defineUtility,
|
|
260
|
-
dirname,
|
|
261
|
-
hasVitePlugin,
|
|
262
|
-
isAbsolute,
|
|
263
|
-
normalizeString,
|
|
264
|
-
normalizeWindowsPath,
|
|
265
|
-
resolve
|
|
266
|
-
};
|
package/dist/wrappers.js
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { Data, Effect, Layer } from "effect";
|
|
2
|
-
import { CacheMaps, CacheService } from "./cache.js";
|
|
3
|
-
import { Duration } from "effect";
|
|
4
|
-
const store = /* @__PURE__ */ new Map();
|
|
5
|
-
const tagIndex = /* @__PURE__ */ new Map();
|
|
6
|
-
const CacheMapLayer = Layer.succeed(CacheMaps, { store, tagIndex });
|
|
7
|
-
const CacheLive = CacheService.Default.pipe(Layer.provide(CacheMapLayer));
|
|
8
|
-
class FetchError extends Data.TaggedError("FetchError") {
|
|
9
|
-
}
|
|
10
|
-
const runEffect = (effect) => Effect.runPromise(effect);
|
|
11
|
-
const cacheableMethods = ["GET", "HEAD"];
|
|
12
|
-
const noOpParser = (_) => Promise.resolve(void 0);
|
|
13
|
-
const fetchAndParse = (url, parser, options) => Effect.gen(function* () {
|
|
14
|
-
const response = yield* Effect.tryPromise({
|
|
15
|
-
try: () => fetch(url, options),
|
|
16
|
-
catch: (cause) => new FetchError({ message: "Failed to fetch", cause })
|
|
17
|
-
});
|
|
18
|
-
const data = yield* Effect.tryPromise({
|
|
19
|
-
try: () => parser(response),
|
|
20
|
-
catch: (cause) => new FetchError({ message: "Failed to parse response", cause })
|
|
21
|
-
});
|
|
22
|
-
return {
|
|
23
|
-
data,
|
|
24
|
-
ok: response.ok,
|
|
25
|
-
status: response.status,
|
|
26
|
-
statusText: response.statusText,
|
|
27
|
-
headers: Object.fromEntries(response.headers.entries())
|
|
28
|
-
};
|
|
29
|
-
});
|
|
30
|
-
const cFetchEffect = (url, parser, options, cacheConfig) => Effect.gen(function* () {
|
|
31
|
-
const cache = yield* CacheService;
|
|
32
|
-
const { key, verbose = false, ...cacheOpts } = cacheConfig || {};
|
|
33
|
-
const method = options?.method?.toUpperCase() || "GET";
|
|
34
|
-
if (!cacheableMethods.includes(method)) {
|
|
35
|
-
if (verbose) console.log(`[c:fetch] Bypassing cache for non-cacheable method: ${method}`);
|
|
36
|
-
return yield* fetchAndParse(url, parser, options);
|
|
37
|
-
}
|
|
38
|
-
const urlString = typeof url === "string" ? url : url.href;
|
|
39
|
-
const cacheRelevantOptions = options ? {
|
|
40
|
-
method: options.method,
|
|
41
|
-
headers: options.headers instanceof Headers ? Object.fromEntries(
|
|
42
|
-
[...options.headers.entries()].sort(([a], [b]) => a.localeCompare(b))
|
|
43
|
-
) : options.headers ? Object.fromEntries(
|
|
44
|
-
Object.entries(options.headers).sort(([a], [b]) => a.localeCompare(b))
|
|
45
|
-
) : void 0,
|
|
46
|
-
body: typeof options.body === "string" ? options.body : void 0
|
|
47
|
-
} : {};
|
|
48
|
-
if (options?.body && typeof options.body !== "string" && !key && verbose) {
|
|
49
|
-
console.warn(
|
|
50
|
-
`[c:fetch] Non-serializable request body detected for ${urlString}. Consider providing an explicit cache key via cacheConfig.key to avoid collisions.`
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
const cacheKey = key ?? `${urlString}-${JSON.stringify(cacheRelevantOptions)}`;
|
|
54
|
-
const cached = yield* cache.get(cacheKey);
|
|
55
|
-
if (cached) {
|
|
56
|
-
if (verbose) console.log(`[c:fetch] Cache hit for: ${cacheKey}, returning cached response.`);
|
|
57
|
-
return cached;
|
|
58
|
-
}
|
|
59
|
-
if (verbose) console.log(`[c:fetch] Cache miss for: ${cacheKey}, fetching from network.`);
|
|
60
|
-
const effectiveParser = method === "HEAD" ? noOpParser : parser;
|
|
61
|
-
const cachedResponse = yield* fetchAndParse(url, effectiveParser, options);
|
|
62
|
-
if (cachedResponse.ok) {
|
|
63
|
-
yield* cache.set(cacheKey, cachedResponse, cacheOpts);
|
|
64
|
-
if (verbose) console.log(`[c:fetch] Cached response for: ${cacheKey}`);
|
|
65
|
-
}
|
|
66
|
-
return cachedResponse;
|
|
67
|
-
}).pipe(Effect.provide(CacheLive));
|
|
68
|
-
const cFetchEffectJson = (url, options, cacheConfig) => cFetchEffect(url, (res) => res.json(), options, cacheConfig);
|
|
69
|
-
const cFetchEffectText = (url, options, cacheConfig) => cFetchEffect(url, (res) => res.text(), options, cacheConfig);
|
|
70
|
-
const cFetchEffectBlob = (url, options, cacheConfig) => cFetchEffect(url, (res) => res.blob(), options, cacheConfig);
|
|
71
|
-
const cFetch = (url, parser, options, cacheConfig) => runEffect(cFetchEffect(url, parser, options, cacheConfig));
|
|
72
|
-
const cFetchJson = (url, options, cacheConfig) => runEffect(cFetchEffectJson(url, options, cacheConfig));
|
|
73
|
-
const cFetchText = (url, options, cacheConfig) => runEffect(cFetchEffectText(url, options, cacheConfig));
|
|
74
|
-
const cFetchBlob = (url, options, cacheConfig) => runEffect(cFetchEffectBlob(url, options, cacheConfig));
|
|
75
|
-
export {
|
|
76
|
-
Duration,
|
|
77
|
-
FetchError,
|
|
78
|
-
cFetch,
|
|
79
|
-
cFetchBlob,
|
|
80
|
-
cFetchEffect,
|
|
81
|
-
cFetchEffectBlob,
|
|
82
|
-
cFetchEffectJson,
|
|
83
|
-
cFetchEffectText,
|
|
84
|
-
cFetchJson,
|
|
85
|
-
cFetchText,
|
|
86
|
-
noOpParser
|
|
87
|
-
};
|