@ereo/data 0.1.6
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 +79 -0
- package/dist/action.d.ts +202 -0
- package/dist/action.d.ts.map +1 -0
- package/dist/cache.d.ts +141 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/define-route.d.ts +354 -0
- package/dist/define-route.d.ts.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1587 -0
- package/dist/loader.d.ts +89 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/pipeline.d.ts +202 -0
- package/dist/pipeline.d.ts.map +1 -0
- package/dist/revalidate.d.ts +70 -0
- package/dist/revalidate.d.ts.map +1 -0
- package/dist/schema-adapters.d.ts +261 -0
- package/dist/schema-adapters.d.ts.map +1 -0
- package/package.json +41 -0
package/README.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# @ereo/data
|
|
2
|
+
|
|
3
|
+
Data loading and caching for the EreoJS framework. One pattern, not four - simple and explicit data fetching with automatic parallelization.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add @ereo/data
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { createLoader, createAction, cached } from '@ereo/data';
|
|
15
|
+
|
|
16
|
+
// Create a loader for fetching data
|
|
17
|
+
export const loader = createLoader(async ({ params }) => {
|
|
18
|
+
const user = await fetchUser(params.id);
|
|
19
|
+
return { user };
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// Create an action for mutations
|
|
23
|
+
export const action = createAction(async ({ request }) => {
|
|
24
|
+
const formData = await request.formData();
|
|
25
|
+
await updateUser(formData);
|
|
26
|
+
return redirect('/users');
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Key Features
|
|
31
|
+
|
|
32
|
+
- **Loaders** - Fetch data with `createLoader`, support for deferred data with `defer`
|
|
33
|
+
- **Actions** - Handle mutations with `createAction`, `typedAction`, and `jsonAction`
|
|
34
|
+
- **Caching** - Built-in memory cache with `cached`, `getCache`, `setCache`
|
|
35
|
+
- **Cache Control** - Fine-grained cache headers with `buildCacheControl`
|
|
36
|
+
- **Revalidation** - On-demand revalidation with `revalidateTag` and `revalidatePath`
|
|
37
|
+
- **Data Pipelines** - Auto-parallelization with `createPipeline` and `dataSource`
|
|
38
|
+
- **Response Helpers** - `redirect`, `json`, and `error` utilities
|
|
39
|
+
|
|
40
|
+
## Caching Example
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { cached, revalidateTag } from '@ereo/data';
|
|
44
|
+
|
|
45
|
+
const getUser = cached(
|
|
46
|
+
async (id: string) => fetchUser(id),
|
|
47
|
+
{ tags: ['user'], ttl: 60000 }
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
// Revalidate when user is updated
|
|
51
|
+
await revalidateTag('user');
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Data Pipeline
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
import { createPipeline, dataSource, cachedSource } from '@ereo/data';
|
|
58
|
+
|
|
59
|
+
const pipeline = createPipeline({
|
|
60
|
+
user: dataSource(() => fetchUser(id)),
|
|
61
|
+
posts: cachedSource(() => fetchPosts(id), { ttl: 5000 }),
|
|
62
|
+
comments: dataSource((ctx) => fetchComments(ctx.posts)),
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const data = await pipeline.execute();
|
|
66
|
+
// { user, posts, comments } - automatically parallelized
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Documentation
|
|
70
|
+
|
|
71
|
+
For full documentation, visit [https://ereojs.dev/docs/data](https://ereojs.dev/docs/data)
|
|
72
|
+
|
|
73
|
+
## Part of EreoJS
|
|
74
|
+
|
|
75
|
+
This package is part of the [EreoJS](https://github.com/ereojs/ereo) monorepo - a modern full-stack framework built for Bun.
|
|
76
|
+
|
|
77
|
+
## License
|
|
78
|
+
|
|
79
|
+
MIT
|
package/dist/action.d.ts
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ereo/data - Mutations (Actions)
|
|
3
|
+
*
|
|
4
|
+
* Handle form submissions and mutations with a simple, type-safe API.
|
|
5
|
+
* Supports both FormData and JSON payloads with complex data types.
|
|
6
|
+
*/
|
|
7
|
+
import type { ActionArgs, ActionFunction, RouteParams } from '@ereo/core';
|
|
8
|
+
/**
|
|
9
|
+
* Parsed action body - can be any type when using JSON.
|
|
10
|
+
*/
|
|
11
|
+
export type ActionBody<T = unknown> = T;
|
|
12
|
+
/**
|
|
13
|
+
* Extended action args with parsed body.
|
|
14
|
+
*/
|
|
15
|
+
export interface TypedActionArgs<TBody, P extends RouteParams = RouteParams> extends ActionArgs<P> {
|
|
16
|
+
/** Parsed body data (from JSON or FormData) */
|
|
17
|
+
body: TBody;
|
|
18
|
+
/** Raw FormData (if content-type was form data) */
|
|
19
|
+
formData?: FormData;
|
|
20
|
+
/** Content type of the request */
|
|
21
|
+
contentType: 'json' | 'form' | 'text' | 'unknown';
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Options for creating an action.
|
|
25
|
+
*/
|
|
26
|
+
export interface ActionOptions<T, P extends RouteParams = RouteParams> {
|
|
27
|
+
/** Handle the form submission */
|
|
28
|
+
handler: (args: ActionArgs<P> & {
|
|
29
|
+
formData: FormData;
|
|
30
|
+
}) => T | Promise<T>;
|
|
31
|
+
/** Validate form data before processing */
|
|
32
|
+
validate?: (formData: FormData) => ValidationResult | Promise<ValidationResult>;
|
|
33
|
+
/** Handle errors */
|
|
34
|
+
onError?: (error: Error, args: ActionArgs<P>) => T | Response | Promise<T | Response>;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Options for creating a typed action with complex data support.
|
|
38
|
+
*/
|
|
39
|
+
export interface TypedActionOptions<TBody, TResult, P extends RouteParams = RouteParams> {
|
|
40
|
+
/** Handle the action with typed body */
|
|
41
|
+
handler: (args: TypedActionArgs<TBody, P>) => TResult | Promise<TResult>;
|
|
42
|
+
/** Validate the parsed body */
|
|
43
|
+
validate?: (body: TBody) => ValidationResult | Promise<ValidationResult>;
|
|
44
|
+
/** Transform/coerce the raw body before validation */
|
|
45
|
+
transform?: (raw: unknown) => TBody;
|
|
46
|
+
/** Handle errors */
|
|
47
|
+
onError?: (error: Error, args: ActionArgs<P>) => TResult | Response | Promise<TResult | Response>;
|
|
48
|
+
/** Schema for automatic validation (compatible with zod, yup, etc.) */
|
|
49
|
+
schema?: {
|
|
50
|
+
parse: (data: unknown) => TBody;
|
|
51
|
+
safeParse?: (data: unknown) => {
|
|
52
|
+
success: true;
|
|
53
|
+
data: TBody;
|
|
54
|
+
} | {
|
|
55
|
+
success: false;
|
|
56
|
+
error: {
|
|
57
|
+
errors: Array<{
|
|
58
|
+
path: (string | number)[];
|
|
59
|
+
message: string;
|
|
60
|
+
}>;
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Validation result.
|
|
67
|
+
*/
|
|
68
|
+
export interface ValidationResult {
|
|
69
|
+
success: boolean;
|
|
70
|
+
errors?: Record<string, string[]>;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Action result with potential errors.
|
|
74
|
+
*/
|
|
75
|
+
export interface ActionResult<T = unknown> {
|
|
76
|
+
success: boolean;
|
|
77
|
+
data?: T;
|
|
78
|
+
errors?: Record<string, string[]>;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Create a type-safe action function.
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* export const action = createAction({
|
|
85
|
+
* handler: async ({ formData }) => {
|
|
86
|
+
* const title = formData.get('title');
|
|
87
|
+
* return db.post.create({ data: { title } });
|
|
88
|
+
* },
|
|
89
|
+
* validate: (formData) => {
|
|
90
|
+
* const errors: Record<string, string[]> = {};
|
|
91
|
+
* if (!formData.get('title')) {
|
|
92
|
+
* errors.title = ['Title is required'];
|
|
93
|
+
* }
|
|
94
|
+
* return { success: Object.keys(errors).length === 0, errors };
|
|
95
|
+
* },
|
|
96
|
+
* });
|
|
97
|
+
*/
|
|
98
|
+
export declare function createAction<T, P extends RouteParams = RouteParams>(options: ActionOptions<T, P>): ActionFunction<ActionResult<T>, P>;
|
|
99
|
+
/**
|
|
100
|
+
* Create a simple action from a handler function.
|
|
101
|
+
*/
|
|
102
|
+
export declare function action<T, P extends RouteParams = RouteParams>(handler: (args: ActionArgs<P> & {
|
|
103
|
+
formData: FormData;
|
|
104
|
+
}) => T | Promise<T>): ActionFunction<ActionResult<T>, P>;
|
|
105
|
+
/**
|
|
106
|
+
* Create a typed action that accepts complex data types.
|
|
107
|
+
* Automatically handles JSON and FormData content types.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* // With inline type
|
|
111
|
+
* export const action = typedAction<{ title: string; count: number; tags: string[] }>({
|
|
112
|
+
* handler: async ({ body }) => {
|
|
113
|
+
* // body is typed as { title: string; count: number; tags: string[] }
|
|
114
|
+
* return db.post.create({ data: body });
|
|
115
|
+
* },
|
|
116
|
+
* });
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* // With zod schema
|
|
120
|
+
* const PostSchema = z.object({
|
|
121
|
+
* title: z.string().min(1),
|
|
122
|
+
* count: z.number(),
|
|
123
|
+
* tags: z.array(z.string()),
|
|
124
|
+
* });
|
|
125
|
+
*
|
|
126
|
+
* export const action = typedAction({
|
|
127
|
+
* schema: PostSchema,
|
|
128
|
+
* handler: async ({ body }) => {
|
|
129
|
+
* // body is inferred from schema
|
|
130
|
+
* return db.post.create({ data: body });
|
|
131
|
+
* },
|
|
132
|
+
* });
|
|
133
|
+
*/
|
|
134
|
+
export declare function typedAction<TBody, TResult = TBody, P extends RouteParams = RouteParams>(options: TypedActionOptions<TBody, TResult, P>): ActionFunction<ActionResult<TResult>, P>;
|
|
135
|
+
/**
|
|
136
|
+
* Parse request body based on content type.
|
|
137
|
+
* Supports JSON, FormData, and text.
|
|
138
|
+
*/
|
|
139
|
+
export declare function parseRequestBody(request: Request): Promise<{
|
|
140
|
+
body: unknown;
|
|
141
|
+
formData?: FormData;
|
|
142
|
+
contentType: 'json' | 'form' | 'text' | 'unknown';
|
|
143
|
+
}>;
|
|
144
|
+
/**
|
|
145
|
+
* Convert FormData to a typed object with automatic type coercion.
|
|
146
|
+
* Handles nested objects, arrays, numbers, booleans, and dates.
|
|
147
|
+
*
|
|
148
|
+
* Conventions:
|
|
149
|
+
* - `field[]` or multiple same-name fields → array
|
|
150
|
+
* - `field.nested` → nested object
|
|
151
|
+
* - `field[0]`, `field[1]` → indexed array
|
|
152
|
+
* - Values "true"/"false" → boolean (when coercing)
|
|
153
|
+
* - Numeric strings → number (when coercing)
|
|
154
|
+
* - ISO date strings → Date (when coercing)
|
|
155
|
+
*/
|
|
156
|
+
export declare function formDataToObject<T = Record<string, unknown>>(formData: FormData, options?: {
|
|
157
|
+
coerce?: boolean;
|
|
158
|
+
}): T;
|
|
159
|
+
/**
|
|
160
|
+
* Coerce a string value to appropriate type.
|
|
161
|
+
*/
|
|
162
|
+
export declare function coerceValue(value: string): unknown;
|
|
163
|
+
/**
|
|
164
|
+
* Create a JSON action that only accepts JSON payloads.
|
|
165
|
+
* Provides better type safety for API endpoints.
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* export const action = jsonAction<CreatePostInput, Post>({
|
|
169
|
+
* handler: async ({ body }) => {
|
|
170
|
+
* return db.post.create({ data: body });
|
|
171
|
+
* },
|
|
172
|
+
* });
|
|
173
|
+
*/
|
|
174
|
+
export declare function jsonAction<TBody, TResult = TBody, P extends RouteParams = RouteParams>(options: Omit<TypedActionOptions<TBody, TResult, P>, 'transform'> & {
|
|
175
|
+
/** Require JSON content type (returns 415 if not JSON) */
|
|
176
|
+
strict?: boolean;
|
|
177
|
+
}): ActionFunction<ActionResult<TResult>, P>;
|
|
178
|
+
/**
|
|
179
|
+
* Redirect response helper.
|
|
180
|
+
*/
|
|
181
|
+
export declare function redirect(url: string, status?: 301 | 302 | 303 | 307 | 308): Response;
|
|
182
|
+
/**
|
|
183
|
+
* JSON response helper.
|
|
184
|
+
*/
|
|
185
|
+
export declare function json<T>(data: T, init?: ResponseInit): Response;
|
|
186
|
+
/**
|
|
187
|
+
* Error response helper.
|
|
188
|
+
*/
|
|
189
|
+
export declare function error(message: string, status?: number): Response;
|
|
190
|
+
/**
|
|
191
|
+
* Form data helper - convert FormData to typed object.
|
|
192
|
+
*/
|
|
193
|
+
export declare function parseFormData<T extends Record<string, unknown>>(formData: FormData): Partial<T>;
|
|
194
|
+
/**
|
|
195
|
+
* Validate that required fields are present.
|
|
196
|
+
*/
|
|
197
|
+
export declare function validateRequired(formData: FormData, fields: string[]): ValidationResult;
|
|
198
|
+
/**
|
|
199
|
+
* Combine multiple validators.
|
|
200
|
+
*/
|
|
201
|
+
export declare function combineValidators(...validators: Array<(formData: FormData) => ValidationResult | Promise<ValidationResult>>): (formData: FormData) => Promise<ValidationResult>;
|
|
202
|
+
//# sourceMappingURL=action.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../src/action.ts"],"names":[],"mappings":"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"}
|
package/dist/cache.d.ts
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ereo/data - Explicit Caching
|
|
3
|
+
*
|
|
4
|
+
* A transparent caching system with tags for invalidation.
|
|
5
|
+
* No hidden magic - you see exactly what's being cached.
|
|
6
|
+
*/
|
|
7
|
+
import type { CacheOptions, CacheAdapter, TaggedCache, CacheSetOptions as CoreCacheSetOptions } from '@ereo/core';
|
|
8
|
+
/**
|
|
9
|
+
* Cache entry with metadata.
|
|
10
|
+
*/
|
|
11
|
+
export interface CacheEntry<T = unknown> {
|
|
12
|
+
value: T;
|
|
13
|
+
timestamp: number;
|
|
14
|
+
maxAge: number;
|
|
15
|
+
staleWhileRevalidate?: number;
|
|
16
|
+
tags: string[];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Cache storage interface.
|
|
20
|
+
* This is the legacy interface used by @ereo/data.
|
|
21
|
+
* For new implementations, consider using CacheAdapter from @ereo/core.
|
|
22
|
+
*/
|
|
23
|
+
export interface CacheStorage {
|
|
24
|
+
get<T>(key: string): Promise<CacheEntry<T> | null>;
|
|
25
|
+
set<T>(key: string, entry: CacheEntry<T>): Promise<void>;
|
|
26
|
+
delete(key: string): Promise<boolean | void>;
|
|
27
|
+
deleteByTag(tag: string): Promise<void>;
|
|
28
|
+
clear(): Promise<void>;
|
|
29
|
+
keys(): Promise<string[]>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* In-memory cache implementation.
|
|
33
|
+
* Implements the CacheStorage interface with full entry metadata support.
|
|
34
|
+
*
|
|
35
|
+
* For the unified CacheAdapter interface, use createDataCacheAdapter() or
|
|
36
|
+
* asCacheAdapter() to get a compatible wrapper.
|
|
37
|
+
*/
|
|
38
|
+
export declare class MemoryCache implements CacheStorage {
|
|
39
|
+
private cache;
|
|
40
|
+
private tagIndex;
|
|
41
|
+
/**
|
|
42
|
+
* Get a cache entry with full metadata.
|
|
43
|
+
*/
|
|
44
|
+
get<T>(key: string): Promise<CacheEntry<T> | null>;
|
|
45
|
+
/**
|
|
46
|
+
* Set a cache entry with full metadata.
|
|
47
|
+
*/
|
|
48
|
+
set<T>(key: string, entry: CacheEntry<T>): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Delete a cache entry.
|
|
51
|
+
*/
|
|
52
|
+
delete(key: string): Promise<boolean>;
|
|
53
|
+
/**
|
|
54
|
+
* Delete all entries with a specific tag.
|
|
55
|
+
*/
|
|
56
|
+
deleteByTag(tag: string): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Clear all entries.
|
|
59
|
+
*/
|
|
60
|
+
clear(): Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Get all keys in the cache.
|
|
63
|
+
*/
|
|
64
|
+
keys(): Promise<string[]>;
|
|
65
|
+
/**
|
|
66
|
+
* Get cache statistics.
|
|
67
|
+
*/
|
|
68
|
+
getStats(): {
|
|
69
|
+
size: number;
|
|
70
|
+
tags: number;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Get just the value from the cache (not the full entry).
|
|
74
|
+
* Use this for CacheAdapter-compatible access.
|
|
75
|
+
*/
|
|
76
|
+
getValue<T>(key: string): Promise<T | undefined>;
|
|
77
|
+
/**
|
|
78
|
+
* Set a value using the unified interface.
|
|
79
|
+
* Converts ttl (seconds) and tags from options to a CacheEntry.
|
|
80
|
+
*/
|
|
81
|
+
setValue<T>(key: string, value: T, options?: CoreCacheSetOptions): Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* Check if a key exists in the cache.
|
|
84
|
+
*/
|
|
85
|
+
has(key: string): Promise<boolean>;
|
|
86
|
+
/**
|
|
87
|
+
* Invalidate all cache entries with a specific tag.
|
|
88
|
+
* Alias for deleteByTag for TaggedCache compatibility.
|
|
89
|
+
*/
|
|
90
|
+
invalidateTag(tag: string): Promise<void>;
|
|
91
|
+
/**
|
|
92
|
+
* Invalidate all cache entries with any of the specified tags.
|
|
93
|
+
*/
|
|
94
|
+
invalidateTags(tags: string[]): Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* Get all cache keys associated with a specific tag.
|
|
97
|
+
*/
|
|
98
|
+
getByTag(tag: string): Promise<string[]>;
|
|
99
|
+
/**
|
|
100
|
+
* Create a CacheAdapter-compatible wrapper around this cache.
|
|
101
|
+
*/
|
|
102
|
+
asCacheAdapter(): CacheAdapter & TaggedCache;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Create a CacheAdapter-compatible wrapper around a new MemoryCache.
|
|
106
|
+
* Use this when you need a pure CacheAdapter without legacy methods.
|
|
107
|
+
*/
|
|
108
|
+
export declare function createDataCacheAdapter(): CacheAdapter & TaggedCache;
|
|
109
|
+
/**
|
|
110
|
+
* Get or create the global cache instance.
|
|
111
|
+
*/
|
|
112
|
+
export declare function getCache(): CacheStorage;
|
|
113
|
+
/**
|
|
114
|
+
* Set a custom cache storage.
|
|
115
|
+
*/
|
|
116
|
+
export declare function setCache(storage: CacheStorage): void;
|
|
117
|
+
/**
|
|
118
|
+
* Cache function result with explicit options.
|
|
119
|
+
*/
|
|
120
|
+
export declare function cached<T>(key: string, fn: () => Promise<T>, options: CacheOptions): Promise<T>;
|
|
121
|
+
/**
|
|
122
|
+
* Generate a cache key from request.
|
|
123
|
+
*/
|
|
124
|
+
export declare function generateCacheKey(request: Request): string;
|
|
125
|
+
/**
|
|
126
|
+
* Generate a cache key with custom prefix.
|
|
127
|
+
*/
|
|
128
|
+
export declare function cacheKey(prefix: string, ...parts: (string | number)[]): string;
|
|
129
|
+
/**
|
|
130
|
+
* Build Cache-Control header from options.
|
|
131
|
+
*/
|
|
132
|
+
export declare function buildCacheControl(options: CacheOptions): string;
|
|
133
|
+
/**
|
|
134
|
+
* Parse Cache-Control header to options.
|
|
135
|
+
*/
|
|
136
|
+
export declare function parseCacheControl(header: string): CacheOptions;
|
|
137
|
+
/**
|
|
138
|
+
* Decorator for caching method results.
|
|
139
|
+
*/
|
|
140
|
+
export declare function Cached(options: CacheOptions): <T extends (...args: any[]) => Promise<any>>(_target: any, propertyKey: string, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T>;
|
|
141
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"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"}
|