@lunora/server 1.0.0-alpha.29 → 1.0.0-alpha.30

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.
@@ -279,8 +279,38 @@ interface SearchReader<TDocument> {
279
279
  take: (limit: number) => Promise<TDocument[]>;
280
280
  unique: () => Promise<TDocument | null>;
281
281
  }
282
+ /** A latitude/longitude point (WGS84 decimal degrees) accepted by geo queries. */
283
+ interface GeoPointInput {
284
+ lat: number;
285
+ lng: number;
286
+ }
287
+ /** An axis-aligned latitude/longitude bounding box (`sw`/`ne` corners). */
288
+ interface GeoBoundingBox {
289
+ ne: GeoPointInput;
290
+ sw: GeoPointInput;
291
+ }
292
+ /**
293
+ * Builder passed to `.withGeoIndex(name, q => …)`. Call exactly one of
294
+ * `.near(point, radiusMeters)` (proximity, nearest-first) or `.within(box)`
295
+ * (bounding-box).
296
+ */
297
+ interface GeoFilterBuilder {
298
+ near: (point: GeoPointInput, radiusMeters: number) => GeoFilterBuilder;
299
+ within: (box: GeoBoundingBox) => GeoFilterBuilder;
300
+ }
301
+ /**
302
+ * Chainable reader returned by `.withGeoIndex()`. `.near()` results come back
303
+ * ordered nearest-first; `.within()` results by row creation time. `.paginate()`
304
+ * is intentionally absent — cap the result set with `.take(n)`.
305
+ */
306
+ interface GeoReader<TDocument> {
307
+ collect: () => Promise<TDocument[]>;
308
+ first: () => Promise<TDocument | null>;
309
+ take: (limit: number) => Promise<TDocument[]>;
310
+ unique: () => Promise<TDocument | null>;
311
+ }
282
312
  /** Read-only typed table accessor exposed on `QueryCtx.db.&lt;table>`. */
283
- interface TableReaderFacade<DM, REL extends Record<keyof DM, object>, RANK extends Record<keyof DM, string>, SEARCH extends Record<keyof DM, string>, T extends keyof DM> {
313
+ interface TableReaderFacade<DM, REL extends Record<keyof DM, object>, RANK extends Record<keyof DM, string>, SEARCH extends Record<keyof DM, string>, T extends keyof DM, GEO extends Record<keyof DM, string> = Record<keyof DM, never>> {
284
314
  /**
285
315
  * Reduce rows in this table to a scalar (`avg`/`max`/`min`/`sum` — `count`
286
316
  * lives on its own method). Routes through a declared `aggregateIndex` when
@@ -329,6 +359,13 @@ interface TableReaderFacade<DM, REL extends Record<keyof DM, object>, RANK exten
329
359
  * follow the Convex-style keyset shape.
330
360
  */
331
361
  rankPage: (indexName: RANK[T], options?: TableRankPageOptions<DM[T]>) => Promise<RankPage<DM[T]>>;
362
+ /**
363
+ * Restrict the query to a declared `.geoIndex()` and run a proximity /
364
+ * bounding-box match. `indexName` is constrained to this table's geo indexes
365
+ * (`never` when it declares none). Returns a distance-ordered reader —
366
+ * finish with `.take(n)` / `.collect()`.
367
+ */
368
+ withGeoIndex: (indexName: GEO[T], build: (q: GeoFilterBuilder) => GeoFilterBuilder) => GeoReader<DM[T]>;
332
369
  /**
333
370
  * Restrict the query to a declared `.searchIndex()` and run a full-text
334
371
  * match. `indexName` is constrained to this table's search indexes
@@ -338,7 +375,7 @@ interface TableReaderFacade<DM, REL extends Record<keyof DM, object>, RANK exten
338
375
  withSearchIndex: (indexName: SEARCH[T], search: (q: SearchFilterBuilder<DM[T]>) => SearchFilterBuilder<DM[T]>) => SearchReader<DM[T]>;
339
376
  }
340
377
  /** Read-write typed table accessor exposed on `MutationCtx.db.&lt;table>` / `ActionCtx.db.&lt;table>`. */
341
- interface TableWriterFacade<DM, IM extends Record<keyof DM, object>, REL extends Record<keyof DM, object>, RANK extends Record<keyof DM, string>, SEARCH extends Record<keyof DM, string>, T extends keyof DM> extends TableReaderFacade<DM, REL, RANK, SEARCH, T> {
378
+ interface TableWriterFacade<DM, IM extends Record<keyof DM, object>, REL extends Record<keyof DM, object>, RANK extends Record<keyof DM, string>, SEARCH extends Record<keyof DM, string>, T extends keyof DM, GEO extends Record<keyof DM, string> = Record<keyof DM, never>> extends TableReaderFacade<DM, REL, RANK, SEARCH, T, GEO> {
342
379
  /**
343
380
  * Delete a row by id. On a `.softDelete()` table this flips the marker column
344
381
  * (and cascades as a soft delete) instead of removing the row; use
@@ -448,7 +485,7 @@ interface TableWriterFacade<DM, IM extends Record<keyof DM, object>, REL extends
448
485
  /** Conflict target for `upsert`/`upsertMany`: one column of table `T`, or a tuple of them. */
449
486
  type UpsertTargetOf<DM, T extends keyof DM> = ReadonlyArray<keyof DM[T] & string> | (keyof DM[T] & string);
450
487
  /** Per-table read facade — `ctx.db.&lt;table>` on a `QueryCtx`. */
451
- type DatabaseReaderFacade<DM, REL extends Record<keyof DM, object>, RANK extends Record<keyof DM, string>, SEARCH extends Record<keyof DM, string>> = { readonly [T in keyof DM]: TableReaderFacade<DM, REL, RANK, SEARCH, T>; };
488
+ type DatabaseReaderFacade<DM, REL extends Record<keyof DM, object>, RANK extends Record<keyof DM, string>, SEARCH extends Record<keyof DM, string>, GEO extends Record<keyof DM, string> = Record<keyof DM, never>> = { readonly [T in keyof DM]: TableReaderFacade<DM, REL, RANK, SEARCH, T, GEO>; };
452
489
  /** Per-table read-write facade — `ctx.db.&lt;table>` on a `MutationCtx` / `ActionCtx`. */
453
- type DatabaseWriterFacade<DM, IM extends Record<keyof DM, object>, REL extends Record<keyof DM, object>, RANK extends Record<keyof DM, string>, SEARCH extends Record<keyof DM, string>> = { readonly [T in keyof DM]: TableWriterFacade<DM, IM, REL, RANK, SEARCH, T>; };
454
- export { AggregateOp, DatabaseReaderFacade, DatabaseWriterFacade, GroupByEntry, Id, LoadWith, ManyRelationWhere, OneRelationWhere, OrderBy, QueryArgs, QueryArgsOf, QueryPage, RankPage, RankResult, RestrictableQueryOptions, RestrictableQueryOptionsOf, SearchFilterBuilder, SearchReader, TableAggregateOptions, TableAggregateOptionsOf, TableGroupByOptions, TableGroupByOptionsOf, TableRankOptions, TableRankPageOptions, TableReaderFacade, TableWriterFacade, UpsertTargetOf, Where, WhereOf, WhereOperators, WithArg };
490
+ type DatabaseWriterFacade<DM, IM extends Record<keyof DM, object>, REL extends Record<keyof DM, object>, RANK extends Record<keyof DM, string>, SEARCH extends Record<keyof DM, string>, GEO extends Record<keyof DM, string> = Record<keyof DM, never>> = { readonly [T in keyof DM]: TableWriterFacade<DM, IM, REL, RANK, SEARCH, T, GEO>; };
491
+ export { AggregateOp, DatabaseReaderFacade, DatabaseWriterFacade, GeoBoundingBox, GeoFilterBuilder, GeoPointInput, GeoReader, GroupByEntry, Id, LoadWith, ManyRelationWhere, OneRelationWhere, OrderBy, QueryArgs, QueryArgsOf, QueryPage, RankPage, RankResult, RestrictableQueryOptions, RestrictableQueryOptionsOf, SearchFilterBuilder, SearchReader, TableAggregateOptions, TableAggregateOptionsOf, TableGroupByOptions, TableGroupByOptionsOf, TableRankOptions, TableRankPageOptions, TableReaderFacade, TableWriterFacade, UpsertTargetOf, Where, WhereOf, WhereOperators, WithArg };
@@ -279,8 +279,38 @@ interface SearchReader<TDocument> {
279
279
  take: (limit: number) => Promise<TDocument[]>;
280
280
  unique: () => Promise<TDocument | null>;
281
281
  }
282
+ /** A latitude/longitude point (WGS84 decimal degrees) accepted by geo queries. */
283
+ interface GeoPointInput {
284
+ lat: number;
285
+ lng: number;
286
+ }
287
+ /** An axis-aligned latitude/longitude bounding box (`sw`/`ne` corners). */
288
+ interface GeoBoundingBox {
289
+ ne: GeoPointInput;
290
+ sw: GeoPointInput;
291
+ }
292
+ /**
293
+ * Builder passed to `.withGeoIndex(name, q => …)`. Call exactly one of
294
+ * `.near(point, radiusMeters)` (proximity, nearest-first) or `.within(box)`
295
+ * (bounding-box).
296
+ */
297
+ interface GeoFilterBuilder {
298
+ near: (point: GeoPointInput, radiusMeters: number) => GeoFilterBuilder;
299
+ within: (box: GeoBoundingBox) => GeoFilterBuilder;
300
+ }
301
+ /**
302
+ * Chainable reader returned by `.withGeoIndex()`. `.near()` results come back
303
+ * ordered nearest-first; `.within()` results by row creation time. `.paginate()`
304
+ * is intentionally absent — cap the result set with `.take(n)`.
305
+ */
306
+ interface GeoReader<TDocument> {
307
+ collect: () => Promise<TDocument[]>;
308
+ first: () => Promise<TDocument | null>;
309
+ take: (limit: number) => Promise<TDocument[]>;
310
+ unique: () => Promise<TDocument | null>;
311
+ }
282
312
  /** Read-only typed table accessor exposed on `QueryCtx.db.&lt;table>`. */
283
- interface TableReaderFacade<DM, REL extends Record<keyof DM, object>, RANK extends Record<keyof DM, string>, SEARCH extends Record<keyof DM, string>, T extends keyof DM> {
313
+ interface TableReaderFacade<DM, REL extends Record<keyof DM, object>, RANK extends Record<keyof DM, string>, SEARCH extends Record<keyof DM, string>, T extends keyof DM, GEO extends Record<keyof DM, string> = Record<keyof DM, never>> {
284
314
  /**
285
315
  * Reduce rows in this table to a scalar (`avg`/`max`/`min`/`sum` — `count`
286
316
  * lives on its own method). Routes through a declared `aggregateIndex` when
@@ -329,6 +359,13 @@ interface TableReaderFacade<DM, REL extends Record<keyof DM, object>, RANK exten
329
359
  * follow the Convex-style keyset shape.
330
360
  */
331
361
  rankPage: (indexName: RANK[T], options?: TableRankPageOptions<DM[T]>) => Promise<RankPage<DM[T]>>;
362
+ /**
363
+ * Restrict the query to a declared `.geoIndex()` and run a proximity /
364
+ * bounding-box match. `indexName` is constrained to this table's geo indexes
365
+ * (`never` when it declares none). Returns a distance-ordered reader —
366
+ * finish with `.take(n)` / `.collect()`.
367
+ */
368
+ withGeoIndex: (indexName: GEO[T], build: (q: GeoFilterBuilder) => GeoFilterBuilder) => GeoReader<DM[T]>;
332
369
  /**
333
370
  * Restrict the query to a declared `.searchIndex()` and run a full-text
334
371
  * match. `indexName` is constrained to this table's search indexes
@@ -338,7 +375,7 @@ interface TableReaderFacade<DM, REL extends Record<keyof DM, object>, RANK exten
338
375
  withSearchIndex: (indexName: SEARCH[T], search: (q: SearchFilterBuilder<DM[T]>) => SearchFilterBuilder<DM[T]>) => SearchReader<DM[T]>;
339
376
  }
340
377
  /** Read-write typed table accessor exposed on `MutationCtx.db.&lt;table>` / `ActionCtx.db.&lt;table>`. */
341
- interface TableWriterFacade<DM, IM extends Record<keyof DM, object>, REL extends Record<keyof DM, object>, RANK extends Record<keyof DM, string>, SEARCH extends Record<keyof DM, string>, T extends keyof DM> extends TableReaderFacade<DM, REL, RANK, SEARCH, T> {
378
+ interface TableWriterFacade<DM, IM extends Record<keyof DM, object>, REL extends Record<keyof DM, object>, RANK extends Record<keyof DM, string>, SEARCH extends Record<keyof DM, string>, T extends keyof DM, GEO extends Record<keyof DM, string> = Record<keyof DM, never>> extends TableReaderFacade<DM, REL, RANK, SEARCH, T, GEO> {
342
379
  /**
343
380
  * Delete a row by id. On a `.softDelete()` table this flips the marker column
344
381
  * (and cascades as a soft delete) instead of removing the row; use
@@ -448,7 +485,7 @@ interface TableWriterFacade<DM, IM extends Record<keyof DM, object>, REL extends
448
485
  /** Conflict target for `upsert`/`upsertMany`: one column of table `T`, or a tuple of them. */
449
486
  type UpsertTargetOf<DM, T extends keyof DM> = ReadonlyArray<keyof DM[T] & string> | (keyof DM[T] & string);
450
487
  /** Per-table read facade — `ctx.db.&lt;table>` on a `QueryCtx`. */
451
- type DatabaseReaderFacade<DM, REL extends Record<keyof DM, object>, RANK extends Record<keyof DM, string>, SEARCH extends Record<keyof DM, string>> = { readonly [T in keyof DM]: TableReaderFacade<DM, REL, RANK, SEARCH, T>; };
488
+ type DatabaseReaderFacade<DM, REL extends Record<keyof DM, object>, RANK extends Record<keyof DM, string>, SEARCH extends Record<keyof DM, string>, GEO extends Record<keyof DM, string> = Record<keyof DM, never>> = { readonly [T in keyof DM]: TableReaderFacade<DM, REL, RANK, SEARCH, T, GEO>; };
452
489
  /** Per-table read-write facade — `ctx.db.&lt;table>` on a `MutationCtx` / `ActionCtx`. */
453
- type DatabaseWriterFacade<DM, IM extends Record<keyof DM, object>, REL extends Record<keyof DM, object>, RANK extends Record<keyof DM, string>, SEARCH extends Record<keyof DM, string>> = { readonly [T in keyof DM]: TableWriterFacade<DM, IM, REL, RANK, SEARCH, T>; };
454
- export { AggregateOp, DatabaseReaderFacade, DatabaseWriterFacade, GroupByEntry, Id, LoadWith, ManyRelationWhere, OneRelationWhere, OrderBy, QueryArgs, QueryArgsOf, QueryPage, RankPage, RankResult, RestrictableQueryOptions, RestrictableQueryOptionsOf, SearchFilterBuilder, SearchReader, TableAggregateOptions, TableAggregateOptionsOf, TableGroupByOptions, TableGroupByOptionsOf, TableRankOptions, TableRankPageOptions, TableReaderFacade, TableWriterFacade, UpsertTargetOf, Where, WhereOf, WhereOperators, WithArg };
490
+ type DatabaseWriterFacade<DM, IM extends Record<keyof DM, object>, REL extends Record<keyof DM, object>, RANK extends Record<keyof DM, string>, SEARCH extends Record<keyof DM, string>, GEO extends Record<keyof DM, string> = Record<keyof DM, never>> = { readonly [T in keyof DM]: TableWriterFacade<DM, IM, REL, RANK, SEARCH, T, GEO>; };
491
+ export { AggregateOp, DatabaseReaderFacade, DatabaseWriterFacade, GeoBoundingBox, GeoFilterBuilder, GeoPointInput, GeoReader, GroupByEntry, Id, LoadWith, ManyRelationWhere, OneRelationWhere, OrderBy, QueryArgs, QueryArgsOf, QueryPage, RankPage, RankResult, RestrictableQueryOptions, RestrictableQueryOptionsOf, SearchFilterBuilder, SearchReader, TableAggregateOptions, TableAggregateOptionsOf, TableGroupByOptions, TableGroupByOptionsOf, TableRankOptions, TableRankPageOptions, TableReaderFacade, TableWriterFacade, UpsertTargetOf, Where, WhereOf, WhereOperators, WithArg };
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Validator, Infer, ValidatorMap, InferValidatorMap, v } from '@lunora/values';
2
- export { type ColumnValidator, type Id, type Infer, ValidationError, type Validator, type ValidatorKind, v } from '@lunora/values';
3
- import { ArgsValidator, InferArgs, RegisteredAction, X402ProcedureConfig, 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 CachePurge, type DatabaseReader, type DatabaseWriter, type FunctionVisibility, type IndexDefinition, type IndexRangeBuilder, type LifecycleEventKind, type LogFields, type LunoraLogMethod, type LunoraLogger, type LunoraMetrics, type LunoraTracer, 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";
2
+ export { type ColumnValidator, type GeoPoint, type Id, type Infer, ValidationError, type Validator, type ValidatorKind, v } from '@lunora/values';
3
+ import { ArgsValidator, InferArgs, RegisteredAction, ExposeConfig, X402ProcedureConfig, 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 CachePurge, type DatabaseReader, type DatabaseWriter, type FunctionVisibility, type GeoBoundingBox, type GeoFilterBuilder, type GeoIndexDefinition, type GeoPointInput, type IndexDefinition, type IndexRangeBuilder, type LifecycleEventKind, type LogFields, type LunoraLogMethod, type LunoraLogger, type LunoraMetrics, type LunoraTracer, type PaginationOptions, type PaginationResult, type RankSortKey, type ReadOnlyStorage, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type SearchFilterBuilder, type SearchIndexDefinition, type ShardMode, type SpanHandle, 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 TtlDefinition, 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';
@@ -62,6 +62,13 @@ type CreateOptions = Record<never, never>;
62
62
  */
63
63
  interface QueryBuilder<Context, Args extends ArgsValidator, Output = undefined> {
64
64
  readonly __lunoraProcedure: "query";
65
+ /**
66
+ * Publish this query on the opt-in public REST surface (plan 167) — the
67
+ * runtime mints `GET /_lunora/rest/&lt;namespace>/&lt;fn>` (and `POST`), dispatching
68
+ * THROUGH the procedure so `ctx.auth` / RLS / validators are enforced, and the
69
+ * generated OpenAPI describes it. Default-closed: omit to keep it RPC-only.
70
+ */
71
+ expose: (config: ExposeConfig) => QueryBuilder<Context, Args, Output>;
65
72
  input: <A extends ArgsValidator>(validators: A) => QueryBuilder<Context, A & Args, Output>;
66
73
  output: <V extends Validator>(validator: V) => QueryBuilder<Context, Args, Infer<V>>;
67
74
  query: [Output] extends [undefined] ? <R>(handler: (options: {
@@ -95,6 +102,13 @@ interface QueryBuilder<Context, Args extends ArgsValidator, Output = undefined>
95
102
  }
96
103
  interface MutationBuilder<Context, Args extends ArgsValidator, Output = undefined> {
97
104
  readonly __lunoraProcedure: "mutation";
105
+ /**
106
+ * Publish this mutation on the opt-in public REST surface (plan 167) — the
107
+ * runtime mints `POST /_lunora/rest/&lt;namespace>/&lt;fn>`, dispatching THROUGH the
108
+ * procedure so `ctx.auth` / RLS / validators are enforced, and the generated
109
+ * OpenAPI describes it. Default-closed: omit to keep it RPC-only.
110
+ */
111
+ expose: (config: ExposeConfig) => MutationBuilder<Context, Args, Output>;
98
112
  input: <A extends ArgsValidator>(validators: A) => MutationBuilder<Context, A & Args, Output>;
99
113
  mutation: [Output] extends [undefined] ? <R>(handler: (options: {
100
114
  args: InferArgs<Args>;
@@ -122,6 +136,13 @@ interface ActionBuilder<Context, Args extends ArgsValidator, Output = undefined>
122
136
  args: InferArgs<Args>;
123
137
  ctx: Context;
124
138
  }) => Output | Promise<Output>) => RegisteredAction<Args, Output>;
139
+ /**
140
+ * Publish this action on the opt-in public REST surface (plan 167) — the
141
+ * runtime mints `POST /_lunora/rest/&lt;namespace>/&lt;fn>`, dispatching THROUGH the
142
+ * procedure so `ctx.auth` / RLS / validators are enforced, and the generated
143
+ * OpenAPI describes it. Default-closed: omit to keep it RPC-only.
144
+ */
145
+ expose: (config: ExposeConfig) => ActionBuilder<Context, Args, Output>;
125
146
  input: <A extends ArgsValidator>(validators: A) => ActionBuilder<Context, A & Args, Output>;
126
147
  output: <V extends Validator>(validator: V) => ActionBuilder<Context, Args, Infer<V>>;
127
148
  use: <ContextOut>(middleware: Middleware<Context, ContextOut>) => ActionBuilder<ContextOut, Args, Output>;
@@ -353,6 +374,7 @@ interface FacadeWriterLike {
353
374
  patched: number;
354
375
  }>;
355
376
  query(tableName: string): {
377
+ withGeoIndex(indexName: string, build: (q: unknown) => unknown): unknown;
356
378
  withSearchIndex(indexName: string, search: (q: unknown) => unknown): unknown;
357
379
  };
358
380
  rank(tableName: string, indexName: string, options: unknown): Promise<unknown>;
@@ -425,6 +447,7 @@ interface FacadeEntry {
425
447
  upsert: (args: UpsertArgs) => Promise<UpsertResult>;
426
448
  /** Sequential `upsert` over many rows sharing one `target`; returns one result per input row in order. */
427
449
  upsertMany: (args: UpsertManyArgs) => Promise<UpsertResult[]>;
450
+ withGeoIndex: (indexName: string, build: (q: unknown) => unknown) => unknown;
428
451
  withSearchIndex: (indexName: string, search: (q: unknown) => unknown) => unknown;
429
452
  }
430
453
  /** Options accepted by the per-table `insert` accessor. */
@@ -893,6 +916,7 @@ interface TableReaderLike$1 {
893
916
  }) => Promise<QueryPage$1>;
894
917
  take: (limit: number) => Promise<Record<string, unknown>[]>;
895
918
  unique: () => Promise<Record<string, unknown> | null>;
919
+ withGeoIndex: (indexName: string, build: (q: unknown) => unknown) => TableReaderLike$1;
896
920
  withIndex: (indexName: string, range?: (q: unknown) => unknown) => TableReaderLike$1;
897
921
  withSearchIndex: (indexName: string, search: (q: unknown) => unknown) => TableReaderLike$1;
898
922
  }
@@ -1349,6 +1373,16 @@ interface TableBuilder<Shape extends Record<string, Validator> = Record<string,
1349
1373
  * `ctx.db.insert(...)`.
1350
1374
  */
1351
1375
  externallyManaged: () => TableBuilder<Shape>;
1376
+ /**
1377
+ * Declare a geospatial index over a `v.geoPoint()` column. The runtime keeps
1378
+ * a geohash companion so `withGeoIndex(name, q => q.near(point, radius))` and
1379
+ * `.within(bbox)` resolve as a geohash-prefix range scan + Haversine
1380
+ * refine/sort. `options.precision` tunes the geohash length (default 9).
1381
+ */
1382
+ geoIndex: (name: string, options: {
1383
+ field: keyof Shape & string;
1384
+ precision?: number;
1385
+ }) => TableBuilder<Shape>;
1352
1386
  /**
1353
1387
  * Mark this table as global (cross-shard). Backed by **D1** by default;
1354
1388
  * pass `{ backend: "hyperdrive" }` to store it in a Postgres/MySQL database
@@ -1415,6 +1449,17 @@ interface TableBuilder<Shape extends Record<string, Validator> = Record<string,
1415
1449
  source: (definition: ExternalSourceDefinition) => TableBuilder<Shape>;
1416
1450
  /** Declare named lifecycle triggers fired inline within the write path. */
1417
1451
  triggers: (build: (t: TriggerBuilder<Shape>) => Record<string, TriggerDefinition>) => TableBuilder<Shape>;
1452
+ /**
1453
+ * Declare a table-level TTL: a DO alarm-driven sweep auto-deletes rows whose
1454
+ * expiry has passed (or soft-deletes them when the table also
1455
+ * `.softDelete()`s). `field` is an epoch-millisecond column; without
1456
+ * `options.after` its value is the absolute expiry instant, with `after` the
1457
+ * row expires `after` ms past `field` (`field + after`). Coarse, cheap,
1458
+ * table-level — for per-row schedules use `@lunora/scheduler`.
1459
+ */
1460
+ ttl: (field: keyof Shape & string, options?: {
1461
+ after?: number;
1462
+ }) => TableBuilder<Shape>;
1418
1463
  /** Declare a vector index over a single text field on this table. */
1419
1464
  vectorize: (field: keyof Shape & string, options: VectorizeOptions<Shape>) => TableBuilder<Shape>;
1420
1465
  }
@@ -1811,6 +1856,7 @@ interface TableReaderLike {
1811
1856
  numItems: number;
1812
1857
  }) => Promise<QueryPage>;
1813
1858
  take: (limit: number) => Promise<Record<string, unknown>[]>;
1859
+ withGeoIndex: (indexName: string, build: (q: unknown) => unknown) => TableReaderLike;
1814
1860
  withIndex: (indexName: string, range?: (q: unknown) => unknown) => TableReaderLike;
1815
1861
  withSearchIndex: (indexName: string, search: (q: unknown) => unknown) => TableReaderLike;
1816
1862
  }
@@ -2122,4 +2168,4 @@ interface StorageContextIn {
2122
2168
  }
2123
2169
  declare const storageRules: <Context extends StorageContextIn = StorageContextIn>(rules: ReadonlyArray<StorageRule<Context>>, options?: StorageRulesOptions) => Middleware<Context, Context>;
2124
2170
  declare const VERSION = "0.0.0";
2125
- export { type ActionBuilder, type ActionCtx, type AggregateIndexDefinition, type AggregateIndexOptions, type AggregateOp, type ArgsValidator, type Component, type ComponentFunctions, type CreateOptions, type DataModelInit, type DefineComponentOptions, type DefineIdentityOptions, type DefinePluginOptions, type DefinePolicyInput, type DefinePresenceOptions, type DefineStorageRuleInput, type DurableObjectJurisdiction, type EmptyArgs, type EnvAccessor, type EnvKeyFailure, type EnvShape, type ExtendableSchema, type FacadeEntry, type FacadeWriterLike, type FunctionKind, type HttpActionCtx, type HttpActionHandler, type HttpMethod, type HttpRoute, type HttpRouteBuilder, type HttpRouteFactory, type HttpRouteHandlerOptions, type HttpStreamHandlerOptions, type IdentityContract, type IdentityRejectMode, type IdentityValidation, type InferArgs, type InferEnv, type InferIdentity, type InlineAggregateIndexOptions, type InlineRankIndexOptions, type InternalActionBuilder, type InternalMutationBuilder, type InternalQueryBuilder, type LifecycleEvent, type LifecycleHandler, type LunoraBuilders, LunoraEnvError, LunoraError, type LunoraHttpApp, type LunoraHttpEnv, type LunoraRouteHandler, type ManyRelation, type MaskColumns, type MaskContext, type MaskFn, type MaskOptions, type MaskPolicies, type MaskStrategy, type Middleware, type MiddlewareNext, type MigrationDefinition, type MigrationDocument, type MigrationTransform, type MutationBuilder, type MutationCtx, type MutatorDefinition, type OnDeleteAction, type OneRelation, type OrmLike, DEFAULT_TTL_MS as PRESENCE_DEFAULT_TTL_MS, PRESENCE_TABLE, type Permission, type Plugin, type Policy, type PrefixedTables, type PresenceComponent, type PresenceFunctions, type PresenceMember, type ProtectPublicOptions, type QueryBuilder, type QueryCtx, type RankIndexDefinition, type RankIndexOptions, type RegisteredAction, type RegisteredFunction, type RegisteredLifecycleHook, type RegisteredMigration, type RegisteredMutation, type RegisteredMutator, type RegisteredQuery, type RegisteredShape, type RegisteredStream, type RelationBuilder, type RelationDefinition, type RlsOptions, type RlsReadRegistry, type Role, type Schema, type SchemaExtension, type ShapeDefinition, type ShapeReadWhereRequest, type StorageOperation, type StorageRule, type StorageRuleContext, type StorageRuleDecision, type StorageRulesOptions, type TableBuilder, type TableDefinition, type TerminalKind, type TriggerBuilder, type TriggerDefinition, type TypedDefinePolicyInput, VERSION, type VectorEmbedder, type VectorIndexDefinition, type VectorIndexOptions, type VectorMetric, type VectorizeOptions, type WhereInput, asBucketStorage, bindOrm, bindTableFacade, buildRlsReadRegistry, composePluginMiddleware, composeShapeReadWhere, createPolicyDsl, createSecrets, defineAggregateIndex, defineComponent, defineEnv, defineIdentity, defineMigration, defineMutator, definePermission, definePlugin, definePolicies, definePolicy, definePresence, defineRankIndex, defineRole, defineSchema, defineSchemaExtension, defineShape, defineStorageRule, defineStorageRules, defineTable, defineVectorIndex, httpAction, httpRoute, httpRouter, initLunora, installPlugins, isSafeHeaderValue, mask, mergeSchemaExtension, onConnect, onDisconnect, presenceExtension, protectPublic, redactSecrets, rls, serveStorageObject, storageRules };
2171
+ export { type ActionBuilder, type ActionCtx, type AggregateIndexDefinition, type AggregateIndexOptions, type AggregateOp, type ArgsValidator, type Component, type ComponentFunctions, type CreateOptions, type DataModelInit, type DefineComponentOptions, type DefineIdentityOptions, type DefinePluginOptions, type DefinePolicyInput, type DefinePresenceOptions, type DefineStorageRuleInput, type DurableObjectJurisdiction, type EmptyArgs, type EnvAccessor, type EnvKeyFailure, type EnvShape, type ExposeConfig, type ExtendableSchema, type FacadeEntry, type FacadeWriterLike, type FunctionKind, type HttpActionCtx, type HttpActionHandler, type HttpMethod, type HttpRoute, type HttpRouteBuilder, type HttpRouteFactory, type HttpRouteHandlerOptions, type HttpStreamHandlerOptions, type IdentityContract, type IdentityRejectMode, type IdentityValidation, type InferArgs, type InferEnv, type InferIdentity, type InlineAggregateIndexOptions, type InlineRankIndexOptions, type InternalActionBuilder, type InternalMutationBuilder, type InternalQueryBuilder, type LifecycleEvent, type LifecycleHandler, type LunoraBuilders, LunoraEnvError, LunoraError, type LunoraHttpApp, type LunoraHttpEnv, type LunoraRouteHandler, type ManyRelation, type MaskColumns, type MaskContext, type MaskFn, type MaskOptions, type MaskPolicies, type MaskStrategy, type Middleware, type MiddlewareNext, type MigrationDefinition, type MigrationDocument, type MigrationTransform, type MutationBuilder, type MutationCtx, type MutatorDefinition, type OnDeleteAction, type OneRelation, type OrmLike, DEFAULT_TTL_MS as PRESENCE_DEFAULT_TTL_MS, PRESENCE_TABLE, type Permission, type Plugin, type Policy, type PrefixedTables, type PresenceComponent, type PresenceFunctions, type PresenceMember, type ProtectPublicOptions, type QueryBuilder, type QueryCtx, type RankIndexDefinition, type RankIndexOptions, type RegisteredAction, type RegisteredFunction, type RegisteredLifecycleHook, type RegisteredMigration, type RegisteredMutation, type RegisteredMutator, type RegisteredQuery, type RegisteredShape, type RegisteredStream, type RelationBuilder, type RelationDefinition, type RlsOptions, type RlsReadRegistry, type Role, type Schema, type SchemaExtension, type ShapeDefinition, type ShapeReadWhereRequest, type StorageOperation, type StorageRule, type StorageRuleContext, type StorageRuleDecision, type StorageRulesOptions, type TableBuilder, type TableDefinition, type TerminalKind, type TriggerBuilder, type TriggerDefinition, type TypedDefinePolicyInput, VERSION, type VectorEmbedder, type VectorIndexDefinition, type VectorIndexOptions, type VectorMetric, type VectorizeOptions, type WhereInput, asBucketStorage, bindOrm, bindTableFacade, buildRlsReadRegistry, composePluginMiddleware, composeShapeReadWhere, createPolicyDsl, createSecrets, defineAggregateIndex, defineComponent, defineEnv, defineIdentity, defineMigration, defineMutator, definePermission, definePlugin, definePolicies, definePolicy, definePresence, defineRankIndex, defineRole, defineSchema, defineSchemaExtension, defineShape, defineStorageRule, defineStorageRules, defineTable, defineVectorIndex, httpAction, httpRoute, httpRouter, initLunora, installPlugins, isSafeHeaderValue, mask, mergeSchemaExtension, onConnect, onDisconnect, presenceExtension, protectPublic, redactSecrets, rls, serveStorageObject, storageRules };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Validator, Infer, ValidatorMap, InferValidatorMap, v } from '@lunora/values';
2
- export { type ColumnValidator, type Id, type Infer, ValidationError, type Validator, type ValidatorKind, v } from '@lunora/values';
3
- import { ArgsValidator, InferArgs, RegisteredAction, X402ProcedureConfig, 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 CachePurge, type DatabaseReader, type DatabaseWriter, type FunctionVisibility, type IndexDefinition, type IndexRangeBuilder, type LifecycleEventKind, type LogFields, type LunoraLogMethod, type LunoraLogger, type LunoraMetrics, type LunoraTracer, 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";
2
+ export { type ColumnValidator, type GeoPoint, type Id, type Infer, ValidationError, type Validator, type ValidatorKind, v } from '@lunora/values';
3
+ import { ArgsValidator, InferArgs, RegisteredAction, ExposeConfig, X402ProcedureConfig, 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 CachePurge, type DatabaseReader, type DatabaseWriter, type FunctionVisibility, type GeoBoundingBox, type GeoFilterBuilder, type GeoIndexDefinition, type GeoPointInput, type IndexDefinition, type IndexRangeBuilder, type LifecycleEventKind, type LogFields, type LunoraLogMethod, type LunoraLogger, type LunoraMetrics, type LunoraTracer, type PaginationOptions, type PaginationResult, type RankSortKey, type ReadOnlyStorage, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type SearchFilterBuilder, type SearchIndexDefinition, type ShardMode, type SpanHandle, 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 TtlDefinition, 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';
@@ -62,6 +62,13 @@ type CreateOptions = Record<never, never>;
62
62
  */
63
63
  interface QueryBuilder<Context, Args extends ArgsValidator, Output = undefined> {
64
64
  readonly __lunoraProcedure: "query";
65
+ /**
66
+ * Publish this query on the opt-in public REST surface (plan 167) — the
67
+ * runtime mints `GET /_lunora/rest/&lt;namespace>/&lt;fn>` (and `POST`), dispatching
68
+ * THROUGH the procedure so `ctx.auth` / RLS / validators are enforced, and the
69
+ * generated OpenAPI describes it. Default-closed: omit to keep it RPC-only.
70
+ */
71
+ expose: (config: ExposeConfig) => QueryBuilder<Context, Args, Output>;
65
72
  input: <A extends ArgsValidator>(validators: A) => QueryBuilder<Context, A & Args, Output>;
66
73
  output: <V extends Validator>(validator: V) => QueryBuilder<Context, Args, Infer<V>>;
67
74
  query: [Output] extends [undefined] ? <R>(handler: (options: {
@@ -95,6 +102,13 @@ interface QueryBuilder<Context, Args extends ArgsValidator, Output = undefined>
95
102
  }
96
103
  interface MutationBuilder<Context, Args extends ArgsValidator, Output = undefined> {
97
104
  readonly __lunoraProcedure: "mutation";
105
+ /**
106
+ * Publish this mutation on the opt-in public REST surface (plan 167) — the
107
+ * runtime mints `POST /_lunora/rest/&lt;namespace>/&lt;fn>`, dispatching THROUGH the
108
+ * procedure so `ctx.auth` / RLS / validators are enforced, and the generated
109
+ * OpenAPI describes it. Default-closed: omit to keep it RPC-only.
110
+ */
111
+ expose: (config: ExposeConfig) => MutationBuilder<Context, Args, Output>;
98
112
  input: <A extends ArgsValidator>(validators: A) => MutationBuilder<Context, A & Args, Output>;
99
113
  mutation: [Output] extends [undefined] ? <R>(handler: (options: {
100
114
  args: InferArgs<Args>;
@@ -122,6 +136,13 @@ interface ActionBuilder<Context, Args extends ArgsValidator, Output = undefined>
122
136
  args: InferArgs<Args>;
123
137
  ctx: Context;
124
138
  }) => Output | Promise<Output>) => RegisteredAction<Args, Output>;
139
+ /**
140
+ * Publish this action on the opt-in public REST surface (plan 167) — the
141
+ * runtime mints `POST /_lunora/rest/&lt;namespace>/&lt;fn>`, dispatching THROUGH the
142
+ * procedure so `ctx.auth` / RLS / validators are enforced, and the generated
143
+ * OpenAPI describes it. Default-closed: omit to keep it RPC-only.
144
+ */
145
+ expose: (config: ExposeConfig) => ActionBuilder<Context, Args, Output>;
125
146
  input: <A extends ArgsValidator>(validators: A) => ActionBuilder<Context, A & Args, Output>;
126
147
  output: <V extends Validator>(validator: V) => ActionBuilder<Context, Args, Infer<V>>;
127
148
  use: <ContextOut>(middleware: Middleware<Context, ContextOut>) => ActionBuilder<ContextOut, Args, Output>;
@@ -353,6 +374,7 @@ interface FacadeWriterLike {
353
374
  patched: number;
354
375
  }>;
355
376
  query(tableName: string): {
377
+ withGeoIndex(indexName: string, build: (q: unknown) => unknown): unknown;
356
378
  withSearchIndex(indexName: string, search: (q: unknown) => unknown): unknown;
357
379
  };
358
380
  rank(tableName: string, indexName: string, options: unknown): Promise<unknown>;
@@ -425,6 +447,7 @@ interface FacadeEntry {
425
447
  upsert: (args: UpsertArgs) => Promise<UpsertResult>;
426
448
  /** Sequential `upsert` over many rows sharing one `target`; returns one result per input row in order. */
427
449
  upsertMany: (args: UpsertManyArgs) => Promise<UpsertResult[]>;
450
+ withGeoIndex: (indexName: string, build: (q: unknown) => unknown) => unknown;
428
451
  withSearchIndex: (indexName: string, search: (q: unknown) => unknown) => unknown;
429
452
  }
430
453
  /** Options accepted by the per-table `insert` accessor. */
@@ -893,6 +916,7 @@ interface TableReaderLike$1 {
893
916
  }) => Promise<QueryPage$1>;
894
917
  take: (limit: number) => Promise<Record<string, unknown>[]>;
895
918
  unique: () => Promise<Record<string, unknown> | null>;
919
+ withGeoIndex: (indexName: string, build: (q: unknown) => unknown) => TableReaderLike$1;
896
920
  withIndex: (indexName: string, range?: (q: unknown) => unknown) => TableReaderLike$1;
897
921
  withSearchIndex: (indexName: string, search: (q: unknown) => unknown) => TableReaderLike$1;
898
922
  }
@@ -1349,6 +1373,16 @@ interface TableBuilder<Shape extends Record<string, Validator> = Record<string,
1349
1373
  * `ctx.db.insert(...)`.
1350
1374
  */
1351
1375
  externallyManaged: () => TableBuilder<Shape>;
1376
+ /**
1377
+ * Declare a geospatial index over a `v.geoPoint()` column. The runtime keeps
1378
+ * a geohash companion so `withGeoIndex(name, q => q.near(point, radius))` and
1379
+ * `.within(bbox)` resolve as a geohash-prefix range scan + Haversine
1380
+ * refine/sort. `options.precision` tunes the geohash length (default 9).
1381
+ */
1382
+ geoIndex: (name: string, options: {
1383
+ field: keyof Shape & string;
1384
+ precision?: number;
1385
+ }) => TableBuilder<Shape>;
1352
1386
  /**
1353
1387
  * Mark this table as global (cross-shard). Backed by **D1** by default;
1354
1388
  * pass `{ backend: "hyperdrive" }` to store it in a Postgres/MySQL database
@@ -1415,6 +1449,17 @@ interface TableBuilder<Shape extends Record<string, Validator> = Record<string,
1415
1449
  source: (definition: ExternalSourceDefinition) => TableBuilder<Shape>;
1416
1450
  /** Declare named lifecycle triggers fired inline within the write path. */
1417
1451
  triggers: (build: (t: TriggerBuilder<Shape>) => Record<string, TriggerDefinition>) => TableBuilder<Shape>;
1452
+ /**
1453
+ * Declare a table-level TTL: a DO alarm-driven sweep auto-deletes rows whose
1454
+ * expiry has passed (or soft-deletes them when the table also
1455
+ * `.softDelete()`s). `field` is an epoch-millisecond column; without
1456
+ * `options.after` its value is the absolute expiry instant, with `after` the
1457
+ * row expires `after` ms past `field` (`field + after`). Coarse, cheap,
1458
+ * table-level — for per-row schedules use `@lunora/scheduler`.
1459
+ */
1460
+ ttl: (field: keyof Shape & string, options?: {
1461
+ after?: number;
1462
+ }) => TableBuilder<Shape>;
1418
1463
  /** Declare a vector index over a single text field on this table. */
1419
1464
  vectorize: (field: keyof Shape & string, options: VectorizeOptions<Shape>) => TableBuilder<Shape>;
1420
1465
  }
@@ -1811,6 +1856,7 @@ interface TableReaderLike {
1811
1856
  numItems: number;
1812
1857
  }) => Promise<QueryPage>;
1813
1858
  take: (limit: number) => Promise<Record<string, unknown>[]>;
1859
+ withGeoIndex: (indexName: string, build: (q: unknown) => unknown) => TableReaderLike;
1814
1860
  withIndex: (indexName: string, range?: (q: unknown) => unknown) => TableReaderLike;
1815
1861
  withSearchIndex: (indexName: string, search: (q: unknown) => unknown) => TableReaderLike;
1816
1862
  }
@@ -2122,4 +2168,4 @@ interface StorageContextIn {
2122
2168
  }
2123
2169
  declare const storageRules: <Context extends StorageContextIn = StorageContextIn>(rules: ReadonlyArray<StorageRule<Context>>, options?: StorageRulesOptions) => Middleware<Context, Context>;
2124
2170
  declare const VERSION = "0.0.0";
2125
- export { type ActionBuilder, type ActionCtx, type AggregateIndexDefinition, type AggregateIndexOptions, type AggregateOp, type ArgsValidator, type Component, type ComponentFunctions, type CreateOptions, type DataModelInit, type DefineComponentOptions, type DefineIdentityOptions, type DefinePluginOptions, type DefinePolicyInput, type DefinePresenceOptions, type DefineStorageRuleInput, type DurableObjectJurisdiction, type EmptyArgs, type EnvAccessor, type EnvKeyFailure, type EnvShape, type ExtendableSchema, type FacadeEntry, type FacadeWriterLike, type FunctionKind, type HttpActionCtx, type HttpActionHandler, type HttpMethod, type HttpRoute, type HttpRouteBuilder, type HttpRouteFactory, type HttpRouteHandlerOptions, type HttpStreamHandlerOptions, type IdentityContract, type IdentityRejectMode, type IdentityValidation, type InferArgs, type InferEnv, type InferIdentity, type InlineAggregateIndexOptions, type InlineRankIndexOptions, type InternalActionBuilder, type InternalMutationBuilder, type InternalQueryBuilder, type LifecycleEvent, type LifecycleHandler, type LunoraBuilders, LunoraEnvError, LunoraError, type LunoraHttpApp, type LunoraHttpEnv, type LunoraRouteHandler, type ManyRelation, type MaskColumns, type MaskContext, type MaskFn, type MaskOptions, type MaskPolicies, type MaskStrategy, type Middleware, type MiddlewareNext, type MigrationDefinition, type MigrationDocument, type MigrationTransform, type MutationBuilder, type MutationCtx, type MutatorDefinition, type OnDeleteAction, type OneRelation, type OrmLike, DEFAULT_TTL_MS as PRESENCE_DEFAULT_TTL_MS, PRESENCE_TABLE, type Permission, type Plugin, type Policy, type PrefixedTables, type PresenceComponent, type PresenceFunctions, type PresenceMember, type ProtectPublicOptions, type QueryBuilder, type QueryCtx, type RankIndexDefinition, type RankIndexOptions, type RegisteredAction, type RegisteredFunction, type RegisteredLifecycleHook, type RegisteredMigration, type RegisteredMutation, type RegisteredMutator, type RegisteredQuery, type RegisteredShape, type RegisteredStream, type RelationBuilder, type RelationDefinition, type RlsOptions, type RlsReadRegistry, type Role, type Schema, type SchemaExtension, type ShapeDefinition, type ShapeReadWhereRequest, type StorageOperation, type StorageRule, type StorageRuleContext, type StorageRuleDecision, type StorageRulesOptions, type TableBuilder, type TableDefinition, type TerminalKind, type TriggerBuilder, type TriggerDefinition, type TypedDefinePolicyInput, VERSION, type VectorEmbedder, type VectorIndexDefinition, type VectorIndexOptions, type VectorMetric, type VectorizeOptions, type WhereInput, asBucketStorage, bindOrm, bindTableFacade, buildRlsReadRegistry, composePluginMiddleware, composeShapeReadWhere, createPolicyDsl, createSecrets, defineAggregateIndex, defineComponent, defineEnv, defineIdentity, defineMigration, defineMutator, definePermission, definePlugin, definePolicies, definePolicy, definePresence, defineRankIndex, defineRole, defineSchema, defineSchemaExtension, defineShape, defineStorageRule, defineStorageRules, defineTable, defineVectorIndex, httpAction, httpRoute, httpRouter, initLunora, installPlugins, isSafeHeaderValue, mask, mergeSchemaExtension, onConnect, onDisconnect, presenceExtension, protectPublic, redactSecrets, rls, serveStorageObject, storageRules };
2171
+ export { type ActionBuilder, type ActionCtx, type AggregateIndexDefinition, type AggregateIndexOptions, type AggregateOp, type ArgsValidator, type Component, type ComponentFunctions, type CreateOptions, type DataModelInit, type DefineComponentOptions, type DefineIdentityOptions, type DefinePluginOptions, type DefinePolicyInput, type DefinePresenceOptions, type DefineStorageRuleInput, type DurableObjectJurisdiction, type EmptyArgs, type EnvAccessor, type EnvKeyFailure, type EnvShape, type ExposeConfig, type ExtendableSchema, type FacadeEntry, type FacadeWriterLike, type FunctionKind, type HttpActionCtx, type HttpActionHandler, type HttpMethod, type HttpRoute, type HttpRouteBuilder, type HttpRouteFactory, type HttpRouteHandlerOptions, type HttpStreamHandlerOptions, type IdentityContract, type IdentityRejectMode, type IdentityValidation, type InferArgs, type InferEnv, type InferIdentity, type InlineAggregateIndexOptions, type InlineRankIndexOptions, type InternalActionBuilder, type InternalMutationBuilder, type InternalQueryBuilder, type LifecycleEvent, type LifecycleHandler, type LunoraBuilders, LunoraEnvError, LunoraError, type LunoraHttpApp, type LunoraHttpEnv, type LunoraRouteHandler, type ManyRelation, type MaskColumns, type MaskContext, type MaskFn, type MaskOptions, type MaskPolicies, type MaskStrategy, type Middleware, type MiddlewareNext, type MigrationDefinition, type MigrationDocument, type MigrationTransform, type MutationBuilder, type MutationCtx, type MutatorDefinition, type OnDeleteAction, type OneRelation, type OrmLike, DEFAULT_TTL_MS as PRESENCE_DEFAULT_TTL_MS, PRESENCE_TABLE, type Permission, type Plugin, type Policy, type PrefixedTables, type PresenceComponent, type PresenceFunctions, type PresenceMember, type ProtectPublicOptions, type QueryBuilder, type QueryCtx, type RankIndexDefinition, type RankIndexOptions, type RegisteredAction, type RegisteredFunction, type RegisteredLifecycleHook, type RegisteredMigration, type RegisteredMutation, type RegisteredMutator, type RegisteredQuery, type RegisteredShape, type RegisteredStream, type RelationBuilder, type RelationDefinition, type RlsOptions, type RlsReadRegistry, type Role, type Schema, type SchemaExtension, type ShapeDefinition, type ShapeReadWhereRequest, type StorageOperation, type StorageRule, type StorageRuleContext, type StorageRuleDecision, type StorageRulesOptions, type TableBuilder, type TableDefinition, type TerminalKind, type TriggerBuilder, type TriggerDefinition, type TypedDefinePolicyInput, VERSION, type VectorEmbedder, type VectorIndexDefinition, type VectorIndexOptions, type VectorMetric, type VectorizeOptions, type WhereInput, asBucketStorage, bindOrm, bindTableFacade, buildRlsReadRegistry, composePluginMiddleware, composeShapeReadWhere, createPolicyDsl, createSecrets, defineAggregateIndex, defineComponent, defineEnv, defineIdentity, defineMigration, defineMutator, definePermission, definePlugin, definePolicies, definePolicy, definePresence, defineRankIndex, defineRole, defineSchema, defineSchemaExtension, defineShape, defineStorageRule, defineStorageRules, defineTable, defineVectorIndex, httpAction, httpRoute, httpRouter, initLunora, installPlugins, isSafeHeaderValue, mask, mergeSchemaExtension, onConnect, onDisconnect, presenceExtension, protectPublic, redactSecrets, rls, serveStorageObject, storageRules };
package/dist/index.mjs CHANGED
@@ -1,27 +1,27 @@
1
1
  export { default as asBucketStorage } from './packem_shared/asBucketStorage-Cnxd9y2q.mjs';
2
- export { initLunora } from './packem_shared/initLunora-CmMVk4i7.mjs';
2
+ export { initLunora } from './packem_shared/initLunora-D0Wuki7S.mjs';
3
3
  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
- export { bindOrm, bindTableFacade } from './packem_shared/bindOrm-Bfgl7f-Q.mjs';
6
+ export { bindOrm, bindTableFacade } from './packem_shared/bindOrm-CaY7Wq9Z.mjs';
7
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';
11
11
  export { defineMutator } from './packem_shared/defineMutator-EIXAWhs9.mjs';
12
12
  export { composePluginMiddleware, defineComponent, definePlugin, defineSchemaExtension, installPlugins, mergeSchemaExtension } from './packem_shared/composePluginMiddleware-z62dttBo.mjs';
13
- export { PRESENCE_DEFAULT_TTL_MS, PRESENCE_TABLE, definePresence, presenceExtension } from './packem_shared/PRESENCE_DEFAULT_TTL_MS-Cv1UPaJj.mjs';
13
+ export { PRESENCE_DEFAULT_TTL_MS, PRESENCE_TABLE, definePresence, presenceExtension } from './packem_shared/PRESENCE_DEFAULT_TTL_MS-Cr0i4mTv.mjs';
14
14
  export { protectPublic } from './packem_shared/protectPublic-BlcGpiRc.mjs';
15
- export { defineAggregateIndex, defineRankIndex, defineSchema, defineTable, defineVectorIndex } from './packem_shared/defineAggregateIndex-DTULzh09.mjs';
15
+ export { defineAggregateIndex, defineRankIndex, defineSchema, defineTable, defineVectorIndex } from './packem_shared/defineAggregateIndex-cdo0g-un.mjs';
16
16
  export { defineShape } from './packem_shared/defineShape-C5scNOrf.mjs';
17
17
  export { anyApi } from './types.mjs';
18
18
  export { cronJobs } from '@lunora/scheduler';
19
19
  export { ValidationError, v } from '@lunora/values';
20
- export { buildRlsReadRegistry, composeShapeReadWhere } from './packem_shared/buildRlsReadRegistry-D54vUQe4.mjs';
20
+ export { buildRlsReadRegistry, composeShapeReadWhere } from './packem_shared/buildRlsReadRegistry-2uk_GfiH.mjs';
21
21
  export { createPolicyDsl, definePermission, definePolicies, definePolicy, defineRole } from './packem_shared/createPolicyDsl-By3QB4he.mjs';
22
22
  export { defineStorageRule, defineStorageRules } from './packem_shared/defineStorageRule-B5nL4Z1P.mjs';
23
- export { mask } from './packem_shared/mask-CZuu9WAF.mjs';
24
- export { rls } from './packem_shared/rls-B_ZWgslr.mjs';
23
+ export { mask } from './packem_shared/mask-BepaW7YN.mjs';
24
+ export { rls } from './packem_shared/rls-BaDQf7MG.mjs';
25
25
  export { storageRules } from './packem_shared/storageRules-6QxzDOcx.mjs';
26
26
 
27
27
  const VERSION = "0.0.0";
@@ -1,9 +1,9 @@
1
1
  import { v } from '@lunora/values';
2
- import { initLunora } from './initLunora-CmMVk4i7.mjs';
2
+ import { initLunora } from './initLunora-D0Wuki7S.mjs';
3
3
  import { LunoraError } from './LunoraError-WbxmrpxR.mjs';
4
4
  import { onDisconnect } from './onConnect-CIPXKPyw.mjs';
5
5
  import { defineSchemaExtension, defineComponent } from './composePluginMiddleware-z62dttBo.mjs';
6
- import { defineTable } from './defineAggregateIndex-DTULzh09.mjs';
6
+ import { defineTable } from './defineAggregateIndex-cdo0g-un.mjs';
7
7
 
8
8
  const DEFAULT_TTL_MS = 3e4;
9
9
  const MAX_DATA_BYTES = 4096;
@@ -117,6 +117,7 @@ const bindTableFacade = (writer, tableName) => {
117
117
  }
118
118
  return results;
119
119
  },
120
+ withGeoIndex: (indexName, build) => writer.query(tableName).withGeoIndex(indexName, build),
120
121
  withSearchIndex: (indexName, search) => writer.query(tableName).withSearchIndex(indexName, search)
121
122
  };
122
123
  };
@@ -1,4 +1,4 @@
1
- import { indexRolePermissions, computeReadBaseWhere, permissionName } from './rls-B_ZWgslr.mjs';
1
+ import { indexRolePermissions, computeReadBaseWhere, permissionName } from './rls-BaDQf7MG.mjs';
2
2
  import { r as readRlsTag } from './policy-tag-DvpVH2tv.mjs';
3
3
 
4
4
  const FALSE_PREDICATE = { OR: [] };
@@ -31,6 +31,7 @@ const defineTable = (inputShape) => {
31
31
  }
32
32
  }
33
33
  const aggregateIndexes = [];
34
+ const geoIndexes = [];
34
35
  const indexes = [];
35
36
  const rankIndexes = [];
36
37
  const relations = {};
@@ -42,6 +43,7 @@ const defineTable = (inputShape) => {
42
43
  let isExternallyManaged = false;
43
44
  let isPublic = false;
44
45
  let softDelete;
46
+ let ttl;
45
47
  let externalSource;
46
48
  const builder = {
47
49
  aggregateIndex(name, options) {
@@ -72,6 +74,13 @@ const defineTable = (inputShape) => {
72
74
  isExternallyManaged = true;
73
75
  return builder;
74
76
  },
77
+ geoIndex(name, options) {
78
+ geoIndexes.push({ field: options.field, name, precision: options.precision });
79
+ return builder;
80
+ },
81
+ get geoIndexes() {
82
+ return geoIndexes;
83
+ },
75
84
  global(options) {
76
85
  shardMode = { backend: options?.backend ?? "d1", kind: "global" };
77
86
  return builder;
@@ -168,6 +177,13 @@ const defineTable = (inputShape) => {
168
177
  Object.assign(triggers, build(triggerBuilder));
169
178
  return builder;
170
179
  },
180
+ ttl(field, options) {
181
+ ttl = { after: options?.after, field };
182
+ return builder;
183
+ },
184
+ get ttlPolicy() {
185
+ return ttl;
186
+ },
171
187
  get vectorIndexes() {
172
188
  return vectorIndexes;
173
189
  },
@@ -54,6 +54,7 @@ const makeBuilder = (kind, state, visibility) => {
54
54
  const rls = collectRls(state.middlewares);
55
55
  return {
56
56
  args: state.args,
57
+ ...state.expose ? { expose: state.expose } : {},
57
58
  handler: makeHandler(state.args, state.middlewares, userHandler, state.output),
58
59
  kind,
59
60
  ...rls ? { rls } : {},
@@ -71,6 +72,7 @@ const makeBuilder = (kind, state, visibility) => {
71
72
  const rls = collectRls(state.middlewares);
72
73
  return {
73
74
  args: state.args,
75
+ ...state.expose ? { expose: state.expose } : {},
74
76
  handler: makeStreamHandler(state.args, state.middlewares, userHandler),
75
77
  kind: "stream",
76
78
  ...rls ? { rls } : {},
@@ -80,6 +82,12 @@ const makeBuilder = (kind, state, visibility) => {
80
82
  }
81
83
  } : {},
82
84
  use: (middleware) => makeBuilder(kind, { ...state, middlewares: [...state.middlewares, middleware] }, visibility),
85
+ // `.expose({ rest: true })` publishes a PUBLIC procedure on the REST surface
86
+ // (plan 167). Public-only for the same reason as `.x402`: an internal
87
+ // function is server-to-server and never reachable over HTTP, so there is
88
+ // nothing to expose. Default-closed — omitting the modifier keeps the
89
+ // procedure RPC-only.
90
+ ...visibility ? {} : { expose: (config) => makeBuilder(kind, { ...state, expose: config }, visibility) },
83
91
  // `.x402({ price })` marks a public procedure as paid. It's public-only:
84
92
  // internal functions are server-to-server (cron/scheduler/`ctx.run*`) and
85
93
  // never reachable via a client RPC, so there's nothing to charge. Omitting
@@ -1,5 +1,5 @@
1
1
  import { LunoraError } from './LunoraError-WbxmrpxR.mjs';
2
- import { bindTableFacade, bindOrm } from './bindOrm-Bfgl7f-Q.mjs';
2
+ import { bindTableFacade, bindOrm } from './bindOrm-CaY7Wq9Z.mjs';
3
3
 
4
4
  const permissionName = (permission) => typeof permission === "string" ? permission : permission.name;
5
5
  const indexRolePermissions = (roles) => {
@@ -119,7 +119,10 @@ const wrapDatabase = (base, perTable, context) => {
119
119
  withSearchIndex: (indexName, search) => {
120
120
  assertIndexFieldsAllowed(search, columns, tableName, "withSearchIndex");
121
121
  return wrapReader(reader.withSearchIndex(indexName, search), columns, tableName);
122
- }
122
+ },
123
+ // A geo query's builder (`.near`/`.within`) exposes no column name, so
124
+ // there's no masked-column value oracle to guard — just mask the output.
125
+ withGeoIndex: (indexName, build) => wrapReader(reader.withGeoIndex(indexName, build), columns, tableName)
123
126
  };
124
127
  };
125
128
  const locate = async (id, expectedTable) => {
@@ -1,5 +1,5 @@
1
1
  import { LunoraError } from './LunoraError-WbxmrpxR.mjs';
2
- import { bindTableFacade, bindOrm } from './bindOrm-Bfgl7f-Q.mjs';
2
+ import { bindTableFacade, bindOrm } from './bindOrm-CaY7Wq9Z.mjs';
3
3
  import { t as tagRlsMiddleware } from './policy-tag-DvpVH2tv.mjs';
4
4
 
5
5
  const DEFAULT_BATCH_LIMIT = 500;
@@ -1,4 +1,4 @@
1
- import { indexRolePermissions, computeReadBaseWhere, matchesWhere, evaluateWrite, permissionName } from '../packem_shared/rls-B_ZWgslr.mjs';
1
+ import { indexRolePermissions, computeReadBaseWhere, matchesWhere, evaluateWrite, permissionName } from '../packem_shared/rls-BaDQf7MG.mjs';
2
2
 
3
3
  const expectPolicy = (policies, options = {}) => {
4
4
  const rolePermissions = indexRolePermissions(options.roles);
package/dist/types.d.mts CHANGED
@@ -117,6 +117,33 @@ interface SearchIndexDefinition {
117
117
  filterFields?: ReadonlyArray<string>;
118
118
  name: string;
119
119
  }
120
+ /**
121
+ * A geospatial index declared via `.geoIndex(name, { field })`. The runtime
122
+ * maintains a geohash companion table over the `v.geoPoint()` column `field` so
123
+ * `withGeoIndex(name, q => q.near(point, radius) | q.within(bbox))` resolves a
124
+ * proximity / bounding-box read as a geohash-prefix range scan plus a Haversine
125
+ * refine/sort on the candidate rows.
126
+ *
127
+ * - `field` — the `v.geoPoint()` column whose lat/lng feed the geohash.
128
+ * - `precision` — geohash character length on the companion (default 9, ~4.8 m cells); higher precision narrows each cell.
129
+ */
130
+ interface GeoIndexDefinition {
131
+ field: string;
132
+ name: string;
133
+ precision?: number;
134
+ }
135
+ /**
136
+ * Declarative table-level TTL declared via `.ttl(field, { after? })`. A DO
137
+ * alarm-driven sweep deletes (or, when the table also `.softDelete()`s,
138
+ * soft-deletes) rows whose expiry timestamp has passed.
139
+ *
140
+ * - `field` — an epoch-millisecond column. Without `after`, its value is the absolute expiry instant; with `after`, `field` is a base timestamp and the row expires `after` milliseconds later (`field + after`).
141
+ * - `after` — optional millisecond offset added to `field` to derive the expiry.
142
+ */
143
+ interface TtlDefinition {
144
+ after?: number;
145
+ field: string;
146
+ }
120
147
  /** Reducer applied by an aggregate index. */
121
148
  type AggregateOp = "avg" | "count" | "max" | "min" | "sum";
122
149
  /**
@@ -230,6 +257,14 @@ interface TableDefinition<Shape extends Record<string, Validator> = Record<strin
230
257
  * loop rather than user mutations. Implies `isExternallyManaged`.
231
258
  */
232
259
  externalSource?: ExternalSourceDefinition;
260
+ /**
261
+ * Geospatial indexes declared via `.geoIndex(name, { field })`. The runtime
262
+ * maintains a geohash companion over the named `v.geoPoint()` column so
263
+ * `withGeoIndex(name, q => q.near(point, radius) | q.within(bbox))` resolves
264
+ * a proximity/bounding-box read as a geohash-prefix range scan plus a
265
+ * Haversine refine/sort. Empty unless `.geoIndex()` was called.
266
+ */
267
+ geoIndexes: ReadonlyArray<GeoIndexDefinition>;
233
268
  indexes: ReadonlyArray<IndexDefinition>;
234
269
  /**
235
270
  * `true` when `.externallyManaged()` was called — the table's rows are
@@ -285,6 +320,15 @@ interface TableDefinition<Shape extends Record<string, Validator> = Record<strin
285
320
  * field — same reasoning as {@link TableDefinition.relationMap}.
286
321
  */
287
322
  triggerMap: Record<string, TriggerDefinition>;
323
+ /**
324
+ * Set by `.ttl(field, { after })` — the declarative auto-expiry policy. A DO
325
+ * alarm-driven sweep deletes rows whose expiry timestamp has passed (or
326
+ * soft-deletes them when the table also `.softDelete()`s). Named `ttlPolicy`
327
+ * (a data field) rather than colliding with the fluent `.ttl()` builder
328
+ * method — same convention as `shardBy()`/`shardMode`. Absent ⇒ rows never
329
+ * auto-expire.
330
+ */
331
+ ttlPolicy?: TtlDefinition;
288
332
  vectorIndexes: ReadonlyArray<TableVectorIndex>;
289
333
  }
290
334
  /**
@@ -339,8 +383,26 @@ interface X402ProcedureConfig {
339
383
  */
340
384
  readonly price: number | string;
341
385
  }
386
+ /**
387
+ * Opt-in public-surface tag attached by the `.expose({ rest: true })` builder
388
+ * modifier (plan 167). Marks a procedure as deliberately published over the
389
+ * public REST surface: the runtime mints a `/_lunora/rest/&lt;namespace>/&lt;fn>` route
390
+ * that dispatches THROUGH the procedure (so `ctx.auth` / RLS / validators are
391
+ * enforced), and the generated OpenAPI describes it. Everything is default-closed
392
+ * — a procedure without this tag is unreachable over REST.
393
+ */
394
+ interface ExposeConfig {
395
+ /** Publish this procedure over the public REST surface. */
396
+ readonly rest?: boolean;
397
+ }
342
398
  interface RegisteredFunction<A extends ArgsValidator, R, Kind extends FunctionKind> {
343
399
  readonly args: A;
400
+ /**
401
+ * Set by the `.expose({ rest: true })` builder modifier. Marks the procedure
402
+ * as published on the public REST surface (plan 167). Absent on procedures that
403
+ * are reachable only via typed RPC (the default).
404
+ */
405
+ readonly expose?: ExposeConfig;
344
406
  readonly handler: (context: unknown, args: InferArgs<A>) => Promise<R> | R;
345
407
  readonly kind: Kind;
346
408
  /**
@@ -544,6 +606,15 @@ interface TableReader<Row = Record<string, unknown>> {
544
606
  * and throws when more than one row matches. Mirrors Convex's `.unique()`.
545
607
  */
546
608
  unique: () => Promise<Row | null>;
609
+ /**
610
+ * Restrict the query to a declared `.geoIndex()`. The builder's
611
+ * `.near(point, radiusMeters)` returns rows within `radiusMeters` of `point`,
612
+ * ordered nearest-first; `.within(bbox)` returns rows inside the
613
+ * latitude/longitude bounding box. Both resolve as a geohash-prefix range
614
+ * scan over the index's companion followed by a Haversine refine. Pair with
615
+ * `.take(n)` to cap results (`.paginate()` is not supported on a geo query).
616
+ */
617
+ withGeoIndex: (indexName: string, build: (q: GeoFilterBuilder) => GeoFilterBuilder) => TableReader<Row>;
547
618
  withIndex: (indexName: string, range?: (q: IndexRangeBuilder) => IndexRangeBuilder) => TableReader<Row>;
548
619
  /**
549
620
  * Restrict the query to a declared `.searchIndex()`. The builder's
@@ -568,6 +639,30 @@ interface SearchFilterBuilder {
568
639
  /** Full-text match `query` against the index's searchable `field`. Call exactly once. */
569
640
  search: (field: string, query: string) => SearchFilterBuilder;
570
641
  }
642
+ /** A latitude/longitude point (WGS84 decimal degrees) accepted by geo queries. */
643
+ interface GeoPointInput {
644
+ lat: number;
645
+ lng: number;
646
+ }
647
+ /**
648
+ * An axis-aligned latitude/longitude bounding box: `sw` is the south-west
649
+ * (min lat, min lng) corner, `ne` the north-east (max lat, max lng) corner.
650
+ */
651
+ interface GeoBoundingBox {
652
+ ne: GeoPointInput;
653
+ sw: GeoPointInput;
654
+ }
655
+ /**
656
+ * Builder passed to {@link TableReader.withGeoIndex}. Call exactly one of
657
+ * `.near(...)` / `.within(...)` — the two are mutually exclusive proximity vs
658
+ * bounding-box modes.
659
+ */
660
+ interface GeoFilterBuilder {
661
+ /** Rows within `radiusMeters` of `point`, resolved nearest-first. Call exactly once. */
662
+ near: (point: GeoPointInput, radiusMeters: number) => GeoFilterBuilder;
663
+ /** Rows whose point falls inside the bounding `box`. Call exactly once. */
664
+ within: (box: GeoBoundingBox) => GeoFilterBuilder;
665
+ }
571
666
  /**
572
667
  * Options shared by the batch-write methods (`insertMany`/`deleteMany`/
573
668
  * `patchMany`) — a per-call payload cap. The default cap (500) rejects an
@@ -1223,6 +1318,21 @@ interface LunoraLogger {
1223
1318
  */
1224
1319
  readonly with: (fields: LogFields) => LunoraLogger;
1225
1320
  }
1321
+ /**
1322
+ * Handle the enclosing `ctx.trace` span hands its body, so the body can attach
1323
+ * attributes only known *after* it resolves (an AI call's token usage / dollar
1324
+ * cost, a downstream status, a computed count). Declared structurally here to
1325
+ * mirror `shared/span-event.ts`'s `SpanHandle` and `@lunora/do`'s implementation;
1326
+ * a cross-package assignability guard in `@lunora/testing` fails the build if the
1327
+ * three drift apart. Start attributes are snapshotted before the body runs;
1328
+ * handle writes are merged over them at record time, post-hoc winning on a clash.
1329
+ */
1330
+ interface SpanHandle {
1331
+ /** Set one attribute on the enclosing span (merged at record time; post-hoc wins on key clash). */
1332
+ setAttribute: (key: string, value: LogFields[string]) => void;
1333
+ /** Merge attributes onto the enclosing span (post-hoc wins on key clash). */
1334
+ setAttributes: (fields: LogFields) => void;
1335
+ }
1226
1336
  /**
1227
1337
  * Span factory on every function `ctx`. Wraps a sub-operation so it becomes its
1228
1338
  * own **span** nested under the dispatch's RPC span, giving a trace real shape:
@@ -1256,15 +1366,26 @@ interface LunoraLogger {
1256
1366
  * unchanged. A throw is recorded as an error span and then **re-thrown** — this
1257
1367
  * is instrumentation, never flow control. Recording is best-effort: a failing
1258
1368
  * sink can't turn a working handler into a broken one.
1369
+ *
1370
+ * **Post-hoc attributes.** The body also receives a {@link SpanHandle} as its
1371
+ * second argument. The `attributes` passed here are stamped at span start (and
1372
+ * snapshotted, so a later mutation can't rewrite them); anything the body sets
1373
+ * through the handle — `span.setAttribute(k, v)` / `span.setAttributes({…})` — is
1374
+ * merged over that snapshot when the span is recorded, so a value known only once
1375
+ * the body has resolved (an AI call's token usage / dollar cost, a computed
1376
+ * count) still lands on the span. Post-hoc wins on a key clash. The handle is a
1377
+ * trailing parameter, so every existing `(trace) => …` body keeps working
1378
+ * unchanged.
1259
1379
  * @param name Span name, e.g. `"stripe.charge"`. Prefer a low-cardinality name
1260
1380
  * and put the varying part in `attributes` — a name built from an id makes every
1261
1381
  * span its own group in a collector.
1262
1382
  * @param fn The body to time, receiving a tracer bound to this span for any
1263
- * nested spans. May be sync or async; the result is awaited.
1264
- * @param attributes Structured attributes to stamp on the span, normalized like
1265
- * a log line's `fields`.
1383
+ * nested spans and the enclosing span's {@link SpanHandle} for post-hoc
1384
+ * attributes. May be sync or async; the result is awaited.
1385
+ * @param attributes Structured attributes to stamp on the span at start,
1386
+ * normalized like a log line's `fields`.
1266
1387
  */
1267
- type LunoraTracer = <T>(name: string, function_: (trace: LunoraTracer) => Promise<T> | T, attributes?: LogFields) => Promise<T>;
1388
+ type LunoraTracer = <T>(name: string, function_: (trace: LunoraTracer, span: SpanHandle) => Promise<T> | T, attributes?: LogFields) => Promise<T>;
1268
1389
  /**
1269
1390
  * Application metrics on every function `ctx` — the third signal alongside
1270
1391
  * `ctx.log` and `ctx.trace`. Each call records one measurement that flows to an
@@ -1465,4 +1586,4 @@ interface ActionCtx {
1465
1586
  */
1466
1587
  type AnyApi = Record<string, Record<string, RegisteredFunction<ArgsValidator, unknown, FunctionKind>>>;
1467
1588
  declare const anyApi: AnyApi;
1468
- export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type DurableObjectJurisdiction, type ExternalSourceCursor, type ExternalSourceDefinition, type ExternalSourceMode, type ExternalSourceRefresh, type FunctionKind, type FunctionVisibility, type GlobalBackend, type IndexDefinition, type IndexRangeBuilder, type InferArgs, type LifecycleEvent, type LifecycleEventKind, type LogFields, type LunoraLogMethod, type LunoraLogger, type LunoraMetrics, type LunoraTracer, 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, type X402ProcedureConfig, anyApi };
1589
+ export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type DurableObjectJurisdiction, type ExposeConfig, type ExternalSourceCursor, type ExternalSourceDefinition, type ExternalSourceMode, type ExternalSourceRefresh, type FunctionKind, type FunctionVisibility, type GeoBoundingBox, type GeoFilterBuilder, type GeoIndexDefinition, type GeoPointInput, type GlobalBackend, type IndexDefinition, type IndexRangeBuilder, type InferArgs, type LifecycleEvent, type LifecycleEventKind, type LogFields, type LunoraLogMethod, type LunoraLogger, type LunoraMetrics, type LunoraTracer, 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 SpanHandle, 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 TtlDefinition, 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, type X402ProcedureConfig, anyApi };
package/dist/types.d.ts CHANGED
@@ -117,6 +117,33 @@ interface SearchIndexDefinition {
117
117
  filterFields?: ReadonlyArray<string>;
118
118
  name: string;
119
119
  }
120
+ /**
121
+ * A geospatial index declared via `.geoIndex(name, { field })`. The runtime
122
+ * maintains a geohash companion table over the `v.geoPoint()` column `field` so
123
+ * `withGeoIndex(name, q => q.near(point, radius) | q.within(bbox))` resolves a
124
+ * proximity / bounding-box read as a geohash-prefix range scan plus a Haversine
125
+ * refine/sort on the candidate rows.
126
+ *
127
+ * - `field` — the `v.geoPoint()` column whose lat/lng feed the geohash.
128
+ * - `precision` — geohash character length on the companion (default 9, ~4.8 m cells); higher precision narrows each cell.
129
+ */
130
+ interface GeoIndexDefinition {
131
+ field: string;
132
+ name: string;
133
+ precision?: number;
134
+ }
135
+ /**
136
+ * Declarative table-level TTL declared via `.ttl(field, { after? })`. A DO
137
+ * alarm-driven sweep deletes (or, when the table also `.softDelete()`s,
138
+ * soft-deletes) rows whose expiry timestamp has passed.
139
+ *
140
+ * - `field` — an epoch-millisecond column. Without `after`, its value is the absolute expiry instant; with `after`, `field` is a base timestamp and the row expires `after` milliseconds later (`field + after`).
141
+ * - `after` — optional millisecond offset added to `field` to derive the expiry.
142
+ */
143
+ interface TtlDefinition {
144
+ after?: number;
145
+ field: string;
146
+ }
120
147
  /** Reducer applied by an aggregate index. */
121
148
  type AggregateOp = "avg" | "count" | "max" | "min" | "sum";
122
149
  /**
@@ -230,6 +257,14 @@ interface TableDefinition<Shape extends Record<string, Validator> = Record<strin
230
257
  * loop rather than user mutations. Implies `isExternallyManaged`.
231
258
  */
232
259
  externalSource?: ExternalSourceDefinition;
260
+ /**
261
+ * Geospatial indexes declared via `.geoIndex(name, { field })`. The runtime
262
+ * maintains a geohash companion over the named `v.geoPoint()` column so
263
+ * `withGeoIndex(name, q => q.near(point, radius) | q.within(bbox))` resolves
264
+ * a proximity/bounding-box read as a geohash-prefix range scan plus a
265
+ * Haversine refine/sort. Empty unless `.geoIndex()` was called.
266
+ */
267
+ geoIndexes: ReadonlyArray<GeoIndexDefinition>;
233
268
  indexes: ReadonlyArray<IndexDefinition>;
234
269
  /**
235
270
  * `true` when `.externallyManaged()` was called — the table's rows are
@@ -285,6 +320,15 @@ interface TableDefinition<Shape extends Record<string, Validator> = Record<strin
285
320
  * field — same reasoning as {@link TableDefinition.relationMap}.
286
321
  */
287
322
  triggerMap: Record<string, TriggerDefinition>;
323
+ /**
324
+ * Set by `.ttl(field, { after })` — the declarative auto-expiry policy. A DO
325
+ * alarm-driven sweep deletes rows whose expiry timestamp has passed (or
326
+ * soft-deletes them when the table also `.softDelete()`s). Named `ttlPolicy`
327
+ * (a data field) rather than colliding with the fluent `.ttl()` builder
328
+ * method — same convention as `shardBy()`/`shardMode`. Absent ⇒ rows never
329
+ * auto-expire.
330
+ */
331
+ ttlPolicy?: TtlDefinition;
288
332
  vectorIndexes: ReadonlyArray<TableVectorIndex>;
289
333
  }
290
334
  /**
@@ -339,8 +383,26 @@ interface X402ProcedureConfig {
339
383
  */
340
384
  readonly price: number | string;
341
385
  }
386
+ /**
387
+ * Opt-in public-surface tag attached by the `.expose({ rest: true })` builder
388
+ * modifier (plan 167). Marks a procedure as deliberately published over the
389
+ * public REST surface: the runtime mints a `/_lunora/rest/&lt;namespace>/&lt;fn>` route
390
+ * that dispatches THROUGH the procedure (so `ctx.auth` / RLS / validators are
391
+ * enforced), and the generated OpenAPI describes it. Everything is default-closed
392
+ * — a procedure without this tag is unreachable over REST.
393
+ */
394
+ interface ExposeConfig {
395
+ /** Publish this procedure over the public REST surface. */
396
+ readonly rest?: boolean;
397
+ }
342
398
  interface RegisteredFunction<A extends ArgsValidator, R, Kind extends FunctionKind> {
343
399
  readonly args: A;
400
+ /**
401
+ * Set by the `.expose({ rest: true })` builder modifier. Marks the procedure
402
+ * as published on the public REST surface (plan 167). Absent on procedures that
403
+ * are reachable only via typed RPC (the default).
404
+ */
405
+ readonly expose?: ExposeConfig;
344
406
  readonly handler: (context: unknown, args: InferArgs<A>) => Promise<R> | R;
345
407
  readonly kind: Kind;
346
408
  /**
@@ -544,6 +606,15 @@ interface TableReader<Row = Record<string, unknown>> {
544
606
  * and throws when more than one row matches. Mirrors Convex's `.unique()`.
545
607
  */
546
608
  unique: () => Promise<Row | null>;
609
+ /**
610
+ * Restrict the query to a declared `.geoIndex()`. The builder's
611
+ * `.near(point, radiusMeters)` returns rows within `radiusMeters` of `point`,
612
+ * ordered nearest-first; `.within(bbox)` returns rows inside the
613
+ * latitude/longitude bounding box. Both resolve as a geohash-prefix range
614
+ * scan over the index's companion followed by a Haversine refine. Pair with
615
+ * `.take(n)` to cap results (`.paginate()` is not supported on a geo query).
616
+ */
617
+ withGeoIndex: (indexName: string, build: (q: GeoFilterBuilder) => GeoFilterBuilder) => TableReader<Row>;
547
618
  withIndex: (indexName: string, range?: (q: IndexRangeBuilder) => IndexRangeBuilder) => TableReader<Row>;
548
619
  /**
549
620
  * Restrict the query to a declared `.searchIndex()`. The builder's
@@ -568,6 +639,30 @@ interface SearchFilterBuilder {
568
639
  /** Full-text match `query` against the index's searchable `field`. Call exactly once. */
569
640
  search: (field: string, query: string) => SearchFilterBuilder;
570
641
  }
642
+ /** A latitude/longitude point (WGS84 decimal degrees) accepted by geo queries. */
643
+ interface GeoPointInput {
644
+ lat: number;
645
+ lng: number;
646
+ }
647
+ /**
648
+ * An axis-aligned latitude/longitude bounding box: `sw` is the south-west
649
+ * (min lat, min lng) corner, `ne` the north-east (max lat, max lng) corner.
650
+ */
651
+ interface GeoBoundingBox {
652
+ ne: GeoPointInput;
653
+ sw: GeoPointInput;
654
+ }
655
+ /**
656
+ * Builder passed to {@link TableReader.withGeoIndex}. Call exactly one of
657
+ * `.near(...)` / `.within(...)` — the two are mutually exclusive proximity vs
658
+ * bounding-box modes.
659
+ */
660
+ interface GeoFilterBuilder {
661
+ /** Rows within `radiusMeters` of `point`, resolved nearest-first. Call exactly once. */
662
+ near: (point: GeoPointInput, radiusMeters: number) => GeoFilterBuilder;
663
+ /** Rows whose point falls inside the bounding `box`. Call exactly once. */
664
+ within: (box: GeoBoundingBox) => GeoFilterBuilder;
665
+ }
571
666
  /**
572
667
  * Options shared by the batch-write methods (`insertMany`/`deleteMany`/
573
668
  * `patchMany`) — a per-call payload cap. The default cap (500) rejects an
@@ -1223,6 +1318,21 @@ interface LunoraLogger {
1223
1318
  */
1224
1319
  readonly with: (fields: LogFields) => LunoraLogger;
1225
1320
  }
1321
+ /**
1322
+ * Handle the enclosing `ctx.trace` span hands its body, so the body can attach
1323
+ * attributes only known *after* it resolves (an AI call's token usage / dollar
1324
+ * cost, a downstream status, a computed count). Declared structurally here to
1325
+ * mirror `shared/span-event.ts`'s `SpanHandle` and `@lunora/do`'s implementation;
1326
+ * a cross-package assignability guard in `@lunora/testing` fails the build if the
1327
+ * three drift apart. Start attributes are snapshotted before the body runs;
1328
+ * handle writes are merged over them at record time, post-hoc winning on a clash.
1329
+ */
1330
+ interface SpanHandle {
1331
+ /** Set one attribute on the enclosing span (merged at record time; post-hoc wins on key clash). */
1332
+ setAttribute: (key: string, value: LogFields[string]) => void;
1333
+ /** Merge attributes onto the enclosing span (post-hoc wins on key clash). */
1334
+ setAttributes: (fields: LogFields) => void;
1335
+ }
1226
1336
  /**
1227
1337
  * Span factory on every function `ctx`. Wraps a sub-operation so it becomes its
1228
1338
  * own **span** nested under the dispatch's RPC span, giving a trace real shape:
@@ -1256,15 +1366,26 @@ interface LunoraLogger {
1256
1366
  * unchanged. A throw is recorded as an error span and then **re-thrown** — this
1257
1367
  * is instrumentation, never flow control. Recording is best-effort: a failing
1258
1368
  * sink can't turn a working handler into a broken one.
1369
+ *
1370
+ * **Post-hoc attributes.** The body also receives a {@link SpanHandle} as its
1371
+ * second argument. The `attributes` passed here are stamped at span start (and
1372
+ * snapshotted, so a later mutation can't rewrite them); anything the body sets
1373
+ * through the handle — `span.setAttribute(k, v)` / `span.setAttributes({…})` — is
1374
+ * merged over that snapshot when the span is recorded, so a value known only once
1375
+ * the body has resolved (an AI call's token usage / dollar cost, a computed
1376
+ * count) still lands on the span. Post-hoc wins on a key clash. The handle is a
1377
+ * trailing parameter, so every existing `(trace) => …` body keeps working
1378
+ * unchanged.
1259
1379
  * @param name Span name, e.g. `"stripe.charge"`. Prefer a low-cardinality name
1260
1380
  * and put the varying part in `attributes` — a name built from an id makes every
1261
1381
  * span its own group in a collector.
1262
1382
  * @param fn The body to time, receiving a tracer bound to this span for any
1263
- * nested spans. May be sync or async; the result is awaited.
1264
- * @param attributes Structured attributes to stamp on the span, normalized like
1265
- * a log line's `fields`.
1383
+ * nested spans and the enclosing span's {@link SpanHandle} for post-hoc
1384
+ * attributes. May be sync or async; the result is awaited.
1385
+ * @param attributes Structured attributes to stamp on the span at start,
1386
+ * normalized like a log line's `fields`.
1266
1387
  */
1267
- type LunoraTracer = <T>(name: string, function_: (trace: LunoraTracer) => Promise<T> | T, attributes?: LogFields) => Promise<T>;
1388
+ type LunoraTracer = <T>(name: string, function_: (trace: LunoraTracer, span: SpanHandle) => Promise<T> | T, attributes?: LogFields) => Promise<T>;
1268
1389
  /**
1269
1390
  * Application metrics on every function `ctx` — the third signal alongside
1270
1391
  * `ctx.log` and `ctx.trace`. Each call records one measurement that flows to an
@@ -1465,4 +1586,4 @@ interface ActionCtx {
1465
1586
  */
1466
1587
  type AnyApi = Record<string, Record<string, RegisteredFunction<ArgsValidator, unknown, FunctionKind>>>;
1467
1588
  declare const anyApi: AnyApi;
1468
- export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type DurableObjectJurisdiction, type ExternalSourceCursor, type ExternalSourceDefinition, type ExternalSourceMode, type ExternalSourceRefresh, type FunctionKind, type FunctionVisibility, type GlobalBackend, type IndexDefinition, type IndexRangeBuilder, type InferArgs, type LifecycleEvent, type LifecycleEventKind, type LogFields, type LunoraLogMethod, type LunoraLogger, type LunoraMetrics, type LunoraTracer, 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, type X402ProcedureConfig, anyApi };
1589
+ export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type DurableObjectJurisdiction, type ExposeConfig, type ExternalSourceCursor, type ExternalSourceDefinition, type ExternalSourceMode, type ExternalSourceRefresh, type FunctionKind, type FunctionVisibility, type GeoBoundingBox, type GeoFilterBuilder, type GeoIndexDefinition, type GeoPointInput, type GlobalBackend, type IndexDefinition, type IndexRangeBuilder, type InferArgs, type LifecycleEvent, type LifecycleEventKind, type LogFields, type LunoraLogMethod, type LunoraLogger, type LunoraMetrics, type LunoraTracer, 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 SpanHandle, 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 TtlDefinition, 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, type X402ProcedureConfig, anyApi };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/server",
3
- "version": "1.0.0-alpha.29",
3
+ "version": "1.0.0-alpha.30",
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.6",
65
+ "@lunora/errors": "1.0.0-alpha.7",
66
66
  "@lunora/scheduler": "1.0.0-alpha.11",
67
- "@lunora/values": "1.0.0-alpha.9",
67
+ "@lunora/values": "1.0.0-alpha.10",
68
68
  "drizzle-orm": "^0.45.2",
69
69
  "hono": "^4.12.30"
70
70
  },