@lunora/server 1.0.0-alpha.16 → 1.0.0-alpha.18
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/LICENSE.md +6 -0
- package/README.md +46 -0
- package/dist/index.d.mts +17 -2
- package/dist/index.d.ts +17 -2
- package/dist/index.mjs +1 -1
- package/dist/packem_shared/{httpAction-B_16WzMO.mjs → httpAction-DCXoYPIk.mjs} +36 -12
- package/dist/types.d.mts +23 -1
- package/dist/types.d.ts +23 -1
- package/package.json +4 -4
package/LICENSE.md
CHANGED
|
@@ -103,3 +103,9 @@ Unless required by applicable law or agreed to in writing, software distributed
|
|
|
103
103
|
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
104
104
|
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
105
105
|
specific language governing permissions and limitations under the License.
|
|
106
|
+
|
|
107
|
+
<!-- DEPENDENCIES -->
|
|
108
|
+
<!-- /DEPENDENCIES -->
|
|
109
|
+
|
|
110
|
+
<!-- TYPE_DEPENDENCIES -->
|
|
111
|
+
<!-- /TYPE_DEPENDENCIES -->
|
package/README.md
CHANGED
|
@@ -99,6 +99,52 @@ The builder chain is `<builder>.input(validators).<kind>(handler)`, plus `.use(m
|
|
|
99
99
|
|
|
100
100
|
> This README covers the basics. For the full API, options, and guides, see the **[documentation](https://lunora.sh/docs/packages/server)**.
|
|
101
101
|
|
|
102
|
+
### Caching with Workers Cache
|
|
103
|
+
|
|
104
|
+
Lunora supports Cloudflare Workers Cache for HTTP actions (`httpRoute`). RPC queries and mutations are `POST /_lunora/rpc` and are not cacheable at the edge by design.
|
|
105
|
+
|
|
106
|
+
**Enable Workers Cache** in `wrangler.jsonc`:
|
|
107
|
+
|
|
108
|
+
```jsonc
|
|
109
|
+
{
|
|
110
|
+
"cache": { "enabled": true },
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
The dev server and CLI automatically bump `compatibility_date` to the minimum required when cache is enabled — you do not need to set it manually.
|
|
115
|
+
|
|
116
|
+
**Set cache headers declaratively** on an `httpRoute`:
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
import { httpRoute } from "./_generated/server";
|
|
120
|
+
|
|
121
|
+
export const getProduct = httpRoute
|
|
122
|
+
.get("/api/products/:id")
|
|
123
|
+
.params({ id: v.string() })
|
|
124
|
+
.cacheControl("public, max-age=300, stale-while-revalidate=3600")
|
|
125
|
+
.cacheTag("products")
|
|
126
|
+
.handler(async ({ ctx, params }) => {
|
|
127
|
+
return { id: params.id, name: "Widget" };
|
|
128
|
+
});
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Purge cache by tag** from an action handler:
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
import { action } from "./_generated/server";
|
|
135
|
+
|
|
136
|
+
export const refreshProducts = action.action(async ({ ctx }) => {
|
|
137
|
+
if (!ctx.cache) {
|
|
138
|
+
throw new Error("Workers Cache is not enabled in wrangler.jsonc");
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
await ctx.cache.purge({ tags: ["products"] });
|
|
142
|
+
return { ok: true };
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
The `ctx.cache.purge` API accepts `{ tags?: string[]; purgeEverything?: boolean }`. Only action handlers expose `ctx.cache`; queries and mutations run inside the Durable Object and do not have access to the Worker-level cache binding.
|
|
147
|
+
|
|
102
148
|
## Related
|
|
103
149
|
|
|
104
150
|
- [`@lunora/values`](https://www.npmjs.com/package/@lunora/values) — the `v.*` validators re-exported here.
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Validator, Infer, ValidatorMap, InferValidatorMap, v } from '@lunora/values';
|
|
2
2
|
export { type ColumnValidator, type Id, type Infer, ValidationError, type Validator, type ValidatorKind, v } from '@lunora/values';
|
|
3
3
|
import { ArgsValidator, InferArgs, RegisteredAction, ActionCtx, MutationCtx, RegisteredMutation, QueryCtx, RegisteredQuery, RegisteredStream, FunctionKind, Secrets, LifecycleEvent, RegisteredLifecycleHook, TableDefinition, RegisteredFunction, VectorIndexDefinition, Schema, AggregateOp, DurableObjectJurisdiction, RelationDefinition, GlobalBackend, OnDeleteAction, ExternalSourceDefinition, TriggerBuilder, TriggerDefinition, VectorEmbedder, VectorMetric, AggregateIndexDefinition, RankIndexDefinition } from "./types.mjs";
|
|
4
|
-
export { type AnyApi, type AuthState, type DatabaseReader, type DatabaseWriter, type FunctionVisibility, type IndexDefinition, type IndexRangeBuilder, type LifecycleEventKind, type LunoraLogger, type PaginationOptions, type PaginationResult, type RankSortKey, type ReadOnlyStorage, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type SearchFilterBuilder, type SearchIndexDefinition, type ShardMode, type Storage, type StorageMetadata, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemTableName, type TableReader, type TableVectorIndex, type TriggerAggregateOptions, type TriggerCtx, type TriggerDatabase, type TriggerDeleteEvent, type TriggerEvent, type TriggerGroupByEntry, type TriggerGroupByOptions, type TriggerHandler, type TriggerInsertEvent, type TriggerOp, type TriggerQueryArgs, type TriggerQueryPage, type TriggerRankOptions, type TriggerRankPageOptions, type TriggerRankResult, type TriggerRow, type TriggerTiming, type TriggerUpdateEvent, type VectorMatch, type VectorMatches, type VectorQueryInput, type VectorRecord, type VectorSearch, type VectorSearchReader, type VectorUpsertInput, type WorkflowCreateOptions, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, anyApi } from "./types.mjs";
|
|
4
|
+
export { type AnyApi, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type FunctionVisibility, type IndexDefinition, type IndexRangeBuilder, type LifecycleEventKind, type LunoraLogger, type PaginationOptions, type PaginationResult, type RankSortKey, type ReadOnlyStorage, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type SearchFilterBuilder, type SearchIndexDefinition, type ShardMode, type Storage, type StorageMetadata, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemTableName, type TableReader, type TableVectorIndex, type TriggerAggregateOptions, type TriggerCtx, type TriggerDatabase, type TriggerDeleteEvent, type TriggerEvent, type TriggerGroupByEntry, type TriggerGroupByOptions, type TriggerHandler, type TriggerInsertEvent, type TriggerOp, type TriggerQueryArgs, type TriggerQueryPage, type TriggerRankOptions, type TriggerRankPageOptions, type TriggerRankResult, type TriggerRow, type TriggerTiming, type TriggerUpdateEvent, type VectorMatch, type VectorMatches, type VectorQueryInput, type VectorRecord, type VectorSearch, type VectorSearchReader, type VectorUpsertInput, type WorkflowCreateOptions, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, anyApi } from "./types.mjs";
|
|
5
5
|
import { LunoraError as LunoraError$1, LunoraErrorCode } from '@lunora/errors';
|
|
6
6
|
export type { LunoraErrorCode } from '@lunora/errors';
|
|
7
7
|
import { Context, Hono } from 'hono';
|
|
@@ -435,7 +435,7 @@ type HttpMethod = "DELETE" | "GET" | "HEAD" | "OPTIONS" | "PATCH" | "POST" | "PU
|
|
|
435
435
|
* `storage` surface — reach the data layer through `runQuery` / `runMutation` /
|
|
436
436
|
* `runAction`, which forward to the owning shard.
|
|
437
437
|
*/
|
|
438
|
-
type HttpActionCtx = Pick<ActionCtx, "auth" | "fetch" | "runAction" | "runMutation" | "runQuery">;
|
|
438
|
+
type HttpActionCtx = Pick<ActionCtx, "auth" | "cache" | "fetch" | "runAction" | "runMutation" | "runQuery">;
|
|
439
439
|
/** A raw handler wrapped by {@link httpAction}. Receives the raw request, returns the raw response. */
|
|
440
440
|
type HttpActionHandler = (context: HttpActionCtx, request: Request) => Promise<Response> | Response;
|
|
441
441
|
/**
|
|
@@ -519,6 +519,16 @@ interface HttpStreamHandlerOptions<SearchParams extends ArgsValidator, Params ex
|
|
|
519
519
|
*/
|
|
520
520
|
interface HttpRouteBuilder<SearchParams extends ArgsValidator, Body extends ArgsValidator, Params extends ArgsValidator, Output = undefined> {
|
|
521
521
|
body: <B extends ArgsValidator>(validators: B) => HttpRouteBuilder<SearchParams, B & Body, Params, Output>;
|
|
522
|
+
/**
|
|
523
|
+
* Attach a `Cache-Control` header to the response. Only meaningful when
|
|
524
|
+
* Workers Cache is enabled in `wrangler.jsonc` (`"cache": { "enabled": true }`).
|
|
525
|
+
*/
|
|
526
|
+
cacheControl: (value: string) => HttpRouteBuilder<SearchParams, Body, Params, Output>;
|
|
527
|
+
/**
|
|
528
|
+
* Attach a `Cache-Tag` header to the response for tag-based purging via
|
|
529
|
+
* `ctx.cache.purge({ tags: [...] })`.
|
|
530
|
+
*/
|
|
531
|
+
cacheTag: (value: string) => HttpRouteBuilder<SearchParams, Body, Params, Output>;
|
|
522
532
|
handler: [Output] extends [undefined] ? <R>(handler: (options: HttpRouteHandlerOptions<SearchParams, Body, Params>) => Promise<R> | R) => LunoraRouteHandler : (handler: (options: HttpRouteHandlerOptions<SearchParams, Body, Params>) => Output | Promise<Output>) => LunoraRouteHandler;
|
|
523
533
|
output: <V extends Validator>(validator: V) => HttpRouteBuilder<SearchParams, Body, Params, Infer<V>>;
|
|
524
534
|
params: <P extends ArgsValidator>(validators: P) => HttpRouteBuilder<SearchParams, Body, P & Params, Output>;
|
|
@@ -533,6 +543,11 @@ interface HttpRouteBuilder<SearchParams extends ArgsValidator, Body extends Args
|
|
|
533
543
|
* handler's yielded type.
|
|
534
544
|
*/
|
|
535
545
|
stream: <R>(handler: (options: HttpStreamHandlerOptions<SearchParams, Params>) => AsyncGenerator<R, void, void> | AsyncIterable<R>) => LunoraRouteHandler;
|
|
546
|
+
/**
|
|
547
|
+
* Attach a `Vary` header to the response so Cloudflare stores separate
|
|
548
|
+
* cached variants per distinct value of the listed request headers.
|
|
549
|
+
*/
|
|
550
|
+
vary: (value: string) => HttpRouteBuilder<SearchParams, Body, Params, Output>;
|
|
536
551
|
}
|
|
537
552
|
/** Opens a fresh {@link HttpRouteBuilder}. The `path` documents intent; hono owns the actual routing at mount. */
|
|
538
553
|
type HttpRouteFactory = (path: string) => HttpRouteBuilder<EmptyArgs, EmptyArgs, EmptyArgs>;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Validator, Infer, ValidatorMap, InferValidatorMap, v } from '@lunora/values';
|
|
2
2
|
export { type ColumnValidator, type Id, type Infer, ValidationError, type Validator, type ValidatorKind, v } from '@lunora/values';
|
|
3
3
|
import { ArgsValidator, InferArgs, RegisteredAction, ActionCtx, MutationCtx, RegisteredMutation, QueryCtx, RegisteredQuery, RegisteredStream, FunctionKind, Secrets, LifecycleEvent, RegisteredLifecycleHook, TableDefinition, RegisteredFunction, VectorIndexDefinition, Schema, AggregateOp, DurableObjectJurisdiction, RelationDefinition, GlobalBackend, OnDeleteAction, ExternalSourceDefinition, TriggerBuilder, TriggerDefinition, VectorEmbedder, VectorMetric, AggregateIndexDefinition, RankIndexDefinition } from "./types.js";
|
|
4
|
-
export { type AnyApi, type AuthState, type DatabaseReader, type DatabaseWriter, type FunctionVisibility, type IndexDefinition, type IndexRangeBuilder, type LifecycleEventKind, type LunoraLogger, type PaginationOptions, type PaginationResult, type RankSortKey, type ReadOnlyStorage, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type SearchFilterBuilder, type SearchIndexDefinition, type ShardMode, type Storage, type StorageMetadata, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemTableName, type TableReader, type TableVectorIndex, type TriggerAggregateOptions, type TriggerCtx, type TriggerDatabase, type TriggerDeleteEvent, type TriggerEvent, type TriggerGroupByEntry, type TriggerGroupByOptions, type TriggerHandler, type TriggerInsertEvent, type TriggerOp, type TriggerQueryArgs, type TriggerQueryPage, type TriggerRankOptions, type TriggerRankPageOptions, type TriggerRankResult, type TriggerRow, type TriggerTiming, type TriggerUpdateEvent, type VectorMatch, type VectorMatches, type VectorQueryInput, type VectorRecord, type VectorSearch, type VectorSearchReader, type VectorUpsertInput, type WorkflowCreateOptions, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, anyApi } from "./types.js";
|
|
4
|
+
export { type AnyApi, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type FunctionVisibility, type IndexDefinition, type IndexRangeBuilder, type LifecycleEventKind, type LunoraLogger, type PaginationOptions, type PaginationResult, type RankSortKey, type ReadOnlyStorage, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type SearchFilterBuilder, type SearchIndexDefinition, type ShardMode, type Storage, type StorageMetadata, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemTableName, type TableReader, type TableVectorIndex, type TriggerAggregateOptions, type TriggerCtx, type TriggerDatabase, type TriggerDeleteEvent, type TriggerEvent, type TriggerGroupByEntry, type TriggerGroupByOptions, type TriggerHandler, type TriggerInsertEvent, type TriggerOp, type TriggerQueryArgs, type TriggerQueryPage, type TriggerRankOptions, type TriggerRankPageOptions, type TriggerRankResult, type TriggerRow, type TriggerTiming, type TriggerUpdateEvent, type VectorMatch, type VectorMatches, type VectorQueryInput, type VectorRecord, type VectorSearch, type VectorSearchReader, type VectorUpsertInput, type WorkflowCreateOptions, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, anyApi } from "./types.js";
|
|
5
5
|
import { LunoraError as LunoraError$1, LunoraErrorCode } from '@lunora/errors';
|
|
6
6
|
export type { LunoraErrorCode } from '@lunora/errors';
|
|
7
7
|
import { Context, Hono } from 'hono';
|
|
@@ -435,7 +435,7 @@ type HttpMethod = "DELETE" | "GET" | "HEAD" | "OPTIONS" | "PATCH" | "POST" | "PU
|
|
|
435
435
|
* `storage` surface — reach the data layer through `runQuery` / `runMutation` /
|
|
436
436
|
* `runAction`, which forward to the owning shard.
|
|
437
437
|
*/
|
|
438
|
-
type HttpActionCtx = Pick<ActionCtx, "auth" | "fetch" | "runAction" | "runMutation" | "runQuery">;
|
|
438
|
+
type HttpActionCtx = Pick<ActionCtx, "auth" | "cache" | "fetch" | "runAction" | "runMutation" | "runQuery">;
|
|
439
439
|
/** A raw handler wrapped by {@link httpAction}. Receives the raw request, returns the raw response. */
|
|
440
440
|
type HttpActionHandler = (context: HttpActionCtx, request: Request) => Promise<Response> | Response;
|
|
441
441
|
/**
|
|
@@ -519,6 +519,16 @@ interface HttpStreamHandlerOptions<SearchParams extends ArgsValidator, Params ex
|
|
|
519
519
|
*/
|
|
520
520
|
interface HttpRouteBuilder<SearchParams extends ArgsValidator, Body extends ArgsValidator, Params extends ArgsValidator, Output = undefined> {
|
|
521
521
|
body: <B extends ArgsValidator>(validators: B) => HttpRouteBuilder<SearchParams, B & Body, Params, Output>;
|
|
522
|
+
/**
|
|
523
|
+
* Attach a `Cache-Control` header to the response. Only meaningful when
|
|
524
|
+
* Workers Cache is enabled in `wrangler.jsonc` (`"cache": { "enabled": true }`).
|
|
525
|
+
*/
|
|
526
|
+
cacheControl: (value: string) => HttpRouteBuilder<SearchParams, Body, Params, Output>;
|
|
527
|
+
/**
|
|
528
|
+
* Attach a `Cache-Tag` header to the response for tag-based purging via
|
|
529
|
+
* `ctx.cache.purge({ tags: [...] })`.
|
|
530
|
+
*/
|
|
531
|
+
cacheTag: (value: string) => HttpRouteBuilder<SearchParams, Body, Params, Output>;
|
|
522
532
|
handler: [Output] extends [undefined] ? <R>(handler: (options: HttpRouteHandlerOptions<SearchParams, Body, Params>) => Promise<R> | R) => LunoraRouteHandler : (handler: (options: HttpRouteHandlerOptions<SearchParams, Body, Params>) => Output | Promise<Output>) => LunoraRouteHandler;
|
|
523
533
|
output: <V extends Validator>(validator: V) => HttpRouteBuilder<SearchParams, Body, Params, Infer<V>>;
|
|
524
534
|
params: <P extends ArgsValidator>(validators: P) => HttpRouteBuilder<SearchParams, Body, P & Params, Output>;
|
|
@@ -533,6 +543,11 @@ interface HttpRouteBuilder<SearchParams extends ArgsValidator, Body extends Args
|
|
|
533
543
|
* handler's yielded type.
|
|
534
544
|
*/
|
|
535
545
|
stream: <R>(handler: (options: HttpStreamHandlerOptions<SearchParams, Params>) => AsyncGenerator<R, void, void> | AsyncIterable<R>) => LunoraRouteHandler;
|
|
546
|
+
/**
|
|
547
|
+
* Attach a `Vary` header to the response so Cloudflare stores separate
|
|
548
|
+
* cached variants per distinct value of the listed request headers.
|
|
549
|
+
*/
|
|
550
|
+
vary: (value: string) => HttpRouteBuilder<SearchParams, Body, Params, Output>;
|
|
536
551
|
}
|
|
537
552
|
/** Opens a fresh {@link HttpRouteBuilder}. The `path` documents intent; hono owns the actual routing at mount. */
|
|
538
553
|
type HttpRouteFactory = (path: string) => HttpRouteBuilder<EmptyArgs, EmptyArgs, EmptyArgs>;
|
package/dist/index.mjs
CHANGED
|
@@ -4,7 +4,7 @@ export { createSecrets } from './packem_shared/createSecrets-DwaR2rNG.mjs';
|
|
|
4
4
|
export { LunoraEnvError, defineEnv, redactSecrets } from './packem_shared/LunoraEnvError-BGmd1Qs0.mjs';
|
|
5
5
|
export { LunoraError } from './packem_shared/LunoraError-WbxmrpxR.mjs';
|
|
6
6
|
export { bindOrm, bindTableFacade } from './packem_shared/bindOrm-CNXKgfUa.mjs';
|
|
7
|
-
export { httpAction, httpRoute, httpRouter, isSafeHeaderValue, serveStorageObject } from './packem_shared/httpAction-
|
|
7
|
+
export { httpAction, httpRoute, httpRouter, isSafeHeaderValue, serveStorageObject } from './packem_shared/httpAction-DCXoYPIk.mjs';
|
|
8
8
|
export { defineIdentity } from './packem_shared/defineIdentity-DiX4zM9x.mjs';
|
|
9
9
|
export { onConnect, onDisconnect } from './packem_shared/onConnect-CIPXKPyw.mjs';
|
|
10
10
|
export { defineMigration } from './packem_shared/defineMigration-Hx01yIht.mjs';
|
|
@@ -110,7 +110,11 @@ const errorResponse = (error) => {
|
|
|
110
110
|
return Response.json({ code: "BAD_REQUEST", error: error.message }, { status: 400 });
|
|
111
111
|
}
|
|
112
112
|
if (error instanceof LunoraError) {
|
|
113
|
-
|
|
113
|
+
const { body, redacted, status } = toErrorBody(error, { fallbackCode: "INTERNAL_SERVER_ERROR", redactedMessage: "Internal error" });
|
|
114
|
+
if (redacted) {
|
|
115
|
+
console.error("[lunora] http action error (redacted on the wire):", error);
|
|
116
|
+
}
|
|
117
|
+
return Response.json({ code: body.code, error: body.message }, { status });
|
|
114
118
|
}
|
|
115
119
|
throw error;
|
|
116
120
|
};
|
|
@@ -122,7 +126,21 @@ const buildRouteHandler = (state, userHandler) => async (c) => {
|
|
|
122
126
|
const body = Object.keys(state.body).length > 0 ? await parseBody(state.body, c) : {};
|
|
123
127
|
const result = await userHandler({ body, ctx: context, params, searchParams });
|
|
124
128
|
const payload = state.output ? applyOutput(state.output, result) : result;
|
|
125
|
-
|
|
129
|
+
const headers = {};
|
|
130
|
+
if (state.cacheControl) {
|
|
131
|
+
headers["cache-control"] = state.cacheControl;
|
|
132
|
+
}
|
|
133
|
+
if (state.cacheTag) {
|
|
134
|
+
headers["cache-tag"] = state.cacheTag;
|
|
135
|
+
}
|
|
136
|
+
if (state.vary) {
|
|
137
|
+
headers.vary = state.vary;
|
|
138
|
+
}
|
|
139
|
+
const hasCacheHeaders = Object.keys(headers).length > 0;
|
|
140
|
+
if (payload === void 0) {
|
|
141
|
+
return new Response(null, { headers: hasCacheHeaders ? headers : void 0, status: 204 });
|
|
142
|
+
}
|
|
143
|
+
return Response.json(payload, { headers: hasCacheHeaders ? headers : void 0 });
|
|
126
144
|
} catch (error) {
|
|
127
145
|
return errorResponse(error);
|
|
128
146
|
}
|
|
@@ -198,25 +216,31 @@ const buildStreamHandler = (state, userHandler) => (
|
|
|
198
216
|
}
|
|
199
217
|
}
|
|
200
218
|
});
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
219
|
+
const headers = {
|
|
220
|
+
// SSE responses must stay uncacheable so proxies don't buffer or
|
|
221
|
+
// coalesce live frames. `cacheControl()` is intentionally ignored
|
|
222
|
+
// for stream() routes; `cacheTag`/`vary` are also omitted because
|
|
223
|
+
// they only make sense alongside a cacheable response.
|
|
224
|
+
"cache-control": "no-cache, no-transform",
|
|
225
|
+
"content-type": "text/event-stream; charset=utf-8",
|
|
226
|
+
// Hint to proxies (including Cloudflare's own buffering layer)
|
|
227
|
+
// that this response must not be coalesced.
|
|
228
|
+
"x-accel-buffering": "no"
|
|
229
|
+
};
|
|
230
|
+
return new Response(stream, { headers });
|
|
210
231
|
}
|
|
211
232
|
);
|
|
212
233
|
const makeRouteBuilder = (state) => {
|
|
213
234
|
return {
|
|
214
235
|
body: (validators) => makeRouteBuilder({ ...state, body: { ...state.body, ...validators } }),
|
|
236
|
+
cacheControl: (value) => makeRouteBuilder({ ...state, cacheControl: value }),
|
|
237
|
+
cacheTag: (value) => makeRouteBuilder({ ...state, cacheTag: value }),
|
|
215
238
|
handler: (userHandler) => buildRouteHandler(state, userHandler),
|
|
216
239
|
output: (validator) => makeRouteBuilder({ ...state, output: validator }),
|
|
217
240
|
params: (validators) => makeRouteBuilder({ ...state, params: { ...state.params, ...validators } }),
|
|
218
241
|
searchParams: (validators) => makeRouteBuilder({ ...state, searchParams: { ...state.searchParams, ...validators } }),
|
|
219
|
-
stream: (userHandler) => buildStreamHandler(state, userHandler)
|
|
242
|
+
stream: (userHandler) => buildStreamHandler(state, userHandler),
|
|
243
|
+
vary: (value) => makeRouteBuilder({ ...state, vary: value })
|
|
220
244
|
};
|
|
221
245
|
};
|
|
222
246
|
const makeRouteFactory = (method) => (path) => makeRouteBuilder({ body: {}, method, params: {}, path, searchParams: {} });
|
package/dist/types.d.mts
CHANGED
|
@@ -690,6 +690,21 @@ interface Workflows {
|
|
|
690
690
|
get: <Params = Record<string, unknown>>(name: string) => WorkflowHandle<Params>;
|
|
691
691
|
}
|
|
692
692
|
/**
|
|
693
|
+
* Programmatic cache purge surface exposed on {@link ActionCtx}. Actions run
|
|
694
|
+
* in the Worker (not the DO), so they can reach the Worker's `ctx.cache.purge`.
|
|
695
|
+
* Queries and mutations do not expose this — they run inside the Durable Object.
|
|
696
|
+
*/
|
|
697
|
+
interface CachePurge {
|
|
698
|
+
/**
|
|
699
|
+
* Purge cached responses matching the given tags, or everything when
|
|
700
|
+
* `purgeEverything` is true. Only available in action handlers.
|
|
701
|
+
*/
|
|
702
|
+
purge: (options: {
|
|
703
|
+
purgeEverything?: boolean;
|
|
704
|
+
tags?: string[];
|
|
705
|
+
}) => Promise<unknown>;
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
693
708
|
* Structural projection of workers-types' `SecretsStoreSecret` binding — the
|
|
694
709
|
* per-secret `secrets_store_secrets[]` binding whose `.get()` resolves the
|
|
695
710
|
* secret value (or throws if it does not exist). Mirrored structurally so the
|
|
@@ -1136,6 +1151,13 @@ interface MutationCtx {
|
|
|
1136
1151
|
}
|
|
1137
1152
|
interface ActionCtx {
|
|
1138
1153
|
readonly auth: AuthState;
|
|
1154
|
+
/**
|
|
1155
|
+
* Programmatic Workers Cache purge; see {@link CachePurge}.
|
|
1156
|
+
* **Action-only** — actions run in the Worker, which has a `cache` binding.
|
|
1157
|
+
* Queries and mutations run inside the Durable Object and do not expose this.
|
|
1158
|
+
* Optional at runtime because Workers Cache is only present when enabled.
|
|
1159
|
+
*/
|
|
1160
|
+
readonly cache?: CachePurge;
|
|
1139
1161
|
readonly db: DatabaseWriter;
|
|
1140
1162
|
/**
|
|
1141
1163
|
* The validated, typed environment. Populated only when the project declares
|
|
@@ -1178,4 +1200,4 @@ interface ActionCtx {
|
|
|
1178
1200
|
*/
|
|
1179
1201
|
type AnyApi = Record<string, Record<string, RegisteredFunction<ArgsValidator, unknown, FunctionKind>>>;
|
|
1180
1202
|
declare const anyApi: AnyApi;
|
|
1181
|
-
export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type DatabaseReader, type DatabaseWriter, type DurableObjectJurisdiction, type ExternalSourceDefinition, type ExternalSourceMode, type ExternalSourceRefresh, type FunctionKind, type FunctionVisibility, type GlobalBackend, type IndexDefinition, type IndexRangeBuilder, type InferArgs, type LifecycleEvent, type LifecycleEventKind, type LunoraLogger, type MutationCtx, type OnDeleteAction, type PaginationOptions, type PaginationResult, type QueryCtx, type RankIndexDefinition, type RankSortKey, type ReadOnlyStorage, type RegisteredAction, type RegisteredFunction, type RegisteredLifecycleHook, type RegisteredMutation, type RegisteredQuery, type RegisteredStream, type RelationDefinition, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type Schema, type SearchFilterBuilder, type SearchIndexDefinition, type Secrets, type SecretsStoreSecretLike, type ShardMode, type Storage, type StorageMetadata, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemTableName, type TableDefinition, type TableReader, type TableVectorIndex, type TriggerAggregateOptions, type TriggerBuilder, type TriggerCtx, type TriggerDatabase, type TriggerDefinition, type TriggerDeleteEvent, type TriggerEvent, type TriggerGroupByEntry, type TriggerGroupByOptions, type TriggerHandler, type TriggerInsertEvent, type TriggerOp, type TriggerQueryArgs, type TriggerQueryPage, type TriggerRankOptions, type TriggerRankPageOptions, type TriggerRankResult, type TriggerRow, type TriggerTiming, type TriggerUpdateEvent, type VectorEmbedder, type VectorIndexDefinition, type VectorMatch, type VectorMatches, type VectorMetric, type VectorQueryInput, type VectorRecord, type VectorSearch, type VectorSearchReader, type VectorUpsertInput, type WorkflowCreateOptions, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, anyApi };
|
|
1203
|
+
export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type DurableObjectJurisdiction, type ExternalSourceDefinition, type ExternalSourceMode, type ExternalSourceRefresh, type FunctionKind, type FunctionVisibility, type GlobalBackend, type IndexDefinition, type IndexRangeBuilder, type InferArgs, type LifecycleEvent, type LifecycleEventKind, type LunoraLogger, type MutationCtx, type OnDeleteAction, type PaginationOptions, type PaginationResult, type QueryCtx, type RankIndexDefinition, type RankSortKey, type ReadOnlyStorage, type RegisteredAction, type RegisteredFunction, type RegisteredLifecycleHook, type RegisteredMutation, type RegisteredQuery, type RegisteredStream, type RelationDefinition, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type Schema, type SearchFilterBuilder, type SearchIndexDefinition, type Secrets, type SecretsStoreSecretLike, type ShardMode, type Storage, type StorageMetadata, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemTableName, type TableDefinition, type TableReader, type TableVectorIndex, type TriggerAggregateOptions, type TriggerBuilder, type TriggerCtx, type TriggerDatabase, type TriggerDefinition, type TriggerDeleteEvent, type TriggerEvent, type TriggerGroupByEntry, type TriggerGroupByOptions, type TriggerHandler, type TriggerInsertEvent, type TriggerOp, type TriggerQueryArgs, type TriggerQueryPage, type TriggerRankOptions, type TriggerRankPageOptions, type TriggerRankResult, type TriggerRow, type TriggerTiming, type TriggerUpdateEvent, type VectorEmbedder, type VectorIndexDefinition, type VectorMatch, type VectorMatches, type VectorMetric, type VectorQueryInput, type VectorRecord, type VectorSearch, type VectorSearchReader, type VectorUpsertInput, type WorkflowCreateOptions, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, anyApi };
|
package/dist/types.d.ts
CHANGED
|
@@ -690,6 +690,21 @@ interface Workflows {
|
|
|
690
690
|
get: <Params = Record<string, unknown>>(name: string) => WorkflowHandle<Params>;
|
|
691
691
|
}
|
|
692
692
|
/**
|
|
693
|
+
* Programmatic cache purge surface exposed on {@link ActionCtx}. Actions run
|
|
694
|
+
* in the Worker (not the DO), so they can reach the Worker's `ctx.cache.purge`.
|
|
695
|
+
* Queries and mutations do not expose this — they run inside the Durable Object.
|
|
696
|
+
*/
|
|
697
|
+
interface CachePurge {
|
|
698
|
+
/**
|
|
699
|
+
* Purge cached responses matching the given tags, or everything when
|
|
700
|
+
* `purgeEverything` is true. Only available in action handlers.
|
|
701
|
+
*/
|
|
702
|
+
purge: (options: {
|
|
703
|
+
purgeEverything?: boolean;
|
|
704
|
+
tags?: string[];
|
|
705
|
+
}) => Promise<unknown>;
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
693
708
|
* Structural projection of workers-types' `SecretsStoreSecret` binding — the
|
|
694
709
|
* per-secret `secrets_store_secrets[]` binding whose `.get()` resolves the
|
|
695
710
|
* secret value (or throws if it does not exist). Mirrored structurally so the
|
|
@@ -1136,6 +1151,13 @@ interface MutationCtx {
|
|
|
1136
1151
|
}
|
|
1137
1152
|
interface ActionCtx {
|
|
1138
1153
|
readonly auth: AuthState;
|
|
1154
|
+
/**
|
|
1155
|
+
* Programmatic Workers Cache purge; see {@link CachePurge}.
|
|
1156
|
+
* **Action-only** — actions run in the Worker, which has a `cache` binding.
|
|
1157
|
+
* Queries and mutations run inside the Durable Object and do not expose this.
|
|
1158
|
+
* Optional at runtime because Workers Cache is only present when enabled.
|
|
1159
|
+
*/
|
|
1160
|
+
readonly cache?: CachePurge;
|
|
1139
1161
|
readonly db: DatabaseWriter;
|
|
1140
1162
|
/**
|
|
1141
1163
|
* The validated, typed environment. Populated only when the project declares
|
|
@@ -1178,4 +1200,4 @@ interface ActionCtx {
|
|
|
1178
1200
|
*/
|
|
1179
1201
|
type AnyApi = Record<string, Record<string, RegisteredFunction<ArgsValidator, unknown, FunctionKind>>>;
|
|
1180
1202
|
declare const anyApi: AnyApi;
|
|
1181
|
-
export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type DatabaseReader, type DatabaseWriter, type DurableObjectJurisdiction, type ExternalSourceDefinition, type ExternalSourceMode, type ExternalSourceRefresh, type FunctionKind, type FunctionVisibility, type GlobalBackend, type IndexDefinition, type IndexRangeBuilder, type InferArgs, type LifecycleEvent, type LifecycleEventKind, type LunoraLogger, type MutationCtx, type OnDeleteAction, type PaginationOptions, type PaginationResult, type QueryCtx, type RankIndexDefinition, type RankSortKey, type ReadOnlyStorage, type RegisteredAction, type RegisteredFunction, type RegisteredLifecycleHook, type RegisteredMutation, type RegisteredQuery, type RegisteredStream, type RelationDefinition, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type Schema, type SearchFilterBuilder, type SearchIndexDefinition, type Secrets, type SecretsStoreSecretLike, type ShardMode, type Storage, type StorageMetadata, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemTableName, type TableDefinition, type TableReader, type TableVectorIndex, type TriggerAggregateOptions, type TriggerBuilder, type TriggerCtx, type TriggerDatabase, type TriggerDefinition, type TriggerDeleteEvent, type TriggerEvent, type TriggerGroupByEntry, type TriggerGroupByOptions, type TriggerHandler, type TriggerInsertEvent, type TriggerOp, type TriggerQueryArgs, type TriggerQueryPage, type TriggerRankOptions, type TriggerRankPageOptions, type TriggerRankResult, type TriggerRow, type TriggerTiming, type TriggerUpdateEvent, type VectorEmbedder, type VectorIndexDefinition, type VectorMatch, type VectorMatches, type VectorMetric, type VectorQueryInput, type VectorRecord, type VectorSearch, type VectorSearchReader, type VectorUpsertInput, type WorkflowCreateOptions, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, anyApi };
|
|
1203
|
+
export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type DurableObjectJurisdiction, type ExternalSourceDefinition, type ExternalSourceMode, type ExternalSourceRefresh, type FunctionKind, type FunctionVisibility, type GlobalBackend, type IndexDefinition, type IndexRangeBuilder, type InferArgs, type LifecycleEvent, type LifecycleEventKind, type LunoraLogger, type MutationCtx, type OnDeleteAction, type PaginationOptions, type PaginationResult, type QueryCtx, type RankIndexDefinition, type RankSortKey, type ReadOnlyStorage, type RegisteredAction, type RegisteredFunction, type RegisteredLifecycleHook, type RegisteredMutation, type RegisteredQuery, type RegisteredStream, type RelationDefinition, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type Schema, type SearchFilterBuilder, type SearchIndexDefinition, type Secrets, type SecretsStoreSecretLike, type ShardMode, type Storage, type StorageMetadata, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemTableName, type TableDefinition, type TableReader, type TableVectorIndex, type TriggerAggregateOptions, type TriggerBuilder, type TriggerCtx, type TriggerDatabase, type TriggerDefinition, type TriggerDeleteEvent, type TriggerEvent, type TriggerGroupByEntry, type TriggerGroupByOptions, type TriggerHandler, type TriggerInsertEvent, type TriggerOp, type TriggerQueryArgs, type TriggerQueryPage, type TriggerRankOptions, type TriggerRankPageOptions, type TriggerRankResult, type TriggerRow, type TriggerTiming, type TriggerUpdateEvent, type VectorEmbedder, type VectorIndexDefinition, type VectorMatch, type VectorMatches, type VectorMetric, type VectorQueryInput, type VectorRecord, type VectorSearch, type VectorSearchReader, type VectorUpsertInput, type WorkflowCreateOptions, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, anyApi };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/server",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.18",
|
|
4
4
|
"description": "Server primitives for Lunora: defineSchema, defineTable, query, mutation, and action",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"backend",
|
|
@@ -62,9 +62,9 @@
|
|
|
62
62
|
"access": "public"
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
|
-
"@lunora/errors": "1.0.0-alpha.
|
|
66
|
-
"@lunora/scheduler": "1.0.0-alpha.
|
|
67
|
-
"@lunora/values": "1.0.0-alpha.
|
|
65
|
+
"@lunora/errors": "1.0.0-alpha.2",
|
|
66
|
+
"@lunora/scheduler": "1.0.0-alpha.6",
|
|
67
|
+
"@lunora/values": "1.0.0-alpha.5",
|
|
68
68
|
"drizzle-orm": "^0.45.2",
|
|
69
69
|
"hono": "^4.12.27"
|
|
70
70
|
},
|