@lunora/shard-engine 1.0.0-alpha.64 → 1.0.0-alpha.65

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.
@@ -1 +1 @@
1
- import{defineEngineContractSuite as t}from"../packem_shared/defineEngineContractSuite-CrV-eh9a.mjs";export{t as defineEngineContractSuite};
1
+ import{defineEngineContractSuite as t}from"../packem_shared/defineEngineContractSuite-BFT_djtN.mjs";export{t as defineEngineContractSuite};
package/dist/index.d.mts CHANGED
@@ -88,6 +88,75 @@ interface WhereInput {
88
88
  OR?: WhereInput[];
89
89
  }
90
90
  declare const RELATION_EXISTS_KEY = "__relationExists";
91
+ interface SubscriptionQuery {
92
+ args?: Record<string, unknown>;
93
+ functionPath?: string;
94
+ sinceEpoch?: string;
95
+ sinceSeq?: number;
96
+ table?: string;
97
+ }
98
+ interface ShapeSubscriptionQuery {
99
+ args?: Record<string, unknown>;
100
+ name: string;
101
+ sinceEpoch?: string;
102
+ sinceSeq?: number;
103
+ }
104
+ interface SubscriptionEnvelope {
105
+ caps?: string[];
106
+ clientId?: string;
107
+ context?: Record<string, unknown>;
108
+ data?: unknown;
109
+ generation?: number;
110
+ id: string;
111
+ query?: SubscriptionQuery;
112
+ shape?: {
113
+ args?: Record<string, unknown>;
114
+ name: string;
115
+ };
116
+ sinceCheckpoint?: number;
117
+ sinceChunk?: number;
118
+ sinceEpoch?: string;
119
+ topic?: string;
120
+ type: "ack" | "connect" | "shape_subscribe" | "shape_unsubscribe" | "stream" | "subscribe" | "unsubscribe" | "whisper" | "whisper_subscribe" | "whisper_unsubscribe";
121
+ }
122
+ interface RpcRequest {
123
+ args?: Record<string, unknown>;
124
+ functionPath: string;
125
+ }
126
+ interface SocketAttachment {
127
+ admin?: boolean;
128
+ adminBinding?: string;
129
+ clientId?: string;
130
+ connected?: boolean;
131
+ connectionId?: string;
132
+ context?: Record<string, unknown>;
133
+ expiresAt?: number;
134
+ identity?: Record<string, unknown>;
135
+ ip?: string;
136
+ pageDeltas?: boolean;
137
+ shapes?: Record<string, ShapeSubscriptionQuery>;
138
+ subs: Record<string, SubscriptionQuery>;
139
+ userId?: string;
140
+ whispers?: string[];
141
+ }
142
+ interface ResolvedShape {
143
+ columns?: ReadonlyArray<string>;
144
+ effectiveWhere?: WhereInput;
145
+ global?: boolean;
146
+ table: string;
147
+ }
148
+ interface SubscriptionIdentity {
149
+ identity?: Record<string, unknown>;
150
+ ip?: string;
151
+ userId?: string;
152
+ }
153
+ interface ShardSocketLike {
154
+ readonly bufferedAmount?: number;
155
+ close?: (code?: number, reason?: string) => void;
156
+ deserializeAttachment?: () => unknown;
157
+ send: (data: string) => void;
158
+ serializeAttachment?: (value: unknown) => void;
159
+ }
91
160
  type AggregateOp = "avg" | "count" | "max" | "min" | "sum";
92
161
  interface AggregateIndexDefinitionLike {
93
162
  readonly by?: ReadonlyArray<string>;
@@ -457,10 +526,8 @@ interface LifecycleEvent {
457
526
  shardKey: string;
458
527
  userId: string | null;
459
528
  }
460
- interface LifecycleDispatchInfo {
529
+ interface LifecycleDispatchInfo extends SubscriptionIdentity {
461
530
  event: LifecycleEvent;
462
- identity: Record<string, unknown> | undefined;
463
- userId: string | undefined;
464
531
  }
465
532
  interface MutationDelta {
466
533
  indexKeys?: ReadonlyArray<IndexKeyEntry>;
@@ -905,73 +972,6 @@ declare const COMMIT_SEQ_FIELD = "_commitSeq";
905
972
  declare const migrateCommitSeq: (sql: SqlExec) => void;
906
973
  declare const readCommitSeq: (sql: SqlExec) => number;
907
974
  declare const allocateCommitSeq: (sql: SqlExec) => number;
908
- interface SubscriptionQuery {
909
- args?: Record<string, unknown>;
910
- functionPath?: string;
911
- sinceEpoch?: string;
912
- sinceSeq?: number;
913
- table?: string;
914
- }
915
- interface ShapeSubscriptionQuery {
916
- args?: Record<string, unknown>;
917
- name: string;
918
- sinceEpoch?: string;
919
- sinceSeq?: number;
920
- }
921
- interface SubscriptionEnvelope {
922
- caps?: string[];
923
- clientId?: string;
924
- context?: Record<string, unknown>;
925
- data?: unknown;
926
- generation?: number;
927
- id: string;
928
- query?: SubscriptionQuery;
929
- shape?: {
930
- args?: Record<string, unknown>;
931
- name: string;
932
- };
933
- sinceCheckpoint?: number;
934
- sinceChunk?: number;
935
- sinceEpoch?: string;
936
- topic?: string;
937
- type: "ack" | "connect" | "shape_subscribe" | "shape_unsubscribe" | "stream" | "subscribe" | "unsubscribe" | "whisper" | "whisper_subscribe" | "whisper_unsubscribe";
938
- }
939
- interface RpcRequest {
940
- args?: Record<string, unknown>;
941
- functionPath: string;
942
- }
943
- interface SocketAttachment {
944
- admin?: boolean;
945
- adminBinding?: string;
946
- clientId?: string;
947
- connected?: boolean;
948
- connectionId?: string;
949
- context?: Record<string, unknown>;
950
- expiresAt?: number;
951
- identity?: Record<string, unknown>;
952
- pageDeltas?: boolean;
953
- shapes?: Record<string, ShapeSubscriptionQuery>;
954
- subs: Record<string, SubscriptionQuery>;
955
- userId?: string;
956
- whispers?: string[];
957
- }
958
- interface ResolvedShape {
959
- columns?: ReadonlyArray<string>;
960
- effectiveWhere?: WhereInput;
961
- global?: boolean;
962
- table: string;
963
- }
964
- interface SubscriptionIdentity {
965
- identity?: Record<string, unknown>;
966
- userId?: string;
967
- }
968
- interface ShardSocketLike {
969
- readonly bufferedAmount?: number;
970
- close?: (code?: number, reason?: string) => void;
971
- deserializeAttachment?: () => unknown;
972
- send: (data: string) => void;
973
- serializeAttachment?: (value: unknown) => void;
974
- }
975
975
  interface CompanionSyncDeps {
976
976
  broadcast: (delta: MutationDelta) => void;
977
977
  indexKeysFor: (table: string, document?: Record<string, unknown>) => ReadonlyArray<{
@@ -2296,10 +2296,7 @@ declare class ShapeDiffCache {
2296
2296
  private getOrLoad;
2297
2297
  }
2298
2298
  declare const createShapeDiffCache: () => ShapeDiffCache;
2299
- declare const globalShapeReadKey: (resolved: ResolvedShape, identity: {
2300
- identity?: Record<string, unknown>;
2301
- userId?: string;
2302
- }) => string | undefined;
2299
+ declare const globalShapeReadKey: (resolved: ResolvedShape, identity: SubscriptionIdentity) => string | undefined;
2303
2300
  type ReadShapeCdcKeys = (sql: SqlExec, table: string, sinceSeq: number, upTo: number) => CdcChangeKey[];
2304
2301
  declare const buildShapeDiff: (sql: SqlExec, resolved: ResolvedShape, sinceSeq: number, upTo: number, cache: ShapeDiffCache, readKeys?: ReadShapeCdcKeys) => ShapeRowOp[];
2305
2302
  interface ShardRunnerOptions {
package/dist/index.d.ts CHANGED
@@ -88,6 +88,75 @@ interface WhereInput {
88
88
  OR?: WhereInput[];
89
89
  }
90
90
  declare const RELATION_EXISTS_KEY = "__relationExists";
91
+ interface SubscriptionQuery {
92
+ args?: Record<string, unknown>;
93
+ functionPath?: string;
94
+ sinceEpoch?: string;
95
+ sinceSeq?: number;
96
+ table?: string;
97
+ }
98
+ interface ShapeSubscriptionQuery {
99
+ args?: Record<string, unknown>;
100
+ name: string;
101
+ sinceEpoch?: string;
102
+ sinceSeq?: number;
103
+ }
104
+ interface SubscriptionEnvelope {
105
+ caps?: string[];
106
+ clientId?: string;
107
+ context?: Record<string, unknown>;
108
+ data?: unknown;
109
+ generation?: number;
110
+ id: string;
111
+ query?: SubscriptionQuery;
112
+ shape?: {
113
+ args?: Record<string, unknown>;
114
+ name: string;
115
+ };
116
+ sinceCheckpoint?: number;
117
+ sinceChunk?: number;
118
+ sinceEpoch?: string;
119
+ topic?: string;
120
+ type: "ack" | "connect" | "shape_subscribe" | "shape_unsubscribe" | "stream" | "subscribe" | "unsubscribe" | "whisper" | "whisper_subscribe" | "whisper_unsubscribe";
121
+ }
122
+ interface RpcRequest {
123
+ args?: Record<string, unknown>;
124
+ functionPath: string;
125
+ }
126
+ interface SocketAttachment {
127
+ admin?: boolean;
128
+ adminBinding?: string;
129
+ clientId?: string;
130
+ connected?: boolean;
131
+ connectionId?: string;
132
+ context?: Record<string, unknown>;
133
+ expiresAt?: number;
134
+ identity?: Record<string, unknown>;
135
+ ip?: string;
136
+ pageDeltas?: boolean;
137
+ shapes?: Record<string, ShapeSubscriptionQuery>;
138
+ subs: Record<string, SubscriptionQuery>;
139
+ userId?: string;
140
+ whispers?: string[];
141
+ }
142
+ interface ResolvedShape {
143
+ columns?: ReadonlyArray<string>;
144
+ effectiveWhere?: WhereInput;
145
+ global?: boolean;
146
+ table: string;
147
+ }
148
+ interface SubscriptionIdentity {
149
+ identity?: Record<string, unknown>;
150
+ ip?: string;
151
+ userId?: string;
152
+ }
153
+ interface ShardSocketLike {
154
+ readonly bufferedAmount?: number;
155
+ close?: (code?: number, reason?: string) => void;
156
+ deserializeAttachment?: () => unknown;
157
+ send: (data: string) => void;
158
+ serializeAttachment?: (value: unknown) => void;
159
+ }
91
160
  type AggregateOp = "avg" | "count" | "max" | "min" | "sum";
92
161
  interface AggregateIndexDefinitionLike {
93
162
  readonly by?: ReadonlyArray<string>;
@@ -457,10 +526,8 @@ interface LifecycleEvent {
457
526
  shardKey: string;
458
527
  userId: string | null;
459
528
  }
460
- interface LifecycleDispatchInfo {
529
+ interface LifecycleDispatchInfo extends SubscriptionIdentity {
461
530
  event: LifecycleEvent;
462
- identity: Record<string, unknown> | undefined;
463
- userId: string | undefined;
464
531
  }
465
532
  interface MutationDelta {
466
533
  indexKeys?: ReadonlyArray<IndexKeyEntry>;
@@ -905,73 +972,6 @@ declare const COMMIT_SEQ_FIELD = "_commitSeq";
905
972
  declare const migrateCommitSeq: (sql: SqlExec) => void;
906
973
  declare const readCommitSeq: (sql: SqlExec) => number;
907
974
  declare const allocateCommitSeq: (sql: SqlExec) => number;
908
- interface SubscriptionQuery {
909
- args?: Record<string, unknown>;
910
- functionPath?: string;
911
- sinceEpoch?: string;
912
- sinceSeq?: number;
913
- table?: string;
914
- }
915
- interface ShapeSubscriptionQuery {
916
- args?: Record<string, unknown>;
917
- name: string;
918
- sinceEpoch?: string;
919
- sinceSeq?: number;
920
- }
921
- interface SubscriptionEnvelope {
922
- caps?: string[];
923
- clientId?: string;
924
- context?: Record<string, unknown>;
925
- data?: unknown;
926
- generation?: number;
927
- id: string;
928
- query?: SubscriptionQuery;
929
- shape?: {
930
- args?: Record<string, unknown>;
931
- name: string;
932
- };
933
- sinceCheckpoint?: number;
934
- sinceChunk?: number;
935
- sinceEpoch?: string;
936
- topic?: string;
937
- type: "ack" | "connect" | "shape_subscribe" | "shape_unsubscribe" | "stream" | "subscribe" | "unsubscribe" | "whisper" | "whisper_subscribe" | "whisper_unsubscribe";
938
- }
939
- interface RpcRequest {
940
- args?: Record<string, unknown>;
941
- functionPath: string;
942
- }
943
- interface SocketAttachment {
944
- admin?: boolean;
945
- adminBinding?: string;
946
- clientId?: string;
947
- connected?: boolean;
948
- connectionId?: string;
949
- context?: Record<string, unknown>;
950
- expiresAt?: number;
951
- identity?: Record<string, unknown>;
952
- pageDeltas?: boolean;
953
- shapes?: Record<string, ShapeSubscriptionQuery>;
954
- subs: Record<string, SubscriptionQuery>;
955
- userId?: string;
956
- whispers?: string[];
957
- }
958
- interface ResolvedShape {
959
- columns?: ReadonlyArray<string>;
960
- effectiveWhere?: WhereInput;
961
- global?: boolean;
962
- table: string;
963
- }
964
- interface SubscriptionIdentity {
965
- identity?: Record<string, unknown>;
966
- userId?: string;
967
- }
968
- interface ShardSocketLike {
969
- readonly bufferedAmount?: number;
970
- close?: (code?: number, reason?: string) => void;
971
- deserializeAttachment?: () => unknown;
972
- send: (data: string) => void;
973
- serializeAttachment?: (value: unknown) => void;
974
- }
975
975
  interface CompanionSyncDeps {
976
976
  broadcast: (delta: MutationDelta) => void;
977
977
  indexKeysFor: (table: string, document?: Record<string, unknown>) => ReadonlyArray<{
@@ -2296,10 +2296,7 @@ declare class ShapeDiffCache {
2296
2296
  private getOrLoad;
2297
2297
  }
2298
2298
  declare const createShapeDiffCache: () => ShapeDiffCache;
2299
- declare const globalShapeReadKey: (resolved: ResolvedShape, identity: {
2300
- identity?: Record<string, unknown>;
2301
- userId?: string;
2302
- }) => string | undefined;
2299
+ declare const globalShapeReadKey: (resolved: ResolvedShape, identity: SubscriptionIdentity) => string | undefined;
2303
2300
  type ReadShapeCdcKeys = (sql: SqlExec, table: string, sinceSeq: number, upTo: number) => CdcChangeKey[];
2304
2301
  declare const buildShapeDiff: (sql: SqlExec, resolved: ResolvedShape, sinceSeq: number, upTo: number, cache: ShapeDiffCache, readKeys?: ReadShapeCdcKeys) => ShapeRowOp[];
2305
2302
  interface ShardRunnerOptions {
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{exportShardRows as o,importShardRows as a,parseExportShardArgs as t,parseImportShardArgs as n,selectExportTables as i,validateImportRow as l}from"./packem_shared/exportShardRows-D_upYHRQ.mjs";import{AGGREGATE_SQL_FUNCTION as m,aggregateSqlFunction as c,matchesStaticWhere as d,normalizeCountArgument as p,throwingScheduler as S}from"./packem_shared/AGGREGATE_SQL_FUNCTION-DDEoMnJR.mjs";import{aggregateTableName as f,coerceAggregateNumber as E,encodeAggregateKey as T,foldAggregateTally as h,readAggregateValue as x}from"./packem_shared/aggregateTableName-C7o-gpms.mjs";import{CountRlsUnsupportedError as R,mergeWhere as A,planAggregateLookup as g,selectIndexForAggregate as _,selectIndexForCount as I,selectIndexForGroupBy as b}from"./packem_shared/CountRlsUnsupportedError-BvsDqfO2.mjs";import{AUDIT_LOG_TABLE as D,appendAuditEntry as P,ensureAuditTable as M,readAuditLog as y}from"./packem_shared/AUDIT_LOG_TABLE-ONxmEAIz.mjs";import{NotUniqueError as N,assertNoExplicitUndefined as O,assertValidClientId as k,createShardCtxDb as B,normalizeIdStructurally as G}from"./packem_shared/NotUniqueError-BMom69SD.mjs";import{backfillAggregateIndexes as q,backfillRankIndexes as K,backfillSearchIndexes as w,backfillSearchIndexesForTable as v}from"./packem_shared/backfillAggregateIndexes-BG5-SC1q.mjs";import{CDC_LOG_TABLE as X,CDC_LOG_TABLE_SEQ_INDEX as H,CDC_META_TABLE as z,appendCdcChange as V,applyCdcChanges as Q,bumpCdcEpoch as Y,cdcCanVouchFor as j,cdcSeqLeavingRows as J,cdcTouchesTables as Z,cdcTrimmedError as $,compactCdcDocs as ee,cursorBelowRetainedFloor as re,migrateCdcLog as oe,migrateCdcMeta as ae,minCdcReplayableSeq as te,minCdcSeq as ne,readCdcChangeKeys as ie,readCdcChanges as le,readCdcCursor as se,readCdcEpoch as me,trimCdcChanges as ce}from"./packem_shared/CDC_LOG_TABLE-vVheEulD.mjs";import{archiveCdcSegment as pe,readArchivedCdcChanges as Se,readCdcArchivedThrough as ue,writeCdcArchivedThrough as fe}from"./packem_shared/archiveCdcSegment-DU4uzDFQ.mjs";import{CLIENT_WATERMARK_TABLE as Te,advanceClientWatermark as he,migrateClientWatermark as xe,readClientWatermark as Ce}from"./packem_shared/CLIENT_WATERMARK_TABLE-CRnrAnJ2.mjs";import{COMMIT_SEQ_FIELD as Ae,COMMIT_SEQ_TABLE as ge,allocateCommitSeq as _e,migrateCommitSeq as Ie,readCommitSeq as be}from"./packem_shared/COMMIT_SEQ_FIELD-BUdOMG5y.mjs";import{c as De}from"./packem_shared/ctx-db-companions-w-CfeOda.mjs";import{GLOBAL_SHAPE_SNAPSHOT_TABLE as Me,deleteGlobalShapeSnapshot as ye,deleteGlobalShapeSnapshotsForConnection as Fe,migrateGlobalShapeSnapshot as Ne,readGlobalShapeSnapshot as Oe,writeGlobalShapeSnapshot as ke}from"./packem_shared/GLOBAL_SHAPE_SNAPSHOT_TABLE-DSA6mzyx.mjs";import{IDEMPOTENCY_TABLE as Ge,migrateIdempotency as Ue,readIdempotent as qe,trimIdempotent as Ke,writeIdempotent as we}from"./packem_shared/IDEMPOTENCY_TABLE-DOpm_oMF.mjs";import{clearMemoryTables as We,isMemoryTable as Xe,memoryTableNames as He}from"./packem_shared/clearMemoryTables-BGbmag2i.mjs";import{computeRankPage as Ve,resolveRankSeekTuple as Qe}from"./packem_shared/computeRankPage-DsQ16o1z.mjs";import{S as je,m as Je,r as Ze,w as $e}from"./packem_shared/ctx-db-search-state-ruTuCsxa.mjs";import{SHAPE_POKE_CURSOR_TABLE as rr,deleteShapePokeCursor as or,deleteShapePokeCursorsForConnection as ar,migrateShapePokeCursor as tr,minShapePokeCursor as nr,readShapePokeCursor as ir,writeShapePokeCursor as lr,writeShapePokeCursors as sr}from"./packem_shared/SHAPE_POKE_CURSOR_TABLE-ByJVDHds.mjs";import{selectShapeMembers as cr,selectShapeRows as dr}from"./packem_shared/selectShapeMembers-CCZyZggM.mjs";import{DATA_MIGRATION_STATE_TABLE as Sr,readMigrationStatus as ur,runDataMigration as fr}from"./packem_shared/DATA_MIGRATION_STATE_TABLE-BNMWxRzv.mjs";import{SCAN_DEP as Tr,createDependencyTracker as hr,depKey as xr,tableFromDepKey as Cr}from"./packem_shared/SCAN_DEP-D7qE3iUe.mjs";import{runDrizzle as Ar,runSql as gr}from"./packem_shared/runDrizzle-2ULFQR_k.mjs";import{A as Ir,a as br,b as Lr,D as Dr,c as Pr,d as Mr,g as yr,i as Fr,j as Nr,e as Or,q as kr,f as Br,r as Gr,t as Ur,h as qr}from"./packem_shared/do-sql-Dvj8Yl5N.mjs";import{param as wr,renderSql as vr,sqliteInList as Wr,unionAll as Xr}from"./packem_shared/param-DlozcSQu.mjs";import{appendStreamChunk as zr,claimStreamRun as Vr,deleteStreamRun as Qr,finishStreamRun as Yr,migrateDurableStreams as jr,readStreamChunks as Jr,readStreamRun as Zr,trimStreamRuns as $r}from"./packem_shared/appendStreamChunk-C1Ok4b6J.mjs";import{DurableStreamRunner as ro,MAX_DURABLE_STREAM_BYTES as oo,MAX_DURABLE_STREAM_CHUNKS as ao,decideDurableAttach as to}from"./packem_shared/DurableStreamRunner-rTYp4v03.mjs";import{envOptionalPositiveInt as io,envPositiveInt as lo}from"./packem_shared/envOptionalPositiveInt-D2pY-c64.mjs";import{diffExternalSource as mo}from"./packem_shared/diffExternalSource-DgDJhslq.mjs";import{liftSourceId as po,normalizeSourceDocument as So,normalizeSourceValue as uo}from"./packem_shared/liftSourceId-CA3ENhXj.mjs";import{materializeExternalRows as Eo,materializeExternalRowsIncremental as To,readExternalSourceBaseline as ho,runExternalSourceTick as xo}from"./packem_shared/materializeExternalRows-iEVQKOKT.mjs";import{isSoftDeleted as Ro,isSourceDue as Ao,pullExternalSourceIncrementalTick as go,pullExternalSourceTick as _o}from"./packem_shared/isSoftDeleted-CYf6ijO3.mjs";import{GEO_DEFAULT_PRECISION as bo,boundingBoxCenter as Lo,boundingBoxGeohashes as Do,coveringGeohashes as Po,encodeGeohash as Mo,haversineMeters as yo,pointInBoundingBox as Fo}from"./packem_shared/GEO_DEFAULT_PRECISION-CqpQZ-J_.mjs";import{default as Oo}from"./packem_shared/GlobalPollTick-BNK4o-XT.mjs";import{ADMIN_FUNCTIONS as Bo,ADMIN_FUNCTION_PREFIX as Go,DEFAULT_FANOUT_TOPIC_LIMIT as Uo,FLAGS_FUNCTION_PREFIX as qo,MAX_PAGE_SIZE as Ko,RELATION_FUNCTION_PREFIX as wo,createFanoutCounters as vo,createGlobalPollCounters as Wo,createShapeProbeCounters as Xo,facetColumn as Ho,findStorageReferences as zo,listTables as Vo,readTablePage as Qo,recordFanoutPass as Yo,recordGlobalPollPass as jo,recordShapeProbePass as Jo,selectMatchingIds as Zo,summarizeFanoutTopics as $o,summarizeSubscriptions as ea}from"./packem_shared/ADMIN_FUNCTIONS-CRXp5IZu.mjs";import{MAIL_RETENTION as oa,MAIL_TABLE as aa,clearCapturedMail as ta,ensureMailTable as na,readCapturedMail as ia,recordCapturedMail as la}from"./packem_shared/MAIL_RETENTION-DGAQTHHs.mjs";import{NotFoundError as ma}from"./packem_shared/NotFoundError-BhF7FeFr.mjs";import{armRestore as da,readBookmark as pa}from"./packem_shared/armRestore-Bu1_8SUa.mjs";import{CURSOR_PREFIX as ua,applySelect as fa,buildSeekBeforeWhere as Ea,buildSeekWhere as Ta,decodeCursor as ha,encodeCursor as xa,equalityPinnedFields as Ca,normalizeOrderKeys as Ra,softDeleteScope as Aa,tiebreakDirectionFor as ga,uniqueIndexFields as _a}from"./packem_shared/CURSOR_PREFIX-Bn8SFoGd.mjs";import{QUEUE_TABLE as ba,clearQueueMessages as La,isLossyBody as Da,readQueueMessageById as Pa,readQueueMessages as Ma,recordQueueMessages as ya}from"./packem_shared/QUEUE_TABLE-s7QJZvBz.mjs";import{RANK_TIEBREAK as Na,encodePartitionKey as Oa,matchesRankStaticWhere as ka,rankKeyFromDoc as Ba,rankPivotConditionSql as Ga,rankTableName as Ua,resolveRankPartition as qa,sortColumnName as Ka}from"./packem_shared/RANK_TIEBREAK-BXDiMmkH.mjs";import{ReactiveCache as va,reactiveCacheKey as Wa}from"./packem_shared/ReactiveCache-CzeUmTTN.mjs";import{REACTOR_STATE_TABLE as Ha,listReactorStates as za,migrateReactorState as Va,reactorNeedsRun as Qa,readReactorState as Ya,writeReactorState as ja}from"./packem_shared/REACTOR_STATE_TABLE-QPRFyxMS.mjs";import{UNVOUCHABLE_DEP as Za,createReadFootprint as $a,markUnvouchableReads as et}from"./packem_shared/UNVOUCHABLE_DEP-C68htACn.mjs";import{buildIndexRange as ot,indexKeysForRow as at,keysTouchRanges as tt}from"./packem_shared/buildIndexRange-NtciKq3M.mjs";import{RELATED_DEFAULT_LIMIT as it,RELATED_DEPTH_DECAY as lt,RELATED_MAX_DEPTH as st,RELATED_MAX_LIMIT as mt,deriveRelationEdges as ct,findRelated as dt}from"./packem_shared/RELATED_DEFAULT_LIMIT-B9PH28Pn.mjs";import{DEFAULT_MAX_RELATION_KEYS as St,assertFlatPredicate as ut,assertShapeShardable as ft,containsRelationPredicate as Et,isRelationPredicate as Tt,resolveRelationPredicates as ht}from"./packem_shared/DEFAULT_MAX_RELATION_KEYS-XESc7TiB.mjs";import{applyOnDelete as Ct,distinctValues as Rt,fanOutScalarCounts as At,relationHooks as gt,resolveWith as _t,runRowValidators as It}from"./packem_shared/applyOnDelete-7JZ4vR9r.mjs";import{DEFAULT_PROMOTION_THRESHOLDS as Lt,clampPromotionThresholds as Dt,nextPromotionState as Pt,relayCountFor as Mt,shapeRoutingKey as yt}from"./packem_shared/DEFAULT_PROMOTION_THRESHOLDS-Bfx7KakS.mjs";import{DEFAULT_MAX_RELAYS as Nt,OwnerRelay as Ot,RelayMember as kt,createRelayLink as Bt}from"./packem_shared/DEFAULT_MAX_RELAYS-DDOVsK5A.mjs";import{createReplicaLink as Ut,gateReplicaDispatch as qt,handleReplicaControl as Kt}from"./packem_shared/createReplicaLink-Bo4IWADY.mjs";import{buildReprojectionMigration as vt,countLegacyRows as Wt,reprojectableFields as Xt,reprojectionTables as Ht}from"./packem_shared/buildReprojectionMigration-Coeg-J0M.mjs";import{RLS_UNWRAP_SYMBOL as Vt,RlsRequiredError as Qt,guardWriter as Yt}from"./packem_shared/RLS_UNWRAP_SYMBOL-BwwTbz3Q.mjs";import{SCHEMA_HISTORY_MAX_VERSIONS as Jt,readSchemaHistory as Zt,readSchemaVersion as $t,recordSchemaVersion as en}from"./packem_shared/SCHEMA_HISTORY_MAX_VERSIONS-BluIj2s-.mjs";import{serializeSqlValue as on}from"./packem_shared/serializeSqlValue-CjbhIHjJ.mjs";import{buildSettings as tn,isDevEnvironment as nn,readDeployInfo as ln}from"./packem_shared/buildSettings-DC3VeQ0H.mjs";import{buildShapeDiff as mn}from"./packem_shared/buildShapeDiff-WSoMs1_h.mjs";import{ShapeDiffCache as dn,createShapeDiffCache as pn,globalShapeReadKey as Sn}from"./packem_shared/ShapeDiffCache-gdaILV5E.mjs";import{buildPokeFrames as fn,diffGlobalMembership as En,encodeRowsPatch as Tn,projectColumns as hn}from"./packem_shared/buildPokeFrames-BBE6J91z.mjs";import{ShardRunner as Cn}from"./packem_shared/ShardRunner-C9p5DVOx.mjs";import{runSocketPool as An}from"./packem_shared/runSocketPool-CZJ2X9cF.mjs";import{MAX_SQL_ROWS as _n,assertReadonly as In,lintReadonlySql as bn,runReadonlySql as Ln}from"./packem_shared/MAX_SQL_ROWS-RvXZ7S7f.mjs";import{B as Pn,b as Mn,d as yn,a as Fn,f as Nn}from"./packem_shared/sql-projection-BB2lCbYV.mjs";import{awaitWsDrain as kn,subscriptionFrames as Bn,subscriptionListDeltas as Gn,trySendFrame as Un}from"./packem_shared/awaitWsDrain-apizgmKY.mjs";import{mergeChangedKeys as Kn,recordChangedKeys as wn,writeTouchesMemo as vn}from"./packem_shared/mergeChangedKeys-CPw4EamV.mjs";import{createSystemReader as Xn}from"./packem_shared/createSystemReader-DcDLFfC-.mjs";import{ConflictError as zn}from"./packem_shared/ConflictError-C8GtJmjS.mjs";import{DEFAULT_TRANSACTION_LIMITS as Qn,TransactionHeadroomTracker as Yn}from"./packem_shared/DEFAULT_TRANSACTION_LIMITS-DDGk9ebh.mjs";import{hasTrigger as Jn,runTriggers as Zn}from"./packem_shared/hasTrigger-CjlwI4le.mjs";import{selectExpiredIds as ei}from"./packem_shared/selectExpiredIds-CKOUTIHn.mjs";import{c as oi,l as ai}from"./packem_shared/where-sql-x1YKldcq.mjs";import{RELATION_EXISTS_KEY as ni}from"./packem_shared/RELATION_EXISTS_KEY-CFUhnZSZ.mjs";import{REPROJECTION_MIGRATION_PREFIX as li,reprojectionMigrationId as si}from"./packem_shared/REPROJECTION_MIGRATION_PREFIX-Czcb6_mO.mjs";import{quoteIdentifier as ci}from"./packem_shared/quoteIdentifier-CObIFRhb.mjs";import{runShardMigrations as pi}from"./packem_shared/runShardMigrations-CeT_SVrI.mjs";import{stableStringify as ui}from"./packem_shared/stableStringify-DibjylKD.mjs";import{stableWireKey as Ei}from"./packem_shared/stableWireKey-D2US4k_J.mjs";export{Bo as ADMIN_FUNCTIONS,Go as ADMIN_FUNCTION_PREFIX,m as AGGREGATE_SQL_FUNCTION,Ir as AGG_COUNT,br as AGG_KEY,Lr as AGG_VALUE,D as AUDIT_LOG_TABLE,Pn as BIGINT_KEY_DIGITS,X as CDC_LOG_TABLE,H as CDC_LOG_TABLE_SEQ_INDEX,z as CDC_META_TABLE,Te as CLIENT_WATERMARK_TABLE,Ae as COMMIT_SEQ_FIELD,ge as COMMIT_SEQ_TABLE,ua as CURSOR_PREFIX,zn as ConflictError,R as CountRlsUnsupportedError,Sr as DATA_MIGRATION_STATE_TABLE,Uo as DEFAULT_FANOUT_TOPIC_LIMIT,St as DEFAULT_MAX_RELATION_KEYS,Nt as DEFAULT_MAX_RELAYS,Lt as DEFAULT_PROMOTION_THRESHOLDS,Qn as DEFAULT_TRANSACTION_LIMITS,Dr as DOC_COLUMN,ro as DurableStreamRunner,qo as FLAGS_FUNCTION_PREFIX,bo as GEO_DEFAULT_PRECISION,Me as GLOBAL_SHAPE_SNAPSHOT_TABLE,Oo as GlobalPollTick,Ge as IDEMPOTENCY_TABLE,oa as MAIL_RETENTION,aa as MAIL_TABLE,oo as MAX_DURABLE_STREAM_BYTES,ao as MAX_DURABLE_STREAM_CHUNKS,Ko as MAX_PAGE_SIZE,_n as MAX_SQL_ROWS,ma as NotFoundError,N as NotUniqueError,Ot as OwnerRelay,ba as QUEUE_TABLE,Na as RANK_TIEBREAK,Ha as REACTOR_STATE_TABLE,it as RELATED_DEFAULT_LIMIT,lt as RELATED_DEPTH_DECAY,st as RELATED_MAX_DEPTH,mt as RELATED_MAX_LIMIT,ni as RELATION_EXISTS_KEY,wo as RELATION_FUNCTION_PREFIX,li as REPROJECTION_MIGRATION_PREFIX,Vt as RLS_UNWRAP_SYMBOL,va as ReactiveCache,kt as RelayMember,Qt as RlsRequiredError,Tr as SCAN_DEP,Jt as SCHEMA_HISTORY_MAX_VERSIONS,je as SEARCH_STATE_TABLE,rr as SHAPE_POKE_CURSOR_TABLE,dn as ShapeDiffCache,Cn as ShardRunner,Yn as TransactionHeadroomTracker,Za as UNVOUCHABLE_DEP,he as advanceClientWatermark,Pr as aggUpsertSql,c as aggregateSqlFunction,f as aggregateTableName,_e as allocateCommitSeq,P as appendAuditEntry,V as appendCdcChange,zr as appendStreamChunk,Q as applyCdcChanges,Ct as applyOnDelete,fa as applySelect,pe as archiveCdcSegment,da as armRestore,ut as assertFlatPredicate,O as assertNoExplicitUndefined,In as assertReadonly,ft as assertShapeShardable,k as assertValidClientId,kn as awaitWsDrain,q as backfillAggregateIndexes,K as backfillRankIndexes,w as backfillSearchIndexes,v as backfillSearchIndexesForTable,Mn as bigintSqlKey,Lo as boundingBoxCenter,Do as boundingBoxGeohashes,ot as buildIndexRange,fn as buildPokeFrames,vt as buildReprojectionMigration,Ea as buildSeekBeforeWhere,Ta as buildSeekWhere,tn as buildSettings,mn as buildShapeDiff,Y as bumpCdcEpoch,j as cdcCanVouchFor,J as cdcSeqLeavingRows,Z as cdcTouchesTables,$ as cdcTrimmedError,Vr as claimStreamRun,Dt as clampPromotionThresholds,ta as clearCapturedMail,We as clearMemoryTables,La as clearQueueMessages,E as coerceAggregateNumber,ee as compactCdcDocs,oi as compileWhereSql,Ve as computeRankPage,Et as containsRelationPredicate,Wt as countLegacyRows,Po as coveringGeohashes,De as createCompanionSync,hr as createDependencyTracker,vo as createFanoutCounters,Wo as createGlobalPollCounters,Mr as createIndexSql,$a as createReadFootprint,Bt as createRelayLink,Ut as createReplicaLink,pn as createShapeDiffCache,Xo as createShapeProbeCounters,B as createShardCtxDb,Xn as createSystemReader,re as cursorBelowRetainedFloor,to as decideDurableAttach,yn as decodeBigintSqlKey,ha as decodeCursor,Fn as decodeFloat64SqlKey,ye as deleteGlobalShapeSnapshot,Fe as deleteGlobalShapeSnapshotsForConnection,or as deleteShapePokeCursor,ar as deleteShapePokeCursorsForConnection,Qr as deleteStreamRun,xr as depKey,ct as deriveRelationEdges,mo as diffExternalSource,En as diffGlobalMembership,Rt as distinctValues,T as encodeAggregateKey,xa as encodeCursor,Mo as encodeGeohash,Oa as encodePartitionKey,Tn as encodeRowsPatch,M as ensureAuditTable,na as ensureMailTable,io as envOptionalPositiveInt,lo as envPositiveInt,Ca as equalityPinnedFields,o as exportShardRows,Ho as facetColumn,At as fanOutScalarCounts,dt as findRelated,zo as findStorageReferences,Yr as finishStreamRun,Nn as float64SqlKey,h as foldAggregateTally,qt as gateReplicaDispatch,yr as geoTableName,Sn as globalShapeReadKey,Yt as guardWriter,Kt as handleReplicaControl,Jn as hasTrigger,yo as haversineMeters,a as importShardRows,at as indexKeysForRow,nn as isDevEnvironment,Fr as isFtsAvailable,Da as isLossyBody,Xe as isMemoryTable,Tt as isRelationPredicate,Ro as isSoftDeleted,Ao as isSourceDue,Nr as jsonPath,Or as jsonPathSql,tt as keysTouchRanges,po as liftSourceId,bn as lintReadonlySql,za as listReactorStates,Vo as listTables,ai as literalInList,et as markUnvouchableReads,ka as matchesRankStaticWhere,d as matchesStaticWhere,Eo as materializeExternalRows,To as materializeExternalRowsIncremental,He as memoryTableNames,Kn as mergeChangedKeys,A as mergeWhere,oe as migrateCdcLog,ae as migrateCdcMeta,xe as migrateClientWatermark,Ie as migrateCommitSeq,jr as migrateDurableStreams,Ne as migrateGlobalShapeSnapshot,Ue as migrateIdempotency,Va as migrateReactorState,Je as migrateSearchState,tr as migrateShapePokeCursor,te as minCdcReplayableSeq,ne as minCdcSeq,nr as minShapePokeCursor,Pt as nextPromotionState,p as normalizeCountArgument,G as normalizeIdStructurally,Ra as normalizeOrderKeys,So as normalizeSourceDocument,uo as normalizeSourceValue,wr as param,t as parseExportShardArgs,n as parseImportShardArgs,g as planAggregateLookup,Fo as pointInBoundingBox,hn as projectColumns,go as pullExternalSourceIncrementalTick,_o as pullExternalSourceTick,kr as qualifiedJsonPath,Br as qualifiedJsonPathSql,ci as quoteIdentifier,Ba as rankKeyFromDoc,Ga as rankPivotConditionSql,Ua as rankTableName,Wa as reactiveCacheKey,Qa as reactorNeedsRun,x as readAggregateValue,Se as readArchivedCdcChanges,y as readAuditLog,pa as readBookmark,ia as readCapturedMail,ue as readCdcArchivedThrough,ie as readCdcChangeKeys,le as readCdcChanges,se as readCdcCursor,me as readCdcEpoch,Ce as readClientWatermark,be as readCommitSeq,ln as readDeployInfo,ho as readExternalSourceBaseline,Oe as readGlobalShapeSnapshot,qe as readIdempotent,ur as readMigrationStatus,Pa as readQueueMessageById,Ma as readQueueMessages,Ya as readReactorState,Zt as readSchemaHistory,$t as readSchemaVersion,Ze as readSearchBackfillState,ir as readShapePokeCursor,Jr as readStreamChunks,Zr as readStreamRun,Qo as readTablePage,la as recordCapturedMail,wn as recordChangedKeys,Yo as recordFanoutPass,jo as recordGlobalPollPass,ya as recordQueueMessages,en as recordSchemaVersion,Jo as recordShapeProbePass,gt as relationHooks,Mt as relayCountFor,vr as renderSql,Xt as reprojectableFields,si as reprojectionMigrationId,Ht as reprojectionTables,qa as resolveRankPartition,Qe as resolveRankSeekTuple,ht as resolveRelationPredicates,_t as resolveWith,Gr as rowToDocument,fr as runDataMigration,Ar as runDrizzle,xo as runExternalSourceTick,Ln as runReadonlySql,It as runRowValidators,pi as runShardMigrations,An as runSocketPool,gr as runSql,Zn as runTriggers,ei as selectExpiredIds,i as selectExportTables,_ as selectIndexForAggregate,I as selectIndexForCount,b as selectIndexForGroupBy,Zo as selectMatchingIds,cr as selectShapeMembers,dr as selectShapeRows,on as serializeSqlValue,yt as shapeRoutingKey,Aa as softDeleteScope,Ka as sortColumnName,Wr as sqliteInList,ui as stableStringify,Ei as stableWireKey,Bn as subscriptionFrames,Gn as subscriptionListDeltas,$o as summarizeFanoutTopics,ea as summarizeSubscriptions,Ur as tableColumns,Cr as tableFromDepKey,S as throwingScheduler,ga as tiebreakDirectionFor,ce as trimCdcChanges,Ke as trimIdempotent,$r as trimStreamRuns,qr as tryRowToDocument,Un as trySendFrame,Xr as unionAll,_a as uniqueIndexFields,l as validateImportRow,fe as writeCdcArchivedThrough,ke as writeGlobalShapeSnapshot,we as writeIdempotent,ja as writeReactorState,$e as writeSearchBackfillState,lr as writeShapePokeCursor,sr as writeShapePokeCursors,vn as writeTouchesMemo};
1
+ import{exportShardRows as o,importShardRows as a,parseExportShardArgs as t,parseImportShardArgs as n,selectExportTables as i,validateImportRow as l}from"./packem_shared/exportShardRows-D_upYHRQ.mjs";import{AGGREGATE_SQL_FUNCTION as m,aggregateSqlFunction as c,matchesStaticWhere as d,normalizeCountArgument as p,throwingScheduler as S}from"./packem_shared/AGGREGATE_SQL_FUNCTION-DDEoMnJR.mjs";import{aggregateTableName as f,coerceAggregateNumber as E,encodeAggregateKey as T,foldAggregateTally as h,readAggregateValue as x}from"./packem_shared/aggregateTableName-C7o-gpms.mjs";import{CountRlsUnsupportedError as R,mergeWhere as A,planAggregateLookup as g,selectIndexForAggregate as _,selectIndexForCount as I,selectIndexForGroupBy as b}from"./packem_shared/CountRlsUnsupportedError-BvsDqfO2.mjs";import{AUDIT_LOG_TABLE as D,appendAuditEntry as P,ensureAuditTable as M,readAuditLog as y}from"./packem_shared/AUDIT_LOG_TABLE-ONxmEAIz.mjs";import{NotUniqueError as N,assertNoExplicitUndefined as O,assertValidClientId as k,createShardCtxDb as B,normalizeIdStructurally as G}from"./packem_shared/NotUniqueError-BMom69SD.mjs";import{backfillAggregateIndexes as q,backfillRankIndexes as K,backfillSearchIndexes as w,backfillSearchIndexesForTable as v}from"./packem_shared/backfillAggregateIndexes-BG5-SC1q.mjs";import{CDC_LOG_TABLE as X,CDC_LOG_TABLE_SEQ_INDEX as H,CDC_META_TABLE as z,appendCdcChange as V,applyCdcChanges as Q,bumpCdcEpoch as Y,cdcCanVouchFor as j,cdcSeqLeavingRows as J,cdcTouchesTables as Z,cdcTrimmedError as $,compactCdcDocs as ee,cursorBelowRetainedFloor as re,migrateCdcLog as oe,migrateCdcMeta as ae,minCdcReplayableSeq as te,minCdcSeq as ne,readCdcChangeKeys as ie,readCdcChanges as le,readCdcCursor as se,readCdcEpoch as me,trimCdcChanges as ce}from"./packem_shared/CDC_LOG_TABLE-vVheEulD.mjs";import{archiveCdcSegment as pe,readArchivedCdcChanges as Se,readCdcArchivedThrough as ue,writeCdcArchivedThrough as fe}from"./packem_shared/archiveCdcSegment-DU4uzDFQ.mjs";import{CLIENT_WATERMARK_TABLE as Te,advanceClientWatermark as he,migrateClientWatermark as xe,readClientWatermark as Ce}from"./packem_shared/CLIENT_WATERMARK_TABLE-CRnrAnJ2.mjs";import{COMMIT_SEQ_FIELD as Ae,COMMIT_SEQ_TABLE as ge,allocateCommitSeq as _e,migrateCommitSeq as Ie,readCommitSeq as be}from"./packem_shared/COMMIT_SEQ_FIELD-BUdOMG5y.mjs";import{c as De}from"./packem_shared/ctx-db-companions-w-CfeOda.mjs";import{GLOBAL_SHAPE_SNAPSHOT_TABLE as Me,deleteGlobalShapeSnapshot as ye,deleteGlobalShapeSnapshotsForConnection as Fe,migrateGlobalShapeSnapshot as Ne,readGlobalShapeSnapshot as Oe,writeGlobalShapeSnapshot as ke}from"./packem_shared/GLOBAL_SHAPE_SNAPSHOT_TABLE-DSA6mzyx.mjs";import{IDEMPOTENCY_TABLE as Ge,migrateIdempotency as Ue,readIdempotent as qe,trimIdempotent as Ke,writeIdempotent as we}from"./packem_shared/IDEMPOTENCY_TABLE-DOpm_oMF.mjs";import{clearMemoryTables as We,isMemoryTable as Xe,memoryTableNames as He}from"./packem_shared/clearMemoryTables-BGbmag2i.mjs";import{computeRankPage as Ve,resolveRankSeekTuple as Qe}from"./packem_shared/computeRankPage-DsQ16o1z.mjs";import{S as je,m as Je,r as Ze,w as $e}from"./packem_shared/ctx-db-search-state-ruTuCsxa.mjs";import{SHAPE_POKE_CURSOR_TABLE as rr,deleteShapePokeCursor as or,deleteShapePokeCursorsForConnection as ar,migrateShapePokeCursor as tr,minShapePokeCursor as nr,readShapePokeCursor as ir,writeShapePokeCursor as lr,writeShapePokeCursors as sr}from"./packem_shared/SHAPE_POKE_CURSOR_TABLE-ByJVDHds.mjs";import{selectShapeMembers as cr,selectShapeRows as dr}from"./packem_shared/selectShapeMembers-CCZyZggM.mjs";import{DATA_MIGRATION_STATE_TABLE as Sr,readMigrationStatus as ur,runDataMigration as fr}from"./packem_shared/DATA_MIGRATION_STATE_TABLE-BNMWxRzv.mjs";import{SCAN_DEP as Tr,createDependencyTracker as hr,depKey as xr,tableFromDepKey as Cr}from"./packem_shared/SCAN_DEP-D7qE3iUe.mjs";import{runDrizzle as Ar,runSql as gr}from"./packem_shared/runDrizzle-2ULFQR_k.mjs";import{A as Ir,a as br,b as Lr,D as Dr,c as Pr,d as Mr,g as yr,i as Fr,j as Nr,e as Or,q as kr,f as Br,r as Gr,t as Ur,h as qr}from"./packem_shared/do-sql-Dvj8Yl5N.mjs";import{param as wr,renderSql as vr,sqliteInList as Wr,unionAll as Xr}from"./packem_shared/param-DlozcSQu.mjs";import{appendStreamChunk as zr,claimStreamRun as Vr,deleteStreamRun as Qr,finishStreamRun as Yr,migrateDurableStreams as jr,readStreamChunks as Jr,readStreamRun as Zr,trimStreamRuns as $r}from"./packem_shared/appendStreamChunk-C1Ok4b6J.mjs";import{DurableStreamRunner as ro,MAX_DURABLE_STREAM_BYTES as oo,MAX_DURABLE_STREAM_CHUNKS as ao,decideDurableAttach as to}from"./packem_shared/DurableStreamRunner-rTYp4v03.mjs";import{envOptionalPositiveInt as io,envPositiveInt as lo}from"./packem_shared/envOptionalPositiveInt-D2pY-c64.mjs";import{diffExternalSource as mo}from"./packem_shared/diffExternalSource-DgDJhslq.mjs";import{liftSourceId as po,normalizeSourceDocument as So,normalizeSourceValue as uo}from"./packem_shared/liftSourceId-CA3ENhXj.mjs";import{materializeExternalRows as Eo,materializeExternalRowsIncremental as To,readExternalSourceBaseline as ho,runExternalSourceTick as xo}from"./packem_shared/materializeExternalRows-iEVQKOKT.mjs";import{isSoftDeleted as Ro,isSourceDue as Ao,pullExternalSourceIncrementalTick as go,pullExternalSourceTick as _o}from"./packem_shared/isSoftDeleted-CYf6ijO3.mjs";import{GEO_DEFAULT_PRECISION as bo,boundingBoxCenter as Lo,boundingBoxGeohashes as Do,coveringGeohashes as Po,encodeGeohash as Mo,haversineMeters as yo,pointInBoundingBox as Fo}from"./packem_shared/GEO_DEFAULT_PRECISION-CqpQZ-J_.mjs";import{default as Oo}from"./packem_shared/GlobalPollTick-BNK4o-XT.mjs";import{ADMIN_FUNCTIONS as Bo,ADMIN_FUNCTION_PREFIX as Go,DEFAULT_FANOUT_TOPIC_LIMIT as Uo,FLAGS_FUNCTION_PREFIX as qo,MAX_PAGE_SIZE as Ko,RELATION_FUNCTION_PREFIX as wo,createFanoutCounters as vo,createGlobalPollCounters as Wo,createShapeProbeCounters as Xo,facetColumn as Ho,findStorageReferences as zo,listTables as Vo,readTablePage as Qo,recordFanoutPass as Yo,recordGlobalPollPass as jo,recordShapeProbePass as Jo,selectMatchingIds as Zo,summarizeFanoutTopics as $o,summarizeSubscriptions as ea}from"./packem_shared/ADMIN_FUNCTIONS-CRXp5IZu.mjs";import{MAIL_RETENTION as oa,MAIL_TABLE as aa,clearCapturedMail as ta,ensureMailTable as na,readCapturedMail as ia,recordCapturedMail as la}from"./packem_shared/MAIL_RETENTION-DGAQTHHs.mjs";import{NotFoundError as ma}from"./packem_shared/NotFoundError-BhF7FeFr.mjs";import{armRestore as da,readBookmark as pa}from"./packem_shared/armRestore-Bu1_8SUa.mjs";import{CURSOR_PREFIX as ua,applySelect as fa,buildSeekBeforeWhere as Ea,buildSeekWhere as Ta,decodeCursor as ha,encodeCursor as xa,equalityPinnedFields as Ca,normalizeOrderKeys as Ra,softDeleteScope as Aa,tiebreakDirectionFor as ga,uniqueIndexFields as _a}from"./packem_shared/CURSOR_PREFIX-Bn8SFoGd.mjs";import{QUEUE_TABLE as ba,clearQueueMessages as La,isLossyBody as Da,readQueueMessageById as Pa,readQueueMessages as Ma,recordQueueMessages as ya}from"./packem_shared/QUEUE_TABLE-s7QJZvBz.mjs";import{RANK_TIEBREAK as Na,encodePartitionKey as Oa,matchesRankStaticWhere as ka,rankKeyFromDoc as Ba,rankPivotConditionSql as Ga,rankTableName as Ua,resolveRankPartition as qa,sortColumnName as Ka}from"./packem_shared/RANK_TIEBREAK-BXDiMmkH.mjs";import{ReactiveCache as va,reactiveCacheKey as Wa}from"./packem_shared/ReactiveCache-CzeUmTTN.mjs";import{REACTOR_STATE_TABLE as Ha,listReactorStates as za,migrateReactorState as Va,reactorNeedsRun as Qa,readReactorState as Ya,writeReactorState as ja}from"./packem_shared/REACTOR_STATE_TABLE-QPRFyxMS.mjs";import{UNVOUCHABLE_DEP as Za,createReadFootprint as $a,markUnvouchableReads as et}from"./packem_shared/UNVOUCHABLE_DEP-C68htACn.mjs";import{buildIndexRange as ot,indexKeysForRow as at,keysTouchRanges as tt}from"./packem_shared/buildIndexRange-NtciKq3M.mjs";import{RELATED_DEFAULT_LIMIT as it,RELATED_DEPTH_DECAY as lt,RELATED_MAX_DEPTH as st,RELATED_MAX_LIMIT as mt,deriveRelationEdges as ct,findRelated as dt}from"./packem_shared/RELATED_DEFAULT_LIMIT-B9PH28Pn.mjs";import{DEFAULT_MAX_RELATION_KEYS as St,assertFlatPredicate as ut,assertShapeShardable as ft,containsRelationPredicate as Et,isRelationPredicate as Tt,resolveRelationPredicates as ht}from"./packem_shared/DEFAULT_MAX_RELATION_KEYS-XESc7TiB.mjs";import{applyOnDelete as Ct,distinctValues as Rt,fanOutScalarCounts as At,relationHooks as gt,resolveWith as _t,runRowValidators as It}from"./packem_shared/applyOnDelete-7JZ4vR9r.mjs";import{DEFAULT_PROMOTION_THRESHOLDS as Lt,clampPromotionThresholds as Dt,nextPromotionState as Pt,relayCountFor as Mt,shapeRoutingKey as yt}from"./packem_shared/DEFAULT_PROMOTION_THRESHOLDS-Bfx7KakS.mjs";import{DEFAULT_MAX_RELAYS as Nt,OwnerRelay as Ot,RelayMember as kt,createRelayLink as Bt}from"./packem_shared/DEFAULT_MAX_RELAYS-Ng4SyJ7k.mjs";import{createReplicaLink as Ut,gateReplicaDispatch as qt,handleReplicaControl as Kt}from"./packem_shared/createReplicaLink-Bo4IWADY.mjs";import{buildReprojectionMigration as vt,countLegacyRows as Wt,reprojectableFields as Xt,reprojectionTables as Ht}from"./packem_shared/buildReprojectionMigration-Coeg-J0M.mjs";import{RLS_UNWRAP_SYMBOL as Vt,RlsRequiredError as Qt,guardWriter as Yt}from"./packem_shared/RLS_UNWRAP_SYMBOL-BwwTbz3Q.mjs";import{SCHEMA_HISTORY_MAX_VERSIONS as Jt,readSchemaHistory as Zt,readSchemaVersion as $t,recordSchemaVersion as en}from"./packem_shared/SCHEMA_HISTORY_MAX_VERSIONS-BluIj2s-.mjs";import{serializeSqlValue as on}from"./packem_shared/serializeSqlValue-CjbhIHjJ.mjs";import{buildSettings as tn,isDevEnvironment as nn,readDeployInfo as ln}from"./packem_shared/buildSettings-DC3VeQ0H.mjs";import{buildShapeDiff as mn}from"./packem_shared/buildShapeDiff-WSoMs1_h.mjs";import{ShapeDiffCache as dn,createShapeDiffCache as pn,globalShapeReadKey as Sn}from"./packem_shared/ShapeDiffCache-gdaILV5E.mjs";import{buildPokeFrames as fn,diffGlobalMembership as En,encodeRowsPatch as Tn,projectColumns as hn}from"./packem_shared/buildPokeFrames-BBE6J91z.mjs";import{ShardRunner as Cn}from"./packem_shared/ShardRunner-C9p5DVOx.mjs";import{runSocketPool as An}from"./packem_shared/runSocketPool-CZJ2X9cF.mjs";import{MAX_SQL_ROWS as _n,assertReadonly as In,lintReadonlySql as bn,runReadonlySql as Ln}from"./packem_shared/MAX_SQL_ROWS-RvXZ7S7f.mjs";import{B as Pn,b as Mn,d as yn,a as Fn,f as Nn}from"./packem_shared/sql-projection-BB2lCbYV.mjs";import{awaitWsDrain as kn,subscriptionFrames as Bn,subscriptionListDeltas as Gn,trySendFrame as Un}from"./packem_shared/awaitWsDrain-apizgmKY.mjs";import{mergeChangedKeys as Kn,recordChangedKeys as wn,writeTouchesMemo as vn}from"./packem_shared/mergeChangedKeys-CPw4EamV.mjs";import{createSystemReader as Xn}from"./packem_shared/createSystemReader-DcDLFfC-.mjs";import{ConflictError as zn}from"./packem_shared/ConflictError-C8GtJmjS.mjs";import{DEFAULT_TRANSACTION_LIMITS as Qn,TransactionHeadroomTracker as Yn}from"./packem_shared/DEFAULT_TRANSACTION_LIMITS-DDGk9ebh.mjs";import{hasTrigger as Jn,runTriggers as Zn}from"./packem_shared/hasTrigger-CjlwI4le.mjs";import{selectExpiredIds as ei}from"./packem_shared/selectExpiredIds-CKOUTIHn.mjs";import{c as oi,l as ai}from"./packem_shared/where-sql-x1YKldcq.mjs";import{RELATION_EXISTS_KEY as ni}from"./packem_shared/RELATION_EXISTS_KEY-CFUhnZSZ.mjs";import{REPROJECTION_MIGRATION_PREFIX as li,reprojectionMigrationId as si}from"./packem_shared/REPROJECTION_MIGRATION_PREFIX-Czcb6_mO.mjs";import{quoteIdentifier as ci}from"./packem_shared/quoteIdentifier-CObIFRhb.mjs";import{runShardMigrations as pi}from"./packem_shared/runShardMigrations-CeT_SVrI.mjs";import{stableStringify as ui}from"./packem_shared/stableStringify-DibjylKD.mjs";import{stableWireKey as Ei}from"./packem_shared/stableWireKey-D2US4k_J.mjs";export{Bo as ADMIN_FUNCTIONS,Go as ADMIN_FUNCTION_PREFIX,m as AGGREGATE_SQL_FUNCTION,Ir as AGG_COUNT,br as AGG_KEY,Lr as AGG_VALUE,D as AUDIT_LOG_TABLE,Pn as BIGINT_KEY_DIGITS,X as CDC_LOG_TABLE,H as CDC_LOG_TABLE_SEQ_INDEX,z as CDC_META_TABLE,Te as CLIENT_WATERMARK_TABLE,Ae as COMMIT_SEQ_FIELD,ge as COMMIT_SEQ_TABLE,ua as CURSOR_PREFIX,zn as ConflictError,R as CountRlsUnsupportedError,Sr as DATA_MIGRATION_STATE_TABLE,Uo as DEFAULT_FANOUT_TOPIC_LIMIT,St as DEFAULT_MAX_RELATION_KEYS,Nt as DEFAULT_MAX_RELAYS,Lt as DEFAULT_PROMOTION_THRESHOLDS,Qn as DEFAULT_TRANSACTION_LIMITS,Dr as DOC_COLUMN,ro as DurableStreamRunner,qo as FLAGS_FUNCTION_PREFIX,bo as GEO_DEFAULT_PRECISION,Me as GLOBAL_SHAPE_SNAPSHOT_TABLE,Oo as GlobalPollTick,Ge as IDEMPOTENCY_TABLE,oa as MAIL_RETENTION,aa as MAIL_TABLE,oo as MAX_DURABLE_STREAM_BYTES,ao as MAX_DURABLE_STREAM_CHUNKS,Ko as MAX_PAGE_SIZE,_n as MAX_SQL_ROWS,ma as NotFoundError,N as NotUniqueError,Ot as OwnerRelay,ba as QUEUE_TABLE,Na as RANK_TIEBREAK,Ha as REACTOR_STATE_TABLE,it as RELATED_DEFAULT_LIMIT,lt as RELATED_DEPTH_DECAY,st as RELATED_MAX_DEPTH,mt as RELATED_MAX_LIMIT,ni as RELATION_EXISTS_KEY,wo as RELATION_FUNCTION_PREFIX,li as REPROJECTION_MIGRATION_PREFIX,Vt as RLS_UNWRAP_SYMBOL,va as ReactiveCache,kt as RelayMember,Qt as RlsRequiredError,Tr as SCAN_DEP,Jt as SCHEMA_HISTORY_MAX_VERSIONS,je as SEARCH_STATE_TABLE,rr as SHAPE_POKE_CURSOR_TABLE,dn as ShapeDiffCache,Cn as ShardRunner,Yn as TransactionHeadroomTracker,Za as UNVOUCHABLE_DEP,he as advanceClientWatermark,Pr as aggUpsertSql,c as aggregateSqlFunction,f as aggregateTableName,_e as allocateCommitSeq,P as appendAuditEntry,V as appendCdcChange,zr as appendStreamChunk,Q as applyCdcChanges,Ct as applyOnDelete,fa as applySelect,pe as archiveCdcSegment,da as armRestore,ut as assertFlatPredicate,O as assertNoExplicitUndefined,In as assertReadonly,ft as assertShapeShardable,k as assertValidClientId,kn as awaitWsDrain,q as backfillAggregateIndexes,K as backfillRankIndexes,w as backfillSearchIndexes,v as backfillSearchIndexesForTable,Mn as bigintSqlKey,Lo as boundingBoxCenter,Do as boundingBoxGeohashes,ot as buildIndexRange,fn as buildPokeFrames,vt as buildReprojectionMigration,Ea as buildSeekBeforeWhere,Ta as buildSeekWhere,tn as buildSettings,mn as buildShapeDiff,Y as bumpCdcEpoch,j as cdcCanVouchFor,J as cdcSeqLeavingRows,Z as cdcTouchesTables,$ as cdcTrimmedError,Vr as claimStreamRun,Dt as clampPromotionThresholds,ta as clearCapturedMail,We as clearMemoryTables,La as clearQueueMessages,E as coerceAggregateNumber,ee as compactCdcDocs,oi as compileWhereSql,Ve as computeRankPage,Et as containsRelationPredicate,Wt as countLegacyRows,Po as coveringGeohashes,De as createCompanionSync,hr as createDependencyTracker,vo as createFanoutCounters,Wo as createGlobalPollCounters,Mr as createIndexSql,$a as createReadFootprint,Bt as createRelayLink,Ut as createReplicaLink,pn as createShapeDiffCache,Xo as createShapeProbeCounters,B as createShardCtxDb,Xn as createSystemReader,re as cursorBelowRetainedFloor,to as decideDurableAttach,yn as decodeBigintSqlKey,ha as decodeCursor,Fn as decodeFloat64SqlKey,ye as deleteGlobalShapeSnapshot,Fe as deleteGlobalShapeSnapshotsForConnection,or as deleteShapePokeCursor,ar as deleteShapePokeCursorsForConnection,Qr as deleteStreamRun,xr as depKey,ct as deriveRelationEdges,mo as diffExternalSource,En as diffGlobalMembership,Rt as distinctValues,T as encodeAggregateKey,xa as encodeCursor,Mo as encodeGeohash,Oa as encodePartitionKey,Tn as encodeRowsPatch,M as ensureAuditTable,na as ensureMailTable,io as envOptionalPositiveInt,lo as envPositiveInt,Ca as equalityPinnedFields,o as exportShardRows,Ho as facetColumn,At as fanOutScalarCounts,dt as findRelated,zo as findStorageReferences,Yr as finishStreamRun,Nn as float64SqlKey,h as foldAggregateTally,qt as gateReplicaDispatch,yr as geoTableName,Sn as globalShapeReadKey,Yt as guardWriter,Kt as handleReplicaControl,Jn as hasTrigger,yo as haversineMeters,a as importShardRows,at as indexKeysForRow,nn as isDevEnvironment,Fr as isFtsAvailable,Da as isLossyBody,Xe as isMemoryTable,Tt as isRelationPredicate,Ro as isSoftDeleted,Ao as isSourceDue,Nr as jsonPath,Or as jsonPathSql,tt as keysTouchRanges,po as liftSourceId,bn as lintReadonlySql,za as listReactorStates,Vo as listTables,ai as literalInList,et as markUnvouchableReads,ka as matchesRankStaticWhere,d as matchesStaticWhere,Eo as materializeExternalRows,To as materializeExternalRowsIncremental,He as memoryTableNames,Kn as mergeChangedKeys,A as mergeWhere,oe as migrateCdcLog,ae as migrateCdcMeta,xe as migrateClientWatermark,Ie as migrateCommitSeq,jr as migrateDurableStreams,Ne as migrateGlobalShapeSnapshot,Ue as migrateIdempotency,Va as migrateReactorState,Je as migrateSearchState,tr as migrateShapePokeCursor,te as minCdcReplayableSeq,ne as minCdcSeq,nr as minShapePokeCursor,Pt as nextPromotionState,p as normalizeCountArgument,G as normalizeIdStructurally,Ra as normalizeOrderKeys,So as normalizeSourceDocument,uo as normalizeSourceValue,wr as param,t as parseExportShardArgs,n as parseImportShardArgs,g as planAggregateLookup,Fo as pointInBoundingBox,hn as projectColumns,go as pullExternalSourceIncrementalTick,_o as pullExternalSourceTick,kr as qualifiedJsonPath,Br as qualifiedJsonPathSql,ci as quoteIdentifier,Ba as rankKeyFromDoc,Ga as rankPivotConditionSql,Ua as rankTableName,Wa as reactiveCacheKey,Qa as reactorNeedsRun,x as readAggregateValue,Se as readArchivedCdcChanges,y as readAuditLog,pa as readBookmark,ia as readCapturedMail,ue as readCdcArchivedThrough,ie as readCdcChangeKeys,le as readCdcChanges,se as readCdcCursor,me as readCdcEpoch,Ce as readClientWatermark,be as readCommitSeq,ln as readDeployInfo,ho as readExternalSourceBaseline,Oe as readGlobalShapeSnapshot,qe as readIdempotent,ur as readMigrationStatus,Pa as readQueueMessageById,Ma as readQueueMessages,Ya as readReactorState,Zt as readSchemaHistory,$t as readSchemaVersion,Ze as readSearchBackfillState,ir as readShapePokeCursor,Jr as readStreamChunks,Zr as readStreamRun,Qo as readTablePage,la as recordCapturedMail,wn as recordChangedKeys,Yo as recordFanoutPass,jo as recordGlobalPollPass,ya as recordQueueMessages,en as recordSchemaVersion,Jo as recordShapeProbePass,gt as relationHooks,Mt as relayCountFor,vr as renderSql,Xt as reprojectableFields,si as reprojectionMigrationId,Ht as reprojectionTables,qa as resolveRankPartition,Qe as resolveRankSeekTuple,ht as resolveRelationPredicates,_t as resolveWith,Gr as rowToDocument,fr as runDataMigration,Ar as runDrizzle,xo as runExternalSourceTick,Ln as runReadonlySql,It as runRowValidators,pi as runShardMigrations,An as runSocketPool,gr as runSql,Zn as runTriggers,ei as selectExpiredIds,i as selectExportTables,_ as selectIndexForAggregate,I as selectIndexForCount,b as selectIndexForGroupBy,Zo as selectMatchingIds,cr as selectShapeMembers,dr as selectShapeRows,on as serializeSqlValue,yt as shapeRoutingKey,Aa as softDeleteScope,Ka as sortColumnName,Wr as sqliteInList,ui as stableStringify,Ei as stableWireKey,Bn as subscriptionFrames,Gn as subscriptionListDeltas,$o as summarizeFanoutTopics,ea as summarizeSubscriptions,Ur as tableColumns,Cr as tableFromDepKey,S as throwingScheduler,ga as tiebreakDirectionFor,ce as trimCdcChanges,Ke as trimIdempotent,$r as trimStreamRuns,qr as tryRowToDocument,Un as trySendFrame,Xr as unionAll,_a as uniqueIndexFields,l as validateImportRow,fe as writeCdcArchivedThrough,ke as writeGlobalShapeSnapshot,we as writeIdempotent,ja as writeReactorState,$e as writeSearchBackfillState,lr as writeShapePokeCursor,sr as writeShapePokeCursors,vn as writeTouchesMemo};
@@ -1,8 +1,8 @@
1
- import{toErrorBody as k,LunoraError as D}from"@lunora/errors";import{e as N,d as v}from"./wire-codec-C-FpWm52.mjs";import{sql as y}from"drizzle-orm";import{runDrizzle as m}from"./runDrizzle-2ULFQR_k.mjs";import{WORKERD_SQLITE_LIMITS as F}from"./param-DlozcSQu.mjs";import{d as U,w,a as A,m as K,r as Y,b as $,c as W}from"./ctx-db-relay-shapes-Bg5YYnmN.mjs";import{envPositiveInt as g}from"./envOptionalPositiveInt-D2pY-c64.mjs";import{relayName as R,DEFAULT_PROMOTION_THRESHOLDS as T,nextPromotionState as B,shapeRoutingKey as E,relayProxyKey as M,parseRelayName as H,clampPromotionThresholds as q}from"./DEFAULT_PROMOTION_THRESHOLDS-Bfx7KakS.mjs";import{encodeRowsPatch as X,buildPokeFrames as O}from"./buildPokeFrames-BBE6J91z.mjs";import{v as j,R as L,s as z,a as G,b as J}from"./sibling-channel-BkL5cTCc.mjs";import{awaitWsDrain as V,trySendFrame as x}from"./awaitWsDrain-apizgmKY.mjs";import{stableWireKey as b}from"./stableWireKey-D2US4k_J.mjs";const f="__lunora_relay_memos",Q=i=>{m(i,y`CREATE TABLE IF NOT EXISTS ${y.identifier(f)} (
1
+ import{toErrorBody as k,LunoraError as D}from"@lunora/errors";import{e as N,d as v}from"./wire-codec-C-FpWm52.mjs";import{sql as y}from"drizzle-orm";import{runDrizzle as m}from"./runDrizzle-2ULFQR_k.mjs";import{WORKERD_SQLITE_LIMITS as F}from"./param-DlozcSQu.mjs";import{d as U,w,a as A,m as $,r as K,b as Y,c as W}from"./ctx-db-relay-shapes-Bg5YYnmN.mjs";import{envPositiveInt as g}from"./envOptionalPositiveInt-D2pY-c64.mjs";import{relayName as R,DEFAULT_PROMOTION_THRESHOLDS as T,nextPromotionState as B,shapeRoutingKey as _,relayProxyKey as M,parseRelayName as H,clampPromotionThresholds as q}from"./DEFAULT_PROMOTION_THRESHOLDS-Bfx7KakS.mjs";import{encodeRowsPatch as X,buildPokeFrames as O}from"./buildPokeFrames-BBE6J91z.mjs";import{v as j,R as L,s as z,a as G,b as J}from"./sibling-channel-BkL5cTCc.mjs";import{awaitWsDrain as V,trySendFrame as x}from"./awaitWsDrain-apizgmKY.mjs";import{stableWireKey as b}from"./stableWireKey-D2US4k_J.mjs";const f="__lunora_relay_memos",Q=i=>{m(i,y`CREATE TABLE IF NOT EXISTS ${y.identifier(f)} (
2
2
  connection_id TEXT NOT NULL,
3
3
  sub_id TEXT NOT NULL,
4
4
  cursor INTEGER NOT NULL,
5
5
  epoch TEXT,
6
6
  PRIMARY KEY (connection_id, sub_id)
7
7
  )`)},Z=i=>{const e=m(i,y`SELECT connection_id, sub_id, cursor, epoch FROM ${y.identifier(f)}`).toArray(),s=new Map;for(const t of e){let o=s.get(t.connection_id);o===void 0&&(o=new Map,s.set(t.connection_id,o)),o.set(t.sub_id,{cursor:Number(t.cursor),epoch:t.epoch??void 0})}return s},ee=4,C=(i,e)=>{const s=Math.floor(F.boundParams/ee);for(let t=0;t<e.length;t+=s){const o=e.slice(t,t+s),n=y.join(o.map(r=>y`(${r.connectionId}, ${r.subId}, ${r.cursor}, ${r.epoch??null})`),y`, `);m(i,y`INSERT INTO ${y.identifier(f)} (connection_id, sub_id, cursor, epoch) VALUES ${n}
8
- ON CONFLICT(connection_id, sub_id) DO UPDATE SET cursor = excluded.cursor, epoch = excluded.epoch`)}},te=(i,e,s)=>{m(i,y`DELETE FROM ${y.identifier(f)} WHERE connection_id = ${e} AND sub_id = ${s}`)},se=(i,e)=>{m(i,y`DELETE FROM ${y.identifier(f)} WHERE connection_id = ${e}`)},oe=i=>{m(i,y`DELETE FROM ${y.identifier(f)}`)},re=2,ne=8,I={},ae=i=>{throw new D("INTERNAL",`unhandled relay frame: ${JSON.stringify(i)}`)},ie=(i,e)=>i===void 0||i.epoch!==e.epoch?!1:i.cursor>=e.fromCursor&&i.cursor<e.checkpoint,ce=i=>Response.json(i,{headers:{"content-type":"application/json"}}),S=()=>new Response(null,{status:204});class P{constructor(e,s){this.host=e,this.roleId=s}host;roleId;async handleControl(e){let s;try{s=await e.text()}catch{return new Response("bad request",{status:400})}if(!await j(this.host.env(),e.headers.get(L),s))return new Response("forbidden",{status:403});let t;try{t=JSON.parse(s)}catch{return new Response("bad request",{status:400})}switch(t.type){case"relay_attach":return this.onAttach(t.relayIndex),S();case"relay_detach":return this.onDetach(t.relayIndex),S();case"relay_frame":return this.host.deliverWhisperLocal(t.topic,t.frame,void 0),await this.onWhisperFrame(t),S();case"relay_shape_poke":{const o=this.host.getWebSockets().length,n=Date.now(),{delivered:r,matched:a}=this.onShapePoke({...t,args:v(t.args)});return this.host.recordShapePokeFanout(o,r,Date.now()-n),r<a?Response.json({delivered:r,matched:a},{status:503}):S()}case"relay_shape_subscribe":return ce(this.onShapeSubscribe({...t,args:v(t.args)}));case"relay_shape_unsubscribe":return this.onShapeUnsubscribe(t),S();default:return ae(t)}}maxRelays(){return g(this.host.env(),"LUNORA_MAX_RELAYS",ne)}canAddressSiblings(){return this.siblingStub(this.roleId.ownerKey)!==void 0}siblingStub(e){return z(this.host.env(),this.bindingName(),e,this.host.shardJurisdiction())}bindingName(){return this.host.shardBinding()}async postRelayMessage(e,s){await this.requestRelayMessage(e,s)}async requestRelayMessage(e,s){const t=this.siblingStub(e);if(t===void 0)return;const o=JSON.stringify(s),n={"content-type":"application/json","x-lunora-shard-binding":this.host.shardBinding()??""},r=G(this.host.env());r!==void 0&&(n[L]=await J(r,o));try{return await t.fetch("https://relay.internal/_lunora/relay",{body:o,headers:n,method:"POST"})}catch{return}}}class he extends P{shapeUniformCache=new Map;relaySetCache;registryCache;recordedBinding;promotionState="owned";constructor(e,s){super(e,{ownerKey:s})}async forwardWhisper(e,s){if(!this.canAddressSiblings())return;const t=this.ownerRelaySet();t.size!==0&&await Promise.all([...t].map(o=>this.postRelayMessage(R(this.roleId.ownerKey,o),{frame:s,topic:e,type:"relay_frame"})))}async onFlush(e,s){this.canAddressSiblings()&&await Promise.all([this.multicastShapePokes(e,s),this.proxyShapePokes(e,s)])}seedRelayShape(){return Promise.resolve(void 0)}announce(){return Promise.resolve()}announceDrain(){return Promise.resolve()}releaseRelayShapes(){return Promise.resolve()}relayCount(){const e=this.host.getWebSockets().length,s=g(this.host.env(),"LUNORA_RELAY_THRESHOLD",T.tUp),t=g(this.host.env(),"LUNORA_RELAY_COLLAPSE_THRESHOLD",T.tDown);if(this.promotionState=B(this.promotionState,e,q(s,t)),this.promotionState==="owned")return 0;const o=g(this.host.env(),"LUNORA_RELAY_FAN",re);return Math.min(this.maxRelays(),Math.max(1,o))}minShapeCursor(){const{cohort:e,proxies:s}=this.relayShapes();let t;for(const o of[...e.values(),...s.values()])t=t===void 0?o.cursor:Math.min(t,o.cursor);return t}isShapeRelayUniform(e,s){const t=E(e,s),o=this.shapeUniformCache.get(t);if(o!==void 0)return o;const n=this.probeShapeRelayUniform(e,s);return this.shapeUniformCache.set(t,n),n}onShapeUnsubscribe(e){const{proxies:s}=this.relayShapes(),t=e.subId===void 0?void 0:M(e.relayIndex,e.connectionId,e.subId);for(const[o,n]of s)n.relayIndex!==e.relayIndex||n.connectionId!==e.connectionId||(t===void 0||o===t)&&s.delete(o);U(this.host.sql(),e.relayIndex,e.connectionId,e.subId)}onAttach(e){this.addRelayToSet(e)}onDetach(e){this.removeRelayFromSet(e)}async onWhisperFrame(e){await Promise.all([...this.ownerRelaySet()].filter(s=>s!==e.originRelay).map(s=>this.postRelayMessage(R(this.roleId.ownerKey,s),{frame:e.frame,topic:e.topic,type:"relay_frame"})))}onShapeSubscribe(e){return this.buildShapeSeedFrames(e)}onShapePoke(){return{delivered:0,matched:0}}buildShapePoke(e,s,t,o,n){let r;try{r=this.host.resolveShape(e.name,e.args,s)}catch{return}if(r===void 0||r.global===!0||!t.has(r.table))return;const a=e,h=a.cursor,c=this.host.buildShapeDiff(r,h,o);if(c.length!==0)return a.cursor=o,w(this.host.sql(),a.key,o),{args:N(e.args),checkpoint:o,epoch:n,fromCursor:h,name:e.name,rowsPatch:X(c),type:"relay_shape_poke"}}async multicastShapePokes(e,s){const t=this.ownerRelaySet();if(t.size===0)return;const{cohort:o}=this.relayShapes();if(o.size===0)return;const n=this.host.currentCdcEpoch(),r=[];for(const a of o.values()){const h=this.buildShapePoke(a,I,e,s,n);h&&r.push(this.multicastToRelays(t,h,a))}await Promise.all(r)}async multicastToRelays(e,s,t){(await Promise.all([...e].map(async n=>(await this.requestRelayMessage(R(this.roleId.ownerKey,n),s))?.ok===!0))).includes(!1)&&this.rewindShapeCursor(t,s.fromCursor)}async proxyShapePokes(e,s){if(this.ownerRelaySet().size===0)return;const{proxies:t}=this.relayShapes();if(t.size===0)return;const o=this.host.currentCdcEpoch(),n=[];for(const r of t.values()){const a=this.buildShapePoke(r,r.identity,e,s,o);a&&n.push(this.proxyToRelay(a,r))}await Promise.all(n)}async proxyToRelay(e,s){(await this.requestRelayMessage(R(this.roleId.ownerKey,s.relayIndex),{...e,targetConnectionId:s.connectionId}))?.ok!==!0&&this.rewindShapeCursor(s,e.fromCursor)}buildShapeSeedFrames(e){const s={identity:e.identity,userId:e.userId};let t;try{t=this.host.resolveShape(e.name,e.args,s)}catch(l){const{body:p}=k(l,{fallbackCode:"SHAPE_RESOLVE_FAILED",redactedMessage:"shape resolution failed"});return{error:{code:p.code,message:p.message}}}if(t===void 0||t.global===!0)return{error:{code:"SHAPE_NOT_FOUND",message:`shape not relayable: ${e.name}`}};e.relayIndex!==void 0&&this.addRelayToSet(e.relayIndex);const{baseCheckpoint:o,cursor:n,epoch:r,reset:a,rowsPatch:h}=this.host.computeOpLogShapeSeed({args:e.args,name:e.name,sinceEpoch:e.sinceEpoch,sinceSeq:e.sinceSeq},t);let c=n;const{cohort:d,proxies:_}=this.relayShapes();if(this.isShapeRelayUniform(e.name,e.args)){const l=E(e.name,e.args);let p=d.get(l);p===void 0&&(p={args:e.args,cursor:n,key:l,name:e.name},d.set(l,p),A(this.host.sql(),p)),c=p.cursor}else if(e.relayIndex!==void 0&&e.connectionId!==void 0){const l=M(e.relayIndex,e.connectionId,e.subId),p={args:e.args,connectionId:e.connectionId,cursor:n,identity:s,key:l,name:e.name,relayIndex:e.relayIndex};_.set(l,p),A(this.host.sql(),p)}else return{error:{code:"RELAY_SHAPE_UNROUTABLE",message:`shape ${e.name} is per-socket on a relay, but the subscribe carries no ${e.relayIndex===void 0?"relay index":"connection id"}`}};const u=O([{reset:a,rowsPatch:h,shapeId:e.subId}],{baseCheckpoint:o,checkpoint:c,epoch:r,lastMutationId:void 0,pokeId:this.host.nextPokeId()});return{cursor:c,epoch:r,frames:u}}ensureRelayTables(){this.host.sql().exec("CREATE TABLE IF NOT EXISTS __lunora_relays (idx INTEGER PRIMARY KEY)"),this.host.sql().exec("CREATE TABLE IF NOT EXISTS __lunora_relay_binding (id INTEGER PRIMARY KEY, binding TEXT NOT NULL)"),K(this.host.sql())}bindingName(){const e=this.host.shardBinding();if(e!==void 0&&e!=="")return e!==this.recordedBinding&&(this.recordedBinding=e,this.ensureRelayTables(),this.host.sql().exec("INSERT INTO __lunora_relay_binding (id, binding) VALUES (1, ?) ON CONFLICT(id) DO UPDATE SET binding = excluded.binding",e)),e;if(this.recordedBinding!==void 0)return this.recordedBinding;try{const s=this.host.sql().exec("SELECT binding FROM __lunora_relay_binding WHERE id = 1").toArray();this.recordedBinding=s[0]?.binding}catch{this.recordedBinding=void 0}return this.recordedBinding}relayShapes(){const e=this.registryCache;if(e!==void 0)return e;this.ensureRelayTables();const s={cohort:new Map,proxies:new Map};for(const t of Y(this.host.sql()))t.relayIndex===void 0||t.connectionId===void 0?s.cohort.set(t.key,{args:t.args,cursor:t.cursor,key:t.key,name:t.name}):s.proxies.set(t.key,{args:t.args,connectionId:t.connectionId,cursor:t.cursor,identity:t.identity??{},key:t.key,name:t.name,relayIndex:t.relayIndex});return this.registryCache=s,s}rewindShapeCursor(e,s){const t=e;t.cursor<=s||(t.cursor=s,w(this.host.sql(),t.key,s))}ownerRelaySet(){if(this.relaySetCache===void 0){this.ensureRelayTables();const e=this.host.sql().exec("SELECT idx FROM __lunora_relays").toArray();this.relaySetCache=new Set(e.map(s=>Number(s.idx)))}return this.relaySetCache}addRelayToSet(e){this.ensureRelayTables(),this.host.sql().exec("INSERT OR IGNORE INTO __lunora_relays (idx) VALUES (?)",e),this.ownerRelaySet().add(e)}removeRelayFromSet(e){this.ensureRelayTables(),this.host.sql().exec("DELETE FROM __lunora_relays WHERE idx = ?",e);const s=this.ownerRelaySet();s.delete(e);const{cohort:t,proxies:o}=this.relayShapes();for(const[n,r]of o)r.relayIndex===e&&o.delete(n);$(this.host.sql(),e),s.size===0&&(t.clear(),this.shapeUniformCache.clear(),W(this.host.sql()))}probeShapeRelayUniform(e,s){let t;try{t=this.host.resolveShape(e,s,I)}catch{return!1}if(t===void 0||t.global===!0||this.host.rlsMetadata().policies.some(c=>c.on==="read"&&c.table===t.table)||this.tableHasAnyMask(t.table))return!1;const o=b(t.effectiveWhere),n=b(t.columns);let r=!1;const a=c=>{const d={groups:[`grp_${c}`],roles:[c],sub:`__lunora_probe_${c}__`};return{identity:new Proxy(d,{get:(u,l)=>typeof l=="symbol"||l in u?Reflect.get(u,l):`${c}:${l}`,getOwnPropertyDescriptor:(u,l)=>(r=!0,Reflect.getOwnPropertyDescriptor(u,l)),has:(u,l)=>typeof l=="symbol"?Reflect.has(u,l):!0,ownKeys:u=>(r=!0,Reflect.ownKeys(u))}),userId:`__lunora_probe_${c}__`}};return[I,a("a"),a("b")].every(c=>{let d;try{d=this.host.resolveShape(e,s,c)}catch{return!1}return d!==void 0&&d.global!==!0&&d.table===t.table&&b(d.effectiveWhere)===o&&b(d.columns)===n})&&!r}tableHasAnyMask(e){return this.host.maskMetadata().columns.some(s=>s.table===e)}}class le extends P{relayAnnounced=!1;relayMemoCache;shapeControl=new Map;constructor(e,s,t){super(e,{ownerKey:s,relayIndex:t})}async forwardWhisper(e,s){this.canAddressSiblings()&&await this.postRelayMessage(this.roleId.ownerKey,{frame:s,originRelay:this.roleId.relayIndex,topic:e,type:"relay_frame"})}onFlush(){return Promise.resolve()}async seedRelayShape(e,s,t,o){if(!this.canAddressSiblings())return{code:"RELAY_MISCONFIGURED",message:"relay cannot address its owner"};const{connectionId:n}=this.host.readAttachment(e),r={args:N(t.args??{}),connectionId:n,identity:o.identity,name:t.name,relayIndex:this.roleId.relayIndex,sinceEpoch:t.sinceEpoch,sinceSeq:t.sinceSeq,subId:s,type:"relay_shape_subscribe",userId:o.userId},a=await this.queueShapeControl(n,async()=>(await this.announce(),this.requestRelayMessage(this.roleId.ownerKey,r)));if(a===void 0)return{code:"RELAY_SEED_FAILED",message:"owner did not answer the shape seed"};let h;try{h=await a.json()}catch{return{code:"RELAY_SEED_FAILED",message:"malformed shape seed from owner"}}if(h.error!==void 0)return h.error;if(h.frames===void 0)return{code:"RELAY_SEED_FAILED",message:"owner returned no shape frames"};await V(e);for(const c of h.frames)x(e,c);return this.recordRelayShapeMemo(e,s,h.cursor??0,h.epoch),"ok"}async announce(){if(this.relayAnnounced||!this.canAddressSiblings())return;this.relayAnnounced=!0,(await this.requestRelayMessage(this.roleId.ownerKey,{relayIndex:this.roleId.relayIndex,type:"relay_attach"}))?.ok||(this.relayAnnounced=!1)}async announceDrain(e){this.host.getWebSockets().some(s=>s!==e)||(this.relayMemos().clear(),oe(this.host.sql()),this.canAddressSiblings()&&(this.relayAnnounced=!1,await this.postRelayMessage(this.roleId.ownerKey,{relayIndex:this.roleId.relayIndex,type:"relay_detach"})))}async releaseRelayShapes(e,s){const{connectionId:t}=this.host.readAttachment(e);t!==void 0&&this.forgetRelayShapeMemos(t,s),!(t===void 0||!this.canAddressSiblings())&&await this.queueShapeControl(t,async()=>this.postRelayMessage(this.roleId.ownerKey,{connectionId:t,relayIndex:this.roleId.relayIndex,...s===void 0?{}:{subId:s},type:"relay_shape_unsubscribe"}))}relayCount(){return 0}isShapeRelayUniform(){return!1}minShapeCursor(){}onAttach(){}onDetach(){}onWhisperFrame(){return Promise.resolve()}onShapeSubscribe(){return{error:{code:"RELAY_CANNOT_SEED",message:"a relay has no op-log to seed from"}}}onShapeUnsubscribe(){}onShapePoke(e){return this.deliverShapePoke(e)}async queueShapeControl(e,s){if(e===void 0)return s();const t=(this.shapeControl.get(e)??Promise.resolve()).then(s,s),o={},n=()=>{this.shapeControl.get(e)===o.chain&&this.shapeControl.delete(e)},r=t.then(n,n);return o.chain=r,this.shapeControl.set(e,r),t}relayMemos(){return this.relayMemoCache===void 0&&(Q(this.host.sql()),this.relayMemoCache=Z(this.host.sql())),this.relayMemoCache}connectionMemos(e){const s=this.relayMemos();let t=s.get(e);return t===void 0&&(t=new Map,s.set(e,t)),t}recordRelayShapeMemo(e,s,t,o){const{connectionId:n}=this.host.readAttachment(e);n!==void 0&&(this.connectionMemos(n).set(s,{cursor:t,epoch:o}),C(this.host.sql(),[{connectionId:n,cursor:t,epoch:o,subId:s}]))}forgetRelayShapeMemos(e,s){if(s===void 0){this.relayMemos().delete(e),se(this.host.sql(),e);return}this.relayMemos().get(e)?.delete(s),te(this.host.sql(),e,s)}deliverShapePoke(e){const s=E(e.name,e.args),t=[];let o=0,n=0;for(const r of this.host.getWebSockets()){const{connectionId:a,shapes:h}=this.host.readAttachment(r);if(h===void 0||a===void 0||e.targetConnectionId!==void 0&&a!==e.targetConnectionId)continue;const c=this.pokeSocketShapes(r,h,this.connectionMemos(a),e,s);n+=c.matched.length,o+=c.sent;for(const d of c.matched)t.push({connectionId:a,cursor:e.checkpoint,epoch:e.epoch,subId:d})}return C(this.host.sql(),t),{delivered:o,matched:n}}pokeSocketShapes(e,s,t,o,n){const r=[];let a=0;for(const[h,c]of Object.entries(s)){const d=t.get(h);if(E(c.name,c.args)!==n||!ie(d,o))continue;const u=O([{baseCheckpoint:d?.cursor,rowsPatch:o.rowsPatch,shapeId:h}],{baseCheckpoint:void 0,checkpoint:o.checkpoint,epoch:o.epoch,lastMutationId:void 0,pokeId:this.host.nextPokeId()},{preEncoded:!0}).map(l=>x(e,l)).every(Boolean);t.set(h,{cursor:o.checkpoint,epoch:o.epoch}),r.push(h),u&&(a+=1)}return{matched:r,sent:a}}}const Ie=i=>{const e=i.doName();if(e===void 0)return;const s=H(e);return s===void 0?new he(i,e):new le(i,s.ownerKey,s.relayIndex)};export{ne as DEFAULT_MAX_RELAYS,he as OwnerRelay,le as RelayMember,Ie as createRelayLink};
8
+ ON CONFLICT(connection_id, sub_id) DO UPDATE SET cursor = excluded.cursor, epoch = excluded.epoch`)}},te=(i,e,s)=>{m(i,y`DELETE FROM ${y.identifier(f)} WHERE connection_id = ${e} AND sub_id = ${s}`)},se=(i,e)=>{m(i,y`DELETE FROM ${y.identifier(f)} WHERE connection_id = ${e}`)},oe=i=>{m(i,y`DELETE FROM ${y.identifier(f)}`)},re=2,ne=8,I={},ae=i=>{throw new D("INTERNAL",`unhandled relay frame: ${JSON.stringify(i)}`)},ie=(i,e)=>i===void 0||i.epoch!==e.epoch?!1:i.cursor>=e.fromCursor&&i.cursor<e.checkpoint,ce=i=>Response.json(i,{headers:{"content-type":"application/json"}}),S=()=>new Response(null,{status:204});class P{constructor(e,s){this.host=e,this.roleId=s}host;roleId;async handleControl(e){let s;try{s=await e.text()}catch{return new Response("bad request",{status:400})}if(!await j(this.host.env(),e.headers.get(L),s))return new Response("forbidden",{status:403});let t;try{t=JSON.parse(s)}catch{return new Response("bad request",{status:400})}switch(t.type){case"relay_attach":return this.onAttach(t.relayIndex),S();case"relay_detach":return this.onDetach(t.relayIndex),S();case"relay_frame":return this.host.deliverWhisperLocal(t.topic,t.frame,void 0),await this.onWhisperFrame(t),S();case"relay_shape_poke":{const o=this.host.getWebSockets().length,n=Date.now(),{delivered:r,matched:a}=this.onShapePoke({...t,args:v(t.args)});return this.host.recordShapePokeFanout(o,r,Date.now()-n),r<a?Response.json({delivered:r,matched:a},{status:503}):S()}case"relay_shape_subscribe":return ce(this.onShapeSubscribe({...t,args:v(t.args)}));case"relay_shape_unsubscribe":return this.onShapeUnsubscribe(t),S();default:return ae(t)}}maxRelays(){return g(this.host.env(),"LUNORA_MAX_RELAYS",ne)}canAddressSiblings(){return this.siblingStub(this.roleId.ownerKey)!==void 0}siblingStub(e){return z(this.host.env(),this.bindingName(),e,this.host.shardJurisdiction())}bindingName(){return this.host.shardBinding()}async postRelayMessage(e,s){await this.requestRelayMessage(e,s)}async requestRelayMessage(e,s){const t=this.siblingStub(e);if(t===void 0)return;const o=JSON.stringify(s),n={"content-type":"application/json","x-lunora-shard-binding":this.host.shardBinding()??""},r=G(this.host.env());r!==void 0&&(n[L]=await J(r,o));try{return await t.fetch("https://relay.internal/_lunora/relay",{body:o,headers:n,method:"POST"})}catch{return}}}class he extends P{shapeUniformCache=new Map;relaySetCache;registryCache;recordedBinding;promotionState="owned";constructor(e,s){super(e,{ownerKey:s})}async forwardWhisper(e,s){if(!this.canAddressSiblings())return;const t=this.ownerRelaySet();t.size!==0&&await Promise.all([...t].map(o=>this.postRelayMessage(R(this.roleId.ownerKey,o),{frame:s,topic:e,type:"relay_frame"})))}async onFlush(e,s){this.canAddressSiblings()&&await Promise.all([this.multicastShapePokes(e,s),this.proxyShapePokes(e,s)])}seedRelayShape(){return Promise.resolve(void 0)}announce(){return Promise.resolve()}announceDrain(){return Promise.resolve()}releaseRelayShapes(){return Promise.resolve()}relayCount(){const e=this.host.getWebSockets().length,s=g(this.host.env(),"LUNORA_RELAY_THRESHOLD",T.tUp),t=g(this.host.env(),"LUNORA_RELAY_COLLAPSE_THRESHOLD",T.tDown);if(this.promotionState=B(this.promotionState,e,q(s,t)),this.promotionState==="owned")return 0;const o=g(this.host.env(),"LUNORA_RELAY_FAN",re);return Math.min(this.maxRelays(),Math.max(1,o))}minShapeCursor(){const{cohort:e,proxies:s}=this.relayShapes();let t;for(const o of[...e.values(),...s.values()])t=t===void 0?o.cursor:Math.min(t,o.cursor);return t}isShapeRelayUniform(e,s){const t=_(e,s),o=this.shapeUniformCache.get(t);if(o!==void 0)return o;const n=this.probeShapeRelayUniform(e,s);return this.shapeUniformCache.set(t,n),n}onShapeUnsubscribe(e){const{proxies:s}=this.relayShapes(),t=e.subId===void 0?void 0:M(e.relayIndex,e.connectionId,e.subId);for(const[o,n]of s)n.relayIndex!==e.relayIndex||n.connectionId!==e.connectionId||(t===void 0||o===t)&&s.delete(o);U(this.host.sql(),e.relayIndex,e.connectionId,e.subId)}onAttach(e){this.addRelayToSet(e)}onDetach(e){this.removeRelayFromSet(e)}async onWhisperFrame(e){await Promise.all([...this.ownerRelaySet()].filter(s=>s!==e.originRelay).map(s=>this.postRelayMessage(R(this.roleId.ownerKey,s),{frame:e.frame,topic:e.topic,type:"relay_frame"})))}onShapeSubscribe(e){return this.buildShapeSeedFrames(e)}onShapePoke(){return{delivered:0,matched:0}}buildShapePoke(e,s,t,o,n){let r;try{r=this.host.resolveShape(e.name,e.args,s)}catch{return}if(r===void 0||r.global===!0||!t.has(r.table))return;const a=e,h=a.cursor,c=this.host.buildShapeDiff(r,h,o);if(c.length!==0)return a.cursor=o,w(this.host.sql(),a.key,o),{args:N(e.args),checkpoint:o,epoch:n,fromCursor:h,name:e.name,rowsPatch:X(c),type:"relay_shape_poke"}}async multicastShapePokes(e,s){const t=this.ownerRelaySet();if(t.size===0)return;const{cohort:o}=this.relayShapes();if(o.size===0)return;const n=this.host.currentCdcEpoch(),r=[];for(const a of o.values()){const h=this.buildShapePoke(a,I,e,s,n);h&&r.push(this.multicastToRelays(t,h,a))}await Promise.all(r)}async multicastToRelays(e,s,t){(await Promise.all([...e].map(async n=>(await this.requestRelayMessage(R(this.roleId.ownerKey,n),s))?.ok===!0))).includes(!1)&&this.rewindShapeCursor(t,s.fromCursor)}async proxyShapePokes(e,s){if(this.ownerRelaySet().size===0)return;const{proxies:t}=this.relayShapes();if(t.size===0)return;const o=this.host.currentCdcEpoch(),n=[];for(const r of t.values()){const a=this.buildShapePoke(r,r.identity,e,s,o);a&&n.push(this.proxyToRelay(a,r))}await Promise.all(n)}async proxyToRelay(e,s){(await this.requestRelayMessage(R(this.roleId.ownerKey,s.relayIndex),{...e,targetConnectionId:s.connectionId}))?.ok!==!0&&this.rewindShapeCursor(s,e.fromCursor)}buildShapeSeedFrames(e){const s={identity:e.identity,userId:e.userId};let t;try{t=this.host.resolveShape(e.name,e.args,s)}catch(l){const{body:p}=k(l,{fallbackCode:"SHAPE_RESOLVE_FAILED",redactedMessage:"shape resolution failed"});return{error:{code:p.code,message:p.message}}}if(t===void 0||t.global===!0)return{error:{code:"SHAPE_NOT_FOUND",message:`shape not relayable: ${e.name}`}};e.relayIndex!==void 0&&this.addRelayToSet(e.relayIndex);const{baseCheckpoint:o,cursor:n,epoch:r,reset:a,rowsPatch:h}=this.host.computeOpLogShapeSeed({args:e.args,name:e.name,sinceEpoch:e.sinceEpoch,sinceSeq:e.sinceSeq},t);let c=n;const{cohort:d,proxies:E}=this.relayShapes();if(this.isShapeRelayUniform(e.name,e.args)){const l=_(e.name,e.args);let p=d.get(l);p===void 0&&(p={args:e.args,cursor:n,key:l,name:e.name},d.set(l,p),A(this.host.sql(),p)),c=p.cursor}else if(e.relayIndex!==void 0&&e.connectionId!==void 0){const l=M(e.relayIndex,e.connectionId,e.subId),p={args:e.args,connectionId:e.connectionId,cursor:n,identity:s,key:l,name:e.name,relayIndex:e.relayIndex};E.set(l,p),A(this.host.sql(),p)}else return{error:{code:"RELAY_SHAPE_UNROUTABLE",message:`shape ${e.name} is per-socket on a relay, but the subscribe carries no ${e.relayIndex===void 0?"relay index":"connection id"}`}};const u=O([{reset:a,rowsPatch:h,shapeId:e.subId}],{baseCheckpoint:o,checkpoint:c,epoch:r,lastMutationId:void 0,pokeId:this.host.nextPokeId()});return{cursor:c,epoch:r,frames:u}}ensureRelayTables(){this.host.sql().exec("CREATE TABLE IF NOT EXISTS __lunora_relays (idx INTEGER PRIMARY KEY)"),this.host.sql().exec("CREATE TABLE IF NOT EXISTS __lunora_relay_binding (id INTEGER PRIMARY KEY, binding TEXT NOT NULL)"),$(this.host.sql())}bindingName(){const e=this.host.shardBinding();if(e!==void 0&&e!=="")return e!==this.recordedBinding&&(this.recordedBinding=e,this.ensureRelayTables(),this.host.sql().exec("INSERT INTO __lunora_relay_binding (id, binding) VALUES (1, ?) ON CONFLICT(id) DO UPDATE SET binding = excluded.binding",e)),e;if(this.recordedBinding!==void 0)return this.recordedBinding;try{const s=this.host.sql().exec("SELECT binding FROM __lunora_relay_binding WHERE id = 1").toArray();this.recordedBinding=s[0]?.binding}catch{this.recordedBinding=void 0}return this.recordedBinding}relayShapes(){const e=this.registryCache;if(e!==void 0)return e;this.ensureRelayTables();const s={cohort:new Map,proxies:new Map};for(const t of K(this.host.sql()))t.relayIndex===void 0||t.connectionId===void 0?s.cohort.set(t.key,{args:t.args,cursor:t.cursor,key:t.key,name:t.name}):s.proxies.set(t.key,{args:t.args,connectionId:t.connectionId,cursor:t.cursor,identity:t.identity??{},key:t.key,name:t.name,relayIndex:t.relayIndex});return this.registryCache=s,s}rewindShapeCursor(e,s){const t=e;t.cursor<=s||(t.cursor=s,w(this.host.sql(),t.key,s))}ownerRelaySet(){if(this.relaySetCache===void 0){this.ensureRelayTables();const e=this.host.sql().exec("SELECT idx FROM __lunora_relays").toArray();this.relaySetCache=new Set(e.map(s=>Number(s.idx)))}return this.relaySetCache}addRelayToSet(e){this.ensureRelayTables(),this.host.sql().exec("INSERT OR IGNORE INTO __lunora_relays (idx) VALUES (?)",e),this.ownerRelaySet().add(e)}removeRelayFromSet(e){this.ensureRelayTables(),this.host.sql().exec("DELETE FROM __lunora_relays WHERE idx = ?",e);const s=this.ownerRelaySet();s.delete(e);const{cohort:t,proxies:o}=this.relayShapes();for(const[n,r]of o)r.relayIndex===e&&o.delete(n);Y(this.host.sql(),e),s.size===0&&(t.clear(),this.shapeUniformCache.clear(),W(this.host.sql()))}probeShapeRelayUniform(e,s){let t;try{t=this.host.resolveShape(e,s,I)}catch{return!1}if(t===void 0||t.global===!0||this.host.rlsMetadata().policies.some(c=>c.on==="read"&&c.table===t.table)||this.tableHasAnyMask(t.table))return!1;const o=b(t.effectiveWhere),n=b(t.columns);let r=!1;const a=c=>{const d={groups:[`grp_${c}`],roles:[c],sub:`__lunora_probe_${c}__`};return{identity:new Proxy(d,{get:(u,l)=>typeof l=="symbol"||l in u?Reflect.get(u,l):`${c}:${l}`,getOwnPropertyDescriptor:(u,l)=>(r=!0,Reflect.getOwnPropertyDescriptor(u,l)),has:(u,l)=>typeof l=="symbol"?Reflect.has(u,l):!0,ownKeys:u=>(r=!0,Reflect.ownKeys(u))}),ip:`__lunora_probe_${c}__`,userId:`__lunora_probe_${c}__`}};return[I,a("a"),a("b")].every(c=>{let d;try{d=this.host.resolveShape(e,s,c)}catch{return!1}return d!==void 0&&d.global!==!0&&d.table===t.table&&b(d.effectiveWhere)===o&&b(d.columns)===n})&&!r}tableHasAnyMask(e){return this.host.maskMetadata().columns.some(s=>s.table===e)}}class le extends P{relayAnnounced=!1;relayMemoCache;shapeControl=new Map;constructor(e,s,t){super(e,{ownerKey:s,relayIndex:t})}async forwardWhisper(e,s){this.canAddressSiblings()&&await this.postRelayMessage(this.roleId.ownerKey,{frame:s,originRelay:this.roleId.relayIndex,topic:e,type:"relay_frame"})}onFlush(){return Promise.resolve()}async seedRelayShape(e,s,t,o){if(!this.canAddressSiblings())return{code:"RELAY_MISCONFIGURED",message:"relay cannot address its owner"};const{connectionId:n}=this.host.readAttachment(e),r={args:N(t.args??{}),connectionId:n,identity:o.identity,name:t.name,relayIndex:this.roleId.relayIndex,sinceEpoch:t.sinceEpoch,sinceSeq:t.sinceSeq,subId:s,type:"relay_shape_subscribe",userId:o.userId},a=await this.queueShapeControl(n,async()=>(await this.announce(),this.requestRelayMessage(this.roleId.ownerKey,r)));if(a===void 0)return{code:"RELAY_SEED_FAILED",message:"owner did not answer the shape seed"};let h;try{h=await a.json()}catch{return{code:"RELAY_SEED_FAILED",message:"malformed shape seed from owner"}}if(h.error!==void 0)return h.error;if(h.frames===void 0)return{code:"RELAY_SEED_FAILED",message:"owner returned no shape frames"};await V(e);for(const c of h.frames)x(e,c);return this.recordRelayShapeMemo(e,s,h.cursor??0,h.epoch),"ok"}async announce(){if(this.relayAnnounced||!this.canAddressSiblings())return;this.relayAnnounced=!0,(await this.requestRelayMessage(this.roleId.ownerKey,{relayIndex:this.roleId.relayIndex,type:"relay_attach"}))?.ok||(this.relayAnnounced=!1)}async announceDrain(e){this.host.getWebSockets().some(s=>s!==e)||(this.relayMemos().clear(),oe(this.host.sql()),this.canAddressSiblings()&&(this.relayAnnounced=!1,await this.postRelayMessage(this.roleId.ownerKey,{relayIndex:this.roleId.relayIndex,type:"relay_detach"})))}async releaseRelayShapes(e,s){const{connectionId:t}=this.host.readAttachment(e);t!==void 0&&this.forgetRelayShapeMemos(t,s),!(t===void 0||!this.canAddressSiblings())&&await this.queueShapeControl(t,async()=>this.postRelayMessage(this.roleId.ownerKey,{connectionId:t,relayIndex:this.roleId.relayIndex,...s===void 0?{}:{subId:s},type:"relay_shape_unsubscribe"}))}relayCount(){return 0}isShapeRelayUniform(){return!1}minShapeCursor(){}onAttach(){}onDetach(){}onWhisperFrame(){return Promise.resolve()}onShapeSubscribe(){return{error:{code:"RELAY_CANNOT_SEED",message:"a relay has no op-log to seed from"}}}onShapeUnsubscribe(){}onShapePoke(e){return this.deliverShapePoke(e)}async queueShapeControl(e,s){if(e===void 0)return s();const t=(this.shapeControl.get(e)??Promise.resolve()).then(s,s),o={},n=()=>{this.shapeControl.get(e)===o.chain&&this.shapeControl.delete(e)},r=t.then(n,n);return o.chain=r,this.shapeControl.set(e,r),t}relayMemos(){return this.relayMemoCache===void 0&&(Q(this.host.sql()),this.relayMemoCache=Z(this.host.sql())),this.relayMemoCache}connectionMemos(e){const s=this.relayMemos();let t=s.get(e);return t===void 0&&(t=new Map,s.set(e,t)),t}recordRelayShapeMemo(e,s,t,o){const{connectionId:n}=this.host.readAttachment(e);n!==void 0&&(this.connectionMemos(n).set(s,{cursor:t,epoch:o}),C(this.host.sql(),[{connectionId:n,cursor:t,epoch:o,subId:s}]))}forgetRelayShapeMemos(e,s){if(s===void 0){this.relayMemos().delete(e),se(this.host.sql(),e);return}this.relayMemos().get(e)?.delete(s),te(this.host.sql(),e,s)}deliverShapePoke(e){const s=_(e.name,e.args),t=[];let o=0,n=0;for(const r of this.host.getWebSockets()){const{connectionId:a,shapes:h}=this.host.readAttachment(r);if(h===void 0||a===void 0||e.targetConnectionId!==void 0&&a!==e.targetConnectionId)continue;const c=this.pokeSocketShapes(r,h,this.connectionMemos(a),e,s);n+=c.matched.length,o+=c.sent;for(const d of c.matched)t.push({connectionId:a,cursor:e.checkpoint,epoch:e.epoch,subId:d})}return C(this.host.sql(),t),{delivered:o,matched:n}}pokeSocketShapes(e,s,t,o,n){const r=[];let a=0;for(const[h,c]of Object.entries(s)){const d=t.get(h);if(_(c.name,c.args)!==n||!ie(d,o))continue;const u=O([{baseCheckpoint:d?.cursor,rowsPatch:o.rowsPatch,shapeId:h}],{baseCheckpoint:void 0,checkpoint:o.checkpoint,epoch:o.epoch,lastMutationId:void 0,pokeId:this.host.nextPokeId()},{preEncoded:!0}).map(l=>x(e,l)).every(Boolean);t.set(h,{cursor:o.checkpoint,epoch:o.epoch}),r.push(h),u&&(a+=1)}return{matched:r,sent:a}}}const Ie=i=>{const e=i.doName();if(e===void 0)return;const s=H(e);return s===void 0?new he(i,e):new le(i,s.ownerKey,s.relayIndex)};export{ne as DEFAULT_MAX_RELAYS,he as OwnerRelay,le as RelayMember,Ie as createRelayLink};
@@ -1 +1 @@
1
- import{createShardCtxDb as v}from"./NotUniqueError-BMom69SD.mjs";import{createRelayLink as I}from"./DEFAULT_MAX_RELAYS-DDOVsK5A.mjs";import{ConflictError as N}from"./ConflictError-C8GtJmjS.mjs";import{runShardMigrations as _}from"./runShardMigrations-CeT_SVrI.mjs";import{relayName as F}from"./DEFAULT_PROMOTION_THRESHOLDS-Bfx7KakS.mjs";const E=(C,m={})=>({_meta:{column:{notNull:!0,...m}},kind:C}),W=(C,m,O)=>{const{describe:S,expect:n,it:y}=O;S(`engine contract: ${C}`,()=>{S("optimistic concurrency",()=>{const b=u=>({tables:{items:{indexes:[],shape:{title:E("string"),version:E("number",{notNull:!1})},triggerMap:{clobber:{handler:()=>{u.exec(`UPDATE "items" SET "__doc__" = json_set("__doc__", '$.version', 99) WHERE "id" = 'i1'`)},op:"update",timing:"before"}}}}});y("raises a CONFLICT of kind `occ` when a write's snapshot is clobbered",async()=>{const{close:u,host:h}=m();try{const i=h.sql,l=b(i);_(i,l);const s=v({schema:l,sql:i});await s.insert("items",{_id:"i1",title:"first",version:1},{allowExplicitId:!0}),await n(s.patch("i1",{title:"second"})).rejects.toBeInstanceOf(N)}finally{u?.()}}),y("reports the conflict as CONFLICT/409 rather than retrying it away",async()=>{const{close:u,host:h}=m();try{const i=h.sql,l=b(i);_(i,l);const s=v({schema:l,sql:i});await s.insert("items",{_id:"i1",title:"first",version:1},{allowExplicitId:!0});let o;try{await s.patch("i1",{title:"second"})}catch(t){o=t}const e=o;n(e.code).toBe("CONFLICT"),n(e.kind).toBe("occ")}finally{u?.()}}),y("leaves the row readable and unchanged after a conflict",async()=>{const{close:u,host:h}=m();try{const i=h.sql,l=b(i);_(i,l);const s=v({schema:l,sql:i});await s.insert("items",{_id:"i1",title:"first",version:1},{allowExplicitId:!0});try{await s.patch("i1",{title:"second"})}catch{}const o=await s.get("i1");n(o?.title).toBe("first"),n(o?.version).toBe(99)}finally{u?.()}}),y("raises a CONFLICT of kind `trigger` when a trigger writes its own row through the db",async()=>{const{close:u,host:h}=m();try{const i=h.sql,l={tables:{items:{indexes:[],shape:{title:E("string"),version:E("number",{notNull:!1})},triggerMap:{recurse:{handler:async(t,a)=>{await t.db.patch(a.doc._id,{version:99})},op:"update",timing:"before"}}}}};_(i,l);const s=v({schema:l,sql:i});await s.insert("items",{_id:"i1",title:"first",version:1},{allowExplicitId:!0});let o;try{await s.patch("i1",{title:"second"})}catch(t){o=t}const e=o;n(e).toBeInstanceOf(N),n(e.code).toBe("CONFLICT"),n(e.kind).toBe("trigger")}finally{u?.()}})}),S("shape-poke ordering",()=>{const b="shard-a",u={args:{},name:"messages"},h=(e,t,a,r)=>e.accept(t?.()??{},{connectionId:a,shapes:{[r]:u}}),i=(e,t,a)=>{let r=0,d=0;const c=g=>()=>{throw new Error(`the relay poke path must not reach RelayHost.${g}`)},p={fetch:(g,q)=>{if(JSON.parse(q?.body??"{}").type!=="relay_shape_subscribe")return Promise.resolve(new Response(void 0,{status:204}));const B=a[d];if(d+=1,B===void 0)throw new Error("the relay asked for more seeds than this fixture supplies");return Promise.resolve(Response.json(B))}},k={get:()=>p,getByName:()=>p,idFromName:g=>g},w={buildShapeDiff:c("buildShapeDiff"),computeOpLogShapeSeed:c("computeOpLogShapeSeed"),currentCdcEpoch:c("currentCdcEpoch"),deliverWhisperLocal:c("deliverWhisperLocal"),doName:()=>F(b,0),env:()=>({SHARD:k}),getWebSockets:()=>e.getSockets(),maskMetadata:c("maskMetadata"),nextPokeId:()=>(r+=1,`poke-${String(r)}`),readAttachment:g=>g.deserializeAttachment?.(),recordShapePokeFanout:()=>{},resolveShape:c("resolveShape"),rlsMetadata:c("rlsMetadata"),shardBinding:()=>"SHARD",shardJurisdiction:()=>{},sql:()=>t},f=I(w);if(f===void 0)throw new Error("expected a relay link for a `…::relay::N` name");return f},l=e=>new Request("https://relay.internal/_lunora/relay",{body:JSON.stringify(e),headers:{"content-type":"application/json"},method:"POST"}),s=async(e,t,a)=>{const r=await e.seedRelayShape(t,a,u,{identity:void 0,userId:void 0});if(r!=="ok")throw new Error(`seed failed: ${JSON.stringify(r)}`)},o=(e={})=>l({...u,checkpoint:20,epoch:"e1",fromCursor:10,rowsPatch:[{id:"r1",op:"upsert",value:{title:"hello"}}],type:"relay_shape_poke",...e});y("frames a poke as pokeStart → pokePart per shape → pokeEnd, under one poke id",async()=>{const{close:e,createSocket:t,host:a,readFrames:r,sockets:d}=m();try{const c=i(d,a.sql,[{cursor:10,epoch:"e1",frames:[]}]),p=h(d,t,"c-alice","s1");await s(c,p,"s1"),await c.handleControl(o());const w=(await r(p)).map(f=>JSON.parse(f));n(w.map(f=>f.type)).toStrictEqual(["pokeStart","pokePart","pokeEnd"]),n(new Set(w.map(f=>f.pokeId)).size).toBe(1),n(w[1]?.shapeId).toBe("s1"),n(w[2]?.checkpoint).toBe(20)}finally{e?.()}}),y("delivers a poke only to sockets whose cursor matches, and advances them past it",async()=>{const{close:e,createSocket:t,host:a,readFrames:r,sockets:d}=m();try{const c=i(d,a.sql,[{cursor:10,epoch:"e1",frames:[]},{cursor:7,epoch:"e1",frames:[]}]),p=h(d,t,"c-alice","s1"),k=h(d,t,"c-bob","s2");await s(c,p,"s1"),await s(c,k,"s2"),await c.handleControl(o());const w=await r(p);n(w.length).toBe(3);const f=await r(k);n(f.length).toBe(0),await c.handleControl(o());const g=await r(p);n(g.length).toBe(3)}finally{e?.()}}),y("skips a socket whose cursor matches under a different CDC epoch",async()=>{const{close:e,createSocket:t,host:a,readFrames:r,sockets:d}=m();try{const c=i(d,a.sql,[{cursor:10,epoch:"e1",frames:[]}]),p=h(d,t,"c-alice","s1");await s(c,p,"s1"),await c.handleControl(o({epoch:"e2"}));const k=await r(p);n(k.length).toBe(0),await c.handleControl(o());const w=await r(p);n(w.length).toBe(3)}finally{e?.()}})}),S("RLS identity under live subscription",()=>{const b="shard-a",u={args:{},name:"lobby-messages"},h={args:{},name:"my-orders"},i=s=>{const o=[],e=[],t={fetch:(d,c)=>(o.push(JSON.parse(c?.body??"{}")),Promise.resolve(new Response(void 0,{status:204})))},r=I({buildShapeDiff:()=>[{id:"r1",op:"upsert",value:{}}],computeOpLogShapeSeed:()=>({baseCheckpoint:void 0,cursor:10,epoch:"e1",reset:!0,rowsPatch:[]}),currentCdcEpoch:()=>"e1",deliverWhisperLocal:()=>0,doName:()=>b,env:()=>({SHARD:{get:()=>t,getByName:()=>t,idFromName:d=>d}}),getWebSockets:()=>[],maskMetadata:()=>({columns:[]}),nextPokeId:()=>"poke-1",readAttachment:()=>({}),recordShapePokeFanout:()=>{},resolveShape:(d,c,p)=>(e.push(p),d===h.name?{columns:["id"],effectiveWhere:{org:p?.identity?.org??"anonymous"},global:!1,table:"orders"}:{columns:["id"],effectiveWhere:{room:"lobby"},global:!1,table:"messages"}),rlsMetadata:()=>({policies:[]}),shardBinding:()=>"SHARD",shardJurisdiction:()=>{},sql:()=>s});if(r===void 0)throw new Error("expected an owner link for an un-suffixed DO name");return{owner:r,posts:o,resolvedUnder:e}},l=async(s,o)=>{await s.handleControl(new Request("https://owner.internal/_lunora/relay",{body:JSON.stringify({...o,connectionId:"c-alice",identity:{org:"acme"},relayIndex:0,subId:"s1",type:"relay_shape_subscribe",userId:"u1"}),headers:{"content-type":"application/json"},method:"POST"}))};y("seeds a subscriber under its own forwarded identity, never the anonymous one",async()=>{const{close:s,host:o}=m();try{const{owner:e,resolvedUnder:t}=i(o.sql);await l(e,h),n(t.some(a=>a?.userId==="u1"&&a.identity?.org==="acme")).toBe(!0)}finally{s?.()}}),y("routes an identity-scoped shape to a per-socket poke, not the cohort multicast",async()=>{const{close:s,host:o}=m();try{const{owner:e,posts:t}=i(o.sql);await l(e,h),t.length=0,await e.onFlush(new Set(["orders"]),20);const a=t.filter(r=>r.type==="relay_shape_poke");n(a.length).toBe(1),n(a[0]?.targetConnectionId).toBe("c-alice")}finally{s?.()}}),y("still multicasts an identity-blind shape to the whole cohort",async()=>{const{close:s,host:o}=m();try{const{owner:e,posts:t}=i(o.sql);await l(e,u),t.length=0,await e.onFlush(new Set(["messages"]),20);const a=t.filter(r=>r.type==="relay_shape_poke");n(a.length).toBe(1),n(a[0]?.targetConnectionId).toBeUndefined()}finally{s?.()}})})})};export{W as defineEngineContractSuite};
1
+ import{createShardCtxDb as v}from"./NotUniqueError-BMom69SD.mjs";import{createRelayLink as I}from"./DEFAULT_MAX_RELAYS-Ng4SyJ7k.mjs";import{ConflictError as N}from"./ConflictError-C8GtJmjS.mjs";import{runShardMigrations as _}from"./runShardMigrations-CeT_SVrI.mjs";import{relayName as F}from"./DEFAULT_PROMOTION_THRESHOLDS-Bfx7KakS.mjs";const E=(C,m={})=>({_meta:{column:{notNull:!0,...m}},kind:C}),W=(C,m,O)=>{const{describe:S,expect:n,it:y}=O;S(`engine contract: ${C}`,()=>{S("optimistic concurrency",()=>{const b=u=>({tables:{items:{indexes:[],shape:{title:E("string"),version:E("number",{notNull:!1})},triggerMap:{clobber:{handler:()=>{u.exec(`UPDATE "items" SET "__doc__" = json_set("__doc__", '$.version', 99) WHERE "id" = 'i1'`)},op:"update",timing:"before"}}}}});y("raises a CONFLICT of kind `occ` when a write's snapshot is clobbered",async()=>{const{close:u,host:h}=m();try{const i=h.sql,l=b(i);_(i,l);const s=v({schema:l,sql:i});await s.insert("items",{_id:"i1",title:"first",version:1},{allowExplicitId:!0}),await n(s.patch("i1",{title:"second"})).rejects.toBeInstanceOf(N)}finally{u?.()}}),y("reports the conflict as CONFLICT/409 rather than retrying it away",async()=>{const{close:u,host:h}=m();try{const i=h.sql,l=b(i);_(i,l);const s=v({schema:l,sql:i});await s.insert("items",{_id:"i1",title:"first",version:1},{allowExplicitId:!0});let o;try{await s.patch("i1",{title:"second"})}catch(t){o=t}const e=o;n(e.code).toBe("CONFLICT"),n(e.kind).toBe("occ")}finally{u?.()}}),y("leaves the row readable and unchanged after a conflict",async()=>{const{close:u,host:h}=m();try{const i=h.sql,l=b(i);_(i,l);const s=v({schema:l,sql:i});await s.insert("items",{_id:"i1",title:"first",version:1},{allowExplicitId:!0});try{await s.patch("i1",{title:"second"})}catch{}const o=await s.get("i1");n(o?.title).toBe("first"),n(o?.version).toBe(99)}finally{u?.()}}),y("raises a CONFLICT of kind `trigger` when a trigger writes its own row through the db",async()=>{const{close:u,host:h}=m();try{const i=h.sql,l={tables:{items:{indexes:[],shape:{title:E("string"),version:E("number",{notNull:!1})},triggerMap:{recurse:{handler:async(t,a)=>{await t.db.patch(a.doc._id,{version:99})},op:"update",timing:"before"}}}}};_(i,l);const s=v({schema:l,sql:i});await s.insert("items",{_id:"i1",title:"first",version:1},{allowExplicitId:!0});let o;try{await s.patch("i1",{title:"second"})}catch(t){o=t}const e=o;n(e).toBeInstanceOf(N),n(e.code).toBe("CONFLICT"),n(e.kind).toBe("trigger")}finally{u?.()}})}),S("shape-poke ordering",()=>{const b="shard-a",u={args:{},name:"messages"},h=(e,t,a,r)=>e.accept(t?.()??{},{connectionId:a,shapes:{[r]:u}}),i=(e,t,a)=>{let r=0,d=0;const c=g=>()=>{throw new Error(`the relay poke path must not reach RelayHost.${g}`)},p={fetch:(g,q)=>{if(JSON.parse(q?.body??"{}").type!=="relay_shape_subscribe")return Promise.resolve(new Response(void 0,{status:204}));const B=a[d];if(d+=1,B===void 0)throw new Error("the relay asked for more seeds than this fixture supplies");return Promise.resolve(Response.json(B))}},k={get:()=>p,getByName:()=>p,idFromName:g=>g},w={buildShapeDiff:c("buildShapeDiff"),computeOpLogShapeSeed:c("computeOpLogShapeSeed"),currentCdcEpoch:c("currentCdcEpoch"),deliverWhisperLocal:c("deliverWhisperLocal"),doName:()=>F(b,0),env:()=>({SHARD:k}),getWebSockets:()=>e.getSockets(),maskMetadata:c("maskMetadata"),nextPokeId:()=>(r+=1,`poke-${String(r)}`),readAttachment:g=>g.deserializeAttachment?.(),recordShapePokeFanout:()=>{},resolveShape:c("resolveShape"),rlsMetadata:c("rlsMetadata"),shardBinding:()=>"SHARD",shardJurisdiction:()=>{},sql:()=>t},f=I(w);if(f===void 0)throw new Error("expected a relay link for a `…::relay::N` name");return f},l=e=>new Request("https://relay.internal/_lunora/relay",{body:JSON.stringify(e),headers:{"content-type":"application/json"},method:"POST"}),s=async(e,t,a)=>{const r=await e.seedRelayShape(t,a,u,{identity:void 0,userId:void 0});if(r!=="ok")throw new Error(`seed failed: ${JSON.stringify(r)}`)},o=(e={})=>l({...u,checkpoint:20,epoch:"e1",fromCursor:10,rowsPatch:[{id:"r1",op:"upsert",value:{title:"hello"}}],type:"relay_shape_poke",...e});y("frames a poke as pokeStart → pokePart per shape → pokeEnd, under one poke id",async()=>{const{close:e,createSocket:t,host:a,readFrames:r,sockets:d}=m();try{const c=i(d,a.sql,[{cursor:10,epoch:"e1",frames:[]}]),p=h(d,t,"c-alice","s1");await s(c,p,"s1"),await c.handleControl(o());const w=(await r(p)).map(f=>JSON.parse(f));n(w.map(f=>f.type)).toStrictEqual(["pokeStart","pokePart","pokeEnd"]),n(new Set(w.map(f=>f.pokeId)).size).toBe(1),n(w[1]?.shapeId).toBe("s1"),n(w[2]?.checkpoint).toBe(20)}finally{e?.()}}),y("delivers a poke only to sockets whose cursor matches, and advances them past it",async()=>{const{close:e,createSocket:t,host:a,readFrames:r,sockets:d}=m();try{const c=i(d,a.sql,[{cursor:10,epoch:"e1",frames:[]},{cursor:7,epoch:"e1",frames:[]}]),p=h(d,t,"c-alice","s1"),k=h(d,t,"c-bob","s2");await s(c,p,"s1"),await s(c,k,"s2"),await c.handleControl(o());const w=await r(p);n(w.length).toBe(3);const f=await r(k);n(f.length).toBe(0),await c.handleControl(o());const g=await r(p);n(g.length).toBe(3)}finally{e?.()}}),y("skips a socket whose cursor matches under a different CDC epoch",async()=>{const{close:e,createSocket:t,host:a,readFrames:r,sockets:d}=m();try{const c=i(d,a.sql,[{cursor:10,epoch:"e1",frames:[]}]),p=h(d,t,"c-alice","s1");await s(c,p,"s1"),await c.handleControl(o({epoch:"e2"}));const k=await r(p);n(k.length).toBe(0),await c.handleControl(o());const w=await r(p);n(w.length).toBe(3)}finally{e?.()}})}),S("RLS identity under live subscription",()=>{const b="shard-a",u={args:{},name:"lobby-messages"},h={args:{},name:"my-orders"},i=s=>{const o=[],e=[],t={fetch:(d,c)=>(o.push(JSON.parse(c?.body??"{}")),Promise.resolve(new Response(void 0,{status:204})))},r=I({buildShapeDiff:()=>[{id:"r1",op:"upsert",value:{}}],computeOpLogShapeSeed:()=>({baseCheckpoint:void 0,cursor:10,epoch:"e1",reset:!0,rowsPatch:[]}),currentCdcEpoch:()=>"e1",deliverWhisperLocal:()=>0,doName:()=>b,env:()=>({SHARD:{get:()=>t,getByName:()=>t,idFromName:d=>d}}),getWebSockets:()=>[],maskMetadata:()=>({columns:[]}),nextPokeId:()=>"poke-1",readAttachment:()=>({}),recordShapePokeFanout:()=>{},resolveShape:(d,c,p)=>(e.push(p),d===h.name?{columns:["id"],effectiveWhere:{org:p?.identity?.org??"anonymous"},global:!1,table:"orders"}:{columns:["id"],effectiveWhere:{room:"lobby"},global:!1,table:"messages"}),rlsMetadata:()=>({policies:[]}),shardBinding:()=>"SHARD",shardJurisdiction:()=>{},sql:()=>s});if(r===void 0)throw new Error("expected an owner link for an un-suffixed DO name");return{owner:r,posts:o,resolvedUnder:e}},l=async(s,o)=>{await s.handleControl(new Request("https://owner.internal/_lunora/relay",{body:JSON.stringify({...o,connectionId:"c-alice",identity:{org:"acme"},relayIndex:0,subId:"s1",type:"relay_shape_subscribe",userId:"u1"}),headers:{"content-type":"application/json"},method:"POST"}))};y("seeds a subscriber under its own forwarded identity, never the anonymous one",async()=>{const{close:s,host:o}=m();try{const{owner:e,resolvedUnder:t}=i(o.sql);await l(e,h),n(t.some(a=>a?.userId==="u1"&&a.identity?.org==="acme")).toBe(!0)}finally{s?.()}}),y("routes an identity-scoped shape to a per-socket poke, not the cohort multicast",async()=>{const{close:s,host:o}=m();try{const{owner:e,posts:t}=i(o.sql);await l(e,h),t.length=0,await e.onFlush(new Set(["orders"]),20);const a=t.filter(r=>r.type==="relay_shape_poke");n(a.length).toBe(1),n(a[0]?.targetConnectionId).toBe("c-alice")}finally{s?.()}}),y("still multicasts an identity-blind shape to the whole cohort",async()=>{const{close:s,host:o}=m();try{const{owner:e,posts:t}=i(o.sql);await l(e,u),t.length=0,await e.onFlush(new Set(["messages"]),20);const a=t.filter(r=>r.type==="relay_shape_poke");n(a.length).toBe(1),n(a[0]?.targetConnectionId).toBeUndefined()}finally{s?.()}})})})};export{W as defineEngineContractSuite};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/shard-engine",
3
- "version": "1.0.0-alpha.64",
3
+ "version": "1.0.0-alpha.65",
4
4
  "description": "Host-neutral reactive engine for Lunora: per-shard state, OCC, CDC, reactive subscriptions, and the poke protocol. Consumes @lunora/platform host contracts and can be mounted on any platform host.",
5
5
  "keywords": [
6
6
  "cloudflare",