@lunora/do 1.0.0-alpha.36 → 1.0.0-alpha.38
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/dist/index.d.mts +126 -3
- package/dist/index.d.ts +126 -3
- package/dist/index.mjs +8 -6
- package/dist/packem_shared/GEO_DEFAULT_PRECISION-BWnsNmpP.mjs +114 -0
- package/dist/packem_shared/{NotUniqueError-Ca21uDuU.mjs → NotUniqueError-DbtlWwcG.mjs} +168 -33
- package/dist/packem_shared/{ROOT_DO_SIZE_WARN_BYTES-CBlw_ir3.mjs → ROOT_DO_SIZE_WARN_BYTES-FAG0bOO5.mjs} +70 -7
- package/dist/packem_shared/{backfillAggregateIndexes-DDoT-UUI.mjs → backfillAggregateIndexes-BGTwynwh.mjs} +1 -1
- package/dist/packem_shared/{ctx-db-shapes-Cz9dHyh1.mjs → ctx-db-shapes-DTeFiHYS.mjs} +1 -1
- package/dist/packem_shared/{do-sql-BCHCWtrD.mjs → do-sql-CGAgiQUz.mjs} +2 -1
- package/dist/packem_shared/{isSoftDeleted-YLKR6JYw.mjs → isSoftDeleted-CFJmhjFP.mjs} +1 -1
- package/dist/packem_shared/{materializeExternalRows-DlQWMlw_.mjs → materializeExternalRows-BtEGs1Fv.mjs} +1 -1
- package/dist/packem_shared/{runShardMigrations-DFzx6Qld.mjs → runShardMigrations-BVax6rYu.mjs} +16 -1
- package/dist/packem_shared/selectExpiredIds-C5W29Upb.mjs +18 -0
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -1312,6 +1312,13 @@ interface SchemaLike {
|
|
|
1312
1312
|
}
|
|
1313
1313
|
interface TableDefinitionLike {
|
|
1314
1314
|
readonly aggregateIndexes?: ReadonlyArray<AggregateIndexDefinitionLike>;
|
|
1315
|
+
/**
|
|
1316
|
+
* Mirror of `@lunora/server`'s `TableDefinition.geoIndexes` (set by
|
|
1317
|
+
* `.geoIndex()`). Each declares a geohash companion over a `v.geoPoint()`
|
|
1318
|
+
* column so `withGeoIndex(name, q => q.near(...) | q.within(...))` resolves
|
|
1319
|
+
* proximity / bounding-box reads. Empty/absent ⇒ the table has no geo index.
|
|
1320
|
+
*/
|
|
1321
|
+
readonly geoIndexes?: ReadonlyArray<GeoIndexDefinitionLike>;
|
|
1315
1322
|
readonly indexes: ReadonlyArray<IndexDefinitionLike>;
|
|
1316
1323
|
/**
|
|
1317
1324
|
* `true` when `.public()` opted this table OUT of secure-by-default RLS
|
|
@@ -1339,6 +1346,15 @@ interface TableDefinitionLike {
|
|
|
1339
1346
|
field: string;
|
|
1340
1347
|
};
|
|
1341
1348
|
readonly triggerMap?: Record<string, TriggerDefinitionLike>;
|
|
1349
|
+
/**
|
|
1350
|
+
* Mirror of `@lunora/server`'s `TableDefinition.ttlPolicy` (set by `.ttl()`).
|
|
1351
|
+
* Drives the DO alarm-driven expiry sweep — see `ttl-sweep.ts`. Absent ⇒ rows
|
|
1352
|
+
* never auto-expire.
|
|
1353
|
+
*/
|
|
1354
|
+
readonly ttlPolicy?: {
|
|
1355
|
+
after?: number;
|
|
1356
|
+
field: string;
|
|
1357
|
+
};
|
|
1342
1358
|
}
|
|
1343
1359
|
interface IndexDefinitionLike {
|
|
1344
1360
|
readonly fields: ReadonlyArray<string>;
|
|
@@ -1350,6 +1366,12 @@ interface SearchIndexDefinitionLike {
|
|
|
1350
1366
|
readonly filterFields?: ReadonlyArray<string>;
|
|
1351
1367
|
readonly name: string;
|
|
1352
1368
|
}
|
|
1369
|
+
/** Mirror of `@lunora/server`'s `GeoIndexDefinition` — a geohash companion over a `v.geoPoint()` column. */
|
|
1370
|
+
interface GeoIndexDefinitionLike {
|
|
1371
|
+
readonly field: string;
|
|
1372
|
+
readonly name: string;
|
|
1373
|
+
readonly precision?: number;
|
|
1374
|
+
}
|
|
1353
1375
|
/**
|
|
1354
1376
|
* Column constraints/defaults the write layer honors, mirrored structurally
|
|
1355
1377
|
* from `@lunora/values`' `ColumnMeta` (kept local so this package doesn't take
|
|
@@ -1423,7 +1445,7 @@ type ReadHook = (table: string, idOrScan?: string) => void;
|
|
|
1423
1445
|
* No-op by default; called at most once per read (not per row), so it adds no
|
|
1424
1446
|
* meaningful hot-path cost.
|
|
1425
1447
|
*/
|
|
1426
|
-
type IndexUseHook = (table: string, indexName: string, kind: "index" | "rank" | "search") => void;
|
|
1448
|
+
type IndexUseHook = (table: string, indexName: string, kind: "geo" | "index" | "rank" | "search") => void;
|
|
1427
1449
|
/** Pluggable wall clock — defaults to `Date.now`. */
|
|
1428
1450
|
type Clock = () => number;
|
|
1429
1451
|
/** Pluggable ID minter — defaults to `crypto.randomUUID()`. */
|
|
@@ -1566,6 +1588,22 @@ interface SearchFilterBuilderLike {
|
|
|
1566
1588
|
eq: (field: string, value: unknown) => SearchFilterBuilderLike;
|
|
1567
1589
|
search: (field: string, query: string) => SearchFilterBuilderLike;
|
|
1568
1590
|
}
|
|
1591
|
+
interface GeoFilterBuilderLike {
|
|
1592
|
+
near: (point: {
|
|
1593
|
+
lat: number;
|
|
1594
|
+
lng: number;
|
|
1595
|
+
}, radiusMeters: number) => GeoFilterBuilderLike;
|
|
1596
|
+
within: (box: {
|
|
1597
|
+
ne: {
|
|
1598
|
+
lat: number;
|
|
1599
|
+
lng: number;
|
|
1600
|
+
};
|
|
1601
|
+
sw: {
|
|
1602
|
+
lat: number;
|
|
1603
|
+
lng: number;
|
|
1604
|
+
};
|
|
1605
|
+
}) => GeoFilterBuilderLike;
|
|
1606
|
+
}
|
|
1569
1607
|
/** Options accepted by {@link TableReaderLike.paginate} — Convex-compatible. */
|
|
1570
1608
|
interface PaginationOptions {
|
|
1571
1609
|
/** Opaque cursor from a prior page's `continueCursor`; `null`/omitted starts at the first page. */
|
|
@@ -1603,6 +1641,7 @@ interface TableReaderLike {
|
|
|
1603
1641
|
* more than one matches. Mirrors Convex's `.unique()`.
|
|
1604
1642
|
*/
|
|
1605
1643
|
unique: () => Promise<Record<string, unknown> | null>;
|
|
1644
|
+
withGeoIndex: (indexName: string, build: (q: GeoFilterBuilderLike) => GeoFilterBuilderLike) => TableReaderLike;
|
|
1606
1645
|
withIndex: (indexName: string, range?: (q: IndexRangeBuilderLike) => IndexRangeBuilderLike) => TableReaderLike;
|
|
1607
1646
|
withSearchIndex: (indexName: string, search: (q: SearchFilterBuilderLike) => SearchFilterBuilderLike) => TableReaderLike;
|
|
1608
1647
|
}
|
|
@@ -2899,7 +2938,7 @@ interface FunctionCallStat {
|
|
|
2899
2938
|
interface TableIndexInfo {
|
|
2900
2939
|
fields: string[];
|
|
2901
2940
|
name: string;
|
|
2902
|
-
type: "index" | "rank" | "search" | "vector";
|
|
2941
|
+
type: "geo" | "index" | "rank" | "search" | "vector";
|
|
2903
2942
|
unique?: boolean;
|
|
2904
2943
|
}
|
|
2905
2944
|
/** Payload of a `__lunora_admin__:listTableIndexes` call: every declared index on the table. */
|
|
@@ -3543,6 +3582,39 @@ declare const readFunctionMetricsTotals: (sql: SqlExec) => {
|
|
|
3543
3582
|
errors: number;
|
|
3544
3583
|
requests: number;
|
|
3545
3584
|
};
|
|
3585
|
+
/** Default geohash precision (characters) maintained by a `.geoIndex()` companion — ~4.8 m cells. */
|
|
3586
|
+
declare const GEO_DEFAULT_PRECISION = 9;
|
|
3587
|
+
/** A latitude/longitude point (WGS84 decimal degrees). */
|
|
3588
|
+
interface GeoPoint {
|
|
3589
|
+
lat: number;
|
|
3590
|
+
lng: number;
|
|
3591
|
+
}
|
|
3592
|
+
/** An axis-aligned latitude/longitude bounding box (`sw`/`ne` corners). */
|
|
3593
|
+
interface GeoBoundingBox {
|
|
3594
|
+
ne: GeoPoint;
|
|
3595
|
+
sw: GeoPoint;
|
|
3596
|
+
}
|
|
3597
|
+
/**
|
|
3598
|
+
* Encode `point` to a geohash of `precision` characters. Standard interleaved
|
|
3599
|
+
* lat/lng bisection over the base-32 alphabet.
|
|
3600
|
+
*/
|
|
3601
|
+
declare const encodeGeohash: (point: GeoPoint, precision: number) => string;
|
|
3602
|
+
/** Great-circle distance between two points in metres (Haversine). */
|
|
3603
|
+
declare const haversineMeters: (a: GeoPoint, b: GeoPoint) => number;
|
|
3604
|
+
/**
|
|
3605
|
+
* The center cell plus its eight neighbours at a precision chosen so each cell is
|
|
3606
|
+
* at least `radiusMeters` wide — the geohash prefixes to range-scan for a
|
|
3607
|
+
* proximity query. Deduplicated (near a pole neighbours can collapse).
|
|
3608
|
+
*/
|
|
3609
|
+
declare const coveringGeohashes: (center: GeoPoint, radiusMeters: number) => string[];
|
|
3610
|
+
/** Whether `point` falls inside `box` (inclusive edges). */
|
|
3611
|
+
declare const pointInBoundingBox: (point: GeoPoint, box: GeoBoundingBox) => boolean;
|
|
3612
|
+
/**
|
|
3613
|
+
* Geohash prefixes covering `box`: the covering cells of the circle centered on
|
|
3614
|
+
* the box whose radius reaches the north-east corner, guaranteeing every point
|
|
3615
|
+
* in the box is scanned before the exact `pointInBoundingBox` refine.
|
|
3616
|
+
*/
|
|
3617
|
+
declare const boundingBoxGeohashes: (box: GeoBoundingBox) => string[];
|
|
3546
3618
|
/**
|
|
3547
3619
|
* Severity of a `ctx.log.*` call. The five console method names (`log` is the
|
|
3548
3620
|
* default level, distinct from `info`) plus `trace`/`fatal`, so the logger spans
|
|
@@ -4152,6 +4224,28 @@ declare class SessionDO {
|
|
|
4152
4224
|
private handleGet;
|
|
4153
4225
|
private handleRevoke;
|
|
4154
4226
|
}
|
|
4227
|
+
/** One table's resolved TTL policy, as surfaced to the DO alarm by the generated shard subclass. */
|
|
4228
|
+
interface TtlSweepSpec {
|
|
4229
|
+
/** Millisecond offset added to `field` to derive the expiry (`field + after`); absent ⇒ `field` is the absolute expiry. */
|
|
4230
|
+
after?: number;
|
|
4231
|
+
/** The epoch-millisecond expiry column. */
|
|
4232
|
+
field: string;
|
|
4233
|
+
/** The `.softDelete()` marker column, when the table soft-deletes — expired-but-already-tombstoned rows are skipped. */
|
|
4234
|
+
softDeleteField?: string;
|
|
4235
|
+
/** The table whose expired rows are swept. */
|
|
4236
|
+
table: string;
|
|
4237
|
+
}
|
|
4238
|
+
/**
|
|
4239
|
+
* Select up to `limit` ids of rows in `spec.table` whose TTL expired at `now`
|
|
4240
|
+
* (i.e. `field + (after ?? 0) < now`). `hasMore` is `true` when matches remained
|
|
4241
|
+
* beyond `limit`, so the caller can loop a bounded batch. When `spec.softDeleteField`
|
|
4242
|
+
* is set, rows already soft-deleted (marker non-null) are excluded so the sweep
|
|
4243
|
+
* never re-touches a tombstone.
|
|
4244
|
+
*/
|
|
4245
|
+
declare const selectExpiredIds: (sql: SqlExec, spec: TtlSweepSpec, now: number, limit: number) => {
|
|
4246
|
+
hasMore: boolean;
|
|
4247
|
+
ids: string[];
|
|
4248
|
+
};
|
|
4155
4249
|
/**
|
|
4156
4250
|
* Diff the previously-sent list snapshot (`previousJson`, the memo's
|
|
4157
4251
|
* `lastJson`) against the new query result and produce per-row
|
|
@@ -5631,6 +5725,35 @@ declare abstract class ShardDO {
|
|
|
5631
5725
|
* no-op when the runtime exposes no `setAlarm` (unit harness).
|
|
5632
5726
|
*/
|
|
5633
5727
|
protected scheduleSourcePoll(): Promise<void>;
|
|
5728
|
+
/**
|
|
5729
|
+
* The resolved TTL policies (`.ttl(field, { after })`) for this DO's schema —
|
|
5730
|
+
* one {@link TtlSweepSpec} per table that declares a TTL. The base `ShardDO`
|
|
5731
|
+
* has no schema, so it returns `[]` and the TTL tier stays dormant. The
|
|
5732
|
+
* codegen subclass overrides it to read each table's `ttlPolicy` (+ its
|
|
5733
|
+
* `.softDelete()` marker) off the imported schema.
|
|
5734
|
+
*/
|
|
5735
|
+
protected ttlSweeps(): ReadonlyArray<TtlSweepSpec>;
|
|
5736
|
+
/**
|
|
5737
|
+
* Sweep every `.ttl()` table once: page the rows past their expiry and remove
|
|
5738
|
+
* each THROUGH the schema-aware writer (`deleteRowThroughWriter`) so companions
|
|
5739
|
+
* / CDC / live subscriptions stay correct and a `.softDelete()` table soft-deletes
|
|
5740
|
+
* instead of physically removing the row. Work is bounded per tick
|
|
5741
|
+
* ({@link TTL_SWEEP_BATCH} × {@link TTL_SWEEP_MAX_BATCHES}) so a large backlog
|
|
5742
|
+
* drains across several alarms without stalling the shard.
|
|
5743
|
+
*
|
|
5744
|
+
* Returns the next-due timestamp (a coarse {@link TTL_SWEEP_INTERVAL_MS}
|
|
5745
|
+
* cadence, so freshly-written rows expire within a bounded window) while any
|
|
5746
|
+
* TTL table exists, or `undefined` when there are none — so a DO with no TTL
|
|
5747
|
+
* table never arms this tier.
|
|
5748
|
+
*/
|
|
5749
|
+
protected pollTtlSweeps(): Promise<number | undefined>;
|
|
5750
|
+
/**
|
|
5751
|
+
* Arm the shared poll alarm for the TTL sweep. Mirrors {@link scheduleSourcePoll};
|
|
5752
|
+
* the codegen subclass calls it once on construction when the schema declares a
|
|
5753
|
+
* `.ttl()` table so the sweep loop starts, after which {@link ShardDO.alarm}
|
|
5754
|
+
* re-arms itself. Idempotent; a no-op when the runtime exposes no `setAlarm`.
|
|
5755
|
+
*/
|
|
5756
|
+
protected scheduleTtlSweep(): Promise<void>;
|
|
5634
5757
|
/** This DO's shard key (its DO name), or `__root__` for the single-DO default. The `tenantBy` mapper binds it into the source query. */
|
|
5635
5758
|
protected currentShardKey(): string;
|
|
5636
5759
|
/** Record a contained external-source ingest failure (one sourced table's poll) into the log ring without aborting the others. */
|
|
@@ -7083,4 +7206,4 @@ interface WhereSqlStrategy {
|
|
|
7083
7206
|
* `undefined` when the input imposes no constraint (empty `where`).
|
|
7084
7207
|
*/
|
|
7085
7208
|
declare const compileWhereSql: (where: WhereInput | undefined, strategy: WhereSqlStrategy) => SQL | undefined;
|
|
7086
|
-
export { ADMIN_FUNCTIONS, ADMIN_FUNCTION_PREFIX, AGGREGATE_SQL_FUNCTION, AUTH_METRICS_BUCKETS_TABLE, AUTH_METRICS_BUCKET_MS, AUTH_METRICS_BUCKET_RETENTION, AUTH_METRICS_TABLE, type AdvisoriesResult, type AdvisoryFinding, type AggregateIndexDefinitionLike, type AggregateOp, type AggregateOptions, type AggregateResult, type AggregateTally, type ApplyOnDeleteOptions, type AuditEntry, type AuditLogResult, type AuthMetrics, type AuthMetricsBucket, type BroadcastDelta, CDC_LOG_TABLE, type CacheEntry, type CapturedMailRow, type CdcChange, type Clock, type ColumnMeta, type ColumnMetaLike, ConflictError, type ContextMetrics, type ContextTracer, type CountArgs, CountRlsUnsupportedError, type CtxDbOptions, DATA_MIGRATION_STATE_TABLE, DEFAULT_MAX_RELATION_KEYS, type DataMigrationDocument, type DataMigrationLike, type DataMigrationTransform, type DatabaseWriterLike, type DependencyTracker, type DeployInfo, type ExportRow, type ExportShardAdminArgs, type ExportShardArgs, type ExternalSourceDiffResult, type ExternalSourceLike, FLAGS_FUNCTION_PREFIX, FUNCTION_METRICS_BUCKETS_TABLE, FUNCTION_METRICS_BUCKET_MS, FUNCTION_METRICS_BUCKET_RETENTION, FUNCTION_METRICS_INDEX_TABLE, FUNCTION_METRICS_TABLE, type FacetColumnOptions, type FacetColumnResult, type FacetValue, type FieldOperators, type FlagEvaluation, type FlagsResult, type FunctionCallStat, type FunctionMetricBucket, type FunctionMetricIndexHit, type FunctionStatsResult, type GroupByEntry, type GroupByOptions, type HibernatableWebSocket, type IdGenerator, type ImportError, type ImportShardAdminArgs, type ImportShardArgs, type ImportShardResult, type IncrementalMaterializeResult, type IndexDefinitionLike, type IndexRangeBuilderLike, LogBuffer, type LogEntry, type LogEventInput, type LogLevel, type LogSink, MAIL_RETENTION, MAIL_TABLE, MAX_SQL_ROWS, MIN_ADMIN_TOKEN_LENGTH, MIN_AUTH_SECRET_LENGTH, type MaskColumnMetadata, type MaskPoliciesResult, type MaterializeResult, type MetricsDeps, type MigrationDirection, type MigrationRunResult, type MigrationStatus, type MigrationStatusRow, type MutationDelta, type NestedWith, NotFoundError, NotUniqueError, type OnDeleteActionLike, type OrderByInput, type OrderKey, type PaginationOptions, type PitrBookmarkResult, type PitrRestoreArgs, type PitrRestoreResult, type PitrStorage, type QueryArgs, type QueryPage, type QueueMetadata, type QueuesResult, RANK_TIEBREAK, RELATION_FUNCTION_PREFIX, RLS_UNWRAP_SYMBOL, ROOT_DO_SIZE_WARN_BYTES, ROOT_SHARD_NAME, type RankDirection, type RankIndexDefinitionLike, type RankOptions, type RankPage, type RankPageOptions, type RankPageRow, type RankPageRowKey, type RankResult, type RankSortKeyLike, ReactiveCache, type ReactiveCacheOptions, type ReadHook, type ReadTablePageOptions, type RecordAuthEventInput, type RecordFunctionMetricInput, type RecordMailInput, type RelationDefinitionLike, type RenderedSql, type ResolveRelationPredicatesOptions, type ResolveWithOptions, type RestrictableQueryOptions, type RlsPoliciesResult, type RlsPolicyMetadata, RlsRequiredError, type RlsRoleMetadata, type RpcRequest, type RunDataMigrationOptions, type RunShardApplyCdcArgs, type RunShardApplyCdcResult, type RunShardBulkDeleteArgs, type RunShardBulkDeleteResult, type RunShardExportArgs, type RunShardImportArgs, type RunShardMigrationArgs, type RunShardRankBeforeArgs, type RunShardRankPageArgs, type RunShardWriteArgs, type RunShardWriteResult, type RunTriggersOptions, SCAN_DEP, SESSION_DO_TTL_DEFAULT, SHARD_REGISTRY_DO_NAME, type SchedulableWorkflowReferenceLike, type ScheduledFunctionDoc, type SchedulerLike, type SchemaLike, type SearchFilterBuilderLike, type SecurityAuditResult, type SecurityFinding, type SecurityFindingKind, type SecurityFindingLevel, type SelectMatchingIdsOptions, type ServerDefaultContextLike, SessionDO, type SessionRecord, type SettingEntry, type SettingKind, type SettingsResult, type ShapeSubscriptionQuery, ShardDO, type ShardDOOptions, type ShardDOState, type ShardRankPageResult, ShardRegistryDO, type SocketAttachment, type SortDirection, type SourceClientLike, type SourceCursorLike, type SourceRefresh, type SqlConsoleResult, type SqlCursor, type SqlEngine, type SqlExec, type StorageRuleMetadata, type StorageRulesResult, type StudioFeaturesResult, type SubscriptionEnvelope, type SubscriptionOutcome, type SubscriptionQuery, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemReaderOptions, type SystemReaderSchedulerLike, type SystemReaderStorageLike, type SystemTableName, type TableColumnsResult, type TableDefinitionLike, type TableIndexInfo, type TableIndexesResult, type TableInfo, type TablePage, type TableReaderLike, type TablesColumnsResult, type TelemetrySink, type TraceAnchor, type TracerDeps, type TransactionSqlLike, type TriggerContextLike, type TriggerDefinitionLike, type TriggerEventLike, type TriggerOpLike, type TriggerTimingLike, type ValidatorLike, type WhereInput, type WhereSqlStrategy, type WithInput, type WorkflowMetadata, type WorkflowsResult, type WriteEvent, type WriteHook, aggregateSqlFunction, aggregateTableName, applyCdcChanges, applyOnDelete, applySelect, armRestore, assertFlatPredicate, assertReadonly, assertShapeShardable, assertValidClientId, backfillAggregateIndexes, backfillRankIndexes, buildFtsMatch, buildSecurityAudit, buildSeekWhere, clearCapturedMail, coerceAggregateNumber, compileWhereSql, containsRelationPredicate, createDependencyTracker, createMetrics, createShardCtxDb, createSystemReader, createTracer, decodeCursor, depKey, diffExternalSource, dispatchRootSpan, encodeAggregateKey, encodeCursor, encodePartitionKey, ensureAuthMetricsTables, ensureFunctionMetricsTables, ensureMailTable, exportShardRows, exportShardTable, facetColumn, fanOutScalarCounts, foldAggregateTally, ftsTableName, guardWriter, hasTrigger, importShardRows, isRelationPredicate, isSoftDeleted, isSourceDue, liftSourceId, listTables, matchesRankStaticWhere, matchesStaticWhere, materializeExternalRows, materializeExternalRowsIncremental, mergeWhere, normalizeCountArgument, normalizeIdStructurally, normalizeOrderKeys, parseExportShardArgs, parseImportShardArgs, planAggregateLookup, pullExternalSourceIncrementalTick, pullExternalSourceTick, rankTableName, reactiveCacheKey, readAggregateValue, readAuthMetrics, readBookmark, readCapturedMail, readCdcChanges, readExternalSourceBaseline, readFunctionMetricBuckets, readFunctionMetricIndexHits, readFunctionMetrics, readFunctionMetricsTotals, readMigrationStatus, readTablePage, recordAuthEvent, recordCapturedMail, recordFunctionMetric, renderSql, resolveRankPartition, resolveRelationPredicates, resolveWith, runDataMigration, runExternalSourceTick, runReadonlySql, runRowValidators, runShardMigrations, runTriggers, scoreDocument, selectExportTables, selectIndexForAggregate, selectIndexForCount, selectIndexForGroupBy, selectMatchingIds, serveRelationFanout, softDeleteScope, sortColumnName, stableStringify, stableWireKey, stringifySearchText, subscriptionListDeltas, throwingScheduler, tokenizeSearch, trimCdcChanges, validateImportRow };
|
|
7209
|
+
export { ADMIN_FUNCTIONS, ADMIN_FUNCTION_PREFIX, AGGREGATE_SQL_FUNCTION, AUTH_METRICS_BUCKETS_TABLE, AUTH_METRICS_BUCKET_MS, AUTH_METRICS_BUCKET_RETENTION, AUTH_METRICS_TABLE, type AdvisoriesResult, type AdvisoryFinding, type AggregateIndexDefinitionLike, type AggregateOp, type AggregateOptions, type AggregateResult, type AggregateTally, type ApplyOnDeleteOptions, type AuditEntry, type AuditLogResult, type AuthMetrics, type AuthMetricsBucket, type BroadcastDelta, CDC_LOG_TABLE, type CacheEntry, type CapturedMailRow, type CdcChange, type Clock, type ColumnMeta, type ColumnMetaLike, ConflictError, type ContextMetrics, type ContextTracer, type CountArgs, CountRlsUnsupportedError, type CtxDbOptions, DATA_MIGRATION_STATE_TABLE, DEFAULT_MAX_RELATION_KEYS, type DataMigrationDocument, type DataMigrationLike, type DataMigrationTransform, type DatabaseWriterLike, type DependencyTracker, type DeployInfo, type ExportRow, type ExportShardAdminArgs, type ExportShardArgs, type ExternalSourceDiffResult, type ExternalSourceLike, FLAGS_FUNCTION_PREFIX, FUNCTION_METRICS_BUCKETS_TABLE, FUNCTION_METRICS_BUCKET_MS, FUNCTION_METRICS_BUCKET_RETENTION, FUNCTION_METRICS_INDEX_TABLE, FUNCTION_METRICS_TABLE, type FacetColumnOptions, type FacetColumnResult, type FacetValue, type FieldOperators, type FlagEvaluation, type FlagsResult, type FunctionCallStat, type FunctionMetricBucket, type FunctionMetricIndexHit, type FunctionStatsResult, GEO_DEFAULT_PRECISION, type GeoBoundingBox, type GeoFilterBuilderLike, type GeoIndexDefinitionLike, type GeoPoint, type GroupByEntry, type GroupByOptions, type HibernatableWebSocket, type IdGenerator, type ImportError, type ImportShardAdminArgs, type ImportShardArgs, type ImportShardResult, type IncrementalMaterializeResult, type IndexDefinitionLike, type IndexRangeBuilderLike, LogBuffer, type LogEntry, type LogEventInput, type LogLevel, type LogSink, MAIL_RETENTION, MAIL_TABLE, MAX_SQL_ROWS, MIN_ADMIN_TOKEN_LENGTH, MIN_AUTH_SECRET_LENGTH, type MaskColumnMetadata, type MaskPoliciesResult, type MaterializeResult, type MetricsDeps, type MigrationDirection, type MigrationRunResult, type MigrationStatus, type MigrationStatusRow, type MutationDelta, type NestedWith, NotFoundError, NotUniqueError, type OnDeleteActionLike, type OrderByInput, type OrderKey, type PaginationOptions, type PitrBookmarkResult, type PitrRestoreArgs, type PitrRestoreResult, type PitrStorage, type QueryArgs, type QueryPage, type QueueMetadata, type QueuesResult, RANK_TIEBREAK, RELATION_FUNCTION_PREFIX, RLS_UNWRAP_SYMBOL, ROOT_DO_SIZE_WARN_BYTES, ROOT_SHARD_NAME, type RankDirection, type RankIndexDefinitionLike, type RankOptions, type RankPage, type RankPageOptions, type RankPageRow, type RankPageRowKey, type RankResult, type RankSortKeyLike, ReactiveCache, type ReactiveCacheOptions, type ReadHook, type ReadTablePageOptions, type RecordAuthEventInput, type RecordFunctionMetricInput, type RecordMailInput, type RelationDefinitionLike, type RenderedSql, type ResolveRelationPredicatesOptions, type ResolveWithOptions, type RestrictableQueryOptions, type RlsPoliciesResult, type RlsPolicyMetadata, RlsRequiredError, type RlsRoleMetadata, type RpcRequest, type RunDataMigrationOptions, type RunShardApplyCdcArgs, type RunShardApplyCdcResult, type RunShardBulkDeleteArgs, type RunShardBulkDeleteResult, type RunShardExportArgs, type RunShardImportArgs, type RunShardMigrationArgs, type RunShardRankBeforeArgs, type RunShardRankPageArgs, type RunShardWriteArgs, type RunShardWriteResult, type RunTriggersOptions, SCAN_DEP, SESSION_DO_TTL_DEFAULT, SHARD_REGISTRY_DO_NAME, type SchedulableWorkflowReferenceLike, type ScheduledFunctionDoc, type SchedulerLike, type SchemaLike, type SearchFilterBuilderLike, type SecurityAuditResult, type SecurityFinding, type SecurityFindingKind, type SecurityFindingLevel, type SelectMatchingIdsOptions, type ServerDefaultContextLike, SessionDO, type SessionRecord, type SettingEntry, type SettingKind, type SettingsResult, type ShapeSubscriptionQuery, ShardDO, type ShardDOOptions, type ShardDOState, type ShardRankPageResult, ShardRegistryDO, type SocketAttachment, type SortDirection, type SourceClientLike, type SourceCursorLike, type SourceRefresh, type SqlConsoleResult, type SqlCursor, type SqlEngine, type SqlExec, type StorageRuleMetadata, type StorageRulesResult, type StudioFeaturesResult, type SubscriptionEnvelope, type SubscriptionOutcome, type SubscriptionQuery, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemReaderOptions, type SystemReaderSchedulerLike, type SystemReaderStorageLike, type SystemTableName, type TableColumnsResult, type TableDefinitionLike, type TableIndexInfo, type TableIndexesResult, type TableInfo, type TablePage, type TableReaderLike, type TablesColumnsResult, type TelemetrySink, type TraceAnchor, type TracerDeps, type TransactionSqlLike, type TriggerContextLike, type TriggerDefinitionLike, type TriggerEventLike, type TriggerOpLike, type TriggerTimingLike, type TtlSweepSpec, type ValidatorLike, type WhereInput, type WhereSqlStrategy, type WithInput, type WorkflowMetadata, type WorkflowsResult, type WriteEvent, type WriteHook, aggregateSqlFunction, aggregateTableName, applyCdcChanges, applyOnDelete, applySelect, armRestore, assertFlatPredicate, assertReadonly, assertShapeShardable, assertValidClientId, backfillAggregateIndexes, backfillRankIndexes, boundingBoxGeohashes, buildFtsMatch, buildSecurityAudit, buildSeekWhere, clearCapturedMail, coerceAggregateNumber, compileWhereSql, containsRelationPredicate, coveringGeohashes, createDependencyTracker, createMetrics, createShardCtxDb, createSystemReader, createTracer, decodeCursor, depKey, diffExternalSource, dispatchRootSpan, encodeAggregateKey, encodeCursor, encodeGeohash, encodePartitionKey, ensureAuthMetricsTables, ensureFunctionMetricsTables, ensureMailTable, exportShardRows, exportShardTable, facetColumn, fanOutScalarCounts, foldAggregateTally, ftsTableName, guardWriter, hasTrigger, haversineMeters, importShardRows, isRelationPredicate, isSoftDeleted, isSourceDue, liftSourceId, listTables, matchesRankStaticWhere, matchesStaticWhere, materializeExternalRows, materializeExternalRowsIncremental, mergeWhere, normalizeCountArgument, normalizeIdStructurally, normalizeOrderKeys, parseExportShardArgs, parseImportShardArgs, planAggregateLookup, pointInBoundingBox, pullExternalSourceIncrementalTick, pullExternalSourceTick, rankTableName, reactiveCacheKey, readAggregateValue, readAuthMetrics, readBookmark, readCapturedMail, readCdcChanges, readExternalSourceBaseline, readFunctionMetricBuckets, readFunctionMetricIndexHits, readFunctionMetrics, readFunctionMetricsTotals, readMigrationStatus, readTablePage, recordAuthEvent, recordCapturedMail, recordFunctionMetric, renderSql, resolveRankPartition, resolveRelationPredicates, resolveWith, runDataMigration, runExternalSourceTick, runReadonlySql, runRowValidators, runShardMigrations, runTriggers, scoreDocument, selectExpiredIds, selectExportTables, selectIndexForAggregate, selectIndexForCount, selectIndexForGroupBy, selectMatchingIds, serveRelationFanout, softDeleteScope, sortColumnName, stableStringify, stableWireKey, stringifySearchText, subscriptionListDeltas, throwingScheduler, tokenizeSearch, trimCdcChanges, validateImportRow };
|
package/dist/index.d.ts
CHANGED
|
@@ -1312,6 +1312,13 @@ interface SchemaLike {
|
|
|
1312
1312
|
}
|
|
1313
1313
|
interface TableDefinitionLike {
|
|
1314
1314
|
readonly aggregateIndexes?: ReadonlyArray<AggregateIndexDefinitionLike>;
|
|
1315
|
+
/**
|
|
1316
|
+
* Mirror of `@lunora/server`'s `TableDefinition.geoIndexes` (set by
|
|
1317
|
+
* `.geoIndex()`). Each declares a geohash companion over a `v.geoPoint()`
|
|
1318
|
+
* column so `withGeoIndex(name, q => q.near(...) | q.within(...))` resolves
|
|
1319
|
+
* proximity / bounding-box reads. Empty/absent ⇒ the table has no geo index.
|
|
1320
|
+
*/
|
|
1321
|
+
readonly geoIndexes?: ReadonlyArray<GeoIndexDefinitionLike>;
|
|
1315
1322
|
readonly indexes: ReadonlyArray<IndexDefinitionLike>;
|
|
1316
1323
|
/**
|
|
1317
1324
|
* `true` when `.public()` opted this table OUT of secure-by-default RLS
|
|
@@ -1339,6 +1346,15 @@ interface TableDefinitionLike {
|
|
|
1339
1346
|
field: string;
|
|
1340
1347
|
};
|
|
1341
1348
|
readonly triggerMap?: Record<string, TriggerDefinitionLike>;
|
|
1349
|
+
/**
|
|
1350
|
+
* Mirror of `@lunora/server`'s `TableDefinition.ttlPolicy` (set by `.ttl()`).
|
|
1351
|
+
* Drives the DO alarm-driven expiry sweep — see `ttl-sweep.ts`. Absent ⇒ rows
|
|
1352
|
+
* never auto-expire.
|
|
1353
|
+
*/
|
|
1354
|
+
readonly ttlPolicy?: {
|
|
1355
|
+
after?: number;
|
|
1356
|
+
field: string;
|
|
1357
|
+
};
|
|
1342
1358
|
}
|
|
1343
1359
|
interface IndexDefinitionLike {
|
|
1344
1360
|
readonly fields: ReadonlyArray<string>;
|
|
@@ -1350,6 +1366,12 @@ interface SearchIndexDefinitionLike {
|
|
|
1350
1366
|
readonly filterFields?: ReadonlyArray<string>;
|
|
1351
1367
|
readonly name: string;
|
|
1352
1368
|
}
|
|
1369
|
+
/** Mirror of `@lunora/server`'s `GeoIndexDefinition` — a geohash companion over a `v.geoPoint()` column. */
|
|
1370
|
+
interface GeoIndexDefinitionLike {
|
|
1371
|
+
readonly field: string;
|
|
1372
|
+
readonly name: string;
|
|
1373
|
+
readonly precision?: number;
|
|
1374
|
+
}
|
|
1353
1375
|
/**
|
|
1354
1376
|
* Column constraints/defaults the write layer honors, mirrored structurally
|
|
1355
1377
|
* from `@lunora/values`' `ColumnMeta` (kept local so this package doesn't take
|
|
@@ -1423,7 +1445,7 @@ type ReadHook = (table: string, idOrScan?: string) => void;
|
|
|
1423
1445
|
* No-op by default; called at most once per read (not per row), so it adds no
|
|
1424
1446
|
* meaningful hot-path cost.
|
|
1425
1447
|
*/
|
|
1426
|
-
type IndexUseHook = (table: string, indexName: string, kind: "index" | "rank" | "search") => void;
|
|
1448
|
+
type IndexUseHook = (table: string, indexName: string, kind: "geo" | "index" | "rank" | "search") => void;
|
|
1427
1449
|
/** Pluggable wall clock — defaults to `Date.now`. */
|
|
1428
1450
|
type Clock = () => number;
|
|
1429
1451
|
/** Pluggable ID minter — defaults to `crypto.randomUUID()`. */
|
|
@@ -1566,6 +1588,22 @@ interface SearchFilterBuilderLike {
|
|
|
1566
1588
|
eq: (field: string, value: unknown) => SearchFilterBuilderLike;
|
|
1567
1589
|
search: (field: string, query: string) => SearchFilterBuilderLike;
|
|
1568
1590
|
}
|
|
1591
|
+
interface GeoFilterBuilderLike {
|
|
1592
|
+
near: (point: {
|
|
1593
|
+
lat: number;
|
|
1594
|
+
lng: number;
|
|
1595
|
+
}, radiusMeters: number) => GeoFilterBuilderLike;
|
|
1596
|
+
within: (box: {
|
|
1597
|
+
ne: {
|
|
1598
|
+
lat: number;
|
|
1599
|
+
lng: number;
|
|
1600
|
+
};
|
|
1601
|
+
sw: {
|
|
1602
|
+
lat: number;
|
|
1603
|
+
lng: number;
|
|
1604
|
+
};
|
|
1605
|
+
}) => GeoFilterBuilderLike;
|
|
1606
|
+
}
|
|
1569
1607
|
/** Options accepted by {@link TableReaderLike.paginate} — Convex-compatible. */
|
|
1570
1608
|
interface PaginationOptions {
|
|
1571
1609
|
/** Opaque cursor from a prior page's `continueCursor`; `null`/omitted starts at the first page. */
|
|
@@ -1603,6 +1641,7 @@ interface TableReaderLike {
|
|
|
1603
1641
|
* more than one matches. Mirrors Convex's `.unique()`.
|
|
1604
1642
|
*/
|
|
1605
1643
|
unique: () => Promise<Record<string, unknown> | null>;
|
|
1644
|
+
withGeoIndex: (indexName: string, build: (q: GeoFilterBuilderLike) => GeoFilterBuilderLike) => TableReaderLike;
|
|
1606
1645
|
withIndex: (indexName: string, range?: (q: IndexRangeBuilderLike) => IndexRangeBuilderLike) => TableReaderLike;
|
|
1607
1646
|
withSearchIndex: (indexName: string, search: (q: SearchFilterBuilderLike) => SearchFilterBuilderLike) => TableReaderLike;
|
|
1608
1647
|
}
|
|
@@ -2899,7 +2938,7 @@ interface FunctionCallStat {
|
|
|
2899
2938
|
interface TableIndexInfo {
|
|
2900
2939
|
fields: string[];
|
|
2901
2940
|
name: string;
|
|
2902
|
-
type: "index" | "rank" | "search" | "vector";
|
|
2941
|
+
type: "geo" | "index" | "rank" | "search" | "vector";
|
|
2903
2942
|
unique?: boolean;
|
|
2904
2943
|
}
|
|
2905
2944
|
/** Payload of a `__lunora_admin__:listTableIndexes` call: every declared index on the table. */
|
|
@@ -3543,6 +3582,39 @@ declare const readFunctionMetricsTotals: (sql: SqlExec) => {
|
|
|
3543
3582
|
errors: number;
|
|
3544
3583
|
requests: number;
|
|
3545
3584
|
};
|
|
3585
|
+
/** Default geohash precision (characters) maintained by a `.geoIndex()` companion — ~4.8 m cells. */
|
|
3586
|
+
declare const GEO_DEFAULT_PRECISION = 9;
|
|
3587
|
+
/** A latitude/longitude point (WGS84 decimal degrees). */
|
|
3588
|
+
interface GeoPoint {
|
|
3589
|
+
lat: number;
|
|
3590
|
+
lng: number;
|
|
3591
|
+
}
|
|
3592
|
+
/** An axis-aligned latitude/longitude bounding box (`sw`/`ne` corners). */
|
|
3593
|
+
interface GeoBoundingBox {
|
|
3594
|
+
ne: GeoPoint;
|
|
3595
|
+
sw: GeoPoint;
|
|
3596
|
+
}
|
|
3597
|
+
/**
|
|
3598
|
+
* Encode `point` to a geohash of `precision` characters. Standard interleaved
|
|
3599
|
+
* lat/lng bisection over the base-32 alphabet.
|
|
3600
|
+
*/
|
|
3601
|
+
declare const encodeGeohash: (point: GeoPoint, precision: number) => string;
|
|
3602
|
+
/** Great-circle distance between two points in metres (Haversine). */
|
|
3603
|
+
declare const haversineMeters: (a: GeoPoint, b: GeoPoint) => number;
|
|
3604
|
+
/**
|
|
3605
|
+
* The center cell plus its eight neighbours at a precision chosen so each cell is
|
|
3606
|
+
* at least `radiusMeters` wide — the geohash prefixes to range-scan for a
|
|
3607
|
+
* proximity query. Deduplicated (near a pole neighbours can collapse).
|
|
3608
|
+
*/
|
|
3609
|
+
declare const coveringGeohashes: (center: GeoPoint, radiusMeters: number) => string[];
|
|
3610
|
+
/** Whether `point` falls inside `box` (inclusive edges). */
|
|
3611
|
+
declare const pointInBoundingBox: (point: GeoPoint, box: GeoBoundingBox) => boolean;
|
|
3612
|
+
/**
|
|
3613
|
+
* Geohash prefixes covering `box`: the covering cells of the circle centered on
|
|
3614
|
+
* the box whose radius reaches the north-east corner, guaranteeing every point
|
|
3615
|
+
* in the box is scanned before the exact `pointInBoundingBox` refine.
|
|
3616
|
+
*/
|
|
3617
|
+
declare const boundingBoxGeohashes: (box: GeoBoundingBox) => string[];
|
|
3546
3618
|
/**
|
|
3547
3619
|
* Severity of a `ctx.log.*` call. The five console method names (`log` is the
|
|
3548
3620
|
* default level, distinct from `info`) plus `trace`/`fatal`, so the logger spans
|
|
@@ -4152,6 +4224,28 @@ declare class SessionDO {
|
|
|
4152
4224
|
private handleGet;
|
|
4153
4225
|
private handleRevoke;
|
|
4154
4226
|
}
|
|
4227
|
+
/** One table's resolved TTL policy, as surfaced to the DO alarm by the generated shard subclass. */
|
|
4228
|
+
interface TtlSweepSpec {
|
|
4229
|
+
/** Millisecond offset added to `field` to derive the expiry (`field + after`); absent ⇒ `field` is the absolute expiry. */
|
|
4230
|
+
after?: number;
|
|
4231
|
+
/** The epoch-millisecond expiry column. */
|
|
4232
|
+
field: string;
|
|
4233
|
+
/** The `.softDelete()` marker column, when the table soft-deletes — expired-but-already-tombstoned rows are skipped. */
|
|
4234
|
+
softDeleteField?: string;
|
|
4235
|
+
/** The table whose expired rows are swept. */
|
|
4236
|
+
table: string;
|
|
4237
|
+
}
|
|
4238
|
+
/**
|
|
4239
|
+
* Select up to `limit` ids of rows in `spec.table` whose TTL expired at `now`
|
|
4240
|
+
* (i.e. `field + (after ?? 0) < now`). `hasMore` is `true` when matches remained
|
|
4241
|
+
* beyond `limit`, so the caller can loop a bounded batch. When `spec.softDeleteField`
|
|
4242
|
+
* is set, rows already soft-deleted (marker non-null) are excluded so the sweep
|
|
4243
|
+
* never re-touches a tombstone.
|
|
4244
|
+
*/
|
|
4245
|
+
declare const selectExpiredIds: (sql: SqlExec, spec: TtlSweepSpec, now: number, limit: number) => {
|
|
4246
|
+
hasMore: boolean;
|
|
4247
|
+
ids: string[];
|
|
4248
|
+
};
|
|
4155
4249
|
/**
|
|
4156
4250
|
* Diff the previously-sent list snapshot (`previousJson`, the memo's
|
|
4157
4251
|
* `lastJson`) against the new query result and produce per-row
|
|
@@ -5631,6 +5725,35 @@ declare abstract class ShardDO {
|
|
|
5631
5725
|
* no-op when the runtime exposes no `setAlarm` (unit harness).
|
|
5632
5726
|
*/
|
|
5633
5727
|
protected scheduleSourcePoll(): Promise<void>;
|
|
5728
|
+
/**
|
|
5729
|
+
* The resolved TTL policies (`.ttl(field, { after })`) for this DO's schema —
|
|
5730
|
+
* one {@link TtlSweepSpec} per table that declares a TTL. The base `ShardDO`
|
|
5731
|
+
* has no schema, so it returns `[]` and the TTL tier stays dormant. The
|
|
5732
|
+
* codegen subclass overrides it to read each table's `ttlPolicy` (+ its
|
|
5733
|
+
* `.softDelete()` marker) off the imported schema.
|
|
5734
|
+
*/
|
|
5735
|
+
protected ttlSweeps(): ReadonlyArray<TtlSweepSpec>;
|
|
5736
|
+
/**
|
|
5737
|
+
* Sweep every `.ttl()` table once: page the rows past their expiry and remove
|
|
5738
|
+
* each THROUGH the schema-aware writer (`deleteRowThroughWriter`) so companions
|
|
5739
|
+
* / CDC / live subscriptions stay correct and a `.softDelete()` table soft-deletes
|
|
5740
|
+
* instead of physically removing the row. Work is bounded per tick
|
|
5741
|
+
* ({@link TTL_SWEEP_BATCH} × {@link TTL_SWEEP_MAX_BATCHES}) so a large backlog
|
|
5742
|
+
* drains across several alarms without stalling the shard.
|
|
5743
|
+
*
|
|
5744
|
+
* Returns the next-due timestamp (a coarse {@link TTL_SWEEP_INTERVAL_MS}
|
|
5745
|
+
* cadence, so freshly-written rows expire within a bounded window) while any
|
|
5746
|
+
* TTL table exists, or `undefined` when there are none — so a DO with no TTL
|
|
5747
|
+
* table never arms this tier.
|
|
5748
|
+
*/
|
|
5749
|
+
protected pollTtlSweeps(): Promise<number | undefined>;
|
|
5750
|
+
/**
|
|
5751
|
+
* Arm the shared poll alarm for the TTL sweep. Mirrors {@link scheduleSourcePoll};
|
|
5752
|
+
* the codegen subclass calls it once on construction when the schema declares a
|
|
5753
|
+
* `.ttl()` table so the sweep loop starts, after which {@link ShardDO.alarm}
|
|
5754
|
+
* re-arms itself. Idempotent; a no-op when the runtime exposes no `setAlarm`.
|
|
5755
|
+
*/
|
|
5756
|
+
protected scheduleTtlSweep(): Promise<void>;
|
|
5634
5757
|
/** This DO's shard key (its DO name), or `__root__` for the single-DO default. The `tenantBy` mapper binds it into the source query. */
|
|
5635
5758
|
protected currentShardKey(): string;
|
|
5636
5759
|
/** Record a contained external-source ingest failure (one sourced table's poll) into the log ring without aborting the others. */
|
|
@@ -7083,4 +7206,4 @@ interface WhereSqlStrategy {
|
|
|
7083
7206
|
* `undefined` when the input imposes no constraint (empty `where`).
|
|
7084
7207
|
*/
|
|
7085
7208
|
declare const compileWhereSql: (where: WhereInput | undefined, strategy: WhereSqlStrategy) => SQL | undefined;
|
|
7086
|
-
export { ADMIN_FUNCTIONS, ADMIN_FUNCTION_PREFIX, AGGREGATE_SQL_FUNCTION, AUTH_METRICS_BUCKETS_TABLE, AUTH_METRICS_BUCKET_MS, AUTH_METRICS_BUCKET_RETENTION, AUTH_METRICS_TABLE, type AdvisoriesResult, type AdvisoryFinding, type AggregateIndexDefinitionLike, type AggregateOp, type AggregateOptions, type AggregateResult, type AggregateTally, type ApplyOnDeleteOptions, type AuditEntry, type AuditLogResult, type AuthMetrics, type AuthMetricsBucket, type BroadcastDelta, CDC_LOG_TABLE, type CacheEntry, type CapturedMailRow, type CdcChange, type Clock, type ColumnMeta, type ColumnMetaLike, ConflictError, type ContextMetrics, type ContextTracer, type CountArgs, CountRlsUnsupportedError, type CtxDbOptions, DATA_MIGRATION_STATE_TABLE, DEFAULT_MAX_RELATION_KEYS, type DataMigrationDocument, type DataMigrationLike, type DataMigrationTransform, type DatabaseWriterLike, type DependencyTracker, type DeployInfo, type ExportRow, type ExportShardAdminArgs, type ExportShardArgs, type ExternalSourceDiffResult, type ExternalSourceLike, FLAGS_FUNCTION_PREFIX, FUNCTION_METRICS_BUCKETS_TABLE, FUNCTION_METRICS_BUCKET_MS, FUNCTION_METRICS_BUCKET_RETENTION, FUNCTION_METRICS_INDEX_TABLE, FUNCTION_METRICS_TABLE, type FacetColumnOptions, type FacetColumnResult, type FacetValue, type FieldOperators, type FlagEvaluation, type FlagsResult, type FunctionCallStat, type FunctionMetricBucket, type FunctionMetricIndexHit, type FunctionStatsResult, type GroupByEntry, type GroupByOptions, type HibernatableWebSocket, type IdGenerator, type ImportError, type ImportShardAdminArgs, type ImportShardArgs, type ImportShardResult, type IncrementalMaterializeResult, type IndexDefinitionLike, type IndexRangeBuilderLike, LogBuffer, type LogEntry, type LogEventInput, type LogLevel, type LogSink, MAIL_RETENTION, MAIL_TABLE, MAX_SQL_ROWS, MIN_ADMIN_TOKEN_LENGTH, MIN_AUTH_SECRET_LENGTH, type MaskColumnMetadata, type MaskPoliciesResult, type MaterializeResult, type MetricsDeps, type MigrationDirection, type MigrationRunResult, type MigrationStatus, type MigrationStatusRow, type MutationDelta, type NestedWith, NotFoundError, NotUniqueError, type OnDeleteActionLike, type OrderByInput, type OrderKey, type PaginationOptions, type PitrBookmarkResult, type PitrRestoreArgs, type PitrRestoreResult, type PitrStorage, type QueryArgs, type QueryPage, type QueueMetadata, type QueuesResult, RANK_TIEBREAK, RELATION_FUNCTION_PREFIX, RLS_UNWRAP_SYMBOL, ROOT_DO_SIZE_WARN_BYTES, ROOT_SHARD_NAME, type RankDirection, type RankIndexDefinitionLike, type RankOptions, type RankPage, type RankPageOptions, type RankPageRow, type RankPageRowKey, type RankResult, type RankSortKeyLike, ReactiveCache, type ReactiveCacheOptions, type ReadHook, type ReadTablePageOptions, type RecordAuthEventInput, type RecordFunctionMetricInput, type RecordMailInput, type RelationDefinitionLike, type RenderedSql, type ResolveRelationPredicatesOptions, type ResolveWithOptions, type RestrictableQueryOptions, type RlsPoliciesResult, type RlsPolicyMetadata, RlsRequiredError, type RlsRoleMetadata, type RpcRequest, type RunDataMigrationOptions, type RunShardApplyCdcArgs, type RunShardApplyCdcResult, type RunShardBulkDeleteArgs, type RunShardBulkDeleteResult, type RunShardExportArgs, type RunShardImportArgs, type RunShardMigrationArgs, type RunShardRankBeforeArgs, type RunShardRankPageArgs, type RunShardWriteArgs, type RunShardWriteResult, type RunTriggersOptions, SCAN_DEP, SESSION_DO_TTL_DEFAULT, SHARD_REGISTRY_DO_NAME, type SchedulableWorkflowReferenceLike, type ScheduledFunctionDoc, type SchedulerLike, type SchemaLike, type SearchFilterBuilderLike, type SecurityAuditResult, type SecurityFinding, type SecurityFindingKind, type SecurityFindingLevel, type SelectMatchingIdsOptions, type ServerDefaultContextLike, SessionDO, type SessionRecord, type SettingEntry, type SettingKind, type SettingsResult, type ShapeSubscriptionQuery, ShardDO, type ShardDOOptions, type ShardDOState, type ShardRankPageResult, ShardRegistryDO, type SocketAttachment, type SortDirection, type SourceClientLike, type SourceCursorLike, type SourceRefresh, type SqlConsoleResult, type SqlCursor, type SqlEngine, type SqlExec, type StorageRuleMetadata, type StorageRulesResult, type StudioFeaturesResult, type SubscriptionEnvelope, type SubscriptionOutcome, type SubscriptionQuery, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemReaderOptions, type SystemReaderSchedulerLike, type SystemReaderStorageLike, type SystemTableName, type TableColumnsResult, type TableDefinitionLike, type TableIndexInfo, type TableIndexesResult, type TableInfo, type TablePage, type TableReaderLike, type TablesColumnsResult, type TelemetrySink, type TraceAnchor, type TracerDeps, type TransactionSqlLike, type TriggerContextLike, type TriggerDefinitionLike, type TriggerEventLike, type TriggerOpLike, type TriggerTimingLike, type ValidatorLike, type WhereInput, type WhereSqlStrategy, type WithInput, type WorkflowMetadata, type WorkflowsResult, type WriteEvent, type WriteHook, aggregateSqlFunction, aggregateTableName, applyCdcChanges, applyOnDelete, applySelect, armRestore, assertFlatPredicate, assertReadonly, assertShapeShardable, assertValidClientId, backfillAggregateIndexes, backfillRankIndexes, buildFtsMatch, buildSecurityAudit, buildSeekWhere, clearCapturedMail, coerceAggregateNumber, compileWhereSql, containsRelationPredicate, createDependencyTracker, createMetrics, createShardCtxDb, createSystemReader, createTracer, decodeCursor, depKey, diffExternalSource, dispatchRootSpan, encodeAggregateKey, encodeCursor, encodePartitionKey, ensureAuthMetricsTables, ensureFunctionMetricsTables, ensureMailTable, exportShardRows, exportShardTable, facetColumn, fanOutScalarCounts, foldAggregateTally, ftsTableName, guardWriter, hasTrigger, importShardRows, isRelationPredicate, isSoftDeleted, isSourceDue, liftSourceId, listTables, matchesRankStaticWhere, matchesStaticWhere, materializeExternalRows, materializeExternalRowsIncremental, mergeWhere, normalizeCountArgument, normalizeIdStructurally, normalizeOrderKeys, parseExportShardArgs, parseImportShardArgs, planAggregateLookup, pullExternalSourceIncrementalTick, pullExternalSourceTick, rankTableName, reactiveCacheKey, readAggregateValue, readAuthMetrics, readBookmark, readCapturedMail, readCdcChanges, readExternalSourceBaseline, readFunctionMetricBuckets, readFunctionMetricIndexHits, readFunctionMetrics, readFunctionMetricsTotals, readMigrationStatus, readTablePage, recordAuthEvent, recordCapturedMail, recordFunctionMetric, renderSql, resolveRankPartition, resolveRelationPredicates, resolveWith, runDataMigration, runExternalSourceTick, runReadonlySql, runRowValidators, runShardMigrations, runTriggers, scoreDocument, selectExportTables, selectIndexForAggregate, selectIndexForCount, selectIndexForGroupBy, selectMatchingIds, serveRelationFanout, softDeleteScope, sortColumnName, stableStringify, stableWireKey, stringifySearchText, subscriptionListDeltas, throwingScheduler, tokenizeSearch, trimCdcChanges, validateImportRow };
|
|
7209
|
+
export { ADMIN_FUNCTIONS, ADMIN_FUNCTION_PREFIX, AGGREGATE_SQL_FUNCTION, AUTH_METRICS_BUCKETS_TABLE, AUTH_METRICS_BUCKET_MS, AUTH_METRICS_BUCKET_RETENTION, AUTH_METRICS_TABLE, type AdvisoriesResult, type AdvisoryFinding, type AggregateIndexDefinitionLike, type AggregateOp, type AggregateOptions, type AggregateResult, type AggregateTally, type ApplyOnDeleteOptions, type AuditEntry, type AuditLogResult, type AuthMetrics, type AuthMetricsBucket, type BroadcastDelta, CDC_LOG_TABLE, type CacheEntry, type CapturedMailRow, type CdcChange, type Clock, type ColumnMeta, type ColumnMetaLike, ConflictError, type ContextMetrics, type ContextTracer, type CountArgs, CountRlsUnsupportedError, type CtxDbOptions, DATA_MIGRATION_STATE_TABLE, DEFAULT_MAX_RELATION_KEYS, type DataMigrationDocument, type DataMigrationLike, type DataMigrationTransform, type DatabaseWriterLike, type DependencyTracker, type DeployInfo, type ExportRow, type ExportShardAdminArgs, type ExportShardArgs, type ExternalSourceDiffResult, type ExternalSourceLike, FLAGS_FUNCTION_PREFIX, FUNCTION_METRICS_BUCKETS_TABLE, FUNCTION_METRICS_BUCKET_MS, FUNCTION_METRICS_BUCKET_RETENTION, FUNCTION_METRICS_INDEX_TABLE, FUNCTION_METRICS_TABLE, type FacetColumnOptions, type FacetColumnResult, type FacetValue, type FieldOperators, type FlagEvaluation, type FlagsResult, type FunctionCallStat, type FunctionMetricBucket, type FunctionMetricIndexHit, type FunctionStatsResult, GEO_DEFAULT_PRECISION, type GeoBoundingBox, type GeoFilterBuilderLike, type GeoIndexDefinitionLike, type GeoPoint, type GroupByEntry, type GroupByOptions, type HibernatableWebSocket, type IdGenerator, type ImportError, type ImportShardAdminArgs, type ImportShardArgs, type ImportShardResult, type IncrementalMaterializeResult, type IndexDefinitionLike, type IndexRangeBuilderLike, LogBuffer, type LogEntry, type LogEventInput, type LogLevel, type LogSink, MAIL_RETENTION, MAIL_TABLE, MAX_SQL_ROWS, MIN_ADMIN_TOKEN_LENGTH, MIN_AUTH_SECRET_LENGTH, type MaskColumnMetadata, type MaskPoliciesResult, type MaterializeResult, type MetricsDeps, type MigrationDirection, type MigrationRunResult, type MigrationStatus, type MigrationStatusRow, type MutationDelta, type NestedWith, NotFoundError, NotUniqueError, type OnDeleteActionLike, type OrderByInput, type OrderKey, type PaginationOptions, type PitrBookmarkResult, type PitrRestoreArgs, type PitrRestoreResult, type PitrStorage, type QueryArgs, type QueryPage, type QueueMetadata, type QueuesResult, RANK_TIEBREAK, RELATION_FUNCTION_PREFIX, RLS_UNWRAP_SYMBOL, ROOT_DO_SIZE_WARN_BYTES, ROOT_SHARD_NAME, type RankDirection, type RankIndexDefinitionLike, type RankOptions, type RankPage, type RankPageOptions, type RankPageRow, type RankPageRowKey, type RankResult, type RankSortKeyLike, ReactiveCache, type ReactiveCacheOptions, type ReadHook, type ReadTablePageOptions, type RecordAuthEventInput, type RecordFunctionMetricInput, type RecordMailInput, type RelationDefinitionLike, type RenderedSql, type ResolveRelationPredicatesOptions, type ResolveWithOptions, type RestrictableQueryOptions, type RlsPoliciesResult, type RlsPolicyMetadata, RlsRequiredError, type RlsRoleMetadata, type RpcRequest, type RunDataMigrationOptions, type RunShardApplyCdcArgs, type RunShardApplyCdcResult, type RunShardBulkDeleteArgs, type RunShardBulkDeleteResult, type RunShardExportArgs, type RunShardImportArgs, type RunShardMigrationArgs, type RunShardRankBeforeArgs, type RunShardRankPageArgs, type RunShardWriteArgs, type RunShardWriteResult, type RunTriggersOptions, SCAN_DEP, SESSION_DO_TTL_DEFAULT, SHARD_REGISTRY_DO_NAME, type SchedulableWorkflowReferenceLike, type ScheduledFunctionDoc, type SchedulerLike, type SchemaLike, type SearchFilterBuilderLike, type SecurityAuditResult, type SecurityFinding, type SecurityFindingKind, type SecurityFindingLevel, type SelectMatchingIdsOptions, type ServerDefaultContextLike, SessionDO, type SessionRecord, type SettingEntry, type SettingKind, type SettingsResult, type ShapeSubscriptionQuery, ShardDO, type ShardDOOptions, type ShardDOState, type ShardRankPageResult, ShardRegistryDO, type SocketAttachment, type SortDirection, type SourceClientLike, type SourceCursorLike, type SourceRefresh, type SqlConsoleResult, type SqlCursor, type SqlEngine, type SqlExec, type StorageRuleMetadata, type StorageRulesResult, type StudioFeaturesResult, type SubscriptionEnvelope, type SubscriptionOutcome, type SubscriptionQuery, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemReaderOptions, type SystemReaderSchedulerLike, type SystemReaderStorageLike, type SystemTableName, type TableColumnsResult, type TableDefinitionLike, type TableIndexInfo, type TableIndexesResult, type TableInfo, type TablePage, type TableReaderLike, type TablesColumnsResult, type TelemetrySink, type TraceAnchor, type TracerDeps, type TransactionSqlLike, type TriggerContextLike, type TriggerDefinitionLike, type TriggerEventLike, type TriggerOpLike, type TriggerTimingLike, type TtlSweepSpec, type ValidatorLike, type WhereInput, type WhereSqlStrategy, type WithInput, type WorkflowMetadata, type WorkflowsResult, type WriteEvent, type WriteHook, aggregateSqlFunction, aggregateTableName, applyCdcChanges, applyOnDelete, applySelect, armRestore, assertFlatPredicate, assertReadonly, assertShapeShardable, assertValidClientId, backfillAggregateIndexes, backfillRankIndexes, boundingBoxGeohashes, buildFtsMatch, buildSecurityAudit, buildSeekWhere, clearCapturedMail, coerceAggregateNumber, compileWhereSql, containsRelationPredicate, coveringGeohashes, createDependencyTracker, createMetrics, createShardCtxDb, createSystemReader, createTracer, decodeCursor, depKey, diffExternalSource, dispatchRootSpan, encodeAggregateKey, encodeCursor, encodeGeohash, encodePartitionKey, ensureAuthMetricsTables, ensureFunctionMetricsTables, ensureMailTable, exportShardRows, exportShardTable, facetColumn, fanOutScalarCounts, foldAggregateTally, ftsTableName, guardWriter, hasTrigger, haversineMeters, importShardRows, isRelationPredicate, isSoftDeleted, isSourceDue, liftSourceId, listTables, matchesRankStaticWhere, matchesStaticWhere, materializeExternalRows, materializeExternalRowsIncremental, mergeWhere, normalizeCountArgument, normalizeIdStructurally, normalizeOrderKeys, parseExportShardArgs, parseImportShardArgs, planAggregateLookup, pointInBoundingBox, pullExternalSourceIncrementalTick, pullExternalSourceTick, rankTableName, reactiveCacheKey, readAggregateValue, readAuthMetrics, readBookmark, readCapturedMail, readCdcChanges, readExternalSourceBaseline, readFunctionMetricBuckets, readFunctionMetricIndexHits, readFunctionMetrics, readFunctionMetricsTotals, readMigrationStatus, readTablePage, recordAuthEvent, recordCapturedMail, recordFunctionMetric, renderSql, resolveRankPartition, resolveRelationPredicates, resolveWith, runDataMigration, runExternalSourceTick, runReadonlySql, runRowValidators, runShardMigrations, runTriggers, scoreDocument, selectExpiredIds, selectExportTables, selectIndexForAggregate, selectIndexForCount, selectIndexForGroupBy, selectMatchingIds, serveRelationFanout, softDeleteScope, sortColumnName, stableStringify, stableWireKey, stringifySearchText, subscriptionListDeltas, throwingScheduler, tokenizeSearch, trimCdcChanges, validateImportRow };
|
package/dist/index.mjs
CHANGED
|
@@ -4,14 +4,15 @@ export { aggregateTableName, coerceAggregateNumber, encodeAggregateKey, foldAggr
|
|
|
4
4
|
export { CountRlsUnsupportedError, mergeWhere, planAggregateLookup, selectIndexForAggregate, selectIndexForCount, selectIndexForGroupBy } from './packem_shared/CountRlsUnsupportedError-BGxj0pgS.mjs';
|
|
5
5
|
export { AUTH_METRICS_BUCKETS_TABLE, AUTH_METRICS_BUCKET_MS, AUTH_METRICS_BUCKET_RETENTION, AUTH_METRICS_TABLE, ensureAuthMetricsTables, readAuthMetrics, recordAuthEvent } from './packem_shared/AUTH_METRICS_BUCKETS_TABLE-CiHHYeJi.mjs';
|
|
6
6
|
export { c as createMetrics, a as createTracer, d as dispatchRootSpan } from './packem_shared/context-telemetry-DWfYDxCS.mjs';
|
|
7
|
-
export { NotUniqueError, assertValidClientId, createShardCtxDb, normalizeIdStructurally } from './packem_shared/NotUniqueError-
|
|
7
|
+
export { NotUniqueError, assertValidClientId, createShardCtxDb, normalizeIdStructurally } from './packem_shared/NotUniqueError-DbtlWwcG.mjs';
|
|
8
8
|
export { DATA_MIGRATION_STATE_TABLE, readMigrationStatus, runDataMigration } from './packem_shared/DATA_MIGRATION_STATE_TABLE-CYwBpyTr.mjs';
|
|
9
9
|
export { SCAN_DEP, createDependencyTracker, depKey } from './packem_shared/SCAN_DEP-DLJF8dsj.mjs';
|
|
10
10
|
export { renderSql } from './packem_shared/renderSql-D6eUcn2N.mjs';
|
|
11
11
|
export { diffExternalSource } from './packem_shared/diffExternalSource-CovHfdyo.mjs';
|
|
12
|
-
export { materializeExternalRows, materializeExternalRowsIncremental, readExternalSourceBaseline, runExternalSourceTick } from './packem_shared/materializeExternalRows-
|
|
13
|
-
export { isSoftDeleted, isSourceDue, liftSourceId, pullExternalSourceIncrementalTick, pullExternalSourceTick } from './packem_shared/isSoftDeleted-
|
|
12
|
+
export { materializeExternalRows, materializeExternalRowsIncremental, readExternalSourceBaseline, runExternalSourceTick } from './packem_shared/materializeExternalRows-BtEGs1Fv.mjs';
|
|
13
|
+
export { isSoftDeleted, isSourceDue, liftSourceId, pullExternalSourceIncrementalTick, pullExternalSourceTick } from './packem_shared/isSoftDeleted-CFJmhjFP.mjs';
|
|
14
14
|
export { FUNCTION_METRICS_BUCKETS_TABLE, FUNCTION_METRICS_BUCKET_MS, FUNCTION_METRICS_BUCKET_RETENTION, FUNCTION_METRICS_INDEX_TABLE, FUNCTION_METRICS_TABLE, ensureFunctionMetricsTables, readFunctionMetricBuckets, readFunctionMetricIndexHits, readFunctionMetrics, readFunctionMetricsTotals, recordFunctionMetric } from './packem_shared/FUNCTION_METRICS_BUCKETS_TABLE-UDNVD7FS.mjs';
|
|
15
|
+
export { GEO_DEFAULT_PRECISION, boundingBoxGeohashes, coveringGeohashes, encodeGeohash, haversineMeters, pointInBoundingBox } from './packem_shared/GEO_DEFAULT_PRECISION-BWnsNmpP.mjs';
|
|
15
16
|
export { ADMIN_FUNCTIONS, ADMIN_FUNCTION_PREFIX, FLAGS_FUNCTION_PREFIX, RELATION_FUNCTION_PREFIX, facetColumn, listTables, readTablePage, selectMatchingIds } from './packem_shared/ADMIN_FUNCTIONS-DVk02KpP.mjs';
|
|
16
17
|
export { LogBuffer } from './packem_shared/LogBuffer-B_Ezju_N.mjs';
|
|
17
18
|
export { MAIL_RETENTION, MAIL_TABLE, clearCapturedMail, ensureMailTable, readCapturedMail, recordCapturedMail } from './packem_shared/MAIL_RETENTION-CPpgl-dX.mjs';
|
|
@@ -27,16 +28,17 @@ export { RLS_UNWRAP_SYMBOL, RlsRequiredError, guardWriter } from './packem_share
|
|
|
27
28
|
export { buildFtsMatch, ftsTableName, scoreDocument, stringifySearchText, tokenizeSearch } from './packem_shared/buildFtsMatch-BLEMawrp.mjs';
|
|
28
29
|
export { M as MIN_ADMIN_TOKEN_LENGTH, a as MIN_AUTH_SECRET_LENGTH, b as buildSecurityAudit } from './packem_shared/security-audit-CucgBice.mjs';
|
|
29
30
|
export { SESSION_DO_TTL_DEFAULT, SessionDO } from './packem_shared/SESSION_DO_TTL_DEFAULT-BnSKgVO4.mjs';
|
|
30
|
-
export { ROOT_DO_SIZE_WARN_BYTES, ROOT_SHARD_NAME, ShardDO } from './packem_shared/ROOT_DO_SIZE_WARN_BYTES-
|
|
31
|
+
export { ROOT_DO_SIZE_WARN_BYTES, ROOT_SHARD_NAME, ShardDO } from './packem_shared/ROOT_DO_SIZE_WARN_BYTES-FAG0bOO5.mjs';
|
|
31
32
|
export { SHARD_REGISTRY_DO_NAME, ShardRegistryDO } from './packem_shared/SHARD_REGISTRY_DO_NAME-D99roc-r.mjs';
|
|
32
33
|
export { MAX_SQL_ROWS, assertReadonly, runReadonlySql } from './packem_shared/MAX_SQL_ROWS-iFAA8FbD.mjs';
|
|
33
34
|
export { createSystemReader } from './packem_shared/createSystemReader-D12eNH13.mjs';
|
|
34
35
|
export { ConflictError } from './packem_shared/ConflictError-CLoq37xH.mjs';
|
|
35
36
|
export { hasTrigger, runTriggers } from './packem_shared/hasTrigger-5N6_Fx0A.mjs';
|
|
37
|
+
export { selectExpiredIds } from './packem_shared/selectExpiredIds-C5W29Upb.mjs';
|
|
36
38
|
export { compileWhereSql } from './packem_shared/compileWhereSql-DE6yfRcQ.mjs';
|
|
37
39
|
export { CDC_LOG_TABLE, applyCdcChanges, readCdcChanges, trimCdcChanges } from './packem_shared/CDC_LOG_TABLE-uwOJxJJZ.mjs';
|
|
38
|
-
export { backfillAggregateIndexes, backfillRankIndexes } from './packem_shared/backfillAggregateIndexes-
|
|
39
|
-
export { runShardMigrations } from './packem_shared/runShardMigrations-
|
|
40
|
+
export { backfillAggregateIndexes, backfillRankIndexes } from './packem_shared/backfillAggregateIndexes-BGTwynwh.mjs';
|
|
41
|
+
export { runShardMigrations } from './packem_shared/runShardMigrations-BVax6rYu.mjs';
|
|
40
42
|
export { stableStringify } from './packem_shared/stableStringify-mC40mZts.mjs';
|
|
41
43
|
export { stableWireKey } from './packem_shared/stableWireKey-DKuXO7T5.mjs';
|
|
42
44
|
export { subscriptionListDeltas } from './packem_shared/subscriptionListDeltas-CT76bYny.mjs';
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
const BASE32 = "0123456789bcdefghjkmnpqrstuvwxyz";
|
|
2
|
+
const GEO_DEFAULT_PRECISION = 9;
|
|
3
|
+
const EARTH_RADIUS_METERS = 63710088e-1;
|
|
4
|
+
const CELL_WIDTH_METERS = [Number.POSITIVE_INFINITY, 5009400, 1252300, 156500, 39100, 4900, 1200, 152.9, 38.2, 4.77, 1.19, 0.149, 0.037];
|
|
5
|
+
const clampPrecision = (precision) => Math.min(Math.max(Math.trunc(precision), 1), 12);
|
|
6
|
+
const encodeGeohash = (point, precision) => {
|
|
7
|
+
const chars = clampPrecision(precision);
|
|
8
|
+
let latMin = -90;
|
|
9
|
+
let latMax = 90;
|
|
10
|
+
let lngMin = -180;
|
|
11
|
+
let lngMax = 180;
|
|
12
|
+
let hash = "";
|
|
13
|
+
let bit = 0;
|
|
14
|
+
let index = 0;
|
|
15
|
+
let even = true;
|
|
16
|
+
while (hash.length < chars) {
|
|
17
|
+
if (even) {
|
|
18
|
+
const mid = (lngMin + lngMax) / 2;
|
|
19
|
+
if (point.lng >= mid) {
|
|
20
|
+
index = index * 2 + 1;
|
|
21
|
+
lngMin = mid;
|
|
22
|
+
} else {
|
|
23
|
+
index *= 2;
|
|
24
|
+
lngMax = mid;
|
|
25
|
+
}
|
|
26
|
+
} else {
|
|
27
|
+
const mid = (latMin + latMax) / 2;
|
|
28
|
+
if (point.lat >= mid) {
|
|
29
|
+
index = index * 2 + 1;
|
|
30
|
+
latMin = mid;
|
|
31
|
+
} else {
|
|
32
|
+
index *= 2;
|
|
33
|
+
latMax = mid;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
even = !even;
|
|
37
|
+
if (bit < 4) {
|
|
38
|
+
bit += 1;
|
|
39
|
+
} else {
|
|
40
|
+
hash += BASE32[index] ?? "0";
|
|
41
|
+
bit = 0;
|
|
42
|
+
index = 0;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return hash;
|
|
46
|
+
};
|
|
47
|
+
const haversineMeters = (a, b) => {
|
|
48
|
+
const toRadians = (degrees) => degrees * Math.PI / 180;
|
|
49
|
+
const dLat = toRadians(b.lat - a.lat);
|
|
50
|
+
const dLng = toRadians(b.lng - a.lng);
|
|
51
|
+
const lat1 = toRadians(a.lat);
|
|
52
|
+
const lat2 = toRadians(b.lat);
|
|
53
|
+
const h = Math.sin(dLat / 2) ** 2 + Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLng / 2) ** 2;
|
|
54
|
+
return 2 * EARTH_RADIUS_METERS * Math.asin(Math.min(1, Math.sqrt(h)));
|
|
55
|
+
};
|
|
56
|
+
const precisionForRadius = (radiusMeters) => {
|
|
57
|
+
for (let length = CELL_WIDTH_METERS.length - 1; length >= 1; length -= 1) {
|
|
58
|
+
const width = CELL_WIDTH_METERS[length];
|
|
59
|
+
if (width !== void 0 && width >= radiusMeters) {
|
|
60
|
+
return length;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return 1;
|
|
64
|
+
};
|
|
65
|
+
const NEIGHBOURS = {
|
|
66
|
+
east: ["bc01fg45238967deuvhjyznpkmstqrwx", "bc01fg45238967deuvhjyznpkmstqrwx"],
|
|
67
|
+
north: ["p0r21436x8zb9dcf5h7kjnmqesgutwvy", "bc01fg45238967deuvhjyznpkmstqrwx"],
|
|
68
|
+
south: ["14365h7k9dcfesgujnmqp0r2twvyx8zb", "238967debc01fg45kmstqrwxuvhjyznp"],
|
|
69
|
+
west: ["238967debc01fg45kmstqrwxuvhjyznp", "238967debc01fg45kmstqrwxuvhjyznp"]
|
|
70
|
+
};
|
|
71
|
+
const BORDERS = {
|
|
72
|
+
east: ["bcfguvyz", "prxz"],
|
|
73
|
+
north: ["prxz", "bcfguvyz"],
|
|
74
|
+
south: ["028b", "0145hjnp"],
|
|
75
|
+
west: ["0145hjnp", "028b"]
|
|
76
|
+
};
|
|
77
|
+
const adjacent = (hash, direction) => {
|
|
78
|
+
const lower = hash.toLowerCase();
|
|
79
|
+
const lastChar = lower.at(-1) ?? "";
|
|
80
|
+
let base = lower.slice(0, -1);
|
|
81
|
+
const type = lower.length % 2 === 0 ? 0 : 1;
|
|
82
|
+
if (BORDERS[direction][type].includes(lastChar) && base !== "") {
|
|
83
|
+
base = adjacent(base, direction);
|
|
84
|
+
}
|
|
85
|
+
return base + (BASE32[NEIGHBOURS[direction][type].indexOf(lastChar)] ?? "");
|
|
86
|
+
};
|
|
87
|
+
const coveringGeohashes = (center, radiusMeters) => {
|
|
88
|
+
const precision = precisionForRadius(Math.max(radiusMeters, 1));
|
|
89
|
+
const origin = encodeGeohash(center, precision);
|
|
90
|
+
const north = adjacent(origin, "north");
|
|
91
|
+
const south = adjacent(origin, "south");
|
|
92
|
+
const cells = [
|
|
93
|
+
origin,
|
|
94
|
+
north,
|
|
95
|
+
south,
|
|
96
|
+
adjacent(origin, "east"),
|
|
97
|
+
adjacent(origin, "west"),
|
|
98
|
+
adjacent(north, "east"),
|
|
99
|
+
adjacent(north, "west"),
|
|
100
|
+
adjacent(south, "east"),
|
|
101
|
+
adjacent(south, "west")
|
|
102
|
+
];
|
|
103
|
+
return [...new Set(cells)];
|
|
104
|
+
};
|
|
105
|
+
const pointInBoundingBox = (point, box) => point.lat >= box.sw.lat && point.lat <= box.ne.lat && point.lng >= box.sw.lng && point.lng <= box.ne.lng;
|
|
106
|
+
const boundingBoxCenter = (box) => {
|
|
107
|
+
return { lat: (box.sw.lat + box.ne.lat) / 2, lng: (box.sw.lng + box.ne.lng) / 2 };
|
|
108
|
+
};
|
|
109
|
+
const boundingBoxGeohashes = (box) => {
|
|
110
|
+
const center = boundingBoxCenter(box);
|
|
111
|
+
return coveringGeohashes(center, Math.max(haversineMeters(center, box.ne), 1));
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export { GEO_DEFAULT_PRECISION, boundingBoxCenter, boundingBoxGeohashes, coveringGeohashes, encodeGeohash, haversineMeters, pointInBoundingBox };
|
|
@@ -6,8 +6,9 @@ import { mergeWhere, CountRlsUnsupportedError, selectIndexForGroupBy, selectInde
|
|
|
6
6
|
import { appendCdcChange } from './CDC_LOG_TABLE-uwOJxJJZ.mjs';
|
|
7
7
|
export { CDC_LOG_TABLE, applyCdcChanges, bumpCdcEpoch, minCdcSeq, readCdcChanges, readCdcCursor, readCdcEpoch, trimCdcChanges } from './CDC_LOG_TABLE-uwOJxJJZ.mjs';
|
|
8
8
|
import { r as runDrizzle } from './do-exec-5eQy5cEi.mjs';
|
|
9
|
-
import { i as isFtsAvailable, D as DOC_COLUMN$1, r as rowToDocument, A as AGG_KEY, a as AGG_VALUE, b as AGG_COUNT, d as aggUpsertSql, j as jsonPathSql, q as quoteIdentifier, t as tableColumns, e as qualifiedJsonPathSql } from './do-sql-
|
|
9
|
+
import { i as isFtsAvailable, D as DOC_COLUMN$1, r as rowToDocument, A as AGG_KEY, a as AGG_VALUE, b as AGG_COUNT, g as geoTableName, d as aggUpsertSql, j as jsonPathSql, q as quoteIdentifier, t as tableColumns, e as qualifiedJsonPathSql } from './do-sql-CGAgiQUz.mjs';
|
|
10
10
|
import { param } from './renderSql-D6eUcn2N.mjs';
|
|
11
|
+
import { encodeGeohash, GEO_DEFAULT_PRECISION, coveringGeohashes, boundingBoxGeohashes, pointInBoundingBox, haversineMeters } from './GEO_DEFAULT_PRECISION-BWnsNmpP.mjs';
|
|
11
12
|
import { sortColumnName, matchesRankStaticWhere, encodePartitionKey, rankTableName, resolveRankPartition, RANK_TIEBREAK } from './RANK_TIEBREAK-CXhdcA1o.mjs';
|
|
12
13
|
import { stringifySearchText, ftsTableName, tokenizeSearch, buildFtsMatch, scoreDocument } from './buildFtsMatch-BLEMawrp.mjs';
|
|
13
14
|
import { s as serializeSqlValue } from './serialize-sql-BlRUoiQe.mjs';
|
|
@@ -21,10 +22,10 @@ import { createSystemReader } from './createSystemReader-D12eNH13.mjs';
|
|
|
21
22
|
import { ConflictError } from './ConflictError-CLoq37xH.mjs';
|
|
22
23
|
import { runTriggers } from './hasTrigger-5N6_Fx0A.mjs';
|
|
23
24
|
import { compileWhereSql } from './compileWhereSql-DE6yfRcQ.mjs';
|
|
24
|
-
export { backfillAggregateIndexes, backfillRankIndexes } from './backfillAggregateIndexes-
|
|
25
|
+
export { backfillAggregateIndexes, backfillRankIndexes } from './backfillAggregateIndexes-BGTwynwh.mjs';
|
|
25
26
|
export { C as CLIENT_WATERMARK_TABLE, G as GLOBAL_SHAPE_SNAPSHOT_TABLE, I as IDEMPOTENCY_TABLE, c as advanceClientWatermark, d as deleteGlobalShapeSnapshot, e as deleteGlobalShapeSnapshotsForConnection, m as migrateClientWatermark, b as migrateGlobalShapeSnapshot, r as readClientWatermark, f as readGlobalShapeSnapshot, g as readIdempotent, t as trimIdempotent, w as writeGlobalShapeSnapshot, h as writeIdempotent } from './ctx-db-idempotency-BdcNpvY4.mjs';
|
|
26
|
-
export { runShardMigrations } from './runShardMigrations-
|
|
27
|
-
export { a as selectShapeMemberIds, s as selectShapeRows } from './ctx-db-shapes-
|
|
27
|
+
export { runShardMigrations } from './runShardMigrations-BVax6rYu.mjs';
|
|
28
|
+
export { a as selectShapeMemberIds, s as selectShapeRows } from './ctx-db-shapes-DTeFiHYS.mjs';
|
|
28
29
|
|
|
29
30
|
const rankIndexFieldsUnchanged = (index, previous, next) => {
|
|
30
31
|
const fields = [...index.partitionBy ?? [], ...index.sortBy.map((key) => key.field), ...index.where ? Object.keys(index.where) : []];
|
|
@@ -314,8 +315,28 @@ const createCompanionSync = (deps) => {
|
|
|
314
315
|
}
|
|
315
316
|
}
|
|
316
317
|
};
|
|
318
|
+
const syncGeo = (tableName, id, document) => {
|
|
319
|
+
const indexes = schema.tables[tableName]?.geoIndexes;
|
|
320
|
+
if (!indexes || indexes.length === 0) {
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
for (const index of indexes) {
|
|
324
|
+
const geoTable = geoTableName(tableName, index.name);
|
|
325
|
+
runDrizzle(sql$1, sql`DELETE FROM ${sql.identifier(geoTable)} WHERE ${sql.identifier("__id__")} = ${id}`);
|
|
326
|
+
const point = document?.[index.field];
|
|
327
|
+
if (point !== null && typeof point === "object" && typeof point.lat === "number" && typeof point.lng === "number") {
|
|
328
|
+
const { lat, lng } = point;
|
|
329
|
+
const hash = encodeGeohash({ lat, lng }, index.precision ?? GEO_DEFAULT_PRECISION);
|
|
330
|
+
runDrizzle(
|
|
331
|
+
sql$1,
|
|
332
|
+
sql`INSERT INTO ${sql.identifier(geoTable)} (${sql.identifier("__id__")}, ${sql.identifier("__geohash__")}, ${sql.identifier("__lat__")}, ${sql.identifier("__lng__")}) VALUES (${id}, ${hash}, ${lat}, ${lng})`
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
};
|
|
317
337
|
const syncCompanionsForInsert = (tableName, id, document) => {
|
|
318
338
|
syncSearch(tableName, id, document);
|
|
339
|
+
syncGeo(tableName, id, document);
|
|
319
340
|
syncAggregates(tableName, void 0, document);
|
|
320
341
|
syncRanks(tableName, id, void 0, document);
|
|
321
342
|
invalidateCache(tableName, id);
|
|
@@ -329,6 +350,7 @@ const createCompanionSync = (deps) => {
|
|
|
329
350
|
ensureRankBackfilledForTable,
|
|
330
351
|
syncAggregates,
|
|
331
352
|
syncCompanionsForInsert,
|
|
353
|
+
syncGeo,
|
|
332
354
|
syncRanks,
|
|
333
355
|
syncSearch
|
|
334
356
|
};
|
|
@@ -599,6 +621,123 @@ const searchViaScan = (sql$1, tableName, search, limit, scopeCondition) => {
|
|
|
599
621
|
const docs = scored.map((entry) => entry.doc);
|
|
600
622
|
return typeof limit === "number" ? docs.slice(0, Math.max(0, Math.floor(limit))) : docs;
|
|
601
623
|
};
|
|
624
|
+
const createGeoBuilder = (geo, tableName) => {
|
|
625
|
+
const staged = geo;
|
|
626
|
+
const builder = {
|
|
627
|
+
near: (point, radiusMeters) => {
|
|
628
|
+
if (staged.within) {
|
|
629
|
+
throw new LunoraError("INTERNAL", `geo index "${staged.indexName}" on table "${tableName}": call .near() or .within(), not both`);
|
|
630
|
+
}
|
|
631
|
+
staged.near = { point: { lat: point.lat, lng: point.lng }, radiusMeters };
|
|
632
|
+
return builder;
|
|
633
|
+
},
|
|
634
|
+
within: (box) => {
|
|
635
|
+
if (staged.near) {
|
|
636
|
+
throw new LunoraError("INTERNAL", `geo index "${staged.indexName}" on table "${tableName}": call .near() or .within(), not both`);
|
|
637
|
+
}
|
|
638
|
+
staged.within = { ne: { lat: box.ne.lat, lng: box.ne.lng }, sw: { lat: box.sw.lat, lng: box.sw.lng } };
|
|
639
|
+
return builder;
|
|
640
|
+
}
|
|
641
|
+
};
|
|
642
|
+
return builder;
|
|
643
|
+
};
|
|
644
|
+
const readGeoPoint = (document, field) => {
|
|
645
|
+
const value = document[field];
|
|
646
|
+
if (value === null || typeof value !== "object") {
|
|
647
|
+
return void 0;
|
|
648
|
+
}
|
|
649
|
+
const { lat, lng } = value;
|
|
650
|
+
return typeof lat === "number" && typeof lng === "number" ? { lat, lng } : void 0;
|
|
651
|
+
};
|
|
652
|
+
const scoreGeoRow = (record, geo) => {
|
|
653
|
+
const point = readGeoPoint(record, geo.definition.field);
|
|
654
|
+
if (!point) {
|
|
655
|
+
return void 0;
|
|
656
|
+
}
|
|
657
|
+
const creationTime = typeof record["_creationTime"] === "number" ? record["_creationTime"] : 0;
|
|
658
|
+
if (geo.near) {
|
|
659
|
+
const distance = haversineMeters(geo.near.point, point);
|
|
660
|
+
return distance <= geo.near.radiusMeters ? { creationTime, distance } : void 0;
|
|
661
|
+
}
|
|
662
|
+
return pointInBoundingBox(point, geo.within) ? { creationTime, distance: 0 } : void 0;
|
|
663
|
+
};
|
|
664
|
+
const runGeoFetch = (sql$1, tableName, geo, limit, scopeCondition) => {
|
|
665
|
+
if (!geo.near && !geo.within) {
|
|
666
|
+
throw new LunoraError("INTERNAL", `geo index "${geo.indexName}" on table "${tableName}": call .near(point, radius) or .within(box)`);
|
|
667
|
+
}
|
|
668
|
+
const prefixes = geo.near ? coveringGeohashes(geo.near.point, geo.near.radiusMeters) : boundingBoxGeohashes(geo.within);
|
|
669
|
+
const geoTable = geoTableName(tableName, geo.indexName);
|
|
670
|
+
const prefixClauses = prefixes.map(
|
|
671
|
+
(prefix) => sql`(g.${sql.identifier("__geohash__")} >= ${prefix} AND g.${sql.identifier("__geohash__")} < ${`${prefix}{`})`
|
|
672
|
+
);
|
|
673
|
+
const whereClauses = [sql`(${sql.join(prefixClauses, sql` OR `)})`];
|
|
674
|
+
if (scopeCondition) {
|
|
675
|
+
whereClauses.push(scopeCondition);
|
|
676
|
+
}
|
|
677
|
+
const query = sql`SELECT m.id, m._creationTime, m.${sql.identifier(DOC_COLUMN$1)} FROM ${sql.identifier(geoTable)} g JOIN ${sql.identifier(tableName)} m ON m.id = g.${sql.identifier("__id__")} WHERE ${sql.join(whereClauses, sql` AND `)}`;
|
|
678
|
+
const rows = runDrizzle(sql$1, query).toArray();
|
|
679
|
+
const scored = [];
|
|
680
|
+
for (const row of rows) {
|
|
681
|
+
const record = rowToDocument(row);
|
|
682
|
+
const score = record ? scoreGeoRow(record, geo) : void 0;
|
|
683
|
+
if (record && score) {
|
|
684
|
+
scored.push({ creationTime: score.creationTime, distance: score.distance, doc: record });
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
scored.sort((a, b) => a.distance - b.distance || b.creationTime - a.creationTime);
|
|
688
|
+
const docs = scored.map((entry) => entry.doc);
|
|
689
|
+
return typeof limit === "number" ? docs.slice(0, Math.max(0, Math.floor(limit))) : docs;
|
|
690
|
+
};
|
|
691
|
+
const runGeoTerminal = (sql, tableName, stage, scopeCondition, limit) => {
|
|
692
|
+
const { geo } = stage;
|
|
693
|
+
if (!geo) {
|
|
694
|
+
throw new LunoraError("INTERNAL", "runGeoTerminal called without a staged geo query");
|
|
695
|
+
}
|
|
696
|
+
const filtered = stage.inMemoryFilters.length > 0;
|
|
697
|
+
const docs = runGeoFetch(sql, tableName, geo, filtered ? void 0 : limit, scopeCondition);
|
|
698
|
+
if (!filtered) {
|
|
699
|
+
return docs;
|
|
700
|
+
}
|
|
701
|
+
const result = [];
|
|
702
|
+
for (const record of docs) {
|
|
703
|
+
if (stage.inMemoryFilters.every((predicate) => predicate(record))) {
|
|
704
|
+
result.push(record);
|
|
705
|
+
if (typeof limit === "number" && result.length >= limit) {
|
|
706
|
+
break;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
return result;
|
|
711
|
+
};
|
|
712
|
+
const runPlainFetch = (sql$1, tableName, stage, scopeCondition, orderClause, limit) => {
|
|
713
|
+
const whereClauses = [];
|
|
714
|
+
for (const condition of stage.sqlConditions) {
|
|
715
|
+
whereClauses.push(sql`${jsonPathSql(condition.field)} ${sql.raw(condition.comparator)} ${serializeSqlValue(condition.value)}`);
|
|
716
|
+
}
|
|
717
|
+
if (scopeCondition) {
|
|
718
|
+
whereClauses.push(scopeCondition);
|
|
719
|
+
}
|
|
720
|
+
let query = sql`SELECT id, _creationTime, ${sql.identifier(DOC_COLUMN$1)} FROM ${sql.identifier(tableName)}`;
|
|
721
|
+
if (whereClauses.length > 0) {
|
|
722
|
+
query = sql`${query} WHERE ${sql.join(whereClauses, sql` AND `)}`;
|
|
723
|
+
}
|
|
724
|
+
query = sql`${query} ORDER BY ${orderClause}`;
|
|
725
|
+
if (typeof limit === "number" && stage.inMemoryFilters.length === 0) {
|
|
726
|
+
query = sql`${query} LIMIT ${sql.raw(String(Math.max(0, Math.floor(limit))))}`;
|
|
727
|
+
}
|
|
728
|
+
const rows = runDrizzle(sql$1, query).toArray();
|
|
729
|
+
const docs = [];
|
|
730
|
+
for (const row of rows) {
|
|
731
|
+
const record = rowToDocument(row);
|
|
732
|
+
if (record && stage.inMemoryFilters.every((predicate) => predicate(record))) {
|
|
733
|
+
docs.push(record);
|
|
734
|
+
if (typeof limit === "number" && docs.length >= limit) {
|
|
735
|
+
break;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
return docs;
|
|
740
|
+
};
|
|
602
741
|
const doWhereSqlStrategy = { fieldRef: jsonPathSql, serialize: serializeSqlValue };
|
|
603
742
|
const makeRelationExistsSqlStrategy = (onRead) => {
|
|
604
743
|
let aliasCounter = 0;
|
|
@@ -774,36 +913,10 @@ const buildReader = (sql$1, schema, tableName, onIndexUse = () => void 0) => {
|
|
|
774
913
|
if (stage.search) {
|
|
775
914
|
return runSearchFetch(limit);
|
|
776
915
|
}
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
whereClauses.push(sql`${jsonPathSql(condition.field)} ${sql.raw(condition.comparator)} ${serializeSqlValue(condition.value)}`);
|
|
780
|
-
}
|
|
781
|
-
if (scopeCondition) {
|
|
782
|
-
whereClauses.push(scopeCondition);
|
|
916
|
+
if (stage.geo) {
|
|
917
|
+
return runGeoTerminal(sql$1, tableName, stage, scopeCondition, limit);
|
|
783
918
|
}
|
|
784
|
-
|
|
785
|
-
if (whereClauses.length > 0) {
|
|
786
|
-
query = sql`${query} WHERE ${sql.join(whereClauses, sql` AND `)}`;
|
|
787
|
-
}
|
|
788
|
-
query = sql`${query} ORDER BY ${buildOrderClause()}`;
|
|
789
|
-
if (typeof limit === "number" && stage.inMemoryFilters.length === 0) {
|
|
790
|
-
query = sql`${query} LIMIT ${sql.raw(String(Math.max(0, Math.floor(limit))))}`;
|
|
791
|
-
}
|
|
792
|
-
const rows = runDrizzle(sql$1, query).toArray();
|
|
793
|
-
const docs = [];
|
|
794
|
-
for (const row of rows) {
|
|
795
|
-
const record = rowToDocument(row);
|
|
796
|
-
if (!record) {
|
|
797
|
-
continue;
|
|
798
|
-
}
|
|
799
|
-
if (stage.inMemoryFilters.every((predicate) => predicate(record))) {
|
|
800
|
-
docs.push(record);
|
|
801
|
-
if (typeof limit === "number" && docs.length >= limit) {
|
|
802
|
-
break;
|
|
803
|
-
}
|
|
804
|
-
}
|
|
805
|
-
}
|
|
806
|
-
return docs;
|
|
919
|
+
return runPlainFetch(sql$1, tableName, stage, scopeCondition, buildOrderClause(), limit);
|
|
807
920
|
};
|
|
808
921
|
const reader = {
|
|
809
922
|
// eslint-disable-next-line @typescript-eslint/require-await -- TableReaderLike returns Promises (the D1 twin awaits real I/O); the DO impl is synchronous over local SQLite
|
|
@@ -828,6 +941,9 @@ const buildReader = (sql$1, schema, tableName, onIndexUse = () => void 0) => {
|
|
|
828
941
|
if (stage.search) {
|
|
829
942
|
throw new LunoraError("INTERNAL", "pagination is not supported on search queries; use .take(n) or .collect()");
|
|
830
943
|
}
|
|
944
|
+
if (stage.geo) {
|
|
945
|
+
throw new LunoraError("INTERNAL", "pagination is not supported on geo queries; use .take(n) or .collect()");
|
|
946
|
+
}
|
|
831
947
|
return paginateStage(sql$1, tableName, stage, options, scopeCondition);
|
|
832
948
|
},
|
|
833
949
|
// eslint-disable-next-line @typescript-eslint/require-await -- TableReaderLike returns Promises (the D1 twin awaits real I/O); the DO impl is synchronous over local SQLite
|
|
@@ -842,6 +958,20 @@ const buildReader = (sql$1, schema, tableName, onIndexUse = () => void 0) => {
|
|
|
842
958
|
}
|
|
843
959
|
return rows[0] ?? null;
|
|
844
960
|
},
|
|
961
|
+
withGeoIndex(indexName, build) {
|
|
962
|
+
const definition = (tableDefinition.geoIndexes ?? []).find((index) => index.name === indexName);
|
|
963
|
+
if (!definition) {
|
|
964
|
+
throw new LunoraError("INTERNAL", `unknown geo index "${indexName}" on table "${tableName}"`);
|
|
965
|
+
}
|
|
966
|
+
onIndexUse(tableName, indexName, "geo");
|
|
967
|
+
const geoStage = { definition, indexName };
|
|
968
|
+
stage.geo = geoStage;
|
|
969
|
+
build(createGeoBuilder(geoStage, tableName));
|
|
970
|
+
if (!geoStage.near && !geoStage.within) {
|
|
971
|
+
throw new LunoraError("INTERNAL", `geo index "${indexName}" on table "${tableName}" requires a .near(point, radius) or .within(box) call`);
|
|
972
|
+
}
|
|
973
|
+
return reader;
|
|
974
|
+
},
|
|
845
975
|
withIndex(indexName, range) {
|
|
846
976
|
const definition = tableDefinition.indexes.find((index) => index.name === indexName);
|
|
847
977
|
if (!definition) {
|
|
@@ -1090,6 +1220,7 @@ const createShardCtxDb = (options) => {
|
|
|
1090
1220
|
ensureRankBackfilledForTable,
|
|
1091
1221
|
syncAggregates,
|
|
1092
1222
|
syncCompanionsForInsert,
|
|
1223
|
+
syncGeo,
|
|
1093
1224
|
syncRanks,
|
|
1094
1225
|
syncSearch
|
|
1095
1226
|
} = createCompanionSync({
|
|
@@ -1291,6 +1422,7 @@ const createShardCtxDb = (options) => {
|
|
|
1291
1422
|
sql`UPDATE ${sql.identifier(tableName)} SET ${sql.identifier(DOC_COLUMN$1)} = ${JSON.stringify(merged)} WHERE id = ${id} AND ${sql.identifier(DOC_COLUMN$1)} = ${existingJson}`
|
|
1292
1423
|
);
|
|
1293
1424
|
syncSearch(tableName, id, merged);
|
|
1425
|
+
syncGeo(tableName, id, void 0);
|
|
1294
1426
|
syncAggregates(tableName, existing, merged);
|
|
1295
1427
|
syncRanks(tableName, id, existing, void 0);
|
|
1296
1428
|
cache?.invalidate(tableName, id);
|
|
@@ -1308,6 +1440,7 @@ const createShardCtxDb = (options) => {
|
|
|
1308
1440
|
sql`DELETE FROM ${sql.identifier(tableName)} WHERE id = ${id} AND ${sql.identifier(DOC_COLUMN$1)} = ${existingJson}`
|
|
1309
1441
|
);
|
|
1310
1442
|
syncSearch(tableName, id, void 0);
|
|
1443
|
+
syncGeo(tableName, id, void 0);
|
|
1311
1444
|
syncAggregates(tableName, existing, void 0);
|
|
1312
1445
|
syncRanks(tableName, id, existing, void 0);
|
|
1313
1446
|
cache?.invalidate(tableName, id);
|
|
@@ -1682,6 +1815,7 @@ const createShardCtxDb = (options) => {
|
|
|
1682
1815
|
sql`UPDATE ${sql.identifier(tableName)} SET ${sql.identifier(DOC_COLUMN$1)} = ${JSON.stringify(merged)} WHERE id = ${id} AND ${sql.identifier(DOC_COLUMN$1)} = ${existingJson}`
|
|
1683
1816
|
);
|
|
1684
1817
|
syncSearch(tableName, id, merged);
|
|
1818
|
+
syncGeo(tableName, id, merged);
|
|
1685
1819
|
syncAggregates(tableName, existing, merged);
|
|
1686
1820
|
syncRanks(tableName, id, existing, merged);
|
|
1687
1821
|
cache?.invalidate(tableName, id);
|
|
@@ -1878,6 +2012,7 @@ const createShardCtxDb = (options) => {
|
|
|
1878
2012
|
sql`UPDATE ${sql.identifier(tableName)} SET _creationTime = ${creationTime}, ${sql.identifier(DOC_COLUMN$1)} = ${JSON.stringify(replaced)} WHERE id = ${id} AND ${sql.identifier(DOC_COLUMN$1)} = ${existingJson}`
|
|
1879
2013
|
);
|
|
1880
2014
|
syncSearch(tableName, id, replaced);
|
|
2015
|
+
syncGeo(tableName, id, replaced);
|
|
1881
2016
|
syncAggregates(tableName, previous, replaced);
|
|
1882
2017
|
syncRanks(tableName, id, previous, replaced);
|
|
1883
2018
|
cache?.invalidate(tableName, id);
|
|
@@ -22,9 +22,10 @@ import { redact, standardRules } from '@visulima/redact';
|
|
|
22
22
|
import { i as isDevEnvironment, c as buildSettings, b as buildSecurityAudit } from './security-audit-CucgBice.mjs';
|
|
23
23
|
import { runReadonlySql } from './MAX_SQL_ROWS-iFAA8FbD.mjs';
|
|
24
24
|
import { ConflictError } from './ConflictError-CLoq37xH.mjs';
|
|
25
|
+
import { selectExpiredIds } from './selectExpiredIds-C5W29Upb.mjs';
|
|
25
26
|
import { e as deleteGlobalShapeSnapshotsForConnection, g as readIdempotent, h as writeIdempotent, t as trimIdempotent, r as readClientWatermark, m as migrateClientWatermark, c as advanceClientWatermark, d as deleteGlobalShapeSnapshot, f as readGlobalShapeSnapshot, w as writeGlobalShapeSnapshot } from './ctx-db-idempotency-BdcNpvY4.mjs';
|
|
26
27
|
import { CDC_LOG_TABLE, readCdcChanges, readCdcCursor, readCdcEpoch, minCdcSeq, bumpCdcEpoch } from './CDC_LOG_TABLE-uwOJxJJZ.mjs';
|
|
27
|
-
import { a as selectShapeMemberIds, s as selectShapeRows } from './ctx-db-shapes-
|
|
28
|
+
import { a as selectShapeMemberIds, s as selectShapeRows } from './ctx-db-shapes-DTeFiHYS.mjs';
|
|
28
29
|
|
|
29
30
|
const MAX_BATCH_ENTRIES = 500;
|
|
30
31
|
|
|
@@ -1855,6 +1856,9 @@ const parseRunMigrationArgs = (args) => {
|
|
|
1855
1856
|
};
|
|
1856
1857
|
};
|
|
1857
1858
|
const SHARD_BULK_DELETE_CAP = MAX_PAGE_SIZE;
|
|
1859
|
+
const TTL_SWEEP_BATCH = 200;
|
|
1860
|
+
const TTL_SWEEP_MAX_BATCHES = 20;
|
|
1861
|
+
const TTL_SWEEP_INTERVAL_MS = 3e4;
|
|
1858
1862
|
const parseWriteRowArgs = (args) => {
|
|
1859
1863
|
const { op } = args;
|
|
1860
1864
|
const table = typeof args["table"] === "string" ? args["table"] : "";
|
|
@@ -2461,12 +2465,10 @@ class ShardDO {
|
|
|
2461
2465
|
* reason; otherwise the earlier of the two candidate times (never later than
|
|
2462
2466
|
* `nowMs`, so a source that's already due arms essentially immediately).
|
|
2463
2467
|
*/
|
|
2464
|
-
static nextPollAlarmTarget(globalShapesRemaining, nextSourceDueAt, nowMs) {
|
|
2468
|
+
static nextPollAlarmTarget(globalShapesRemaining, nextSourceDueAt, nextTtlDueAt, nowMs) {
|
|
2465
2469
|
const globalTarget = globalShapesRemaining > 0 ? nowMs + ShardDO.GLOBAL_SHAPE_POLL_INTERVAL_MS : void 0;
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
}
|
|
2469
|
-
return nextSourceDueAt === void 0 ? globalTarget : Math.min(globalTarget, nextSourceDueAt);
|
|
2470
|
+
const candidates = [globalTarget, nextSourceDueAt, nextTtlDueAt].filter((value) => value !== void 0).map((value) => Math.max(value, nowMs));
|
|
2471
|
+
return candidates.length > 0 ? Math.min(...candidates) : void 0;
|
|
2470
2472
|
}
|
|
2471
2473
|
state;
|
|
2472
2474
|
env;
|
|
@@ -3147,8 +3149,15 @@ class ShardDO {
|
|
|
3147
3149
|
this.recordShapeError("source:poll", error);
|
|
3148
3150
|
nextSourceDueAt = Date.now() + ShardDO.GLOBAL_SHAPE_POLL_INTERVAL_MS;
|
|
3149
3151
|
}
|
|
3152
|
+
let nextTtlDueAt;
|
|
3153
|
+
try {
|
|
3154
|
+
nextTtlDueAt = await this.pollTtlSweeps();
|
|
3155
|
+
} catch (error) {
|
|
3156
|
+
this.recordShapeError("ttl:sweep", error);
|
|
3157
|
+
nextTtlDueAt = Date.now() + ShardDO.GLOBAL_SHAPE_POLL_INTERVAL_MS;
|
|
3158
|
+
}
|
|
3150
3159
|
await this.flushChangedTables();
|
|
3151
|
-
const nextAlarmAt = ShardDO.nextPollAlarmTarget(globalShapesRemaining, nextSourceDueAt, Date.now());
|
|
3160
|
+
const nextAlarmAt = ShardDO.nextPollAlarmTarget(globalShapesRemaining, nextSourceDueAt, nextTtlDueAt, Date.now());
|
|
3152
3161
|
if (nextAlarmAt !== void 0) {
|
|
3153
3162
|
await this.scheduleGlobalPoll(nextAlarmAt);
|
|
3154
3163
|
}
|
|
@@ -4337,6 +4346,60 @@ class ShardDO {
|
|
|
4337
4346
|
scheduleSourcePoll() {
|
|
4338
4347
|
return this.scheduleGlobalPoll();
|
|
4339
4348
|
}
|
|
4349
|
+
/**
|
|
4350
|
+
* The resolved TTL policies (`.ttl(field, { after })`) for this DO's schema —
|
|
4351
|
+
* one {@link TtlSweepSpec} per table that declares a TTL. The base `ShardDO`
|
|
4352
|
+
* has no schema, so it returns `[]` and the TTL tier stays dormant. The
|
|
4353
|
+
* codegen subclass overrides it to read each table's `ttlPolicy` (+ its
|
|
4354
|
+
* `.softDelete()` marker) off the imported schema.
|
|
4355
|
+
*/
|
|
4356
|
+
// eslint-disable-next-line class-methods-use-this -- base-class override hook: the codegen subclass reads the imported schema
|
|
4357
|
+
ttlSweeps() {
|
|
4358
|
+
return [];
|
|
4359
|
+
}
|
|
4360
|
+
/**
|
|
4361
|
+
* Sweep every `.ttl()` table once: page the rows past their expiry and remove
|
|
4362
|
+
* each THROUGH the schema-aware writer (`deleteRowThroughWriter`) so companions
|
|
4363
|
+
* / CDC / live subscriptions stay correct and a `.softDelete()` table soft-deletes
|
|
4364
|
+
* instead of physically removing the row. Work is bounded per tick
|
|
4365
|
+
* ({@link TTL_SWEEP_BATCH} × {@link TTL_SWEEP_MAX_BATCHES}) so a large backlog
|
|
4366
|
+
* drains across several alarms without stalling the shard.
|
|
4367
|
+
*
|
|
4368
|
+
* Returns the next-due timestamp (a coarse {@link TTL_SWEEP_INTERVAL_MS}
|
|
4369
|
+
* cadence, so freshly-written rows expire within a bounded window) while any
|
|
4370
|
+
* TTL table exists, or `undefined` when there are none — so a DO with no TTL
|
|
4371
|
+
* table never arms this tier.
|
|
4372
|
+
*/
|
|
4373
|
+
async pollTtlSweeps() {
|
|
4374
|
+
const specs = this.ttlSweeps();
|
|
4375
|
+
if (specs.length === 0) {
|
|
4376
|
+
return void 0;
|
|
4377
|
+
}
|
|
4378
|
+
const sql = this.sql;
|
|
4379
|
+
const now = Date.now();
|
|
4380
|
+
for (const spec of specs) {
|
|
4381
|
+
let batches = 0;
|
|
4382
|
+
let hasMore = true;
|
|
4383
|
+
while (hasMore && batches < TTL_SWEEP_MAX_BATCHES) {
|
|
4384
|
+
const page = selectExpiredIds(sql, spec, now, TTL_SWEEP_BATCH);
|
|
4385
|
+
for (const id of page.ids) {
|
|
4386
|
+
await this.deleteRowThroughWriter(spec.table, id);
|
|
4387
|
+
}
|
|
4388
|
+
hasMore = page.hasMore;
|
|
4389
|
+
batches += 1;
|
|
4390
|
+
}
|
|
4391
|
+
}
|
|
4392
|
+
return now + TTL_SWEEP_INTERVAL_MS;
|
|
4393
|
+
}
|
|
4394
|
+
/**
|
|
4395
|
+
* Arm the shared poll alarm for the TTL sweep. Mirrors {@link scheduleSourcePoll};
|
|
4396
|
+
* the codegen subclass calls it once on construction when the schema declares a
|
|
4397
|
+
* `.ttl()` table so the sweep loop starts, after which {@link ShardDO.alarm}
|
|
4398
|
+
* re-arms itself. Idempotent; a no-op when the runtime exposes no `setAlarm`.
|
|
4399
|
+
*/
|
|
4400
|
+
scheduleTtlSweep() {
|
|
4401
|
+
return this.scheduleGlobalPoll();
|
|
4402
|
+
}
|
|
4340
4403
|
/** This DO's shard key (its DO name), or `__root__` for the single-DO default. The `tenantBy` mapper binds it into the source query. */
|
|
4341
4404
|
currentShardKey() {
|
|
4342
4405
|
return this.state.id?.name ?? ROOT_SHARD_NAME;
|
|
@@ -2,7 +2,7 @@ import { sql } from 'drizzle-orm';
|
|
|
2
2
|
import { matchesStaticWhere } from './AGGREGATE_SQL_FUNCTION-CQsu2Xga.mjs';
|
|
3
3
|
import { encodeAggregateKey, foldAggregateTally, aggregateTableName } from './aggregateTableName-CxNqY1Sl.mjs';
|
|
4
4
|
import { r as runDrizzle } from './do-exec-5eQy5cEi.mjs';
|
|
5
|
-
import { D as DOC_COLUMN, r as rowToDocument, A as AGG_KEY, a as AGG_VALUE, b as AGG_COUNT } from './do-sql-
|
|
5
|
+
import { D as DOC_COLUMN, r as rowToDocument, A as AGG_KEY, a as AGG_VALUE, b as AGG_COUNT } from './do-sql-CGAgiQUz.mjs';
|
|
6
6
|
import { param } from './renderSql-D6eUcn2N.mjs';
|
|
7
7
|
import { sortColumnName, matchesRankStaticWhere, encodePartitionKey, rankTableName } from './RANK_TIEBREAK-CXhdcA1o.mjs';
|
|
8
8
|
import { s as serializeSqlValue } from './serialize-sql-BlRUoiQe.mjs';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { sql } from 'drizzle-orm';
|
|
2
2
|
import { r as runDrizzle } from './do-exec-5eQy5cEi.mjs';
|
|
3
|
-
import { D as DOC_COLUMN, r as rowToDocument, j as jsonPathSql } from './do-sql-
|
|
3
|
+
import { D as DOC_COLUMN, r as rowToDocument, j as jsonPathSql } from './do-sql-CGAgiQUz.mjs';
|
|
4
4
|
import { compileWhereSql } from './compileWhereSql-DE6yfRcQ.mjs';
|
|
5
5
|
import { s as serializeSqlValue } from './serialize-sql-BlRUoiQe.mjs';
|
|
6
6
|
|
|
@@ -2,6 +2,7 @@ import { sql } from 'drizzle-orm';
|
|
|
2
2
|
import { r as runDrizzle } from './do-exec-5eQy5cEi.mjs';
|
|
3
3
|
|
|
4
4
|
const DOC_COLUMN = "__doc__";
|
|
5
|
+
const geoTableName = (table, indexName) => `${table}__geo_${indexName}`;
|
|
5
6
|
const quoteIdentifier = (name) => `"${name.replaceAll('"', '""')}"`;
|
|
6
7
|
const jsonPath = (field) => {
|
|
7
8
|
if (field === "_id" || field === "id") {
|
|
@@ -84,4 +85,4 @@ const isFtsAvailable = (sql$1) => {
|
|
|
84
85
|
return available;
|
|
85
86
|
};
|
|
86
87
|
|
|
87
|
-
export { AGG_KEY as A, DOC_COLUMN as D, AGG_VALUE as a, AGG_COUNT as b, createIndexSql as c, aggUpsertSql as d, qualifiedJsonPathSql as e, isFtsAvailable as i, jsonPathSql as j, quoteIdentifier as q, rowToDocument as r, tableColumns as t };
|
|
88
|
+
export { AGG_KEY as A, DOC_COLUMN as D, AGG_VALUE as a, AGG_COUNT as b, createIndexSql as c, aggUpsertSql as d, qualifiedJsonPathSql as e, geoTableName as g, isFtsAvailable as i, jsonPathSql as j, quoteIdentifier as q, rowToDocument as r, tableColumns as t };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { LunoraError } from '@lunora/errors';
|
|
2
2
|
import { sql } from 'drizzle-orm';
|
|
3
3
|
import { r as runDrizzle } from './do-exec-5eQy5cEi.mjs';
|
|
4
|
-
import { runExternalSourceTick, materializeExternalRowsIncremental } from './materializeExternalRows-
|
|
4
|
+
import { runExternalSourceTick, materializeExternalRowsIncremental } from './materializeExternalRows-BtEGs1Fv.mjs';
|
|
5
5
|
|
|
6
6
|
const SOURCE_CURSOR_TABLE = "__lunora_source_cursor";
|
|
7
7
|
const serializeCursor = (value) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { applyCdcChanges } from './CDC_LOG_TABLE-uwOJxJJZ.mjs';
|
|
2
|
-
import { s as selectShapeRows } from './ctx-db-shapes-
|
|
2
|
+
import { s as selectShapeRows } from './ctx-db-shapes-DTeFiHYS.mjs';
|
|
3
3
|
import { diffExternalSource, projectExternalSourceRow } from './diffExternalSource-CovHfdyo.mjs';
|
|
4
4
|
import { stableStringify } from './stableStringify-mC40mZts.mjs';
|
|
5
5
|
|
package/dist/packem_shared/{runShardMigrations-DFzx6Qld.mjs → runShardMigrations-BVax6rYu.mjs}
RENAMED
|
@@ -3,7 +3,7 @@ import { aggregateTableName } from './aggregateTableName-CxNqY1Sl.mjs';
|
|
|
3
3
|
import { migrateCdcLog, migrateCdcMeta } from './CDC_LOG_TABLE-uwOJxJJZ.mjs';
|
|
4
4
|
import { m as migrateClientWatermark, a as migrateIdempotency, b as migrateGlobalShapeSnapshot } from './ctx-db-idempotency-BdcNpvY4.mjs';
|
|
5
5
|
import { r as runDrizzle } from './do-exec-5eQy5cEi.mjs';
|
|
6
|
-
import { D as DOC_COLUMN, j as jsonPathSql, c as createIndexSql, t as tableColumns, i as isFtsAvailable, A as AGG_KEY, a as AGG_VALUE, b as AGG_COUNT } from './do-sql-
|
|
6
|
+
import { D as DOC_COLUMN, j as jsonPathSql, c as createIndexSql, t as tableColumns, i as isFtsAvailable, A as AGG_KEY, a as AGG_VALUE, b as AGG_COUNT, g as geoTableName } from './do-sql-CGAgiQUz.mjs';
|
|
7
7
|
import { sortColumnName, rankTableName } from './RANK_TIEBREAK-CXhdcA1o.mjs';
|
|
8
8
|
import { ftsTableName } from './buildFtsMatch-BLEMawrp.mjs';
|
|
9
9
|
|
|
@@ -36,6 +36,20 @@ const migrateSearchIndexes = (sql$1, tableName, definition) => {
|
|
|
36
36
|
);
|
|
37
37
|
}
|
|
38
38
|
};
|
|
39
|
+
const migrateGeoIndexes = (sql$1, tableName, definition) => {
|
|
40
|
+
if (!definition.geoIndexes) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
for (const index of definition.geoIndexes) {
|
|
44
|
+
const geoTable = geoTableName(tableName, index.name);
|
|
45
|
+
runDrizzle(
|
|
46
|
+
sql$1,
|
|
47
|
+
sql`CREATE TABLE IF NOT EXISTS ${sql.identifier(geoTable)} (${sql.identifier("__id__")} TEXT PRIMARY KEY, ${sql.identifier("__geohash__")} TEXT NOT NULL, ${sql.identifier("__lat__")} REAL NOT NULL, ${sql.identifier("__lng__")} REAL NOT NULL)`
|
|
48
|
+
);
|
|
49
|
+
const btreeName = `${tableName}__geo_${index.name}__btree`;
|
|
50
|
+
runDrizzle(sql$1, createIndexSql(btreeName, geoTable, sql`${sql.identifier("__geohash__")} ASC, ${sql.identifier("__id__")} ASC`, false));
|
|
51
|
+
}
|
|
52
|
+
};
|
|
39
53
|
const migrateAggregateIndexes = (sql$1, tableName, definition) => {
|
|
40
54
|
if (!definition.aggregateIndexes) {
|
|
41
55
|
return;
|
|
@@ -90,6 +104,7 @@ const runShardMigrations = (sql$1, schema, options = {}) => {
|
|
|
90
104
|
);
|
|
91
105
|
migrateSecondaryIndexes(sql$1, tableName, definition);
|
|
92
106
|
migrateSearchIndexes(sql$1, tableName, definition);
|
|
107
|
+
migrateGeoIndexes(sql$1, tableName, definition);
|
|
93
108
|
migrateAggregateIndexes(sql$1, tableName, definition);
|
|
94
109
|
migrateRankIndexes(sql$1, tableName, definition);
|
|
95
110
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { sql } from 'drizzle-orm';
|
|
2
|
+
import { r as runDrizzle } from './do-exec-5eQy5cEi.mjs';
|
|
3
|
+
import { j as jsonPathSql } from './do-sql-CGAgiQUz.mjs';
|
|
4
|
+
|
|
5
|
+
const selectExpiredIds = (sql$1, spec, now, limit) => {
|
|
6
|
+
const cutoff = now - (spec.after ?? 0);
|
|
7
|
+
const conditions = [sql`${jsonPathSql(spec.field)} IS NOT NULL`, sql`${jsonPathSql(spec.field)} < ${cutoff}`];
|
|
8
|
+
if (spec.softDeleteField !== void 0) {
|
|
9
|
+
conditions.push(sql`${jsonPathSql(spec.softDeleteField)} IS NULL`);
|
|
10
|
+
}
|
|
11
|
+
const query = sql`SELECT id FROM ${sql.identifier(spec.table)} WHERE ${sql.join(conditions, sql` AND `)} LIMIT ${sql.raw(String(Math.max(0, Math.floor(limit)) + 1))}`;
|
|
12
|
+
const rows = runDrizzle(sql$1, query).toArray();
|
|
13
|
+
const hasMore = rows.length > limit;
|
|
14
|
+
const ids = rows.slice(0, limit).map((row) => row.id);
|
|
15
|
+
return { hasMore, ids };
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export { selectExpiredIds };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/do",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.38",
|
|
4
4
|
"description": "Lunora Durable Objects: ShardDO (SQLite, OCC, hibernated WebSocket subscriptions) and SessionDO",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cloudflare",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"access": "public"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@lunora/errors": "1.0.0-alpha.
|
|
49
|
+
"@lunora/errors": "1.0.0-alpha.7",
|
|
50
50
|
"@lunora/fingerprint": "1.0.0-alpha.3",
|
|
51
51
|
"@visulima/redact": "3.0.0",
|
|
52
52
|
"drizzle-orm": "^0.45.2"
|