@lunora/shard-engine 1.0.0-alpha.30 → 1.0.0-alpha.31

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-0XtjRA7F.mjs";export{t as defineEngineContractSuite};
1
+ import{defineEngineContractSuite as t}from"../packem_shared/defineEngineContractSuite-B0Ofch97.mjs";export{t as defineEngineContractSuite};
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{exportShardRows as o,exportShardTable as a,importShardRows as t,parseExportShardArgs as n,parseImportShardArgs as s,selectExportTables as i,validateImportRow as l}from"./packem_shared/exportShardRows-Cgt3ITwH.mjs";import{AGGREGATE_SQL_FUNCTION as p,aggregateSqlFunction as d,matchesStaticWhere as c,normalizeCountArgument as S,throwingScheduler as u}from"./packem_shared/AGGREGATE_SQL_FUNCTION-m1iUU1rv.mjs";import{aggregateTableName as f,coerceAggregateNumber as h,encodeAggregateKey as A,foldAggregateTally as E,readAggregateValue as T}from"./packem_shared/aggregateTableName-Cy5e03oz.mjs";import{CountRlsUnsupportedError as R,mergeWhere as C,planAggregateLookup as _,selectIndexForAggregate as I,selectIndexForCount as L,selectIndexForGroupBy as b}from"./packem_shared/CountRlsUnsupportedError-Bdfupt3g.mjs";import{AUDIT_LOG_TABLE as N,appendAuditEntry as y,ensureAuditTable as D,readAuditLog as O}from"./packem_shared/AUDIT_LOG_TABLE-uNVU9O1W.mjs";import{NotUniqueError as P,assertValidClientId as k,createShardCtxDb as B,normalizeIdStructurally as G}from"./packem_shared/NotUniqueError-BixDiv4O.mjs";import{backfillAggregateIndexes as w,backfillRankIndexes as K,backfillSearchIndexes as q,backfillSearchIndexesForTable as W}from"./packem_shared/backfillAggregateIndexes-DVQ2sVuV.mjs";import{CDC_LOG_TABLE as z,CDC_META_TABLE as H,appendCdcChange as X,applyCdcChanges as V,bumpCdcEpoch as j,migrateCdcLog as Y,migrateCdcMeta as Q,minCdcSeq as J,readCdcChanges as Z,readCdcCursor as $,readCdcEpoch as ee,trimCdcChanges as re}from"./packem_shared/CDC_LOG_TABLE-B58N8NQO.mjs";import{CLIENT_WATERMARK_TABLE as ae,advanceClientWatermark as te,migrateClientWatermark as ne,readClientWatermark as se}from"./packem_shared/CLIENT_WATERMARK_TABLE-BoS1HEqz.mjs";import{c as le}from"./packem_shared/ctx-db-companions-lTt-rvKG.mjs";import{GLOBAL_SHAPE_SNAPSHOT_TABLE as pe,deleteGlobalShapeSnapshot as de,deleteGlobalShapeSnapshotsForConnection as ce,migrateGlobalShapeSnapshot as Se,readGlobalShapeSnapshot as ue,writeGlobalShapeSnapshot as xe}from"./packem_shared/GLOBAL_SHAPE_SNAPSHOT_TABLE-NWaL77m5.mjs";import{IDEMPOTENCY_TABLE as he,migrateIdempotency as Ae,readIdempotent as Ee,trimIdempotent as Te,writeIdempotent as ge}from"./packem_shared/IDEMPOTENCY_TABLE-DKVe2Ohf.mjs";import{computeRankPage as Ce,hydrateDocsById as _e}from"./packem_shared/computeRankPage-Bby1Npkd.mjs";import{SEARCH_STATE_TABLE as Le,migrateSearchState as be,readSearchBackfillState as Me,writeSearchBackfillState as Ne}from"./packem_shared/SEARCH_STATE_TABLE-Dju8ebbU.mjs";import{SHAPE_POKE_CURSOR_TABLE as De,deleteShapePokeCursor as Oe,deleteShapePokeCursorsForConnection as Fe,migrateShapePokeCursor as Pe,readShapePokeCursor as ke,writeShapePokeCursor as Be}from"./packem_shared/SHAPE_POKE_CURSOR_TABLE-Dh4HfSdC.mjs";import{selectShapeMemberIds as Ue,selectShapeRows as we}from"./packem_shared/selectShapeMemberIds-B-pQJHAu.mjs";import{DATA_MIGRATION_STATE_TABLE as qe,readMigrationStatus as We,runDataMigration as ve}from"./packem_shared/DATA_MIGRATION_STATE_TABLE-4l6aU1Vc.mjs";import{SCAN_DEP as He,createDependencyTracker as Xe,depKey as Ve,tableFromDepKey as je}from"./packem_shared/SCAN_DEP-D7qE3iUe.mjs";import{runDrizzle as Qe,runSql as Je}from"./packem_shared/runDrizzle-it6rL9bR.mjs";import{A as $e,a as er,b as rr,D as or,c as ar,d as tr,g as nr,i as sr,j as ir,e as lr,q as mr,f as pr,r as dr,t as cr,h as Sr}from"./packem_shared/do-sql-Dk_DJxn4.mjs";import{param as xr,renderSql as fr,sqliteInList as hr,unionAll as Ar}from"./packem_shared/param-Ib8WHnrF.mjs";import{appendStreamChunk as Tr,claimStreamRun as gr,deleteStreamRun as Rr,finishStreamRun as Cr,migrateDurableStreams as _r,readStreamChunks as Ir,readStreamRun as Lr,trimStreamRuns as br}from"./packem_shared/appendStreamChunk-CH4e4nJn.mjs";import{DurableStreamRunner as Nr,MAX_DURABLE_STREAM_BYTES as yr,MAX_DURABLE_STREAM_CHUNKS as Dr,decideDurableAttach as Or}from"./packem_shared/DurableStreamRunner-Bm6KDMBU.mjs";import{diffExternalSource as Pr}from"./packem_shared/diffExternalSource-pozJ4UdZ.mjs";import{liftSourceId as Br,normalizeSourceDocument as Gr,normalizeSourceValue as Ur}from"./packem_shared/liftSourceId-CA3ENhXj.mjs";import{materializeExternalRows as Kr,materializeExternalRowsIncremental as qr,readExternalSourceBaseline as Wr,runExternalSourceTick as vr}from"./packem_shared/materializeExternalRows-Drn0FGdb.mjs";import{isSoftDeleted as Hr,isSourceDue as Xr,pullExternalSourceIncrementalTick as Vr,pullExternalSourceTick as jr}from"./packem_shared/isSoftDeleted-DcGB0pov.mjs";import{GEO_DEFAULT_PRECISION as Qr,boundingBoxCenter as Jr,boundingBoxGeohashes as Zr,coveringGeohashes as $r,encodeGeohash as eo,haversineMeters as ro,pointInBoundingBox as oo}from"./packem_shared/GEO_DEFAULT_PRECISION-CqpQZ-J_.mjs";import{ADMIN_FUNCTIONS as to,ADMIN_FUNCTION_PREFIX as no,DEFAULT_FANOUT_TOPIC_LIMIT as so,FLAGS_FUNCTION_PREFIX as io,MAX_PAGE_SIZE as lo,RELATION_FUNCTION_PREFIX as mo,createFanoutCounters as po,facetColumn as co,findStorageReferences as So,listTables as uo,readTablePage as xo,recordFanoutPass as fo,selectMatchingIds as ho,summarizeFanoutTopics as Ao,summarizeSubscriptions as Eo}from"./packem_shared/ADMIN_FUNCTIONS-Ddr79XHG.mjs";import{MAIL_RETENTION as go,MAIL_TABLE as Ro,clearCapturedMail as Co,ensureMailTable as _o,readCapturedMail as Io,recordCapturedMail as Lo}from"./packem_shared/MAIL_RETENTION-Cig9Dmc8.mjs";import{NotFoundError as Mo}from"./packem_shared/NotFoundError-BhF7FeFr.mjs";import{armRestore as yo,readBookmark as Do}from"./packem_shared/armRestore-Bu1_8SUa.mjs";import{applySelect as Fo,buildSeekBeforeWhere as Po,buildSeekWhere as ko,decodeCursor as Bo,encodeCursor as Go,normalizeOrderKeys as Uo,softDeleteScope as wo}from"./packem_shared/applySelect-BQbHyo-W.mjs";import{QUEUE_TABLE as qo,clearQueueMessages as Wo,isLossyBody as vo,readQueueMessageById as zo,readQueueMessages as Ho,recordQueueMessages as Xo}from"./packem_shared/QUEUE_TABLE-zj9Tt6tk.mjs";import{RANK_TIEBREAK as jo,encodePartitionKey as Yo,matchesRankStaticWhere as Qo,rankKeyFromDoc as Jo,rankTableName as Zo,resolveRankPartition as $o,sortColumnName as ea}from"./packem_shared/RANK_TIEBREAK-ci3MaM65.mjs";import{ReactiveCache as oa,reactiveCacheKey as aa}from"./packem_shared/ReactiveCache-DfyeaJOA.mjs";import{createReadFootprint as na}from"./packem_shared/createReadFootprint-MRH1If3F.mjs";import{buildIndexRange as ia,indexKeysForRow as la,keysTouchRanges as ma}from"./packem_shared/buildIndexRange-CBKQmHSS.mjs";import{DEFAULT_MAX_RELATION_KEYS as da,assertFlatPredicate as ca,assertShapeShardable as Sa,containsRelationPredicate as ua,isRelationPredicate as xa,resolveRelationPredicates as fa}from"./packem_shared/DEFAULT_MAX_RELATION_KEYS-BAWGIEvC.mjs";import{applyOnDelete as Aa,distinctValues as Ea,fanOutScalarCounts as Ta,relationHooks as ga,resolveWith as Ra,runRowValidators as Ca}from"./packem_shared/applyOnDelete-BlcwKjuO.mjs";import{DEFAULT_PROMOTION_THRESHOLDS as Ia,clampPromotionThresholds as La,nextPromotionState as ba,relayCountFor as Ma,shapeRoutingKey as Na}from"./packem_shared/DEFAULT_PROMOTION_THRESHOLDS-DVTD9iu0.mjs";import{DEFAULT_MAX_RELAYS as Da,OwnerRelay as Oa,RelayMember as Fa,createRelayLink as Pa}from"./packem_shared/DEFAULT_MAX_RELAYS-DeVcEXBh.mjs";import{createReplicaLink as Ba,gateReplicaDispatch as Ga,handleReplicaControl as Ua}from"./packem_shared/createReplicaLink-C1JuP_DN.mjs";import{buildReprojectionMigration as Ka,countLegacyRows as qa,reprojectableFields as Wa,reprojectionTables as va}from"./packem_shared/buildReprojectionMigration-8nVn8Qwb.mjs";import{RLS_UNWRAP_SYMBOL as Ha,RlsRequiredError as Xa,guardWriter as Va}from"./packem_shared/RLS_UNWRAP_SYMBOL-BWloGsd3.mjs";import{SCHEMA_HISTORY_MAX_VERSIONS as Ya,readSchemaHistory as Qa,readSchemaVersion as Ja,recordSchemaVersion as Za}from"./packem_shared/SCHEMA_HISTORY_MAX_VERSIONS-DsycDXWm.mjs";import{serializeSqlValue as et}from"./packem_shared/serializeSqlValue-DbI1VQYM.mjs";import{buildSettings as ot,isDevEnvironment as at}from"./packem_shared/buildSettings-B4igo4rJ.mjs";import{buildPokeFrames as nt,diffGlobalMembership as st,encodeRowsPatch as it,projectColumns as lt}from"./packem_shared/buildPokeFrames-BXejpiII.mjs";import{ShardRunner as pt}from"./packem_shared/ShardRunner-C9p5DVOx.mjs";import{runSocketPool as ct}from"./packem_shared/runSocketPool-CZJ2X9cF.mjs";import{MAX_SQL_ROWS as ut,assertReadonly as xt,lintReadonlySql as ft,runReadonlySql as ht}from"./packem_shared/MAX_SQL_ROWS-DnDyeZph.mjs";import{awaitWsDrain as Et,subscriptionFrames as Tt,subscriptionListDeltas as gt,trySendFrame as Rt}from"./packem_shared/awaitWsDrain-kSGvAfw1.mjs";import{mergeChangedKeys as _t,recordChangedKeys as It,writeTouchesMemo as Lt}from"./packem_shared/mergeChangedKeys-D1T-TPUb.mjs";import{createSystemReader as Mt}from"./packem_shared/createSystemReader-BtYeSMDb.mjs";import{ConflictError as yt}from"./packem_shared/ConflictError-C8GtJmjS.mjs";import{DEFAULT_TRANSACTION_LIMITS as Ot,TransactionHeadroomTracker as Ft}from"./packem_shared/DEFAULT_TRANSACTION_LIMITS-Bcoi7Bvf.mjs";import{hasTrigger as kt,runTriggers as Bt}from"./packem_shared/hasTrigger-CjlwI4le.mjs";import{selectExpiredIds as Ut}from"./packem_shared/selectExpiredIds-_5514W_v.mjs";import{compileWhereSql as Kt,literalInList as qt}from"./packem_shared/compileWhereSql-JBpSfQm9.mjs";import{RELATION_EXISTS_KEY as vt}from"./packem_shared/RELATION_EXISTS_KEY-CFUhnZSZ.mjs";import{REPROJECTION_MIGRATION_PREFIX as Ht,reprojectionMigrationId as Xt}from"./packem_shared/REPROJECTION_MIGRATION_PREFIX-Czcb6_mO.mjs";import{quoteIdentifier as jt}from"./packem_shared/quoteIdentifier-CObIFRhb.mjs";import{runShardMigrations as Qt}from"./packem_shared/runShardMigrations-Crppyq1f.mjs";import{stableStringify as Zt}from"./packem_shared/stableStringify-CujpENIO.mjs";import{stableWireKey as en}from"./packem_shared/stableWireKey-BYB5GQJa.mjs";export{to as ADMIN_FUNCTIONS,no as ADMIN_FUNCTION_PREFIX,p as AGGREGATE_SQL_FUNCTION,$e as AGG_COUNT,er as AGG_KEY,rr as AGG_VALUE,N as AUDIT_LOG_TABLE,z as CDC_LOG_TABLE,H as CDC_META_TABLE,ae as CLIENT_WATERMARK_TABLE,yt as ConflictError,R as CountRlsUnsupportedError,qe as DATA_MIGRATION_STATE_TABLE,so as DEFAULT_FANOUT_TOPIC_LIMIT,da as DEFAULT_MAX_RELATION_KEYS,Da as DEFAULT_MAX_RELAYS,Ia as DEFAULT_PROMOTION_THRESHOLDS,Ot as DEFAULT_TRANSACTION_LIMITS,or as DOC_COLUMN,Nr as DurableStreamRunner,io as FLAGS_FUNCTION_PREFIX,Qr as GEO_DEFAULT_PRECISION,pe as GLOBAL_SHAPE_SNAPSHOT_TABLE,he as IDEMPOTENCY_TABLE,go as MAIL_RETENTION,Ro as MAIL_TABLE,yr as MAX_DURABLE_STREAM_BYTES,Dr as MAX_DURABLE_STREAM_CHUNKS,lo as MAX_PAGE_SIZE,ut as MAX_SQL_ROWS,Mo as NotFoundError,P as NotUniqueError,Oa as OwnerRelay,qo as QUEUE_TABLE,jo as RANK_TIEBREAK,vt as RELATION_EXISTS_KEY,mo as RELATION_FUNCTION_PREFIX,Ht as REPROJECTION_MIGRATION_PREFIX,Ha as RLS_UNWRAP_SYMBOL,oa as ReactiveCache,Fa as RelayMember,Xa as RlsRequiredError,He as SCAN_DEP,Ya as SCHEMA_HISTORY_MAX_VERSIONS,Le as SEARCH_STATE_TABLE,De as SHAPE_POKE_CURSOR_TABLE,pt as ShardRunner,Ft as TransactionHeadroomTracker,te as advanceClientWatermark,ar as aggUpsertSql,d as aggregateSqlFunction,f as aggregateTableName,y as appendAuditEntry,X as appendCdcChange,Tr as appendStreamChunk,V as applyCdcChanges,Aa as applyOnDelete,Fo as applySelect,yo as armRestore,ca as assertFlatPredicate,xt as assertReadonly,Sa as assertShapeShardable,k as assertValidClientId,Et as awaitWsDrain,w as backfillAggregateIndexes,K as backfillRankIndexes,q as backfillSearchIndexes,W as backfillSearchIndexesForTable,Jr as boundingBoxCenter,Zr as boundingBoxGeohashes,ia as buildIndexRange,nt as buildPokeFrames,Ka as buildReprojectionMigration,Po as buildSeekBeforeWhere,ko as buildSeekWhere,ot as buildSettings,j as bumpCdcEpoch,gr as claimStreamRun,La as clampPromotionThresholds,Co as clearCapturedMail,Wo as clearQueueMessages,h as coerceAggregateNumber,Kt as compileWhereSql,Ce as computeRankPage,ua as containsRelationPredicate,qa as countLegacyRows,$r as coveringGeohashes,le as createCompanionSync,Xe as createDependencyTracker,po as createFanoutCounters,tr as createIndexSql,na as createReadFootprint,Pa as createRelayLink,Ba as createReplicaLink,B as createShardCtxDb,Mt as createSystemReader,Or as decideDurableAttach,Bo as decodeCursor,de as deleteGlobalShapeSnapshot,ce as deleteGlobalShapeSnapshotsForConnection,Oe as deleteShapePokeCursor,Fe as deleteShapePokeCursorsForConnection,Rr as deleteStreamRun,Ve as depKey,Pr as diffExternalSource,st as diffGlobalMembership,Ea as distinctValues,A as encodeAggregateKey,Go as encodeCursor,eo as encodeGeohash,Yo as encodePartitionKey,it as encodeRowsPatch,D as ensureAuditTable,_o as ensureMailTable,o as exportShardRows,a as exportShardTable,co as facetColumn,Ta as fanOutScalarCounts,So as findStorageReferences,Cr as finishStreamRun,E as foldAggregateTally,Ga as gateReplicaDispatch,nr as geoTableName,Va as guardWriter,Ua as handleReplicaControl,kt as hasTrigger,ro as haversineMeters,_e as hydrateDocsById,t as importShardRows,la as indexKeysForRow,at as isDevEnvironment,sr as isFtsAvailable,vo as isLossyBody,xa as isRelationPredicate,Hr as isSoftDeleted,Xr as isSourceDue,ir as jsonPath,lr as jsonPathSql,ma as keysTouchRanges,Br as liftSourceId,ft as lintReadonlySql,uo as listTables,qt as literalInList,Qo as matchesRankStaticWhere,c as matchesStaticWhere,Kr as materializeExternalRows,qr as materializeExternalRowsIncremental,_t as mergeChangedKeys,C as mergeWhere,Y as migrateCdcLog,Q as migrateCdcMeta,ne as migrateClientWatermark,_r as migrateDurableStreams,Se as migrateGlobalShapeSnapshot,Ae as migrateIdempotency,be as migrateSearchState,Pe as migrateShapePokeCursor,J as minCdcSeq,ba as nextPromotionState,S as normalizeCountArgument,G as normalizeIdStructurally,Uo as normalizeOrderKeys,Gr as normalizeSourceDocument,Ur as normalizeSourceValue,xr as param,n as parseExportShardArgs,s as parseImportShardArgs,_ as planAggregateLookup,oo as pointInBoundingBox,lt as projectColumns,Vr as pullExternalSourceIncrementalTick,jr as pullExternalSourceTick,mr as qualifiedJsonPath,pr as qualifiedJsonPathSql,jt as quoteIdentifier,Jo as rankKeyFromDoc,Zo as rankTableName,aa as reactiveCacheKey,T as readAggregateValue,O as readAuditLog,Do as readBookmark,Io as readCapturedMail,Z as readCdcChanges,$ as readCdcCursor,ee as readCdcEpoch,se as readClientWatermark,Wr as readExternalSourceBaseline,ue as readGlobalShapeSnapshot,Ee as readIdempotent,We as readMigrationStatus,zo as readQueueMessageById,Ho as readQueueMessages,Qa as readSchemaHistory,Ja as readSchemaVersion,Me as readSearchBackfillState,ke as readShapePokeCursor,Ir as readStreamChunks,Lr as readStreamRun,xo as readTablePage,Lo as recordCapturedMail,It as recordChangedKeys,fo as recordFanoutPass,Xo as recordQueueMessages,Za as recordSchemaVersion,ga as relationHooks,Ma as relayCountFor,fr as renderSql,Wa as reprojectableFields,Xt as reprojectionMigrationId,va as reprojectionTables,$o as resolveRankPartition,fa as resolveRelationPredicates,Ra as resolveWith,dr as rowToDocument,ve as runDataMigration,Qe as runDrizzle,vr as runExternalSourceTick,ht as runReadonlySql,Ca as runRowValidators,Qt as runShardMigrations,ct as runSocketPool,Je as runSql,Bt as runTriggers,Ut as selectExpiredIds,i as selectExportTables,I as selectIndexForAggregate,L as selectIndexForCount,b as selectIndexForGroupBy,ho as selectMatchingIds,Ue as selectShapeMemberIds,we as selectShapeRows,et as serializeSqlValue,Na as shapeRoutingKey,wo as softDeleteScope,ea as sortColumnName,hr as sqliteInList,Zt as stableStringify,en as stableWireKey,Tt as subscriptionFrames,gt as subscriptionListDeltas,Ao as summarizeFanoutTopics,Eo as summarizeSubscriptions,cr as tableColumns,je as tableFromDepKey,u as throwingScheduler,re as trimCdcChanges,Te as trimIdempotent,br as trimStreamRuns,Sr as tryRowToDocument,Rt as trySendFrame,Ar as unionAll,l as validateImportRow,xe as writeGlobalShapeSnapshot,ge as writeIdempotent,Ne as writeSearchBackfillState,Be as writeShapePokeCursor,Lt as writeTouchesMemo};
1
+ import{exportShardRows as o,exportShardTable as a,importShardRows as t,parseExportShardArgs as n,parseImportShardArgs as s,selectExportTables as i,validateImportRow as l}from"./packem_shared/exportShardRows-Cgt3ITwH.mjs";import{AGGREGATE_SQL_FUNCTION as p,aggregateSqlFunction as d,matchesStaticWhere as c,normalizeCountArgument as S,throwingScheduler as u}from"./packem_shared/AGGREGATE_SQL_FUNCTION-m1iUU1rv.mjs";import{aggregateTableName as f,coerceAggregateNumber as h,encodeAggregateKey as A,foldAggregateTally as E,readAggregateValue as T}from"./packem_shared/aggregateTableName-Cy5e03oz.mjs";import{CountRlsUnsupportedError as R,mergeWhere as C,planAggregateLookup as _,selectIndexForAggregate as I,selectIndexForCount as L,selectIndexForGroupBy as b}from"./packem_shared/CountRlsUnsupportedError-Bdfupt3g.mjs";import{AUDIT_LOG_TABLE as N,appendAuditEntry as y,ensureAuditTable as D,readAuditLog as O}from"./packem_shared/AUDIT_LOG_TABLE-uNVU9O1W.mjs";import{NotUniqueError as P,assertValidClientId as k,createShardCtxDb as B,normalizeIdStructurally as G}from"./packem_shared/NotUniqueError-BixDiv4O.mjs";import{backfillAggregateIndexes as w,backfillRankIndexes as K,backfillSearchIndexes as q,backfillSearchIndexesForTable as W}from"./packem_shared/backfillAggregateIndexes-DVQ2sVuV.mjs";import{CDC_LOG_TABLE as z,CDC_META_TABLE as H,appendCdcChange as X,applyCdcChanges as V,bumpCdcEpoch as j,migrateCdcLog as Y,migrateCdcMeta as Q,minCdcSeq as J,readCdcChanges as Z,readCdcCursor as $,readCdcEpoch as ee,trimCdcChanges as re}from"./packem_shared/CDC_LOG_TABLE-B58N8NQO.mjs";import{CLIENT_WATERMARK_TABLE as ae,advanceClientWatermark as te,migrateClientWatermark as ne,readClientWatermark as se}from"./packem_shared/CLIENT_WATERMARK_TABLE-BoS1HEqz.mjs";import{c as le}from"./packem_shared/ctx-db-companions-lTt-rvKG.mjs";import{GLOBAL_SHAPE_SNAPSHOT_TABLE as pe,deleteGlobalShapeSnapshot as de,deleteGlobalShapeSnapshotsForConnection as ce,migrateGlobalShapeSnapshot as Se,readGlobalShapeSnapshot as ue,writeGlobalShapeSnapshot as xe}from"./packem_shared/GLOBAL_SHAPE_SNAPSHOT_TABLE-NWaL77m5.mjs";import{IDEMPOTENCY_TABLE as he,migrateIdempotency as Ae,readIdempotent as Ee,trimIdempotent as Te,writeIdempotent as ge}from"./packem_shared/IDEMPOTENCY_TABLE-DKVe2Ohf.mjs";import{computeRankPage as Ce,hydrateDocsById as _e}from"./packem_shared/computeRankPage-Bby1Npkd.mjs";import{SEARCH_STATE_TABLE as Le,migrateSearchState as be,readSearchBackfillState as Me,writeSearchBackfillState as Ne}from"./packem_shared/SEARCH_STATE_TABLE-Dju8ebbU.mjs";import{SHAPE_POKE_CURSOR_TABLE as De,deleteShapePokeCursor as Oe,deleteShapePokeCursorsForConnection as Fe,migrateShapePokeCursor as Pe,readShapePokeCursor as ke,writeShapePokeCursor as Be}from"./packem_shared/SHAPE_POKE_CURSOR_TABLE-Dh4HfSdC.mjs";import{selectShapeMemberIds as Ue,selectShapeRows as we}from"./packem_shared/selectShapeMemberIds-B-pQJHAu.mjs";import{DATA_MIGRATION_STATE_TABLE as qe,readMigrationStatus as We,runDataMigration as ve}from"./packem_shared/DATA_MIGRATION_STATE_TABLE-4l6aU1Vc.mjs";import{SCAN_DEP as He,createDependencyTracker as Xe,depKey as Ve,tableFromDepKey as je}from"./packem_shared/SCAN_DEP-D7qE3iUe.mjs";import{runDrizzle as Qe,runSql as Je}from"./packem_shared/runDrizzle-it6rL9bR.mjs";import{A as $e,a as er,b as rr,D as or,c as ar,d as tr,g as nr,i as sr,j as ir,e as lr,q as mr,f as pr,r as dr,t as cr,h as Sr}from"./packem_shared/do-sql-Dk_DJxn4.mjs";import{param as xr,renderSql as fr,sqliteInList as hr,unionAll as Ar}from"./packem_shared/param-Ib8WHnrF.mjs";import{appendStreamChunk as Tr,claimStreamRun as gr,deleteStreamRun as Rr,finishStreamRun as Cr,migrateDurableStreams as _r,readStreamChunks as Ir,readStreamRun as Lr,trimStreamRuns as br}from"./packem_shared/appendStreamChunk-CH4e4nJn.mjs";import{DurableStreamRunner as Nr,MAX_DURABLE_STREAM_BYTES as yr,MAX_DURABLE_STREAM_CHUNKS as Dr,decideDurableAttach as Or}from"./packem_shared/DurableStreamRunner-Bm6KDMBU.mjs";import{diffExternalSource as Pr}from"./packem_shared/diffExternalSource-DbHrcoZK.mjs";import{liftSourceId as Br,normalizeSourceDocument as Gr,normalizeSourceValue as Ur}from"./packem_shared/liftSourceId-CA3ENhXj.mjs";import{materializeExternalRows as Kr,materializeExternalRowsIncremental as qr,readExternalSourceBaseline as Wr,runExternalSourceTick as vr}from"./packem_shared/materializeExternalRows-D5tgL1mR.mjs";import{isSoftDeleted as Hr,isSourceDue as Xr,pullExternalSourceIncrementalTick as Vr,pullExternalSourceTick as jr}from"./packem_shared/isSoftDeleted-DR79pnU-.mjs";import{GEO_DEFAULT_PRECISION as Qr,boundingBoxCenter as Jr,boundingBoxGeohashes as Zr,coveringGeohashes as $r,encodeGeohash as eo,haversineMeters as ro,pointInBoundingBox as oo}from"./packem_shared/GEO_DEFAULT_PRECISION-CqpQZ-J_.mjs";import{ADMIN_FUNCTIONS as to,ADMIN_FUNCTION_PREFIX as no,DEFAULT_FANOUT_TOPIC_LIMIT as so,FLAGS_FUNCTION_PREFIX as io,MAX_PAGE_SIZE as lo,RELATION_FUNCTION_PREFIX as mo,createFanoutCounters as po,facetColumn as co,findStorageReferences as So,listTables as uo,readTablePage as xo,recordFanoutPass as fo,selectMatchingIds as ho,summarizeFanoutTopics as Ao,summarizeSubscriptions as Eo}from"./packem_shared/ADMIN_FUNCTIONS-Ddr79XHG.mjs";import{MAIL_RETENTION as go,MAIL_TABLE as Ro,clearCapturedMail as Co,ensureMailTable as _o,readCapturedMail as Io,recordCapturedMail as Lo}from"./packem_shared/MAIL_RETENTION-Cig9Dmc8.mjs";import{NotFoundError as Mo}from"./packem_shared/NotFoundError-BhF7FeFr.mjs";import{armRestore as yo,readBookmark as Do}from"./packem_shared/armRestore-Bu1_8SUa.mjs";import{applySelect as Fo,buildSeekBeforeWhere as Po,buildSeekWhere as ko,decodeCursor as Bo,encodeCursor as Go,normalizeOrderKeys as Uo,softDeleteScope as wo}from"./packem_shared/applySelect-BQbHyo-W.mjs";import{QUEUE_TABLE as qo,clearQueueMessages as Wo,isLossyBody as vo,readQueueMessageById as zo,readQueueMessages as Ho,recordQueueMessages as Xo}from"./packem_shared/QUEUE_TABLE-zj9Tt6tk.mjs";import{RANK_TIEBREAK as jo,encodePartitionKey as Yo,matchesRankStaticWhere as Qo,rankKeyFromDoc as Jo,rankTableName as Zo,resolveRankPartition as $o,sortColumnName as ea}from"./packem_shared/RANK_TIEBREAK-ci3MaM65.mjs";import{ReactiveCache as oa,reactiveCacheKey as aa}from"./packem_shared/ReactiveCache-DlJ38txF.mjs";import{createReadFootprint as na}from"./packem_shared/createReadFootprint-MRH1If3F.mjs";import{buildIndexRange as ia,indexKeysForRow as la,keysTouchRanges as ma}from"./packem_shared/buildIndexRange-CBKQmHSS.mjs";import{DEFAULT_MAX_RELATION_KEYS as da,assertFlatPredicate as ca,assertShapeShardable as Sa,containsRelationPredicate as ua,isRelationPredicate as xa,resolveRelationPredicates as fa}from"./packem_shared/DEFAULT_MAX_RELATION_KEYS-BAWGIEvC.mjs";import{applyOnDelete as Aa,distinctValues as Ea,fanOutScalarCounts as Ta,relationHooks as ga,resolveWith as Ra,runRowValidators as Ca}from"./packem_shared/applyOnDelete-BlcwKjuO.mjs";import{DEFAULT_PROMOTION_THRESHOLDS as Ia,clampPromotionThresholds as La,nextPromotionState as ba,relayCountFor as Ma,shapeRoutingKey as Na}from"./packem_shared/DEFAULT_PROMOTION_THRESHOLDS-H2sHFvlw.mjs";import{DEFAULT_MAX_RELAYS as Da,OwnerRelay as Oa,RelayMember as Fa,createRelayLink as Pa}from"./packem_shared/DEFAULT_MAX_RELAYS-tuHNDUZr.mjs";import{createReplicaLink as Ba,gateReplicaDispatch as Ga,handleReplicaControl as Ua}from"./packem_shared/createReplicaLink-C1JuP_DN.mjs";import{buildReprojectionMigration as Ka,countLegacyRows as qa,reprojectableFields as Wa,reprojectionTables as va}from"./packem_shared/buildReprojectionMigration-8nVn8Qwb.mjs";import{RLS_UNWRAP_SYMBOL as Ha,RlsRequiredError as Xa,guardWriter as Va}from"./packem_shared/RLS_UNWRAP_SYMBOL-BWloGsd3.mjs";import{SCHEMA_HISTORY_MAX_VERSIONS as Ya,readSchemaHistory as Qa,readSchemaVersion as Ja,recordSchemaVersion as Za}from"./packem_shared/SCHEMA_HISTORY_MAX_VERSIONS-DsycDXWm.mjs";import{serializeSqlValue as et}from"./packem_shared/serializeSqlValue-DbI1VQYM.mjs";import{buildSettings as ot,isDevEnvironment as at}from"./packem_shared/buildSettings-B4igo4rJ.mjs";import{buildPokeFrames as nt,diffGlobalMembership as st,encodeRowsPatch as it,projectColumns as lt}from"./packem_shared/buildPokeFrames-BXejpiII.mjs";import{ShardRunner as pt}from"./packem_shared/ShardRunner-C9p5DVOx.mjs";import{runSocketPool as ct}from"./packem_shared/runSocketPool-CZJ2X9cF.mjs";import{MAX_SQL_ROWS as ut,assertReadonly as xt,lintReadonlySql as ft,runReadonlySql as ht}from"./packem_shared/MAX_SQL_ROWS-DnDyeZph.mjs";import{awaitWsDrain as Et,subscriptionFrames as Tt,subscriptionListDeltas as gt,trySendFrame as Rt}from"./packem_shared/awaitWsDrain-Cs-1HHP6.mjs";import{mergeChangedKeys as _t,recordChangedKeys as It,writeTouchesMemo as Lt}from"./packem_shared/mergeChangedKeys-D1T-TPUb.mjs";import{createSystemReader as Mt}from"./packem_shared/createSystemReader-BtYeSMDb.mjs";import{ConflictError as yt}from"./packem_shared/ConflictError-C8GtJmjS.mjs";import{DEFAULT_TRANSACTION_LIMITS as Ot,TransactionHeadroomTracker as Ft}from"./packem_shared/DEFAULT_TRANSACTION_LIMITS-Bcoi7Bvf.mjs";import{hasTrigger as kt,runTriggers as Bt}from"./packem_shared/hasTrigger-CjlwI4le.mjs";import{selectExpiredIds as Ut}from"./packem_shared/selectExpiredIds-_5514W_v.mjs";import{compileWhereSql as Kt,literalInList as qt}from"./packem_shared/compileWhereSql-JBpSfQm9.mjs";import{RELATION_EXISTS_KEY as vt}from"./packem_shared/RELATION_EXISTS_KEY-CFUhnZSZ.mjs";import{REPROJECTION_MIGRATION_PREFIX as Ht,reprojectionMigrationId as Xt}from"./packem_shared/REPROJECTION_MIGRATION_PREFIX-Czcb6_mO.mjs";import{quoteIdentifier as jt}from"./packem_shared/quoteIdentifier-CObIFRhb.mjs";import{runShardMigrations as Qt}from"./packem_shared/runShardMigrations-Crppyq1f.mjs";import{stableStringify as Zt}from"./packem_shared/stableStringify-G9OF5wcs.mjs";import{stableWireKey as en}from"./packem_shared/stableWireKey-DSCJB6E7.mjs";export{to as ADMIN_FUNCTIONS,no as ADMIN_FUNCTION_PREFIX,p as AGGREGATE_SQL_FUNCTION,$e as AGG_COUNT,er as AGG_KEY,rr as AGG_VALUE,N as AUDIT_LOG_TABLE,z as CDC_LOG_TABLE,H as CDC_META_TABLE,ae as CLIENT_WATERMARK_TABLE,yt as ConflictError,R as CountRlsUnsupportedError,qe as DATA_MIGRATION_STATE_TABLE,so as DEFAULT_FANOUT_TOPIC_LIMIT,da as DEFAULT_MAX_RELATION_KEYS,Da as DEFAULT_MAX_RELAYS,Ia as DEFAULT_PROMOTION_THRESHOLDS,Ot as DEFAULT_TRANSACTION_LIMITS,or as DOC_COLUMN,Nr as DurableStreamRunner,io as FLAGS_FUNCTION_PREFIX,Qr as GEO_DEFAULT_PRECISION,pe as GLOBAL_SHAPE_SNAPSHOT_TABLE,he as IDEMPOTENCY_TABLE,go as MAIL_RETENTION,Ro as MAIL_TABLE,yr as MAX_DURABLE_STREAM_BYTES,Dr as MAX_DURABLE_STREAM_CHUNKS,lo as MAX_PAGE_SIZE,ut as MAX_SQL_ROWS,Mo as NotFoundError,P as NotUniqueError,Oa as OwnerRelay,qo as QUEUE_TABLE,jo as RANK_TIEBREAK,vt as RELATION_EXISTS_KEY,mo as RELATION_FUNCTION_PREFIX,Ht as REPROJECTION_MIGRATION_PREFIX,Ha as RLS_UNWRAP_SYMBOL,oa as ReactiveCache,Fa as RelayMember,Xa as RlsRequiredError,He as SCAN_DEP,Ya as SCHEMA_HISTORY_MAX_VERSIONS,Le as SEARCH_STATE_TABLE,De as SHAPE_POKE_CURSOR_TABLE,pt as ShardRunner,Ft as TransactionHeadroomTracker,te as advanceClientWatermark,ar as aggUpsertSql,d as aggregateSqlFunction,f as aggregateTableName,y as appendAuditEntry,X as appendCdcChange,Tr as appendStreamChunk,V as applyCdcChanges,Aa as applyOnDelete,Fo as applySelect,yo as armRestore,ca as assertFlatPredicate,xt as assertReadonly,Sa as assertShapeShardable,k as assertValidClientId,Et as awaitWsDrain,w as backfillAggregateIndexes,K as backfillRankIndexes,q as backfillSearchIndexes,W as backfillSearchIndexesForTable,Jr as boundingBoxCenter,Zr as boundingBoxGeohashes,ia as buildIndexRange,nt as buildPokeFrames,Ka as buildReprojectionMigration,Po as buildSeekBeforeWhere,ko as buildSeekWhere,ot as buildSettings,j as bumpCdcEpoch,gr as claimStreamRun,La as clampPromotionThresholds,Co as clearCapturedMail,Wo as clearQueueMessages,h as coerceAggregateNumber,Kt as compileWhereSql,Ce as computeRankPage,ua as containsRelationPredicate,qa as countLegacyRows,$r as coveringGeohashes,le as createCompanionSync,Xe as createDependencyTracker,po as createFanoutCounters,tr as createIndexSql,na as createReadFootprint,Pa as createRelayLink,Ba as createReplicaLink,B as createShardCtxDb,Mt as createSystemReader,Or as decideDurableAttach,Bo as decodeCursor,de as deleteGlobalShapeSnapshot,ce as deleteGlobalShapeSnapshotsForConnection,Oe as deleteShapePokeCursor,Fe as deleteShapePokeCursorsForConnection,Rr as deleteStreamRun,Ve as depKey,Pr as diffExternalSource,st as diffGlobalMembership,Ea as distinctValues,A as encodeAggregateKey,Go as encodeCursor,eo as encodeGeohash,Yo as encodePartitionKey,it as encodeRowsPatch,D as ensureAuditTable,_o as ensureMailTable,o as exportShardRows,a as exportShardTable,co as facetColumn,Ta as fanOutScalarCounts,So as findStorageReferences,Cr as finishStreamRun,E as foldAggregateTally,Ga as gateReplicaDispatch,nr as geoTableName,Va as guardWriter,Ua as handleReplicaControl,kt as hasTrigger,ro as haversineMeters,_e as hydrateDocsById,t as importShardRows,la as indexKeysForRow,at as isDevEnvironment,sr as isFtsAvailable,vo as isLossyBody,xa as isRelationPredicate,Hr as isSoftDeleted,Xr as isSourceDue,ir as jsonPath,lr as jsonPathSql,ma as keysTouchRanges,Br as liftSourceId,ft as lintReadonlySql,uo as listTables,qt as literalInList,Qo as matchesRankStaticWhere,c as matchesStaticWhere,Kr as materializeExternalRows,qr as materializeExternalRowsIncremental,_t as mergeChangedKeys,C as mergeWhere,Y as migrateCdcLog,Q as migrateCdcMeta,ne as migrateClientWatermark,_r as migrateDurableStreams,Se as migrateGlobalShapeSnapshot,Ae as migrateIdempotency,be as migrateSearchState,Pe as migrateShapePokeCursor,J as minCdcSeq,ba as nextPromotionState,S as normalizeCountArgument,G as normalizeIdStructurally,Uo as normalizeOrderKeys,Gr as normalizeSourceDocument,Ur as normalizeSourceValue,xr as param,n as parseExportShardArgs,s as parseImportShardArgs,_ as planAggregateLookup,oo as pointInBoundingBox,lt as projectColumns,Vr as pullExternalSourceIncrementalTick,jr as pullExternalSourceTick,mr as qualifiedJsonPath,pr as qualifiedJsonPathSql,jt as quoteIdentifier,Jo as rankKeyFromDoc,Zo as rankTableName,aa as reactiveCacheKey,T as readAggregateValue,O as readAuditLog,Do as readBookmark,Io as readCapturedMail,Z as readCdcChanges,$ as readCdcCursor,ee as readCdcEpoch,se as readClientWatermark,Wr as readExternalSourceBaseline,ue as readGlobalShapeSnapshot,Ee as readIdempotent,We as readMigrationStatus,zo as readQueueMessageById,Ho as readQueueMessages,Qa as readSchemaHistory,Ja as readSchemaVersion,Me as readSearchBackfillState,ke as readShapePokeCursor,Ir as readStreamChunks,Lr as readStreamRun,xo as readTablePage,Lo as recordCapturedMail,It as recordChangedKeys,fo as recordFanoutPass,Xo as recordQueueMessages,Za as recordSchemaVersion,ga as relationHooks,Ma as relayCountFor,fr as renderSql,Wa as reprojectableFields,Xt as reprojectionMigrationId,va as reprojectionTables,$o as resolveRankPartition,fa as resolveRelationPredicates,Ra as resolveWith,dr as rowToDocument,ve as runDataMigration,Qe as runDrizzle,vr as runExternalSourceTick,ht as runReadonlySql,Ca as runRowValidators,Qt as runShardMigrations,ct as runSocketPool,Je as runSql,Bt as runTriggers,Ut as selectExpiredIds,i as selectExportTables,I as selectIndexForAggregate,L as selectIndexForCount,b as selectIndexForGroupBy,ho as selectMatchingIds,Ue as selectShapeMemberIds,we as selectShapeRows,et as serializeSqlValue,Na as shapeRoutingKey,wo as softDeleteScope,ea as sortColumnName,hr as sqliteInList,Zt as stableStringify,en as stableWireKey,Tt as subscriptionFrames,gt as subscriptionListDeltas,Ao as summarizeFanoutTopics,Eo as summarizeSubscriptions,cr as tableColumns,je as tableFromDepKey,u as throwingScheduler,re as trimCdcChanges,Te as trimIdempotent,br as trimStreamRuns,Sr as tryRowToDocument,Rt as trySendFrame,Ar as unionAll,l as validateImportRow,xe as writeGlobalShapeSnapshot,ge as writeIdempotent,Ne as writeSearchBackfillState,Be as writeShapePokeCursor,Lt as writeTouchesMemo};
@@ -1 +1 @@
1
- import{toErrorBody as P,LunoraError as x}from"@lunora/errors";import{e as v,d as b}from"./wire-codec-BU9T2xJ7.mjs";import{e as S,v as L,R as I,s as M,a as T,b as D}from"./sibling-channel-BRZpLiDA.mjs";import{relayName as u,DEFAULT_PROMOTION_THRESHOLDS as w,nextPromotionState as O,shapeRoutingKey as R,parseRelayName as k,clampPromotionThresholds as N}from"./DEFAULT_PROMOTION_THRESHOLDS-DVTD9iu0.mjs";import{encodeRowsPatch as C,buildPokeFrames as E}from"./buildPokeFrames-BXejpiII.mjs";import{awaitWsDrain as F,trySendFrame as _}from"./awaitWsDrain-kSGvAfw1.mjs";import{stableWireKey as m}from"./stableWireKey-BYB5GQJa.mjs";const U=2,W=8,g={},K=l=>{throw new x("INTERNAL",`unhandled relay frame: ${JSON.stringify(l)}`)},Y=l=>Response.json(l,{headers:{"content-type":"application/json"}}),f=()=>new Response(null,{status:204});class A{constructor(e,t){this.host=e,this.roleId=t}host;roleId;async handleControl(e){let t;try{t=await e.text()}catch{return new Response("bad request",{status:400})}if(!await L(this.host.env(),e.headers.get(I),t))return new Response("forbidden",{status:403});let s;try{s=JSON.parse(t)}catch{return new Response("bad request",{status:400})}switch(s.type){case"relay_attach":return this.onAttach(s.relayIndex),f();case"relay_detach":return this.onDetach(s.relayIndex),f();case"relay_frame":return this.host.deliverWhisperLocal(s.topic,s.frame,void 0),await this.onWhisperFrame(s),f();case"relay_shape_poke":{const r=this.host.getWebSockets().length,o=Date.now(),a=this.onShapePoke({...s,args:b(s.args)});return this.host.recordShapePokeFanout(r,a,Date.now()-o),f()}case"relay_shape_subscribe":return Y(this.onShapeSubscribe({...s,args:b(s.args)}));default:return K(s)}}maxRelays(){return S(this.host.env(),"LUNORA_MAX_RELAYS",W)}canAddressSiblings(){return this.siblingStub(this.roleId.ownerKey)!==void 0}siblingStub(e){return M(this.host.env(),this.host.shardBinding(),e)}async postRelayMessage(e,t){await this.requestRelayMessage(e,t)}async requestRelayMessage(e,t){const s=this.siblingStub(e);if(s===void 0)return;const r=JSON.stringify(t),o={"content-type":"application/json","x-lunora-shard-binding":this.host.shardBinding()??""},a=T(this.host.env());a!==void 0&&(o[I]=await D(a,r));try{return await s.fetch("https://relay.internal/_lunora/relay",{body:r,headers:o,method:"POST"})}catch{return}}}class H extends A{shapeUniformCache=new Map;relaySetCache;relayShapeRegistry=new Map;relayShapeProxies=new Map;promotionState="owned";constructor(e,t){super(e,{ownerKey:t})}async forwardWhisper(e,t){if(!this.canAddressSiblings())return;const s=this.ownerRelaySet();s.size!==0&&await Promise.all([...s].map(r=>this.postRelayMessage(u(this.roleId.ownerKey,r),{frame:t,topic:e,type:"relay_frame"})))}async onFlush(e,t){await Promise.all([this.multicastShapePokes(e,t),this.proxyShapePokes(e,t)])}seedRelayShape(){return Promise.resolve(void 0)}announce(){return Promise.resolve()}announceDrain(){return Promise.resolve()}relayCount(){const e=this.host.getWebSockets().length,t=S(this.host.env(),"LUNORA_RELAY_THRESHOLD",w.tUp),s=S(this.host.env(),"LUNORA_RELAY_COLLAPSE_THRESHOLD",w.tDown);if(this.promotionState=O(this.promotionState,e,N(t,s)),this.promotionState==="owned")return 0;const r=S(this.host.env(),"LUNORA_RELAY_FAN",U);return Math.min(this.maxRelays(),Math.max(1,r))}isShapeRelayUniform(e,t){const s=R(e,t),r=this.shapeUniformCache.get(s);if(r!==void 0)return r;const o=this.probeShapeRelayUniform(e,t);return this.shapeUniformCache.set(s,o),o}onAttach(e){this.addRelayToSet(e)}onDetach(e){this.removeRelayFromSet(e)}async onWhisperFrame(e){await Promise.all([...this.ownerRelaySet()].filter(t=>t!==e.originRelay).map(t=>this.postRelayMessage(u(this.roleId.ownerKey,t),{frame:e.frame,topic:e.topic,type:"relay_frame"})))}onShapeSubscribe(e){return this.buildShapeSeedFrames(e)}onShapePoke(){return 0}buildShapePoke(e,t,s,r,o){let a;try{a=this.host.resolveShape(e.name,e.args,t)}catch{return}if(a===void 0||a.global===!0||!s.has(a.table))return;const n=e,c=n.cursor,i=this.host.buildShapeDiff(a,c,r);if(i.length!==0)return n.cursor=r,{args:v(e.args),checkpoint:r,epoch:o,fromCursor:c,name:e.name,rowsPatch:C(i),type:"relay_shape_poke"}}async multicastShapePokes(e,t){if(this.relayShapeRegistry.size===0)return;const s=this.ownerRelaySet();if(s.size===0)return;const r=this.host.currentCdcEpoch(),o=[];for(const a of this.relayShapeRegistry.values()){const n=this.buildShapePoke(a,g,e,t,r);if(n)for(const c of s)o.push(this.postRelayMessage(u(this.roleId.ownerKey,c),n))}await Promise.all(o)}async proxyShapePokes(e,t){if(this.relayShapeProxies.size===0)return;const s=this.host.currentCdcEpoch(),r=[];for(const o of this.relayShapeProxies.values()){const a=this.buildShapePoke(o,o.identity,e,t,s);a&&r.push(this.postRelayMessage(u(this.roleId.ownerKey,o.relayIndex),{...a,targetConnectionId:o.connectionId}))}await Promise.all(r)}buildShapeSeedFrames(e){const t={identity:e.identity,userId:e.userId};let s;try{s=this.host.resolveShape(e.name,e.args,t)}catch(h){const{body:d}=P(h,{fallbackCode:"SHAPE_RESOLVE_FAILED",redactedMessage:"shape resolution failed"});return{error:{code:d.code,message:d.message}}}if(s===void 0||s.global===!0)return{error:{code:"SHAPE_NOT_FOUND",message:`shape not relayable: ${e.name}`}};e.relayIndex!==void 0&&this.addRelayToSet(e.relayIndex);const{baseCheckpoint:r,cursor:o,epoch:a,rowsPatch:n}=this.host.computeOpLogShapeSeed({args:e.args,name:e.name,sinceEpoch:e.sinceEpoch,sinceSeq:e.sinceSeq},s);let c=o;if(this.isShapeRelayUniform(e.name,e.args)){const h=R(e.name,e.args);let d=this.relayShapeRegistry.get(h);d===void 0&&(d={args:e.args,cursor:o,name:e.name},this.relayShapeRegistry.set(h,d)),c=d.cursor}else e.relayIndex!==void 0&&e.connectionId!==void 0&&this.relayShapeProxies.set(`${String(e.relayIndex)}:${e.connectionId}:${e.subId}`,{args:e.args,connectionId:e.connectionId,cursor:o,epoch:a,identity:t,name:e.name,relayIndex:e.relayIndex,subId:e.subId});const i=E([{rowsPatch:n,shapeId:e.subId}],{baseCheckpoint:r,checkpoint:o,epoch:a,lastMutationId:void 0,pokeId:this.host.nextPokeId()});return{cursor:c,epoch:a,frames:i}}ensureRelayTable(){this.host.sql().exec("CREATE TABLE IF NOT EXISTS __lunora_relays (idx INTEGER PRIMARY KEY)")}ownerRelaySet(){if(this.relaySetCache===void 0){this.ensureRelayTable();const e=this.host.sql().exec("SELECT idx FROM __lunora_relays").toArray();this.relaySetCache=new Set(e.map(t=>Number(t.idx)))}return this.relaySetCache}addRelayToSet(e){this.ensureRelayTable(),this.host.sql().exec("INSERT OR IGNORE INTO __lunora_relays (idx) VALUES (?)",e),this.ownerRelaySet().add(e)}removeRelayFromSet(e){this.ensureRelayTable(),this.host.sql().exec("DELETE FROM __lunora_relays WHERE idx = ?",e);const t=this.ownerRelaySet();t.delete(e);for(const[s,r]of this.relayShapeProxies)r.relayIndex===e&&this.relayShapeProxies.delete(s);t.size===0&&(this.relayShapeRegistry.clear(),this.shapeUniformCache.clear())}probeShapeRelayUniform(e,t){let s;try{s=this.host.resolveShape(e,t,g)}catch{return!1}if(s===void 0||s.global===!0||this.host.rlsMetadata().policies.some(i=>i.on==="read"&&i.table===s.table)||this.tableHasAnyMask(s.table))return!1;const r=m(s.effectiveWhere),o=m(s.columns);let a=!1;const n=i=>{const h={groups:[`grp_${i}`],roles:[i],sub:`__lunora_probe_${i}__`};return{identity:new Proxy(h,{get:(y,p)=>typeof p=="symbol"||p in y?Reflect.get(y,p):`${i}:${p}`,getOwnPropertyDescriptor:(y,p)=>(a=!0,Reflect.getOwnPropertyDescriptor(y,p)),has:(y,p)=>typeof p=="symbol"?Reflect.has(y,p):!0,ownKeys:y=>(a=!0,Reflect.ownKeys(y))}),userId:`__lunora_probe_${i}__`}};return[g,n("a"),n("b")].every(i=>{let h;try{h=this.host.resolveShape(e,t,i)}catch{return!1}return h!==void 0&&h.global!==!0&&h.table===s.table&&m(h.effectiveWhere)===r&&m(h.columns)===o})&&!a}tableHasAnyMask(e){return this.host.maskMetadata().columns.some(t=>t.table===e)}}class $ extends A{relayAnnounced=!1;shapeRelayMemos=new WeakMap;constructor(e,t,s){super(e,{ownerKey:t,relayIndex:s})}async forwardWhisper(e,t){this.canAddressSiblings()&&await this.postRelayMessage(this.roleId.ownerKey,{frame:t,originRelay:this.roleId.relayIndex,topic:e,type:"relay_frame"})}onFlush(){return Promise.resolve()}async seedRelayShape(e,t,s,r){if(!this.canAddressSiblings())return{code:"RELAY_MISCONFIGURED",message:"relay cannot address its owner"};await this.announce();const o={args:v(s.args??{}),connectionId:this.host.readAttachment(e).connectionId,identity:r.identity,name:s.name,relayIndex:this.roleId.relayIndex,sinceEpoch:s.sinceEpoch,sinceSeq:s.sinceSeq,subId:t,type:"relay_shape_subscribe",userId:r.userId},a=await this.requestRelayMessage(this.roleId.ownerKey,o);if(a===void 0)return{code:"RELAY_SEED_FAILED",message:"owner did not answer the shape seed"};let n;try{n=await a.json()}catch{return{code:"RELAY_SEED_FAILED",message:"malformed shape seed from owner"}}if(n.error!==void 0)return n.error;if(n.frames===void 0)return{code:"RELAY_SEED_FAILED",message:"owner returned no shape frames"};await F(e);for(const c of n.frames)_(e,c);return this.recordRelayShapeMemo(e,t,n.cursor??0,n.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.canAddressSiblings()&&(this.host.getWebSockets().some(t=>t!==e)||(this.relayAnnounced=!1,await this.postRelayMessage(this.roleId.ownerKey,{relayIndex:this.roleId.relayIndex,type:"relay_detach"})))}relayCount(){return 0}isShapeRelayUniform(){return!1}onAttach(){}onDetach(){}onWhisperFrame(){return Promise.resolve()}onShapeSubscribe(){return{error:{code:"RELAY_CANNOT_SEED",message:"a relay has no op-log to seed from"}}}onShapePoke(e){return this.deliverShapePoke(e)}recordRelayShapeMemo(e,t,s,r){let o=this.shapeRelayMemos.get(e);o===void 0&&(o=new Map,this.shapeRelayMemos.set(e,o)),o.set(t,{cursor:s,epoch:r})}deliverShapePoke(e){const t=R(e.name,e.args);let s=0;for(const r of this.host.getWebSockets()){const o=this.host.readAttachment(r),{shapes:a}=o,n=this.shapeRelayMemos.get(r);if(!(a===void 0||n===void 0)&&!(e.targetConnectionId!==void 0&&o.connectionId!==e.targetConnectionId))for(const[c,i]of Object.entries(a)){const h=n.get(c);if(h?.cursor!==e.fromCursor||h.epoch!==e.epoch||R(i.name,i.args)!==t)continue;const d=E([{rowsPatch:e.rowsPatch,shapeId:c}],{baseCheckpoint:void 0,checkpoint:e.checkpoint,epoch:e.epoch,lastMutationId:void 0,pokeId:this.host.nextPokeId()},{preEncoded:!0});for(const y of d)_(r,y);n.set(c,{cursor:e.checkpoint,epoch:e.epoch}),s+=1}}return s}}const Q=l=>{const e=l.doName();if(e===void 0)return;const t=k(e);return t===void 0?new H(l,e):new $(l,t.ownerKey,t.relayIndex)};export{W as DEFAULT_MAX_RELAYS,H as OwnerRelay,$ as RelayMember,Q as createRelayLink};
1
+ import{toErrorBody as P,LunoraError as x}from"@lunora/errors";import{e as v,d as b}from"./wire-codec-BU9T2xJ7.mjs";import{e as S,v as L,R as I,s as M,a as T,b as D}from"./sibling-channel-BRZpLiDA.mjs";import{relayName as u,DEFAULT_PROMOTION_THRESHOLDS as w,nextPromotionState as O,shapeRoutingKey as R,parseRelayName as k,clampPromotionThresholds as N}from"./DEFAULT_PROMOTION_THRESHOLDS-H2sHFvlw.mjs";import{encodeRowsPatch as C,buildPokeFrames as E}from"./buildPokeFrames-BXejpiII.mjs";import{awaitWsDrain as F,trySendFrame as _}from"./awaitWsDrain-Cs-1HHP6.mjs";import{stableWireKey as m}from"./stableWireKey-DSCJB6E7.mjs";const U=2,W=8,g={},K=l=>{throw new x("INTERNAL",`unhandled relay frame: ${JSON.stringify(l)}`)},Y=l=>Response.json(l,{headers:{"content-type":"application/json"}}),f=()=>new Response(null,{status:204});class A{constructor(e,t){this.host=e,this.roleId=t}host;roleId;async handleControl(e){let t;try{t=await e.text()}catch{return new Response("bad request",{status:400})}if(!await L(this.host.env(),e.headers.get(I),t))return new Response("forbidden",{status:403});let s;try{s=JSON.parse(t)}catch{return new Response("bad request",{status:400})}switch(s.type){case"relay_attach":return this.onAttach(s.relayIndex),f();case"relay_detach":return this.onDetach(s.relayIndex),f();case"relay_frame":return this.host.deliverWhisperLocal(s.topic,s.frame,void 0),await this.onWhisperFrame(s),f();case"relay_shape_poke":{const r=this.host.getWebSockets().length,o=Date.now(),a=this.onShapePoke({...s,args:b(s.args)});return this.host.recordShapePokeFanout(r,a,Date.now()-o),f()}case"relay_shape_subscribe":return Y(this.onShapeSubscribe({...s,args:b(s.args)}));default:return K(s)}}maxRelays(){return S(this.host.env(),"LUNORA_MAX_RELAYS",W)}canAddressSiblings(){return this.siblingStub(this.roleId.ownerKey)!==void 0}siblingStub(e){return M(this.host.env(),this.host.shardBinding(),e)}async postRelayMessage(e,t){await this.requestRelayMessage(e,t)}async requestRelayMessage(e,t){const s=this.siblingStub(e);if(s===void 0)return;const r=JSON.stringify(t),o={"content-type":"application/json","x-lunora-shard-binding":this.host.shardBinding()??""},a=T(this.host.env());a!==void 0&&(o[I]=await D(a,r));try{return await s.fetch("https://relay.internal/_lunora/relay",{body:r,headers:o,method:"POST"})}catch{return}}}class H extends A{shapeUniformCache=new Map;relaySetCache;relayShapeRegistry=new Map;relayShapeProxies=new Map;promotionState="owned";constructor(e,t){super(e,{ownerKey:t})}async forwardWhisper(e,t){if(!this.canAddressSiblings())return;const s=this.ownerRelaySet();s.size!==0&&await Promise.all([...s].map(r=>this.postRelayMessage(u(this.roleId.ownerKey,r),{frame:t,topic:e,type:"relay_frame"})))}async onFlush(e,t){await Promise.all([this.multicastShapePokes(e,t),this.proxyShapePokes(e,t)])}seedRelayShape(){return Promise.resolve(void 0)}announce(){return Promise.resolve()}announceDrain(){return Promise.resolve()}relayCount(){const e=this.host.getWebSockets().length,t=S(this.host.env(),"LUNORA_RELAY_THRESHOLD",w.tUp),s=S(this.host.env(),"LUNORA_RELAY_COLLAPSE_THRESHOLD",w.tDown);if(this.promotionState=O(this.promotionState,e,N(t,s)),this.promotionState==="owned")return 0;const r=S(this.host.env(),"LUNORA_RELAY_FAN",U);return Math.min(this.maxRelays(),Math.max(1,r))}isShapeRelayUniform(e,t){const s=R(e,t),r=this.shapeUniformCache.get(s);if(r!==void 0)return r;const o=this.probeShapeRelayUniform(e,t);return this.shapeUniformCache.set(s,o),o}onAttach(e){this.addRelayToSet(e)}onDetach(e){this.removeRelayFromSet(e)}async onWhisperFrame(e){await Promise.all([...this.ownerRelaySet()].filter(t=>t!==e.originRelay).map(t=>this.postRelayMessage(u(this.roleId.ownerKey,t),{frame:e.frame,topic:e.topic,type:"relay_frame"})))}onShapeSubscribe(e){return this.buildShapeSeedFrames(e)}onShapePoke(){return 0}buildShapePoke(e,t,s,r,o){let a;try{a=this.host.resolveShape(e.name,e.args,t)}catch{return}if(a===void 0||a.global===!0||!s.has(a.table))return;const n=e,c=n.cursor,i=this.host.buildShapeDiff(a,c,r);if(i.length!==0)return n.cursor=r,{args:v(e.args),checkpoint:r,epoch:o,fromCursor:c,name:e.name,rowsPatch:C(i),type:"relay_shape_poke"}}async multicastShapePokes(e,t){if(this.relayShapeRegistry.size===0)return;const s=this.ownerRelaySet();if(s.size===0)return;const r=this.host.currentCdcEpoch(),o=[];for(const a of this.relayShapeRegistry.values()){const n=this.buildShapePoke(a,g,e,t,r);if(n)for(const c of s)o.push(this.postRelayMessage(u(this.roleId.ownerKey,c),n))}await Promise.all(o)}async proxyShapePokes(e,t){if(this.relayShapeProxies.size===0)return;const s=this.host.currentCdcEpoch(),r=[];for(const o of this.relayShapeProxies.values()){const a=this.buildShapePoke(o,o.identity,e,t,s);a&&r.push(this.postRelayMessage(u(this.roleId.ownerKey,o.relayIndex),{...a,targetConnectionId:o.connectionId}))}await Promise.all(r)}buildShapeSeedFrames(e){const t={identity:e.identity,userId:e.userId};let s;try{s=this.host.resolveShape(e.name,e.args,t)}catch(h){const{body:d}=P(h,{fallbackCode:"SHAPE_RESOLVE_FAILED",redactedMessage:"shape resolution failed"});return{error:{code:d.code,message:d.message}}}if(s===void 0||s.global===!0)return{error:{code:"SHAPE_NOT_FOUND",message:`shape not relayable: ${e.name}`}};e.relayIndex!==void 0&&this.addRelayToSet(e.relayIndex);const{baseCheckpoint:r,cursor:o,epoch:a,rowsPatch:n}=this.host.computeOpLogShapeSeed({args:e.args,name:e.name,sinceEpoch:e.sinceEpoch,sinceSeq:e.sinceSeq},s);let c=o;if(this.isShapeRelayUniform(e.name,e.args)){const h=R(e.name,e.args);let d=this.relayShapeRegistry.get(h);d===void 0&&(d={args:e.args,cursor:o,name:e.name},this.relayShapeRegistry.set(h,d)),c=d.cursor}else e.relayIndex!==void 0&&e.connectionId!==void 0&&this.relayShapeProxies.set(`${String(e.relayIndex)}:${e.connectionId}:${e.subId}`,{args:e.args,connectionId:e.connectionId,cursor:o,epoch:a,identity:t,name:e.name,relayIndex:e.relayIndex,subId:e.subId});const i=E([{rowsPatch:n,shapeId:e.subId}],{baseCheckpoint:r,checkpoint:o,epoch:a,lastMutationId:void 0,pokeId:this.host.nextPokeId()});return{cursor:c,epoch:a,frames:i}}ensureRelayTable(){this.host.sql().exec("CREATE TABLE IF NOT EXISTS __lunora_relays (idx INTEGER PRIMARY KEY)")}ownerRelaySet(){if(this.relaySetCache===void 0){this.ensureRelayTable();const e=this.host.sql().exec("SELECT idx FROM __lunora_relays").toArray();this.relaySetCache=new Set(e.map(t=>Number(t.idx)))}return this.relaySetCache}addRelayToSet(e){this.ensureRelayTable(),this.host.sql().exec("INSERT OR IGNORE INTO __lunora_relays (idx) VALUES (?)",e),this.ownerRelaySet().add(e)}removeRelayFromSet(e){this.ensureRelayTable(),this.host.sql().exec("DELETE FROM __lunora_relays WHERE idx = ?",e);const t=this.ownerRelaySet();t.delete(e);for(const[s,r]of this.relayShapeProxies)r.relayIndex===e&&this.relayShapeProxies.delete(s);t.size===0&&(this.relayShapeRegistry.clear(),this.shapeUniformCache.clear())}probeShapeRelayUniform(e,t){let s;try{s=this.host.resolveShape(e,t,g)}catch{return!1}if(s===void 0||s.global===!0||this.host.rlsMetadata().policies.some(i=>i.on==="read"&&i.table===s.table)||this.tableHasAnyMask(s.table))return!1;const r=m(s.effectiveWhere),o=m(s.columns);let a=!1;const n=i=>{const h={groups:[`grp_${i}`],roles:[i],sub:`__lunora_probe_${i}__`};return{identity:new Proxy(h,{get:(y,p)=>typeof p=="symbol"||p in y?Reflect.get(y,p):`${i}:${p}`,getOwnPropertyDescriptor:(y,p)=>(a=!0,Reflect.getOwnPropertyDescriptor(y,p)),has:(y,p)=>typeof p=="symbol"?Reflect.has(y,p):!0,ownKeys:y=>(a=!0,Reflect.ownKeys(y))}),userId:`__lunora_probe_${i}__`}};return[g,n("a"),n("b")].every(i=>{let h;try{h=this.host.resolveShape(e,t,i)}catch{return!1}return h!==void 0&&h.global!==!0&&h.table===s.table&&m(h.effectiveWhere)===r&&m(h.columns)===o})&&!a}tableHasAnyMask(e){return this.host.maskMetadata().columns.some(t=>t.table===e)}}class $ extends A{relayAnnounced=!1;shapeRelayMemos=new WeakMap;constructor(e,t,s){super(e,{ownerKey:t,relayIndex:s})}async forwardWhisper(e,t){this.canAddressSiblings()&&await this.postRelayMessage(this.roleId.ownerKey,{frame:t,originRelay:this.roleId.relayIndex,topic:e,type:"relay_frame"})}onFlush(){return Promise.resolve()}async seedRelayShape(e,t,s,r){if(!this.canAddressSiblings())return{code:"RELAY_MISCONFIGURED",message:"relay cannot address its owner"};await this.announce();const o={args:v(s.args??{}),connectionId:this.host.readAttachment(e).connectionId,identity:r.identity,name:s.name,relayIndex:this.roleId.relayIndex,sinceEpoch:s.sinceEpoch,sinceSeq:s.sinceSeq,subId:t,type:"relay_shape_subscribe",userId:r.userId},a=await this.requestRelayMessage(this.roleId.ownerKey,o);if(a===void 0)return{code:"RELAY_SEED_FAILED",message:"owner did not answer the shape seed"};let n;try{n=await a.json()}catch{return{code:"RELAY_SEED_FAILED",message:"malformed shape seed from owner"}}if(n.error!==void 0)return n.error;if(n.frames===void 0)return{code:"RELAY_SEED_FAILED",message:"owner returned no shape frames"};await F(e);for(const c of n.frames)_(e,c);return this.recordRelayShapeMemo(e,t,n.cursor??0,n.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.canAddressSiblings()&&(this.host.getWebSockets().some(t=>t!==e)||(this.relayAnnounced=!1,await this.postRelayMessage(this.roleId.ownerKey,{relayIndex:this.roleId.relayIndex,type:"relay_detach"})))}relayCount(){return 0}isShapeRelayUniform(){return!1}onAttach(){}onDetach(){}onWhisperFrame(){return Promise.resolve()}onShapeSubscribe(){return{error:{code:"RELAY_CANNOT_SEED",message:"a relay has no op-log to seed from"}}}onShapePoke(e){return this.deliverShapePoke(e)}recordRelayShapeMemo(e,t,s,r){let o=this.shapeRelayMemos.get(e);o===void 0&&(o=new Map,this.shapeRelayMemos.set(e,o)),o.set(t,{cursor:s,epoch:r})}deliverShapePoke(e){const t=R(e.name,e.args);let s=0;for(const r of this.host.getWebSockets()){const o=this.host.readAttachment(r),{shapes:a}=o,n=this.shapeRelayMemos.get(r);if(!(a===void 0||n===void 0)&&!(e.targetConnectionId!==void 0&&o.connectionId!==e.targetConnectionId))for(const[c,i]of Object.entries(a)){const h=n.get(c);if(h?.cursor!==e.fromCursor||h.epoch!==e.epoch||R(i.name,i.args)!==t)continue;const d=E([{rowsPatch:e.rowsPatch,shapeId:c}],{baseCheckpoint:void 0,checkpoint:e.checkpoint,epoch:e.epoch,lastMutationId:void 0,pokeId:this.host.nextPokeId()},{preEncoded:!0});for(const y of d)_(r,y);n.set(c,{cursor:e.checkpoint,epoch:e.epoch}),s+=1}}return s}}const Q=l=>{const e=l.doName();if(e===void 0)return;const t=k(e);return t===void 0?new H(l,e):new $(l,t.ownerKey,t.relayIndex)};export{W as DEFAULT_MAX_RELAYS,H as OwnerRelay,$ as RelayMember,Q as createRelayLink};
@@ -1 +1 @@
1
- import{LunoraError as m}from"@lunora/errors";import{stableWireKey as a}from"./stableWireKey-BYB5GQJa.mjs";const i="::relay::",f=(t,n)=>`${t}${i}${String(n)}`,s=t=>{const n=t.lastIndexOf(i);if(n===-1)return;const o=t.slice(0,n),e=t.slice(n+i.length),r=Number(e);if(!(o.length===0||!Number.isInteger(r)||r<0||String(r)!==e))return{ownerKey:o,relayIndex:r}},d=(t,n)=>a({args:n??{},name:t}),c={tDown:4e3,tUp:8e3},l=(t,n,o=c)=>{if(o.tDown>=o.tUp)throw new m("INTERNAL",`invalid promotion thresholds: tDown (${String(o.tDown)}) must be < tUp (${String(o.tUp)})`);return t==="owned"?n>=o.tUp?"promoted":"owned":n<o.tDown?"owned":"promoted"},g=(t,n)=>n<t?{tDown:n,tUp:t}:{tDown:Math.min(Math.max(1,Math.floor(t/2)),t-1),tUp:t},N=(t,n,o)=>{if(t<=n||n<=0)return 0;const e=t-n,r=Math.ceil(e/n);return Math.min(r,Math.max(0,o))};export{c as DEFAULT_PROMOTION_THRESHOLDS,i as RELAY_NAME_INFIX,g as clampPromotionThresholds,l as nextPromotionState,s as parseRelayName,N as relayCountFor,f as relayName,d as shapeRoutingKey};
1
+ import{LunoraError as m}from"@lunora/errors";import{stableWireKey as a}from"./stableWireKey-DSCJB6E7.mjs";const i="::relay::",f=(t,n)=>`${t}${i}${String(n)}`,s=t=>{const n=t.lastIndexOf(i);if(n===-1)return;const o=t.slice(0,n),e=t.slice(n+i.length),r=Number(e);if(!(o.length===0||!Number.isInteger(r)||r<0||String(r)!==e))return{ownerKey:o,relayIndex:r}},d=(t,n)=>a({args:n??{},name:t}),c={tDown:4e3,tUp:8e3},l=(t,n,o=c)=>{if(o.tDown>=o.tUp)throw new m("INTERNAL",`invalid promotion thresholds: tDown (${String(o.tDown)}) must be < tUp (${String(o.tUp)})`);return t==="owned"?n>=o.tUp?"promoted":"owned":n<o.tDown?"owned":"promoted"},g=(t,n)=>n<t?{tDown:n,tUp:t}:{tDown:Math.min(Math.max(1,Math.floor(t/2)),t-1),tUp:t},N=(t,n,o)=>{if(t<=n||n<=0)return 0;const e=t-n,r=Math.ceil(e/n);return Math.min(r,Math.max(0,o))};export{c as DEFAULT_PROMOTION_THRESHOLDS,i as RELAY_NAME_INFIX,g as clampPromotionThresholds,l as nextPromotionState,s as parseRelayName,N as relayCountFor,f as relayName,d as shapeRoutingKey};
@@ -1 +1 @@
1
- import{stableWireKey as b}from"./stableWireKey-BYB5GQJa.mjs";import{depKey as l,SCAN_DEP as y}from"./SCAN_DEP-D7qE3iUe.mjs";import{e as g}from"./estimate-bytes-CzG5x1f8.mjs";import{keysTouchRanges as p}from"./buildIndexRange-CBKQmHSS.mjs";import{stableStringify as A}from"./stableStringify-CujpENIO.mjs";const h=(o,t,s)=>{let e=o.get(t);return e===void 0&&(e=s(),o.set(t,e)),e},m=1e3,x=4*1024*1024;class w{entries=new Map;tableIndex=new Map;rangeIndex=new Map;totalBytes=0;hits=0;misses=0;evictions=0;maxEntries;maxBytes;now;monotonic=0;constructor(t={}){this.maxEntries=t.maxEntries??m,this.maxBytes=t.maxBytes??x,this.now=t.now??(()=>(this.monotonic+=1,this.monotonic))}async run(t,s,e,i=()=>[]){const n=this.entries.get(t);if(n)return this.hits+=1,n.lastUsed=this.now(),this.entries.delete(t),this.entries.set(t,n),n.result;this.misses+=1;const r=await e(),c=g(r);if(c===void 0)return r;const d=i(),f={bytes:c,deps:s,ranges:d,lastUsed:this.now(),result:r,subscribers:new Set};this.entries.set(t,f),this.totalBytes+=c;for(const a of s)h(this.tableIndex,a,()=>new Set).add(t);for(const a of d){const u=h(this.rangeIndex,a.table,()=>new Map);h(u,a,()=>new Set).add(t)}return this.evict(),r}invalidate(t,s,e){const i=[];return this.collectAndDrop(l(t,s),i),this.collectAndDrop(l(t,y),i),this.dropRangeDeps(t,e,i),i}invalidateTable(t){const s=[],e=`${t}:`;for(const i of this.tableIndex.keys())i.startsWith(e)&&this.collectAndDrop(i,s);return this.dropRangeDeps(t,void 0,s),s}subscribe(t,s){const e=this.entries.get(t);e&&e.subscribers.add(s)}unsubscribe(t,s){const e=this.entries.get(t);e&&e.subscribers.delete(s)}size(){return{bytes:this.totalBytes,entries:this.entries.size}}clear(){this.entries.clear(),this.tableIndex.clear(),this.rangeIndex.clear(),this.totalBytes=0}subscribers(t){const s=this.entries.get(t);return s?[...s.subscribers]:[]}stats(){return{bytes:this.totalBytes,entries:this.entries.size,evictions:this.evictions,hits:this.hits,misses:this.misses}}dropRangeDeps(t,s,e){const i=this.rangeIndex.get(t);if(!(!i||i.size===0))for(const[n,r]of i)p([n],s)&&this.dropKeys(r,e)}collectAndDrop(t,s){const e=this.tableIndex.get(t);e&&this.dropKeys(e,s)}dropKeys(t,s){for(const e of t){const i=this.entries.get(e);i&&(this.dropEntry(e,i),s.push(e))}}dropEntry(t,s){this.entries.delete(t),this.totalBytes-=s.bytes;for(const e of s.deps){const i=this.tableIndex.get(e);i&&(i.delete(t),i.size===0&&this.tableIndex.delete(e))}for(const e of s.ranges){const i=this.rangeIndex.get(e.table),n=i?.get(e);n?.delete(t),i&&n?.size===0&&(i.delete(e),i.size===0&&this.rangeIndex.delete(e.table))}}evict(){if(!(this.entries.size<=this.maxEntries&&this.totalBytes<=this.maxBytes))for(const[t,s]of this.entries){if(this.entries.size<=this.maxEntries&&this.totalBytes<=this.maxBytes)return;s.subscribers.size>0||(this.dropEntry(t,s),this.evictions+=1)}}}const z=(o,t,s)=>`${s??"\0anon"}\0${o}:${b(t)}`;export{w as ReactiveCache,z as reactiveCacheKey,A as stableStringify,b as stableWireKey};
1
+ import{stableWireKey as b}from"./stableWireKey-DSCJB6E7.mjs";import{depKey as l,SCAN_DEP as y}from"./SCAN_DEP-D7qE3iUe.mjs";import{e as g}from"./estimate-bytes-CzG5x1f8.mjs";import{keysTouchRanges as p}from"./buildIndexRange-CBKQmHSS.mjs";import{stableStringify as A}from"./stableStringify-G9OF5wcs.mjs";const h=(o,t,s)=>{let e=o.get(t);return e===void 0&&(e=s(),o.set(t,e)),e},m=1e3,x=4*1024*1024;class w{entries=new Map;tableIndex=new Map;rangeIndex=new Map;totalBytes=0;hits=0;misses=0;evictions=0;maxEntries;maxBytes;now;monotonic=0;constructor(t={}){this.maxEntries=t.maxEntries??m,this.maxBytes=t.maxBytes??x,this.now=t.now??(()=>(this.monotonic+=1,this.monotonic))}async run(t,s,e,i=()=>[]){const n=this.entries.get(t);if(n)return this.hits+=1,n.lastUsed=this.now(),this.entries.delete(t),this.entries.set(t,n),n.result;this.misses+=1;const r=await e(),c=g(r);if(c===void 0)return r;const d=i(),f={bytes:c,deps:s,ranges:d,lastUsed:this.now(),result:r,subscribers:new Set};this.entries.set(t,f),this.totalBytes+=c;for(const a of s)h(this.tableIndex,a,()=>new Set).add(t);for(const a of d){const u=h(this.rangeIndex,a.table,()=>new Map);h(u,a,()=>new Set).add(t)}return this.evict(),r}invalidate(t,s,e){const i=[];return this.collectAndDrop(l(t,s),i),this.collectAndDrop(l(t,y),i),this.dropRangeDeps(t,e,i),i}invalidateTable(t){const s=[],e=`${t}:`;for(const i of this.tableIndex.keys())i.startsWith(e)&&this.collectAndDrop(i,s);return this.dropRangeDeps(t,void 0,s),s}subscribe(t,s){const e=this.entries.get(t);e&&e.subscribers.add(s)}unsubscribe(t,s){const e=this.entries.get(t);e&&e.subscribers.delete(s)}size(){return{bytes:this.totalBytes,entries:this.entries.size}}clear(){this.entries.clear(),this.tableIndex.clear(),this.rangeIndex.clear(),this.totalBytes=0}subscribers(t){const s=this.entries.get(t);return s?[...s.subscribers]:[]}stats(){return{bytes:this.totalBytes,entries:this.entries.size,evictions:this.evictions,hits:this.hits,misses:this.misses}}dropRangeDeps(t,s,e){const i=this.rangeIndex.get(t);if(!(!i||i.size===0))for(const[n,r]of i)p([n],s)&&this.dropKeys(r,e)}collectAndDrop(t,s){const e=this.tableIndex.get(t);e&&this.dropKeys(e,s)}dropKeys(t,s){for(const e of t){const i=this.entries.get(e);i&&(this.dropEntry(e,i),s.push(e))}}dropEntry(t,s){this.entries.delete(t),this.totalBytes-=s.bytes;for(const e of s.deps){const i=this.tableIndex.get(e);i&&(i.delete(t),i.size===0&&this.tableIndex.delete(e))}for(const e of s.ranges){const i=this.rangeIndex.get(e.table),n=i?.get(e);n?.delete(t),i&&n?.size===0&&(i.delete(e),i.size===0&&this.rangeIndex.delete(e.table))}}evict(){if(!(this.entries.size<=this.maxEntries&&this.totalBytes<=this.maxBytes))for(const[t,s]of this.entries){if(this.entries.size<=this.maxEntries&&this.totalBytes<=this.maxBytes)return;s.subscribers.size>0||(this.dropEntry(t,s),this.evictions+=1)}}}const z=(o,t,s)=>`${s??"\0anon"}\0${o}:${b(t)}`;export{w as ReactiveCache,z as reactiveCacheKey,A as stableStringify,b as stableWireKey};
@@ -1 +1 @@
1
- import{stableStringify as h}from"./stableStringify-CujpENIO.mjs";import{i as m,e as I}from"./wire-codec-BU9T2xJ7.mjs";const w="_id",p="_creationTime",y="page",$=e=>{let t;for(const s of e){const n=s[p];if(typeof n=="number"){if(t!==void 0){if(n<t)return!0;if(n>t)return!1}t=n}}return!1},J=(e,t)=>{const s=t[p];if(typeof s!="number")return e.length;const n=$(e);for(const[o,r]of e.entries()){const i=r[p];if(typeof i=="number"&&(n?i<s:i>s))return o}return e.length},S="__lunora__",_=e=>{if(typeof e!="object"||e===null||Array.isArray(e))return;const t=e[w];return typeof t=="string"?t:void 0},A=e=>{const t=new Map,s=[];for(const n of e){const o=_(n);if(o===void 0||t.has(o))return;t.set(o,n),s.push(o)}return{byId:t,order:s}},x=(e,t)=>{const s=e.order.filter(o=>t.byId.has(o)),n=t.order.filter(o=>e.byId.has(o));return s.length!==n.length?!1:s.every((o,r)=>n[r]===o)},F=(e,t,s,n)=>{const o=[];for(const r of e.order)t.byId.has(r)||o.push({delta:{key:r,op:"delete",table:s},frame:`{"key":${JSON.stringify(r)},"op":"delete","table":${n}}`});return o},L=(e,t,s,n)=>{const o=[];for(const r of t.order){const i=t.byId.get(r),c=e.byId.get(r),d=JSON.stringify(I(i)),a=c===void 0?void 0:JSON.stringify(c);if(a===d)continue;const f=a===void 0?"insert":"update";o.push({delta:{key:r,op:f,row:i,table:s},frame:`{"key":${JSON.stringify(r)},"op":"${f}","row":${d},"table":${n}}`})}return o},N=(e,t)=>{if(Array.isArray(e)&&Array.isArray(t))return{next:t,previous:e};if(!m(e)||!m(t))return;const s=e[y],n=t[y];if(!Array.isArray(s)||!Array.isArray(n))return;const o=r=>Object.fromEntries(Object.entries(r).filter(([i])=>i!==y));if(h(o(e))===h(I(o(t))))return{next:n,previous:s}},E=(e,t,s)=>{const n=s.filter(({delta:r})=>r.op==="insert");if(n.length===0)return!0;const o=e.order.filter(r=>t.byId.has(r)).map(r=>e.byId.get(r));for(const{delta:r}of n){const i=r.row;o.splice(J(o,i),0,i)}return o.length===t.order.length&&o.every((r,i)=>r[w]===t.order[i])},D=(e,t,s)=>{let n;try{n=JSON.parse(e)}catch{return}const o=N(n,t);if(o===void 0)return;const r=A(o.previous),i=A(o.next);if(r===void 0||i===void 0||!x(r,i))return;const c=s===""?S:s,d=JSON.stringify(c),a=[...F(r,i,c,d),...L(r,i,c,d)];return E(r,i,a)?a:void 0},j=(e,t,s,n)=>{const o=D(e,t,s);if(o!==void 0){if(n!==void 0)for(const{frame:r}of o)n.push(r);return o.map(({delta:r})=>r)}},k=(e,t)=>{try{return e.send(t),!0}catch{return!1}},M=e=>{const{cursorSuffix:t,lastMutationId:s,nextResult:n,pageDeltas:o,previousJson:r,snapshotJson:i,subId:c,table:d}=e,a=JSON.stringify(c),f=(s===void 0?"":`,"lastMutationId":${String(s)}`)+t,u=`{"type":"data","id":${a},"data":${i}${f}}`,l=r!==void 0&&(o===!0||Array.isArray(n))?D(r,n,d):void 0;if(l===void 0||l.length===0)return[u];const g=[];let v=0;for(const{frame:O}of l){const b=`{"type":"delta","id":${a},"delta":${O}${f}}`;if(v+=b.length,v>=u.length)return[u];g.push(b)}return g},B=async e=>{let t=0;for(;t<100;){t+=1;const{bufferedAmount:s}=e;if(typeof s!="number"||s<1048576)return;await new Promise(n=>{setTimeout(n,20)})}};export{B as awaitWsDrain,M as subscriptionFrames,j as subscriptionListDeltas,k as trySendFrame};
1
+ import{stableStringify as h}from"./stableStringify-G9OF5wcs.mjs";import{i as m,e as I}from"./wire-codec-BU9T2xJ7.mjs";const w="_id",p="_creationTime",y="page",$=e=>{let t;for(const s of e){const n=s[p];if(typeof n=="number"){if(t!==void 0){if(n<t)return!0;if(n>t)return!1}t=n}}return!1},J=(e,t)=>{const s=t[p];if(typeof s!="number")return e.length;const n=$(e);for(const[o,r]of e.entries()){const i=r[p];if(typeof i=="number"&&(n?i<s:i>s))return o}return e.length},S="__lunora__",_=e=>{if(typeof e!="object"||e===null||Array.isArray(e))return;const t=e[w];return typeof t=="string"?t:void 0},A=e=>{const t=new Map,s=[];for(const n of e){const o=_(n);if(o===void 0||t.has(o))return;t.set(o,n),s.push(o)}return{byId:t,order:s}},x=(e,t)=>{const s=e.order.filter(o=>t.byId.has(o)),n=t.order.filter(o=>e.byId.has(o));return s.length!==n.length?!1:s.every((o,r)=>n[r]===o)},F=(e,t,s,n)=>{const o=[];for(const r of e.order)t.byId.has(r)||o.push({delta:{key:r,op:"delete",table:s},frame:`{"key":${JSON.stringify(r)},"op":"delete","table":${n}}`});return o},L=(e,t,s,n)=>{const o=[];for(const r of t.order){const i=t.byId.get(r),c=e.byId.get(r),d=JSON.stringify(I(i)),a=c===void 0?void 0:JSON.stringify(c);if(a===d)continue;const f=a===void 0?"insert":"update";o.push({delta:{key:r,op:f,row:i,table:s},frame:`{"key":${JSON.stringify(r)},"op":"${f}","row":${d},"table":${n}}`})}return o},N=(e,t)=>{if(Array.isArray(e)&&Array.isArray(t))return{next:t,previous:e};if(!m(e)||!m(t))return;const s=e[y],n=t[y];if(!Array.isArray(s)||!Array.isArray(n))return;const o=r=>Object.fromEntries(Object.entries(r).filter(([i])=>i!==y));if(h(o(e))===h(I(o(t))))return{next:n,previous:s}},E=(e,t,s)=>{const n=s.filter(({delta:r})=>r.op==="insert");if(n.length===0)return!0;const o=e.order.filter(r=>t.byId.has(r)).map(r=>e.byId.get(r));for(const{delta:r}of n){const i=r.row;o.splice(J(o,i),0,i)}return o.length===t.order.length&&o.every((r,i)=>r[w]===t.order[i])},D=(e,t,s)=>{let n;try{n=JSON.parse(e)}catch{return}const o=N(n,t);if(o===void 0)return;const r=A(o.previous),i=A(o.next);if(r===void 0||i===void 0||!x(r,i))return;const c=s===""?S:s,d=JSON.stringify(c),a=[...F(r,i,c,d),...L(r,i,c,d)];return E(r,i,a)?a:void 0},j=(e,t,s,n)=>{const o=D(e,t,s);if(o!==void 0){if(n!==void 0)for(const{frame:r}of o)n.push(r);return o.map(({delta:r})=>r)}},k=(e,t)=>{try{return e.send(t),!0}catch{return!1}},M=e=>{const{cursorSuffix:t,lastMutationId:s,nextResult:n,pageDeltas:o,previousJson:r,snapshotJson:i,subId:c,table:d}=e,a=JSON.stringify(c),f=(s===void 0?"":`,"lastMutationId":${String(s)}`)+t,u=`{"type":"data","id":${a},"data":${i}${f}}`,l=r!==void 0&&(o===!0||Array.isArray(n))?D(r,n,d):void 0;if(l===void 0||l.length===0)return[u];const g=[];let v=0;for(const{frame:O}of l){const b=`{"type":"delta","id":${a},"delta":${O}${f}}`;if(v+=b.length,v>=u.length)return[u];g.push(b)}return g},B=async e=>{let t=0;for(;t<100;){t+=1;const{bufferedAmount:s}=e;if(typeof s!="number"||s<1048576)return;await new Promise(n=>{setTimeout(n,20)})}};export{B as awaitWsDrain,M as subscriptionFrames,j as subscriptionListDeltas,k as trySendFrame};
@@ -1 +1 @@
1
- import{createShardCtxDb as S}from"./NotUniqueError-BixDiv4O.mjs";import{createRelayLink as B}from"./DEFAULT_MAX_RELAYS-DeVcEXBh.mjs";import{ConflictError as I}from"./ConflictError-C8GtJmjS.mjs";import{runShardMigrations as v}from"./runShardMigrations-Crppyq1f.mjs";import{relayName as F}from"./DEFAULT_PROMOTION_THRESHOLDS-DVTD9iu0.mjs";const _=(E,u={})=>({_meta:{column:{notNull:!0,...u}},kind:E}),D=(E,u,N)=>{const{describe:k,expect:i,it:m}=N;k(`engine contract: ${E}`,()=>{k("optimistic concurrency",()=>{const b=h=>({tables:{items:{indexes:[],shape:{title:_("string"),version:_("number",{notNull:!1})},triggerMap:{clobber:{handler:()=>{h.exec(`UPDATE "items" SET "__doc__" = json_set("__doc__", '$.version', 99) WHERE "id" = 'i1'`)},op:"update",timing:"before"}}}}});m("raises a CONFLICT of kind `occ` when a write's snapshot is clobbered",async()=>{const{close:h,host:d}=u();try{const c=d.sql,l=b(c);v(c,l);const s=S({schema:l,sql:c});await s.insert("items",{_id:"i1",title:"first",version:1},{allowExplicitId:!0}),await i(s.patch("i1",{title:"second"})).rejects.toBeInstanceOf(I)}finally{h?.()}}),m("reports the conflict as CONFLICT/409 rather than retrying it away",async()=>{const{close:h,host:d}=u();try{const c=d.sql,l=b(c);v(c,l);const s=S({schema:l,sql:c});await s.insert("items",{_id:"i1",title:"first",version:1},{allowExplicitId:!0});let a;try{await s.patch("i1",{title:"second"})}catch(t){a=t}const e=a;i(e.code).toBe("CONFLICT"),i(e.kind).toBe("occ")}finally{h?.()}}),m("leaves the row readable and unchanged after a conflict",async()=>{const{close:h,host:d}=u();try{const c=d.sql,l=b(c);v(c,l);const s=S({schema:l,sql:c});await s.insert("items",{_id:"i1",title:"first",version:1},{allowExplicitId:!0});try{await s.patch("i1",{title:"second"})}catch{}const a=await s.get("i1");i(a?.title).toBe("first"),i(a?.version).toBe(99)}finally{h?.()}}),m("raises a CONFLICT of kind `trigger` when a trigger writes its own row through the db",async()=>{const{close:h,host:d}=u();try{const c=d.sql,l={tables:{items:{indexes:[],shape:{title:_("string"),version:_("number",{notNull:!1})},triggerMap:{recurse:{handler:async(t,o)=>{await t.db.patch(o.doc._id,{version:99})},op:"update",timing:"before"}}}}};v(c,l);const s=S({schema:l,sql:c});await s.insert("items",{_id:"i1",title:"first",version:1},{allowExplicitId:!0});let a;try{await s.patch("i1",{title:"second"})}catch(t){a=t}const e=a;i(e).toBeInstanceOf(I),i(e.code).toBe("CONFLICT"),i(e.kind).toBe("trigger")}finally{h?.()}})}),k("shape-poke ordering",()=>{const b="shard-a",h={args:{},name:"messages"},d=(e,t,o,n)=>e.accept(t?.()??{},{connectionId:o,shapes:{[n]:h}}),c=(e,t)=>{let o=0,n=0;const r=g=>()=>{throw new Error(`the relay poke path must not reach RelayHost.${g}`)},p={fetch:(g,O)=>{if(JSON.parse(O?.body??"{}").type!=="relay_shape_subscribe")return Promise.resolve(new Response(void 0,{status:204}));const C=t[n];if(n+=1,C===void 0)throw new Error("the relay asked for more seeds than this fixture supplies");return Promise.resolve(Response.json(C))}},y={get:()=>p,getByName:()=>p,idFromName:g=>g},w={buildShapeDiff:r("buildShapeDiff"),computeOpLogShapeSeed:r("computeOpLogShapeSeed"),currentCdcEpoch:r("currentCdcEpoch"),deliverWhisperLocal:r("deliverWhisperLocal"),doName:()=>F(b,0),env:()=>({SHARD:y}),getWebSockets:()=>e.getSockets(),maskMetadata:r("maskMetadata"),nextPokeId:()=>(o+=1,`poke-${String(o)}`),readAttachment:g=>g.deserializeAttachment?.(),recordShapePokeFanout:()=>{},resolveShape:r("resolveShape"),rlsMetadata:r("rlsMetadata"),shardBinding:()=>"SHARD",sql:r("sql")},f=B(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,o)=>{const n=await e.seedRelayShape(t,o,h,{identity:void 0,userId:void 0});if(n!=="ok")throw new Error(`seed failed: ${JSON.stringify(n)}`)},a=(e={})=>l({...h,checkpoint:20,epoch:"e1",fromCursor:10,rowsPatch:[{id:"r1",op:"upsert",value:{title:"hello"}}],type:"relay_shape_poke",...e});m("frames a poke as pokeStart → pokePart per shape → pokeEnd, under one poke id",async()=>{const{close:e,createSocket:t,readFrames:o,sockets:n}=u();try{const r=c(n,[{cursor:10,epoch:"e1",frames:[]}]),p=d(n,t,"c-alice","s1");await s(r,p,"s1"),await r.handleControl(a());const w=(await o(p)).map(f=>JSON.parse(f));i(w.map(f=>f.type)).toStrictEqual(["pokeStart","pokePart","pokeEnd"]),i(new Set(w.map(f=>f.pokeId)).size).toBe(1),i(w[1]?.shapeId).toBe("s1"),i(w[2]?.checkpoint).toBe(20)}finally{e?.()}}),m("delivers a poke only to sockets whose cursor matches, and advances them past it",async()=>{const{close:e,createSocket:t,readFrames:o,sockets:n}=u();try{const r=c(n,[{cursor:10,epoch:"e1",frames:[]},{cursor:7,epoch:"e1",frames:[]}]),p=d(n,t,"c-alice","s1"),y=d(n,t,"c-bob","s2");await s(r,p,"s1"),await s(r,y,"s2"),await r.handleControl(a());const w=await o(p);i(w.length).toBe(3);const f=await o(y);i(f.length).toBe(0),await r.handleControl(a());const g=await o(p);i(g.length).toBe(3)}finally{e?.()}}),m("skips a socket whose cursor matches under a different CDC epoch",async()=>{const{close:e,createSocket:t,readFrames:o,sockets:n}=u();try{const r=c(n,[{cursor:10,epoch:"e1",frames:[]}]),p=d(n,t,"c-alice","s1");await s(r,p,"s1"),await r.handleControl(a({epoch:"e2"}));const y=await o(p);i(y.length).toBe(0),await r.handleControl(a());const w=await o(p);i(w.length).toBe(3)}finally{e?.()}})}),k("RLS identity under live subscription",()=>{const b="shard-a",h={args:{},name:"lobby-messages"},d={args:{},name:"my-orders"},c=s=>{const a=[],e=[],t={fetch:(r,p)=>(a.push(JSON.parse(p?.body??"{}")),Promise.resolve(new Response(void 0,{status:204})))},n=B({buildShapeDiff:()=>[{id:"r1",op:"upsert",value:{}}],computeOpLogShapeSeed:()=>({baseCheckpoint:void 0,cursor:10,epoch:"e1",rowsPatch:[]}),currentCdcEpoch:()=>"e1",deliverWhisperLocal:()=>0,doName:()=>b,env:()=>({SHARD:{get:()=>t,getByName:()=>t,idFromName:r=>r}}),getWebSockets:()=>[],maskMetadata:()=>({columns:[]}),nextPokeId:()=>"poke-1",readAttachment:()=>({}),recordShapePokeFanout:()=>{},resolveShape:(r,p,y)=>(e.push(y),r===d.name?{columns:["id"],effectiveWhere:{org:y?.identity?.org??"anonymous"},global:!1,table:"orders"}:{columns:["id"],effectiveWhere:{room:"lobby"},global:!1,table:"messages"}),rlsMetadata:()=>({policies:[]}),shardBinding:()=>"SHARD",sql:()=>s});if(n===void 0)throw new Error("expected an owner link for an un-suffixed DO name");return{owner:n,posts:a,resolvedUnder:e}},l=async(s,a)=>{await s.handleControl(new Request("https://owner.internal/_lunora/relay",{body:JSON.stringify({...a,connectionId:"c-alice",identity:{org:"acme"},relayIndex:0,subId:"s1",type:"relay_shape_subscribe",userId:"u1"}),headers:{"content-type":"application/json"},method:"POST"}))};m("seeds a subscriber under its own forwarded identity, never the anonymous one",async()=>{const{close:s,host:a}=u();try{const{owner:e,resolvedUnder:t}=c(a.sql);await l(e,d),i(t.some(o=>o?.userId==="u1"&&o.identity?.org==="acme")).toBe(!0)}finally{s?.()}}),m("routes an identity-scoped shape to a per-socket poke, not the cohort multicast",async()=>{const{close:s,host:a}=u();try{const{owner:e,posts:t}=c(a.sql);await l(e,d),t.length=0,await e.onFlush(new Set(["orders"]),20);const o=t.filter(n=>n.type==="relay_shape_poke");i(o.length).toBe(1),i(o[0]?.targetConnectionId).toBe("c-alice")}finally{s?.()}}),m("still multicasts an identity-blind shape to the whole cohort",async()=>{const{close:s,host:a}=u();try{const{owner:e,posts:t}=c(a.sql);await l(e,h),t.length=0,await e.onFlush(new Set(["messages"]),20);const o=t.filter(n=>n.type==="relay_shape_poke");i(o.length).toBe(1),i(o[0]?.targetConnectionId).toBeUndefined()}finally{s?.()}})})})};export{D as defineEngineContractSuite};
1
+ import{createShardCtxDb as S}from"./NotUniqueError-BixDiv4O.mjs";import{createRelayLink as B}from"./DEFAULT_MAX_RELAYS-tuHNDUZr.mjs";import{ConflictError as I}from"./ConflictError-C8GtJmjS.mjs";import{runShardMigrations as v}from"./runShardMigrations-Crppyq1f.mjs";import{relayName as F}from"./DEFAULT_PROMOTION_THRESHOLDS-H2sHFvlw.mjs";const _=(E,u={})=>({_meta:{column:{notNull:!0,...u}},kind:E}),D=(E,u,N)=>{const{describe:k,expect:i,it:m}=N;k(`engine contract: ${E}`,()=>{k("optimistic concurrency",()=>{const b=h=>({tables:{items:{indexes:[],shape:{title:_("string"),version:_("number",{notNull:!1})},triggerMap:{clobber:{handler:()=>{h.exec(`UPDATE "items" SET "__doc__" = json_set("__doc__", '$.version', 99) WHERE "id" = 'i1'`)},op:"update",timing:"before"}}}}});m("raises a CONFLICT of kind `occ` when a write's snapshot is clobbered",async()=>{const{close:h,host:d}=u();try{const c=d.sql,l=b(c);v(c,l);const s=S({schema:l,sql:c});await s.insert("items",{_id:"i1",title:"first",version:1},{allowExplicitId:!0}),await i(s.patch("i1",{title:"second"})).rejects.toBeInstanceOf(I)}finally{h?.()}}),m("reports the conflict as CONFLICT/409 rather than retrying it away",async()=>{const{close:h,host:d}=u();try{const c=d.sql,l=b(c);v(c,l);const s=S({schema:l,sql:c});await s.insert("items",{_id:"i1",title:"first",version:1},{allowExplicitId:!0});let a;try{await s.patch("i1",{title:"second"})}catch(t){a=t}const e=a;i(e.code).toBe("CONFLICT"),i(e.kind).toBe("occ")}finally{h?.()}}),m("leaves the row readable and unchanged after a conflict",async()=>{const{close:h,host:d}=u();try{const c=d.sql,l=b(c);v(c,l);const s=S({schema:l,sql:c});await s.insert("items",{_id:"i1",title:"first",version:1},{allowExplicitId:!0});try{await s.patch("i1",{title:"second"})}catch{}const a=await s.get("i1");i(a?.title).toBe("first"),i(a?.version).toBe(99)}finally{h?.()}}),m("raises a CONFLICT of kind `trigger` when a trigger writes its own row through the db",async()=>{const{close:h,host:d}=u();try{const c=d.sql,l={tables:{items:{indexes:[],shape:{title:_("string"),version:_("number",{notNull:!1})},triggerMap:{recurse:{handler:async(t,o)=>{await t.db.patch(o.doc._id,{version:99})},op:"update",timing:"before"}}}}};v(c,l);const s=S({schema:l,sql:c});await s.insert("items",{_id:"i1",title:"first",version:1},{allowExplicitId:!0});let a;try{await s.patch("i1",{title:"second"})}catch(t){a=t}const e=a;i(e).toBeInstanceOf(I),i(e.code).toBe("CONFLICT"),i(e.kind).toBe("trigger")}finally{h?.()}})}),k("shape-poke ordering",()=>{const b="shard-a",h={args:{},name:"messages"},d=(e,t,o,n)=>e.accept(t?.()??{},{connectionId:o,shapes:{[n]:h}}),c=(e,t)=>{let o=0,n=0;const r=g=>()=>{throw new Error(`the relay poke path must not reach RelayHost.${g}`)},p={fetch:(g,O)=>{if(JSON.parse(O?.body??"{}").type!=="relay_shape_subscribe")return Promise.resolve(new Response(void 0,{status:204}));const C=t[n];if(n+=1,C===void 0)throw new Error("the relay asked for more seeds than this fixture supplies");return Promise.resolve(Response.json(C))}},y={get:()=>p,getByName:()=>p,idFromName:g=>g},w={buildShapeDiff:r("buildShapeDiff"),computeOpLogShapeSeed:r("computeOpLogShapeSeed"),currentCdcEpoch:r("currentCdcEpoch"),deliverWhisperLocal:r("deliverWhisperLocal"),doName:()=>F(b,0),env:()=>({SHARD:y}),getWebSockets:()=>e.getSockets(),maskMetadata:r("maskMetadata"),nextPokeId:()=>(o+=1,`poke-${String(o)}`),readAttachment:g=>g.deserializeAttachment?.(),recordShapePokeFanout:()=>{},resolveShape:r("resolveShape"),rlsMetadata:r("rlsMetadata"),shardBinding:()=>"SHARD",sql:r("sql")},f=B(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,o)=>{const n=await e.seedRelayShape(t,o,h,{identity:void 0,userId:void 0});if(n!=="ok")throw new Error(`seed failed: ${JSON.stringify(n)}`)},a=(e={})=>l({...h,checkpoint:20,epoch:"e1",fromCursor:10,rowsPatch:[{id:"r1",op:"upsert",value:{title:"hello"}}],type:"relay_shape_poke",...e});m("frames a poke as pokeStart → pokePart per shape → pokeEnd, under one poke id",async()=>{const{close:e,createSocket:t,readFrames:o,sockets:n}=u();try{const r=c(n,[{cursor:10,epoch:"e1",frames:[]}]),p=d(n,t,"c-alice","s1");await s(r,p,"s1"),await r.handleControl(a());const w=(await o(p)).map(f=>JSON.parse(f));i(w.map(f=>f.type)).toStrictEqual(["pokeStart","pokePart","pokeEnd"]),i(new Set(w.map(f=>f.pokeId)).size).toBe(1),i(w[1]?.shapeId).toBe("s1"),i(w[2]?.checkpoint).toBe(20)}finally{e?.()}}),m("delivers a poke only to sockets whose cursor matches, and advances them past it",async()=>{const{close:e,createSocket:t,readFrames:o,sockets:n}=u();try{const r=c(n,[{cursor:10,epoch:"e1",frames:[]},{cursor:7,epoch:"e1",frames:[]}]),p=d(n,t,"c-alice","s1"),y=d(n,t,"c-bob","s2");await s(r,p,"s1"),await s(r,y,"s2"),await r.handleControl(a());const w=await o(p);i(w.length).toBe(3);const f=await o(y);i(f.length).toBe(0),await r.handleControl(a());const g=await o(p);i(g.length).toBe(3)}finally{e?.()}}),m("skips a socket whose cursor matches under a different CDC epoch",async()=>{const{close:e,createSocket:t,readFrames:o,sockets:n}=u();try{const r=c(n,[{cursor:10,epoch:"e1",frames:[]}]),p=d(n,t,"c-alice","s1");await s(r,p,"s1"),await r.handleControl(a({epoch:"e2"}));const y=await o(p);i(y.length).toBe(0),await r.handleControl(a());const w=await o(p);i(w.length).toBe(3)}finally{e?.()}})}),k("RLS identity under live subscription",()=>{const b="shard-a",h={args:{},name:"lobby-messages"},d={args:{},name:"my-orders"},c=s=>{const a=[],e=[],t={fetch:(r,p)=>(a.push(JSON.parse(p?.body??"{}")),Promise.resolve(new Response(void 0,{status:204})))},n=B({buildShapeDiff:()=>[{id:"r1",op:"upsert",value:{}}],computeOpLogShapeSeed:()=>({baseCheckpoint:void 0,cursor:10,epoch:"e1",rowsPatch:[]}),currentCdcEpoch:()=>"e1",deliverWhisperLocal:()=>0,doName:()=>b,env:()=>({SHARD:{get:()=>t,getByName:()=>t,idFromName:r=>r}}),getWebSockets:()=>[],maskMetadata:()=>({columns:[]}),nextPokeId:()=>"poke-1",readAttachment:()=>({}),recordShapePokeFanout:()=>{},resolveShape:(r,p,y)=>(e.push(y),r===d.name?{columns:["id"],effectiveWhere:{org:y?.identity?.org??"anonymous"},global:!1,table:"orders"}:{columns:["id"],effectiveWhere:{room:"lobby"},global:!1,table:"messages"}),rlsMetadata:()=>({policies:[]}),shardBinding:()=>"SHARD",sql:()=>s});if(n===void 0)throw new Error("expected an owner link for an un-suffixed DO name");return{owner:n,posts:a,resolvedUnder:e}},l=async(s,a)=>{await s.handleControl(new Request("https://owner.internal/_lunora/relay",{body:JSON.stringify({...a,connectionId:"c-alice",identity:{org:"acme"},relayIndex:0,subId:"s1",type:"relay_shape_subscribe",userId:"u1"}),headers:{"content-type":"application/json"},method:"POST"}))};m("seeds a subscriber under its own forwarded identity, never the anonymous one",async()=>{const{close:s,host:a}=u();try{const{owner:e,resolvedUnder:t}=c(a.sql);await l(e,d),i(t.some(o=>o?.userId==="u1"&&o.identity?.org==="acme")).toBe(!0)}finally{s?.()}}),m("routes an identity-scoped shape to a per-socket poke, not the cohort multicast",async()=>{const{close:s,host:a}=u();try{const{owner:e,posts:t}=c(a.sql);await l(e,d),t.length=0,await e.onFlush(new Set(["orders"]),20);const o=t.filter(n=>n.type==="relay_shape_poke");i(o.length).toBe(1),i(o[0]?.targetConnectionId).toBe("c-alice")}finally{s?.()}}),m("still multicasts an identity-blind shape to the whole cohort",async()=>{const{close:s,host:a}=u();try{const{owner:e,posts:t}=c(a.sql);await l(e,h),t.length=0,await e.onFlush(new Set(["messages"]),20);const o=t.filter(n=>n.type==="relay_shape_poke");i(o.length).toBe(1),i(o[0]?.targetConnectionId).toBeUndefined()}finally{s?.()}})})})};export{D as defineEngineContractSuite};
@@ -1 +1 @@
1
- import{stableStringify as u}from"./stableStringify-CujpENIO.mjs";const l=(t,s)=>{const o={_id:t._id};if(s){for(const e of s)Object.hasOwn(t,e)&&(o[e]=t[e]);return o}for(const[e,n]of Object.entries(t))e!=="_id"&&e!=="_creationTime"&&(o[e]=n);return o},j=(t,s,o)=>{const{columns:e,table:n}=o,c=[],d=new Map;for(const r of t){const i=l(r,e),f=String(i._id),a=u(i);d.set(f,a);const p=s.get(f);p===void 0?c.push({doc:i,id:f,op:"insert",seq:0,table:n,ts:0}):p!==a&&c.push({doc:i,id:f,op:"update",seq:0,table:n,ts:0})}for(const r of s.keys())d.has(r)||c.push({id:r,op:"delete",seq:0,table:n,ts:0});return{changes:c,nextBaseline:d}};export{j as diffExternalSource,l as projectExternalSourceRow};
1
+ import{stableStringify as u}from"./stableStringify-G9OF5wcs.mjs";const l=(t,s)=>{const o={_id:t._id};if(s){for(const e of s)Object.hasOwn(t,e)&&(o[e]=t[e]);return o}for(const[e,n]of Object.entries(t))e!=="_id"&&e!=="_creationTime"&&(o[e]=n);return o},j=(t,s,o)=>{const{columns:e,table:n}=o,c=[],d=new Map;for(const r of t){const i=l(r,e),f=String(i._id),a=u(i);d.set(f,a);const p=s.get(f);p===void 0?c.push({doc:i,id:f,op:"insert",seq:0,table:n,ts:0}):p!==a&&c.push({doc:i,id:f,op:"update",seq:0,table:n,ts:0})}for(const r of s.keys())d.has(r)||c.push({id:r,op:"delete",seq:0,table:n,ts:0});return{changes:c,nextBaseline:d}};export{j as diffExternalSource,l as projectExternalSourceRow};
@@ -1,4 +1,4 @@
1
- import{LunoraError as T}from"@lunora/errors";import{sql as m}from"drizzle-orm";import{runDrizzle as S}from"./runDrizzle-it6rL9bR.mjs";import{liftSourceId as A}from"./liftSourceId-CA3ENhXj.mjs";import{normalizeSourceValue as W}from"./liftSourceId-CA3ENhXj.mjs";import{runExternalSourceTick as C,materializeExternalRowsIncremental as D}from"./materializeExternalRows-Drn0FGdb.mjs";const p="__lunora_source_cursor",M=e=>e instanceof Date?`d:${e.toISOString()}`:typeof e=="bigint"?`b:${e.toString()}`:typeof e=="number"?`n:${e.toString()}`:`s:${e}`,v=e=>{const t=e.slice(2);switch(e[0]){case"b":return BigInt(t);case"d":return new Date(t);case"n":return Number(t);default:return t}},h=/^-?\d+$/,N=/^-?\d+(?:\.\d+)?$/,x=(e,t)=>e instanceof Date&&t instanceof Date?e.getTime()>t.getTime():typeof e=="bigint"&&typeof t=="bigint"||typeof e=="number"&&typeof t=="number"?e>t:typeof e=="string"&&typeof t=="string"&&N.test(e)&&N.test(t)?h.test(e)&&h.test(t)?BigInt(e)>BigInt(t):Number(e)>Number(t):String(e)>String(t),O=(e,t,o)=>{let n=o===null?void 0:v(o);for(const r of e){const c=r[t];if(c==null)continue;const a=c;(n===void 0||x(a,n))&&(n=a)}return n===void 0?null:M(n)},B=e=>{S(e,m`CREATE TABLE IF NOT EXISTS ${m.identifier(p)} (
1
+ import{LunoraError as T}from"@lunora/errors";import{sql as m}from"drizzle-orm";import{runDrizzle as S}from"./runDrizzle-it6rL9bR.mjs";import{liftSourceId as A}from"./liftSourceId-CA3ENhXj.mjs";import{normalizeSourceValue as W}from"./liftSourceId-CA3ENhXj.mjs";import{runExternalSourceTick as C,materializeExternalRowsIncremental as D}from"./materializeExternalRows-D5tgL1mR.mjs";const p="__lunora_source_cursor",M=e=>e instanceof Date?`d:${e.toISOString()}`:typeof e=="bigint"?`b:${e.toString()}`:typeof e=="number"?`n:${e.toString()}`:`s:${e}`,v=e=>{const t=e.slice(2);switch(e[0]){case"b":return BigInt(t);case"d":return new Date(t);case"n":return Number(t);default:return t}},h=/^-?\d+$/,N=/^-?\d+(?:\.\d+)?$/,x=(e,t)=>e instanceof Date&&t instanceof Date?e.getTime()>t.getTime():typeof e=="bigint"&&typeof t=="bigint"||typeof e=="number"&&typeof t=="number"?e>t:typeof e=="string"&&typeof t=="string"&&N.test(e)&&N.test(t)?h.test(e)&&h.test(t)?BigInt(e)>BigInt(t):Number(e)>Number(t):String(e)>String(t),O=(e,t,o)=>{let n=o===null?void 0:v(o);for(const r of e){const c=r[t];if(c==null)continue;const a=c;(n===void 0||x(a,n))&&(n=a)}return n===void 0?null:M(n)},B=e=>{S(e,m`CREATE TABLE IF NOT EXISTS ${m.identifier(p)} (
2
2
  table_name TEXT NOT NULL,
3
3
  shard_key TEXT NOT NULL,
4
4
  watermark TEXT,
@@ -1 +1 @@
1
- import{applyCdcChanges as p}from"./CDC_LOG_TABLE-B58N8NQO.mjs";import{selectShapeRows as m}from"./selectShapeMemberIds-B-pQJHAu.mjs";import{diffExternalSource as g,projectExternalSourceRow as l}from"./diffExternalSource-pozJ4UdZ.mjs";import{stableStringify as d}from"./stableStringify-CujpENIO.mjs";const x=async(t,s,a,e)=>{const{changes:o,nextBaseline:n}=g(s,a,e);return await p(t,o),{applied:o.length,nextBaseline:n}},R=async(t,s,a)=>{const{columns:e,deletedIds:o,table:n}=a,r=[];for(const f of s){const i=l(f,e),c=String(i._id);if(o?.has(c)){await t.get(c,n)&&r.push({id:c,op:"delete",seq:0,table:n,ts:0});continue}const u=await t.get(c,n);u&&d(l({...u,_id:c},e))===d(i)||r.push({doc:i,id:c,op:"insert",seq:0,table:n,ts:0})}return await p(t,r),{applied:r.length}},h=(t,s,a)=>{const e=new Map;for(const{doc:o,id:n}of m(t,s,void 0))e.set(n,d(l({...o,_id:n},a)));return e},_=async(t,s,a,e)=>{const o=h(t,e.table,e.columns);return x(s,a,o,e)};export{x as materializeExternalRows,R as materializeExternalRowsIncremental,h as readExternalSourceBaseline,_ as runExternalSourceTick};
1
+ import{applyCdcChanges as p}from"./CDC_LOG_TABLE-B58N8NQO.mjs";import{selectShapeRows as m}from"./selectShapeMemberIds-B-pQJHAu.mjs";import{diffExternalSource as g,projectExternalSourceRow as l}from"./diffExternalSource-DbHrcoZK.mjs";import{stableStringify as d}from"./stableStringify-G9OF5wcs.mjs";const x=async(t,s,a,e)=>{const{changes:o,nextBaseline:n}=g(s,a,e);return await p(t,o),{applied:o.length,nextBaseline:n}},R=async(t,s,a)=>{const{columns:e,deletedIds:o,table:n}=a,r=[];for(const f of s){const i=l(f,e),c=String(i._id);if(o?.has(c)){await t.get(c,n)&&r.push({id:c,op:"delete",seq:0,table:n,ts:0});continue}const u=await t.get(c,n);u&&d(l({...u,_id:c},e))===d(i)||r.push({doc:i,id:c,op:"insert",seq:0,table:n,ts:0})}return await p(t,r),{applied:r.length}},h=(t,s,a)=>{const e=new Map;for(const{doc:o,id:n}of m(t,s,void 0))e.set(n,d(l({...o,_id:n},a)));return e},_=async(t,s,a,e)=>{const o=h(t,e.table,e.columns);return x(s,a,o,e)};export{x as materializeExternalRows,R as materializeExternalRowsIncremental,h as readExternalSourceBaseline,_ as runExternalSourceTick};
@@ -0,0 +1 @@
1
+ const f=(t,n)=>t<n?-1:t>n?1:0,s=t=>{if(t===void 0)return"null";if(typeof t=="bigint")throw new TypeError("stableStringify: cannot use a bigint in a stable JSON cache key — pass it as a string, or use stableWireKey");if(typeof t=="number"){if(Number.isNaN(t))return"nan";if(t===1/0)return"inf";if(t===-1/0)return"-inf";if(Object.is(t,-0))return"-0"}if(t===null||typeof t!="object")return JSON.stringify(t);if(Array.isArray(t))return`[${t.map(r=>s(r)).join(",")}]`;const n=Object.getPrototypeOf(t);if(n!==null&&n!==Object.prototype){const r=t.constructor?.name??"value";throw new TypeError(`stableStringify: cannot use a ${r} in a stable JSON cache key — only plain objects, arrays, and JSON primitives are supported (wire-typed values key via stableWireKey)`)}const i=t,y=Object.keys(i).toSorted(f),e=[];for(const r of y){const o=i[r];o!==void 0&&e.push(`${JSON.stringify(r)}:${s(o)}`)}return`{${e.join(",")}}`};export{s as stableStringify};
@@ -1 +1 @@
1
- import{stableStringify as r}from"./stableStringify-CujpENIO.mjs";import{e as o}from"./wire-codec-BU9T2xJ7.mjs";const m=e=>r(o(e));export{m as stableWireKey};
1
+ import{stableStringify as r}from"./stableStringify-G9OF5wcs.mjs";import{e as o}from"./wire-codec-BU9T2xJ7.mjs";const m=e=>r(o(e));export{m as stableWireKey};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/shard-engine",
3
- "version": "1.0.0-alpha.30",
3
+ "version": "1.0.0-alpha.31",
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",
@@ -49,7 +49,7 @@
49
49
  },
50
50
  "dependencies": {
51
51
  "@lunora/errors": "1.0.0-alpha.22",
52
- "@lunora/platform": "1.0.0-alpha.13",
52
+ "@lunora/platform": "1.0.0-alpha.14",
53
53
  "drizzle-orm": "^0.45.2"
54
54
  },
55
55
  "engines": {
@@ -1 +0,0 @@
1
- const y=(t,e)=>t<e?-1:t>e?1:0,s=t=>{if(t===void 0)return"null";if(typeof t=="bigint")throw new TypeError("stableStringify: cannot use a bigint in a stable JSON cache key — pass it as a string, or use stableWireKey");if(t===null||typeof t!="object")return JSON.stringify(t);if(Array.isArray(t))return`[${t.map(r=>s(r)).join(",")}]`;const e=Object.getPrototypeOf(t);if(e!==null&&e!==Object.prototype){const r=t.constructor?.name??"value";throw new TypeError(`stableStringify: cannot use a ${r} in a stable JSON cache key — only plain objects, arrays, and JSON primitives are supported (wire-typed values key via stableWireKey)`)}const n=t,c=Object.keys(n).toSorted(y),o=[];for(const r of c){const i=n[r];i!==void 0&&o.push(`${JSON.stringify(r)}:${s(i)}`)}return`{${o.join(",")}}`};export{s as stableStringify};