@lunora/shard-engine 1.0.0-alpha.53 → 1.0.0-alpha.55

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.
Files changed (47) hide show
  1. package/dist/conformance/index.mjs +1 -1
  2. package/dist/index.d.mts +14 -5
  3. package/dist/index.d.ts +14 -5
  4. package/dist/index.mjs +1 -1
  5. package/dist/packem_shared/{ADMIN_FUNCTIONS-Jsbz35Pz.mjs → ADMIN_FUNCTIONS-PfT6efQf.mjs} +1 -1
  6. package/dist/packem_shared/{AGG_COUNT-FqmOn0fB.mjs → AGG_COUNT-D0supEvF.mjs} +1 -1
  7. package/dist/packem_shared/{CDC_LOG_TABLE-DVUFJikx.mjs → CDC_LOG_TABLE-DELonHMe.mjs} +4 -4
  8. package/dist/packem_shared/{CURSOR_PREFIX-B1i1J8Zi.mjs → CURSOR_PREFIX-BoaSx8bs.mjs} +1 -1
  9. package/dist/packem_shared/{DATA_MIGRATION_STATE_TABLE-Jrx6cqEc.mjs → DATA_MIGRATION_STATE_TABLE-CO1FLIVO.mjs} +1 -1
  10. package/dist/packem_shared/{DEFAULT_MAX_RELATION_KEYS-BbmpfQE4.mjs → DEFAULT_MAX_RELATION_KEYS-Zf2Yn4YT.mjs} +1 -1
  11. package/dist/packem_shared/DEFAULT_MAX_RELAYS-DlyTtTEl.mjs +8 -0
  12. package/dist/packem_shared/{DEFAULT_PROMOTION_THRESHOLDS-CrzPqmGP.mjs → DEFAULT_PROMOTION_THRESHOLDS-BewDXVhw.mjs} +1 -1
  13. package/dist/packem_shared/{DurableStreamRunner-Ds3cmo3F.mjs → DurableStreamRunner-prbsN-c8.mjs} +1 -1
  14. package/dist/packem_shared/MAX_SQL_ROWS-CY5qwGU3.mjs +4 -0
  15. package/dist/packem_shared/{NotUniqueError-BdMwMt_A.mjs → NotUniqueError-jtPeUPmD.mjs} +1 -1
  16. package/dist/packem_shared/{RANK_TIEBREAK-DGlhcKKv.mjs → RANK_TIEBREAK-CWCVFaq_.mjs} +1 -1
  17. package/dist/packem_shared/{ReactiveCache-C8Y0FuN8.mjs → ReactiveCache-DpfLbuFX.mjs} +1 -1
  18. package/dist/packem_shared/{ShapeDiffCache-BmVH30dI.mjs → ShapeDiffCache-DOTafqGL.mjs} +1 -1
  19. package/dist/packem_shared/{aggregateTableName-CCCIulmn.mjs → aggregateTableName-qWuEmkPn.mjs} +1 -1
  20. package/dist/packem_shared/appendStreamChunk-C1Ok4b6J.mjs +19 -0
  21. package/dist/packem_shared/{applyOnDelete-CeHLU-Hh.mjs → applyOnDelete-CYV38T1y.mjs} +1 -1
  22. package/dist/packem_shared/{awaitWsDrain-BqSGNI0W.mjs → awaitWsDrain-CPihRl1x.mjs} +1 -1
  23. package/dist/packem_shared/{backfillAggregateIndexes-vSnbgww7.mjs → backfillAggregateIndexes-T3lmKtDf.mjs} +1 -1
  24. package/dist/packem_shared/{buildPokeFrames-CySyxldi.mjs → buildPokeFrames-p3hk61w7.mjs} +1 -1
  25. package/dist/packem_shared/{buildReprojectionMigration-CD97i4QW.mjs → buildReprojectionMigration-HbwBP2Xx.mjs} +1 -1
  26. package/dist/packem_shared/{buildShapeDiff-BcSSPYR8.mjs → buildShapeDiff-BNRhEpVK.mjs} +1 -1
  27. package/dist/packem_shared/{computeRankPage-BjcLdI-1.mjs → computeRankPage-BSxeZLfg.mjs} +1 -1
  28. package/dist/packem_shared/createCompanionSync-D4VL_kWa.mjs +1 -0
  29. package/dist/packem_shared/{createReplicaLink-BtUkvhFo.mjs → createReplicaLink-B4cdZv8z.mjs} +1 -1
  30. package/dist/packem_shared/{ctx-db-companions-QC15-pzG.mjs → ctx-db-companions-CPMFTDV1.mjs} +1 -1
  31. package/dist/packem_shared/{ctx-db-relay-shapes-B4bmET4W.mjs → ctx-db-relay-shapes-1gdkHCG2.mjs} +1 -1
  32. package/dist/packem_shared/defineEngineContractSuite-Dtb4oupe.mjs +1 -0
  33. package/dist/packem_shared/{do-sql-A80W5VLt.mjs → do-sql-By2TU17Q.mjs} +1 -1
  34. package/dist/packem_shared/{isSoftDeleted-DVEZ9xVv.mjs → isSoftDeleted-q1fob5XF.mjs} +1 -1
  35. package/dist/packem_shared/{materializeExternalRows-a5CvNwTW.mjs → materializeExternalRows-Dk3HhwxL.mjs} +1 -1
  36. package/dist/packem_shared/{runShardMigrations-DtD-pA0_.mjs → runShardMigrations-56dKx7Jq.mjs} +1 -1
  37. package/dist/packem_shared/{selectExpiredIds-Dbwd__6n.mjs → selectExpiredIds-CZ-ABXDQ.mjs} +1 -1
  38. package/dist/packem_shared/{selectShapeMembers-9Jz7ec_-.mjs → selectShapeMembers-g5Fqi2XK.mjs} +1 -1
  39. package/dist/packem_shared/{stableWireKey-CSJKu_ID.mjs → stableWireKey-iezqS3-d.mjs} +1 -1
  40. package/dist/packem_shared/wire-codec-Cu_2ZASD.mjs +1 -0
  41. package/package.json +3 -3
  42. package/dist/packem_shared/DEFAULT_MAX_RELAYS-BAJHxoe-.mjs +0 -1
  43. package/dist/packem_shared/MAX_SQL_ROWS-DOEw2HBt.mjs +0 -4
  44. package/dist/packem_shared/appendStreamChunk-8eH4HB1Q.mjs +0 -19
  45. package/dist/packem_shared/createCompanionSync-BtNrMh1X.mjs +0 -1
  46. package/dist/packem_shared/defineEngineContractSuite-1aM30yIJ.mjs +0 -1
  47. package/dist/packem_shared/wire-codec-UyQIjlyN.mjs +0 -1
@@ -1 +1 @@
1
- import{sql as e}from"drizzle-orm";import{runDrizzle as m}from"./runDrizzle-2ULFQR_k.mjs";import{D as p,r as d,e as h}from"./do-sql-A80W5VLt.mjs";import{sqliteInList as w}from"./param-DlozcSQu.mjs";import{c as S}from"./where-sql-B1l5NcUZ.mjs";import{serializeSqlValue as $}from"./serializeSqlValue-B_-zaEWZ.mjs";const C={fieldRef:h,serialize:$},g=o=>{if(o.length!==0)return w(e`${e.identifier("id")}`,o,!1)},u=(o,i)=>{const r=[];i&&r.push(i);const t=S(o,C);return t&&r.push(t),r.length===0?e``:e` WHERE ${e.join(r,e` AND `)}`},v=(o,i,r)=>{const t=u(r,void 0),s=m(o,e`SELECT id, _creationTime, ${e.identifier(p)} FROM ${e.identifier(i)}${t}`).toArray(),f=[];for(const l of s){const n=d(l),{id:c}=l;n!==void 0&&typeof c=="string"&&f.push({doc:n,id:c})}return f},z=(o,i,r,t)=>{const s=new Map;if(t.length===0)return s;const f=u(r,g(t)),l=m(o,e`SELECT id, _creationTime, ${e.identifier(p)} FROM ${e.identifier(i)}${f}`).toArray();for(const n of l){const c=d(n),{id:a}=n;c!==void 0&&typeof a=="string"&&s.set(a,c)}return s};export{z as selectShapeMembers,v as selectShapeRows};
1
+ import{sql as e}from"drizzle-orm";import{runDrizzle as m}from"./runDrizzle-2ULFQR_k.mjs";import{D as p,r as d,e as h}from"./do-sql-By2TU17Q.mjs";import{sqliteInList as w}from"./param-DlozcSQu.mjs";import{c as S}from"./where-sql-B1l5NcUZ.mjs";import{serializeSqlValue as $}from"./serializeSqlValue-B_-zaEWZ.mjs";const C={fieldRef:h,serialize:$},g=o=>{if(o.length!==0)return w(e`${e.identifier("id")}`,o,!1)},u=(o,i)=>{const r=[];i&&r.push(i);const t=S(o,C);return t&&r.push(t),r.length===0?e``:e` WHERE ${e.join(r,e` AND `)}`},v=(o,i,r)=>{const t=u(r,void 0),s=m(o,e`SELECT id, _creationTime, ${e.identifier(p)} FROM ${e.identifier(i)}${t}`).toArray(),f=[];for(const l of s){const n=d(l),{id:c}=l;n!==void 0&&typeof c=="string"&&f.push({doc:n,id:c})}return f},z=(o,i,r,t)=>{const s=new Map;if(t.length===0)return s;const f=u(r,g(t)),l=m(o,e`SELECT id, _creationTime, ${e.identifier(p)} FROM ${e.identifier(i)}${f}`).toArray();for(const n of l){const c=d(n),{id:a}=n;c!==void 0&&typeof a=="string"&&s.set(a,c)}return s};export{z as selectShapeMembers,v as selectShapeRows};
@@ -1 +1 @@
1
- import{stableStringify as r}from"./stableStringify-DibjylKD.mjs";import{e as o}from"./wire-codec-UyQIjlyN.mjs";const m=e=>r(o(e));export{m as stableWireKey};
1
+ import{stableStringify as r}from"./stableStringify-DibjylKD.mjs";import{e as o}from"./wire-codec-Cu_2ZASD.mjs";const m=e=>r(o(e));export{m as stableWireKey};
@@ -0,0 +1 @@
1
+ import{t as g,f as j}from"./base64-DfpzS4o_.mjs";const o="$lunora.wire$",d=64,p=1024,w="__proto__",A={BigInt64Array,BigUint64Array,Float32Array,Float64Array,Int8Array,Int16Array,Int32Array,Uint8Array,Uint8ClampedArray,Uint16Array,Uint32Array},E={Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError},O=r=>{if(r===null||typeof r!="object")return!1;const t=Object.getPrototypeOf(r);return t===null||t===Object.prototype},l=(r,t=0)=>{if(t>d)return!0;if(r===null)return!1;const f=typeof r;if(f==="string"||f==="boolean")return!1;if(f==="number")return!Number.isFinite(r);if(f!=="object")return!0;if(Array.isArray(r))return r.length>0&&r[0]===o?!0:r.some(a=>a===void 0||l(a,t+1));if(!O(r)||Object.hasOwn(r,w))return!0;for(const a of Object.keys(r)){const i=r[a];if(i!==void 0&&l(i,t+1))return!0}return!1},u=(r,t=0)=>{if(t>d)throw new RangeError(`wire-codec: value nesting exceeds the ${d}-level limit`);if(r===void 0)return[o,"undefined"];if(r===null)return null;const f=typeof r;if(f==="bigint")return[o,"bigint",r.toString()];if(f==="number"){const e=r;return Number.isNaN(e)?[o,"nan"]:e===1/0?[o,"inf"]:e===-1/0?[o,"-inf"]:e}if(f!=="object")return r;if(r instanceof Date)return[o,"date",u(r.getTime(),t+1)];if(r instanceof Error){const e=r,n={};for(const c of Object.keys(e))e[c]!==void 0&&(n[c]=u(e[c],t+1));const s=[o,"error",e.name,e.message,n];return e.cause!==void 0&&s.push(u(e.cause,t+1)),s}if(r instanceof URL)return[o,"url",r.href];if(r instanceof Map)return[o,"map",[...r.entries()].map(([e,n])=>[u(e,t+1),u(n,t+1)])];if(r instanceof Set)return[o,"set",[...r].map(e=>u(e,t+1))];if(r instanceof ArrayBuffer)return[o,"bytes",g(new Uint8Array(r)),"ArrayBuffer"];if(ArrayBuffer.isView(r)){const e=r,n=e.constructor.name,s=new Uint8Array(e.buffer,e.byteOffset,e.byteLength);return n==="Uint8Array"?[o,"bytes",g(s)]:[o,"bytes",g(s),n]}if(Array.isArray(r)){const e=r.map(n=>u(n,t+1));return e.length>0&&e[0]===o?[o,"arr",e]:e}if(!O(r)){const e=r.constructor?.name??"value";throw new TypeError(`wire-codec: cannot encode a ${e} over the Lunora wire — only plain objects, arrays, and the supported built-ins (Date, Error, URL, Map, Set, ArrayBuffer/typed arrays, bigint) round-trip`)}const a=r,i={};for(const e of Object.keys(a)){const n=a[e];if(n===void 0)continue;const s=u(n,t+1);e===w?Object.defineProperty(i,e,{configurable:!0,enumerable:!0,value:s,writable:!0}):i[e]=s}return i},y=(r,t=0)=>{if(t>d)throw new RangeError(`wire-codec: value nesting exceeds the ${d}-level limit`);if(r===null||typeof r!="object")return r;if(Array.isArray(r)){if(r[0]===o)switch(r[1]){case"-inf":return-1/0;case"arr":return r[2].map(e=>y(e,t+1));case"bigint":{const e=r[2];if(typeof e!="string"||e.length>p||!/^-?\d+$/.test(e))throw new RangeError(`wire-codec: invalid or over-long bigint (max ${p} digits)`);return BigInt(e)}case"date":{const e=y(r[2],t+1);if(typeof e!="number")throw new TypeError("wire-codec: malformed date — epoch must be a number");return new Date(e)}case"map":{const e=r[2];return new Map(e.map(n=>{if(!Array.isArray(n)||n.length!==2)throw new TypeError("wire-codec: malformed map entry — expected a [key, value] pair");return[y(n[0],t+1),y(n[1],t+1)]}))}case"set":return new Set(r[2].map(e=>y(e,t+1)));case"url":{const e=r[2];if(typeof e!="string")throw new TypeError("wire-codec: malformed url — href must be a string");return new URL(e)}case"error":{const e=r[2],n=r[3],s=(Object.hasOwn(E,e)?E[e]:void 0)??Error,c=new s(n);c.name!==e&&Object.defineProperty(c,"name",{configurable:!0,value:e,writable:!0});const b=y(r[4],t+1);if(b===null||typeof b!="object"||Array.isArray(b))throw new TypeError("wire-codec: malformed error — props must be an object");for(const m of Object.keys(b))m===w?Object.defineProperty(c,m,{configurable:!0,enumerable:!0,value:b[m],writable:!0}):c[m]=b[m];return r.length>5&&Object.defineProperty(c,"cause",{configurable:!0,value:y(r[5],t+1),writable:!0}),c}case"bytes":{const e=r[2];if(typeof e!="string")throw new TypeError("wire-codec: malformed bytes — payload must be a base64 string");const n=j(e),s=r[3]??"Uint8Array";if(s==="ArrayBuffer")return n.buffer.byteLength===n.byteLength?n.buffer:n.slice().buffer;const c=Object.hasOwn(A,s)?A[s]:void 0;return c?new c(n.slice().buffer):n}case"inf":return 1/0;case"nan":return Number.NaN;case"undefined":return;default:return r.map(e=>y(e,t+1))}return r.map(i=>y(i,t+1))}const f=r,a={};for(const i of Object.keys(f)){const e=y(f[i],t+1);i===w?Object.defineProperty(a,i,{configurable:!0,enumerable:!0,value:e,writable:!0}):a[i]=e}return a};export{y as d,u as e,O as i,l as n};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/shard-engine",
3
- "version": "1.0.0-alpha.53",
3
+ "version": "1.0.0-alpha.55",
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",
@@ -48,8 +48,8 @@
48
48
  "access": "public"
49
49
  },
50
50
  "dependencies": {
51
- "@lunora/errors": "1.0.0-alpha.30",
52
- "@lunora/platform": "1.0.0-alpha.25",
51
+ "@lunora/errors": "1.0.0-alpha.31",
52
+ "@lunora/platform": "1.0.0-alpha.26",
53
53
  "drizzle-orm": "^0.45.2"
54
54
  },
55
55
  "engines": {
@@ -1 +0,0 @@
1
- import{toErrorBody as L,LunoraError as M}from"@lunora/errors";import{e as T,d as I}from"./wire-codec-UyQIjlyN.mjs";import{d as k,w as _,a as v,m as N,r as O,b as D,c as F}from"./ctx-db-relay-shapes-B4bmET4W.mjs";import{envPositiveInt as R}from"./envOptionalPositiveInt-D2pY-c64.mjs";import{relayName as f,DEFAULT_PROMOTION_THRESHOLDS as w,nextPromotionState as U,shapeRoutingKey as b,relayProxyKey as E,parseRelayName as K,clampPromotionThresholds as W}from"./DEFAULT_PROMOTION_THRESHOLDS-CrzPqmGP.mjs";import{encodeRowsPatch as Y,buildPokeFrames as P}from"./buildPokeFrames-CySyxldi.mjs";import{v as B,R as A,s as H,a as $,b as j}from"./sibling-channel-Cxvk0Zca.mjs";import{awaitWsDrain as z,trySendFrame as x}from"./awaitWsDrain-BqSGNI0W.mjs";import{stableWireKey as S}from"./stableWireKey-CSJKu_ID.mjs";const G=2,X=8,g={},q=l=>{throw new M("INTERNAL",`unhandled relay frame: ${JSON.stringify(l)}`)},J=(l,e)=>l===void 0||l.epoch!==e.epoch?!1:l.cursor>=e.fromCursor&&l.cursor<e.checkpoint,V=l=>Response.json(l,{headers:{"content-type":"application/json"}}),p=()=>new Response(null,{status:204});class C{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 B(this.host.env(),e.headers.get(A),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),p();case"relay_detach":return this.onDetach(s.relayIndex),p();case"relay_frame":return this.host.deliverWhisperLocal(s.topic,s.frame,void 0),await this.onWhisperFrame(s),p();case"relay_shape_poke":{const r=this.host.getWebSockets().length,o=Date.now(),n=this.onShapePoke({...s,args:I(s.args)});return this.host.recordShapePokeFanout(r,n,Date.now()-o),p()}case"relay_shape_subscribe":return V(this.onShapeSubscribe({...s,args:I(s.args)}));case"relay_shape_unsubscribe":return this.onShapeUnsubscribe(s),p();default:return q(s)}}maxRelays(){return R(this.host.env(),"LUNORA_MAX_RELAYS",X)}canAddressSiblings(){return this.siblingStub(this.roleId.ownerKey)!==void 0}siblingStub(e){return H(this.host.env(),this.bindingName(),e)}bindingName(){return this.host.shardBinding()}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()??""},n=$(this.host.env());n!==void 0&&(o[A]=await j(n,r));try{return await s.fetch("https://relay.internal/_lunora/relay",{body:r,headers:o,method:"POST"})}catch{return}}}class Q extends C{shapeUniformCache=new Map;relaySetCache;registryCache;recordedBinding;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(f(this.roleId.ownerKey,r),{frame:t,topic:e,type:"relay_frame"})))}async onFlush(e,t){this.canAddressSiblings()&&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()}releaseRelayShapes(){return Promise.resolve()}relayCount(){const e=this.host.getWebSockets().length,t=R(this.host.env(),"LUNORA_RELAY_THRESHOLD",w.tUp),s=R(this.host.env(),"LUNORA_RELAY_COLLAPSE_THRESHOLD",w.tDown);if(this.promotionState=U(this.promotionState,e,W(t,s)),this.promotionState==="owned")return 0;const r=R(this.host.env(),"LUNORA_RELAY_FAN",G);return Math.min(this.maxRelays(),Math.max(1,r))}minShapeCursor(){const{cohort:e,proxies:t}=this.relayShapes();let s;for(const r of[...e.values(),...t.values()])s=s===void 0?r.cursor:Math.min(s,r.cursor);return s}isShapeRelayUniform(e,t){const s=b(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}onShapeUnsubscribe(e){const{proxies:t}=this.relayShapes(),s=e.subId===void 0?void 0:E(e.relayIndex,e.connectionId,e.subId);for(const[r,o]of t)o.relayIndex!==e.relayIndex||o.connectionId!==e.connectionId||(s===void 0||r===s)&&t.delete(r);k(this.host.sql(),e.relayIndex,e.connectionId,e.subId)}onAttach(e){this.addRelayToSet(e)}onDetach(e){this.removeRelayFromSet(e)}async onWhisperFrame(e){await Promise.all([...this.ownerRelaySet()].filter(t=>t!==e.originRelay).map(t=>this.postRelayMessage(f(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 n;try{n=this.host.resolveShape(e.name,e.args,t)}catch{return}if(n===void 0||n.global===!0||!s.has(n.table))return;const i=e,h=i.cursor,a=this.host.buildShapeDiff(n,h,r);if(a.length!==0)return i.cursor=r,_(this.host.sql(),i.key,r),{args:T(e.args),checkpoint:r,epoch:o,fromCursor:h,name:e.name,rowsPatch:Y(a),type:"relay_shape_poke"}}async multicastShapePokes(e,t){const s=this.ownerRelaySet();if(s.size===0)return;const{cohort:r}=this.relayShapes();if(r.size===0)return;const o=this.host.currentCdcEpoch(),n=[];for(const i of r.values()){const h=this.buildShapePoke(i,g,e,t,o);h&&n.push(this.multicastToRelays(s,h,i))}await Promise.all(n)}async multicastToRelays(e,t,s){(await Promise.all([...e].map(async o=>(await this.requestRelayMessage(f(this.roleId.ownerKey,o),t))?.ok===!0))).includes(!1)&&this.rewindShapeCursor(s,t.fromCursor)}async proxyShapePokes(e,t){if(this.ownerRelaySet().size===0)return;const{proxies:s}=this.relayShapes();if(s.size===0)return;const r=this.host.currentCdcEpoch(),o=[];for(const n of s.values()){const i=this.buildShapePoke(n,n.identity,e,t,r);i&&o.push(this.proxyToRelay(i,n))}await Promise.all(o)}async proxyToRelay(e,t){(await this.requestRelayMessage(f(this.roleId.ownerKey,t.relayIndex),{...e,targetConnectionId:t.connectionId}))?.ok!==!0&&this.rewindShapeCursor(t,e.fromCursor)}buildShapeSeedFrames(e){const t={identity:e.identity,userId:e.userId};let s;try{s=this.host.resolveShape(e.name,e.args,t)}catch(c){const{body:u}=L(c,{fallbackCode:"SHAPE_RESOLVE_FAILED",redactedMessage:"shape resolution failed"});return{error:{code:u.code,message:u.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:n,reset:i,rowsPatch:h}=this.host.computeOpLogShapeSeed({args:e.args,name:e.name,sinceEpoch:e.sinceEpoch,sinceSeq:e.sinceSeq},s);let a=o;const{cohort:d,proxies:m}=this.relayShapes();if(this.isShapeRelayUniform(e.name,e.args)){const c=b(e.name,e.args);let u=d.get(c);u===void 0&&(u={args:e.args,cursor:o,key:c,name:e.name},d.set(c,u),v(this.host.sql(),u)),a=u.cursor}else if(e.relayIndex!==void 0&&e.connectionId!==void 0){const c=E(e.relayIndex,e.connectionId,e.subId),u={args:e.args,connectionId:e.connectionId,cursor:o,identity:t,key:c,name:e.name,relayIndex:e.relayIndex};m.set(c,u),v(this.host.sql(),u)}else return{error:{code:"RELAY_SHAPE_UNROUTABLE",message:`shape ${e.name} is per-socket on a relay, but the subscribe carries no ${e.relayIndex===void 0?"relay index":"connection id"}`}};const y=P([{reset:i,rowsPatch:h,shapeId:e.subId}],{baseCheckpoint:r,checkpoint:a,epoch:n,lastMutationId:void 0,pokeId:this.host.nextPokeId()});return{cursor:a,epoch:n,frames:y}}ensureRelayTables(){this.host.sql().exec("CREATE TABLE IF NOT EXISTS __lunora_relays (idx INTEGER PRIMARY KEY)"),this.host.sql().exec("CREATE TABLE IF NOT EXISTS __lunora_relay_binding (id INTEGER PRIMARY KEY, binding TEXT NOT NULL)"),N(this.host.sql())}bindingName(){const e=this.host.shardBinding();if(e!==void 0&&e!=="")return e!==this.recordedBinding&&(this.recordedBinding=e,this.ensureRelayTables(),this.host.sql().exec("INSERT INTO __lunora_relay_binding (id, binding) VALUES (1, ?) ON CONFLICT(id) DO UPDATE SET binding = excluded.binding",e)),e;if(this.recordedBinding!==void 0)return this.recordedBinding;try{const t=this.host.sql().exec("SELECT binding FROM __lunora_relay_binding WHERE id = 1").toArray();this.recordedBinding=t[0]?.binding}catch{this.recordedBinding=void 0}return this.recordedBinding}relayShapes(){const e=this.registryCache;if(e!==void 0)return e;this.ensureRelayTables();const t={cohort:new Map,proxies:new Map};for(const s of O(this.host.sql()))s.relayIndex===void 0||s.connectionId===void 0?t.cohort.set(s.key,{args:s.args,cursor:s.cursor,key:s.key,name:s.name}):t.proxies.set(s.key,{args:s.args,connectionId:s.connectionId,cursor:s.cursor,identity:s.identity??{},key:s.key,name:s.name,relayIndex:s.relayIndex});return this.registryCache=t,t}rewindShapeCursor(e,t){const s=e;s.cursor<=t||(s.cursor=t,_(this.host.sql(),s.key,t))}ownerRelaySet(){if(this.relaySetCache===void 0){this.ensureRelayTables();const e=this.host.sql().exec("SELECT idx FROM __lunora_relays").toArray();this.relaySetCache=new Set(e.map(t=>Number(t.idx)))}return this.relaySetCache}addRelayToSet(e){this.ensureRelayTables(),this.host.sql().exec("INSERT OR IGNORE INTO __lunora_relays (idx) VALUES (?)",e),this.ownerRelaySet().add(e)}removeRelayFromSet(e){this.ensureRelayTables(),this.host.sql().exec("DELETE FROM __lunora_relays WHERE idx = ?",e);const t=this.ownerRelaySet();t.delete(e);const{cohort:s,proxies:r}=this.relayShapes();for(const[o,n]of r)n.relayIndex===e&&r.delete(o);D(this.host.sql(),e),t.size===0&&(s.clear(),this.shapeUniformCache.clear(),F(this.host.sql()))}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(a=>a.on==="read"&&a.table===s.table)||this.tableHasAnyMask(s.table))return!1;const r=S(s.effectiveWhere),o=S(s.columns);let n=!1;const i=a=>{const d={groups:[`grp_${a}`],roles:[a],sub:`__lunora_probe_${a}__`};return{identity:new Proxy(d,{get:(y,c)=>typeof c=="symbol"||c in y?Reflect.get(y,c):`${a}:${c}`,getOwnPropertyDescriptor:(y,c)=>(n=!0,Reflect.getOwnPropertyDescriptor(y,c)),has:(y,c)=>typeof c=="symbol"?Reflect.has(y,c):!0,ownKeys:y=>(n=!0,Reflect.ownKeys(y))}),userId:`__lunora_probe_${a}__`}};return[g,i("a"),i("b")].every(a=>{let d;try{d=this.host.resolveShape(e,t,a)}catch{return!1}return d!==void 0&&d.global!==!0&&d.table===s.table&&S(d.effectiveWhere)===r&&S(d.columns)===o})&&!n}tableHasAnyMask(e){return this.host.maskMetadata().columns.some(t=>t.table===e)}}class Z extends C{relayAnnounced=!1;shapeRelayMemos=new WeakMap;shapeControl=new Map;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"};const{connectionId:o}=this.host.readAttachment(e),n={args:T(s.args??{}),connectionId:o,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},i=await this.queueShapeControl(o,async()=>(await this.announce(),this.requestRelayMessage(this.roleId.ownerKey,n)));if(i===void 0)return{code:"RELAY_SEED_FAILED",message:"owner did not answer the shape seed"};let h;try{h=await i.json()}catch{return{code:"RELAY_SEED_FAILED",message:"malformed shape seed from owner"}}if(h.error!==void 0)return h.error;if(h.frames===void 0)return{code:"RELAY_SEED_FAILED",message:"owner returned no shape frames"};await z(e);for(const a of h.frames)x(e,a);return this.recordRelayShapeMemo(e,t,h.cursor??0,h.epoch),"ok"}async announce(){if(this.relayAnnounced||!this.canAddressSiblings())return;this.relayAnnounced=!0,(await this.requestRelayMessage(this.roleId.ownerKey,{relayIndex:this.roleId.relayIndex,type:"relay_attach"}))?.ok||(this.relayAnnounced=!1)}async announceDrain(e){this.canAddressSiblings()&&(this.host.getWebSockets().some(t=>t!==e)||(this.relayAnnounced=!1,await this.postRelayMessage(this.roleId.ownerKey,{relayIndex:this.roleId.relayIndex,type:"relay_detach"})))}async releaseRelayShapes(e,t){const{connectionId:s}=this.host.readAttachment(e);s===void 0||!this.canAddressSiblings()||await this.queueShapeControl(s,async()=>this.postRelayMessage(this.roleId.ownerKey,{connectionId:s,relayIndex:this.roleId.relayIndex,...t===void 0?{}:{subId:t},type:"relay_shape_unsubscribe"}))}relayCount(){return 0}isShapeRelayUniform(){return!1}minShapeCursor(){}onAttach(){}onDetach(){}onWhisperFrame(){return Promise.resolve()}onShapeSubscribe(){return{error:{code:"RELAY_CANNOT_SEED",message:"a relay has no op-log to seed from"}}}onShapeUnsubscribe(){}onShapePoke(e){return this.deliverShapePoke(e)}async queueShapeControl(e,t){if(e===void 0)return t();const s=(this.shapeControl.get(e)??Promise.resolve()).then(t,t),r={},o=()=>{this.shapeControl.get(e)===r.chain&&this.shapeControl.delete(e)},n=s.then(o,o);return r.chain=n,this.shapeControl.set(e,n),s}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=b(e.name,e.args);let s=0;for(const r of this.host.getWebSockets()){const o=this.host.readAttachment(r),{shapes:n}=o,i=this.shapeRelayMemos.get(r);if(!(n===void 0||i===void 0)&&!(e.targetConnectionId!==void 0&&o.connectionId!==e.targetConnectionId))for(const[h,a]of Object.entries(n)){const d=i.get(h);if(b(a.name,a.args)!==t||!J(d,e))continue;const m=P([{baseCheckpoint:d?.cursor,rowsPatch:e.rowsPatch,shapeId:h}],{baseCheckpoint:void 0,checkpoint:e.checkpoint,epoch:e.epoch,lastMutationId:void 0,pokeId:this.host.nextPokeId()},{preEncoded:!0});for(const y of m)x(r,y);i.set(h,{cursor:e.checkpoint,epoch:e.epoch}),s+=1}}return s}}const ce=l=>{const e=l.doName();if(e===void 0)return;const t=K(e);return t===void 0?new Q(l,e):new Z(l,t.ownerKey,t.relayIndex)};export{X as DEFAULT_MAX_RELAYS,Q as OwnerRelay,Z as RelayMember,ce as createRelayLink};
@@ -1,4 +0,0 @@
1
- import{LunoraError as h}from"@lunora/errors";const l="x",E={'"':'"',"'":"'","[":"]","`":"`"},f=(n,t)=>{let e=t+2;for(;e<n.length&&n[e]!==`
2
- `;)e+=1;return e},u=(n,t)=>{const e=n.indexOf("*/",t+2);return e===-1?-1:e+2},m=n=>{const t=n.split("");let e=0;for(;e<n.length;){const s=n[e]??"",c=E[s];if(s==="-"&&n[e+1]==="-"){const o=f(n,e);t.fill(l,e,o),e=o}else if(s==="/"&&n[e+1]==="*"){const o=u(n,e);if(o===-1)return;t.fill(l,e,o),e=o}else if(c!==void 0){let o=e+1;for(;o<n.length;)if(n[o]!==c)o+=1;else if(c!=="]"&&n[o+1]===c)o+=2;else break;if(o>=n.length)return;t.fill(l,e,o+1),e=o+1}else e+=1}for(let s=0;s<n.length;s+=1)n[s]===`
3
- `&&(t[s]=`
4
- `);return t.join("")},S=/^(?:explain\s+(?:query\s+plan\s+)?)?(?:select|with)\b/iu,L=/\b(?:alter|attach|create|delete|detach|drop|insert|pragma|reindex|replace|truncate|update|vacuum)\b/iu,p=/^\w+/u,A=/;\s*$/u,N=/\s/u,x=n=>{let t=0;for(;t<n.length;){const e=n[t];if(e!==void 0&&N.test(e))t+=1;else if(e==="-"&&n[t+1]==="-")t=f(n,t);else if(e==="/"&&n[t+1]==="*"){const s=u(n,t);if(s===-1)break;t=s}else break}return t},g=n=>{const t=x(n),e=n.slice(t).trimEnd();if(e==="")return{code:"SQL_EMPTY",message:"the query is empty"};const s=e.replace(A,""),c=(m(s)??s).indexOf(";");if(c!==-1)return{code:"SQL_MULTIPLE_STATEMENTS",length:1,message:"only a single statement may be run",offset:t+c};const o="the SQL editor is read-only — only SELECT / WITH / EXPLAIN queries are allowed";if(!S.test(s))return{code:"SQL_NOT_READONLY",length:p.exec(s)?.[0].length??1,message:o,offset:t};const r=L.exec(s);if(r!==null)return{code:"SQL_NOT_READONLY",length:r[0].length,message:`${o} (\`${r[0].toUpperCase()}\` is not allowed)`,offset:t+r.index}},d=1e3,y=n=>{const t=g(n);if(t!==void 0)throw new h(t.code,t.message,{status:400})},w=(n,t)=>{y(t);const e=n.exec(t).toArray(),s=e.length>d?e.slice(0,d):e;return{columns:s.length>0?Object.keys(s[0]):[],rowCount:e.length,rows:s,truncated:e.length>d}},O=/near "([^"]*)": syntax error/iu,T=/^SCAN (?:TABLE )?(?!CONSTANT\b|SUBQUERY\b)([^\s(]+)/u,_=(n,t)=>{if(t==="")return{};const e=n.indexOf(t);return e===-1?{}:{length:t.length,offset:e}},b=(n,t)=>{const e=g(t);if(e!==void 0)return{diagnostics:e.code==="SQL_EMPTY"?[]:[{length:e.length,message:e.message,offset:e.offset,severity:"error",source:"gate"}],plan:[]};let s;try{s=n.exec(`EXPLAIN QUERY PLAN ${t}`).toArray().map(r=>{const{detail:i}=r;return typeof i=="string"?i:""}).filter(r=>r!=="")}catch(r){const i=r instanceof Error?r.message:String(r),a=O.exec(i);return{diagnostics:[{...a?_(t,a[1]??""):{},message:i,severity:"error",source:"syntax"}],plan:[]}}const c=[],o=new Set;for(const r of s){const i=T.exec(r);if(i){const a=i[1]??"";o.has(a)||(o.add(a),c.push({message:`full table scan on \`${a}\` — this query reads every row`,severity:"warning",source:"plan"}))}}return{diagnostics:c,plan:s}};export{d as MAX_SQL_ROWS,y as assertReadonly,b as lintReadonlySql,w as runReadonlySql};
@@ -1,19 +0,0 @@
1
- import{sql as r}from"drizzle-orm";import{runDrizzle as E}from"./runDrizzle-2ULFQR_k.mjs";const a="__stream_runs",o="__stream_chunks",L=e=>{E(e,r`CREATE TABLE IF NOT EXISTS ${r.identifier(a)} (
2
- run_key TEXT PRIMARY KEY,
3
- status TEXT NOT NULL,
4
- last_seq INTEGER NOT NULL DEFAULT 0,
5
- error_code TEXT,
6
- error TEXT,
7
- started_at REAL NOT NULL,
8
- ttl_ms REAL NOT NULL
9
- )`),E(e,r`CREATE TABLE IF NOT EXISTS ${r.identifier(o)} (
10
- run_key TEXT NOT NULL,
11
- seq INTEGER NOT NULL,
12
- data_json TEXT NOT NULL,
13
- PRIMARY KEY (run_key, seq)
14
- )`)},d=(e,s)=>{const t=E(e,r`SELECT status, last_seq, error_code, error, started_at FROM ${r.identifier(a)} WHERE run_key = ${s} LIMIT 1`).toArray()[0];if(t!==void 0)return{...t.error===null?{}:{error:t.error},...t.error_code===null?{}:{errorCode:t.error_code},lastSeq:t.last_seq,startedAt:t.started_at,status:t.status}},N=(e,s,n,t)=>d(e,s)!==void 0?!1:(E(e,r`INSERT INTO ${r.identifier(a)} (run_key, status, last_seq, started_at, ttl_ms)
15
- VALUES (${s}, ${"running"}, 0, ${n}, ${t})`),!0),$=(e,s)=>{E(e,r`DELETE FROM ${r.identifier(o)} WHERE run_key = ${s}`),E(e,r`DELETE FROM ${r.identifier(a)} WHERE run_key = ${s}`)},S=(e,s,n,t)=>{E(e,r`INSERT OR IGNORE INTO ${r.identifier(o)} (run_key, seq, data_json) VALUES (${s}, ${n}, ${t})`)},m=(e,s,n)=>E(e,r`SELECT seq, data_json FROM ${r.identifier(o)} WHERE run_key = ${s} AND seq > ${n} ORDER BY seq ASC`).toArray().map(t=>({dataJson:t.data_json,seq:t.seq})),c=(e,s,n,t,i)=>{const T=i?.code??null,_=i?.message??null;E(e,r`UPDATE ${r.identifier(a)}
16
- SET status = ${n}, last_seq = ${t}, error_code = ${T}, error = ${_}
17
- WHERE run_key = ${s}`)},A=(e,s)=>{E(e,r`DELETE FROM ${r.identifier(o)} WHERE run_key IN (
18
- SELECT run_key FROM ${r.identifier(a)} WHERE started_at + ttl_ms < ${s}
19
- )`),E(e,r`DELETE FROM ${r.identifier(a)} WHERE started_at + ttl_ms < ${s}`)};export{o as STREAM_CHUNKS_TABLE,a as STREAM_RUNS_TABLE,S as appendStreamChunk,N as claimStreamRun,$ as deleteStreamRun,c as finishStreamRun,L as migrateDurableStreams,m as readStreamChunks,d as readStreamRun,A as trimStreamRuns};
@@ -1 +0,0 @@
1
- import{c as l,i as C,r as R}from"./ctx-db-companions-QC15-pzG.mjs";import"./AGGREGATE_SQL_FUNCTION-m1iUU1rv.mjs";import"./aggregateTableName-CCCIulmn.mjs";import"./runDrizzle-2ULFQR_k.mjs";import"./do-sql-A80W5VLt.mjs";import"./param-DlozcSQu.mjs";import"./GEO_DEFAULT_PRECISION-CqpQZ-J_.mjs";import"./CURSOR_PREFIX-B1i1J8Zi.mjs";import"./RANK_TIEBREAK-DGlhcKKv.mjs";import"./BIGINT_KEY_DIGITS-GvEBhyR5.mjs";import"./serializeSqlValue-B_-zaEWZ.mjs";export{l as createCompanionSync,C as insertRankRow,R as rankColumnsSql};
@@ -1 +0,0 @@
1
- import{createShardCtxDb as S}from"./NotUniqueError-BdMwMt_A.mjs";import{createRelayLink as B}from"./DEFAULT_MAX_RELAYS-BAJHxoe-.mjs";import{ConflictError as I}from"./ConflictError-C8GtJmjS.mjs";import{runShardMigrations as v}from"./runShardMigrations-DtD-pA0_.mjs";import{relayName as F}from"./DEFAULT_PROMOTION_THRESHOLDS-CrzPqmGP.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",reset:!0,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 +0,0 @@
1
- import{t as g,f as l}from"./base64-DfpzS4o_.mjs";const o="$lunora.wire$",d=64,A=1024,w="__proto__",p={BigInt64Array,BigUint64Array,Float32Array,Float64Array,Int8Array,Int16Array,Int32Array,Uint8Array,Uint8ClampedArray,Uint16Array,Uint32Array},E={Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError},j=r=>{if(r===null||typeof r!="object")return!1;const t=Object.getPrototypeOf(r);return t===null||t===Object.prototype},O=(r,t=0)=>{if(t>d)return!0;if(r===null)return!1;const c=typeof r;if(c==="string"||c==="boolean")return!1;if(c==="number")return!Number.isFinite(r);if(c!=="object")return!0;if(Array.isArray(r))return r.length>0&&r[0]===o?!0:r.some(f=>f===void 0||O(f,t+1));if(!j(r)||Object.hasOwn(r,w))return!0;for(const f of Object.keys(r)){const i=r[f];if(i!==void 0&&O(i,t+1))return!0}return!1},u=(r,t=0)=>{if(t>d)throw new RangeError(`wire-codec: value nesting exceeds the ${d}-level limit`);if(r===void 0)return[o,"undefined"];if(r===null)return null;const c=typeof r;if(c==="bigint")return[o,"bigint",r.toString()];if(c==="number"){const e=r;return Number.isNaN(e)?[o,"nan"]:e===1/0?[o,"inf"]:e===-1/0?[o,"-inf"]:e}if(c!=="object")return r;if(r instanceof Date)return[o,"date",u(r.getTime(),t+1)];if(r instanceof Error){const e=r,n={};for(const a of Object.keys(e))e[a]!==void 0&&(n[a]=u(e[a],t+1));const s=[o,"error",e.name,e.message,n];return e.cause!==void 0&&s.push(u(e.cause,t+1)),s}if(r instanceof URL)return[o,"url",r.href];if(r instanceof Map)return[o,"map",[...r.entries()].map(([e,n])=>[u(e,t+1),u(n,t+1)])];if(r instanceof Set)return[o,"set",[...r].map(e=>u(e,t+1))];if(r instanceof ArrayBuffer)return[o,"bytes",g(new Uint8Array(r)),"ArrayBuffer"];if(ArrayBuffer.isView(r)){const e=r,n=e.constructor.name,s=new Uint8Array(e.buffer,e.byteOffset,e.byteLength);return n==="Uint8Array"?[o,"bytes",g(s)]:[o,"bytes",g(s),n]}if(Array.isArray(r)){const e=r.map(n=>u(n,t+1));return e.length>0&&e[0]===o?[o,"arr",e]:e}if(!j(r)){const e=r.constructor?.name??"value";throw new TypeError(`wire-codec: cannot encode a ${e} over the Lunora wire — only plain objects, arrays, and the supported built-ins (Date, Error, URL, Map, Set, ArrayBuffer/typed arrays, bigint) round-trip`)}const f=r,i={};for(const e of Object.keys(f)){const n=f[e];if(n===void 0)continue;const s=u(n,t+1);e===w?Object.defineProperty(i,e,{configurable:!0,enumerable:!0,value:s,writable:!0}):i[e]=s}return i},y=(r,t=0)=>{if(t>d)throw new RangeError(`wire-codec: value nesting exceeds the ${d}-level limit`);if(r===null||typeof r!="object")return r;if(Array.isArray(r)){if(r[0]===o)switch(r[1]){case"-inf":return-1/0;case"arr":return r[2].map(e=>y(e,t+1));case"bigint":{const e=r[2];if(typeof e!="string"||e.length>A||!/^-?\d+$/.test(e))throw new RangeError(`wire-codec: invalid or over-long bigint (max ${A} digits)`);return BigInt(e)}case"date":{if(r.length<3)throw new TypeError("wire-codec: malformed date — missing payload");return new Date(y(r[2],t+1))}case"map":{const e=r[2];return new Map(e.map(n=>{if(!Array.isArray(n)||n.length!==2)throw new TypeError("wire-codec: malformed map entry — expected a [key, value] pair");return[y(n[0],t+1),y(n[1],t+1)]}))}case"set":return new Set(r[2].map(e=>y(e,t+1)));case"url":return new URL(r[2]);case"error":{const e=r[2],n=r[3],s=(Object.hasOwn(E,e)?E[e]:void 0)??Error,a=new s(n);a.name!==e&&Object.defineProperty(a,"name",{configurable:!0,value:e,writable:!0});const b=y(r[4],t+1);if(b===null||typeof b!="object"||Array.isArray(b))throw new TypeError("wire-codec: malformed error — props must be an object");for(const m of Object.keys(b))m===w?Object.defineProperty(a,m,{configurable:!0,enumerable:!0,value:b[m],writable:!0}):a[m]=b[m];return r.length>5&&Object.defineProperty(a,"cause",{configurable:!0,value:y(r[5],t+1),writable:!0}),a}case"bytes":{const e=l(r[2]),n=r[3]??"Uint8Array";if(n==="ArrayBuffer")return e.buffer.byteLength===e.byteLength?e.buffer:e.slice().buffer;const s=Object.hasOwn(p,n)?p[n]:void 0;return s?new s(e.slice().buffer):e}case"inf":return 1/0;case"nan":return Number.NaN;case"undefined":return;default:return r.map(e=>y(e,t+1))}return r.map(i=>y(i,t+1))}const c=r,f={};for(const i of Object.keys(c)){const e=y(c[i],t+1);i===w?Object.defineProperty(f,i,{configurable:!0,enumerable:!0,value:e,writable:!0}):f[i]=e}return f};export{y as d,u as e,j as i,O as n};