@lunora/client 1.0.0-alpha.25 → 1.0.0-alpha.250

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 (96) hide show
  1. package/README.md +16 -3
  2. package/dist/auth/index.d.mts +35 -4
  3. package/dist/auth/index.d.ts +35 -4
  4. package/dist/auth/index.mjs +1 -60
  5. package/dist/index.d.mts +721 -187
  6. package/dist/index.d.ts +721 -187
  7. package/dist/index.mjs +1 -21
  8. package/dist/packem_shared/CONFLICT_ERROR_CODE-B7qNZMMk.mjs +1 -0
  9. package/dist/packem_shared/DEFAULT_MAX_BUFFER-Bd-_iyiV.mjs +1 -0
  10. package/dist/packem_shared/LunoraClient-C-auNTDs.mjs +1 -0
  11. package/dist/packem_shared/OfflineQueue-Ba2qgZK1.mjs +1 -0
  12. package/dist/packem_shared/RETIRE_AFTER_DURABLE_SEQ_ADVANCE-DoEHtuR8.mjs +1 -0
  13. package/dist/packem_shared/SKIP-d7LeP-sY.mjs +1 -0
  14. package/dist/packem_shared/SubscriptionRegistry-BKgQtuh9.mjs +1 -0
  15. package/dist/packem_shared/TabCoordinator-DBuR7Dwv.mjs +1 -0
  16. package/dist/packem_shared/applyDelta-CWpwS3Bb.mjs +1 -0
  17. package/dist/packem_shared/client-tuning-C10B2KCO.mjs +1 -0
  18. package/dist/packem_shared/client-urls-BHLUjjcG.mjs +1 -0
  19. package/dist/packem_shared/connectLiveStream-BdjsWP1-.mjs +1 -0
  20. package/dist/packem_shared/createAsyncStoragePersistence-6FCvqc6C.mjs +1 -0
  21. package/dist/packem_shared/createAsyncStorageQueryCache-COqH5_SV.mjs +1 -0
  22. package/dist/packem_shared/createCallRunner-Bwcrfh76.mjs +1 -0
  23. package/dist/packem_shared/createClientQuery-B8Nfj-7o.mjs +1 -0
  24. package/dist/packem_shared/createInMemoryBookmarkStorage-BooZhW0n.mjs +1 -0
  25. package/dist/packem_shared/createInMemoryPersistence-BfgXApi_.mjs +1 -0
  26. package/dist/packem_shared/createInMemoryQueryCache-B5wX-gTy.mjs +1 -0
  27. package/dist/packem_shared/createLocalStore-CsKA0HPB.mjs +1 -0
  28. package/dist/packem_shared/createMutatorRunner-CuMRJpUx.mjs +1 -0
  29. package/dist/packem_shared/createReconnect-CjTmjJDH.mjs +1 -0
  30. package/dist/packem_shared/createServerClient-kd9cUs8g.mjs +1 -0
  31. package/dist/packem_shared/createSnapshotPrecondition-BXP1NPBW.mjs +1 -0
  32. package/dist/packem_shared/delta-merge-Ls3DED4g.mjs +1 -0
  33. package/dist/packem_shared/deserializePreloaded-CyFK_cv6.mjs +1 -0
  34. package/dist/packem_shared/function-reference.d-Br_hsKje.d.mts +45 -0
  35. package/dist/packem_shared/function-reference.d-Br_hsKje.d.ts +45 -0
  36. package/dist/packem_shared/getServerSession-BaOoo1p6.mjs +1 -0
  37. package/dist/packem_shared/httpStream-B9iENFKq.mjs +7 -0
  38. package/dist/packem_shared/idb-utility-BS7xvou1.mjs +1 -0
  39. package/dist/packem_shared/live-stream-DBKgZlnb.mjs +10 -0
  40. package/dist/packem_shared/liveTopicSubscription-DQtKMFKw.mjs +1 -0
  41. package/dist/packem_shared/local-store-C3bw2MPY.mjs +1 -0
  42. package/dist/packem_shared/lunora-client.d-7WaMRZUK.d.ts +5305 -0
  43. package/dist/packem_shared/lunora-client.d-DtTKDhtw.d.mts +5305 -0
  44. package/dist/packem_shared/offline-queue-BEqCPDmw.mjs +1 -0
  45. package/dist/packem_shared/{preload.d-B6-lqUf2.d.ts → preload.d-B26QlpOB.d.ts} +2 -1
  46. package/dist/packem_shared/{preload.d-Dvk8zg6m.d.mts → preload.d-CT_9YaL9.d.mts} +2 -1
  47. package/dist/packem_shared/preloadQuery-uFy24PCR.mjs +1 -0
  48. package/dist/packem_shared/single-blob-store-DpqSxsgi.mjs +1 -0
  49. package/dist/packem_shared/snapshot-precondition-BEtcSbWr.mjs +1 -0
  50. package/dist/packem_shared/stream-idle-C7CsIT_m.mjs +1 -0
  51. package/dist/packem_shared/wire-errors-BgFi7ONA.mjs +1 -0
  52. package/dist/pagination/index.mjs +1 -61
  53. package/dist/query/index.d.mts +71 -3
  54. package/dist/query/index.d.ts +71 -3
  55. package/dist/query/index.mjs +1 -1
  56. package/dist/service.d.mts +49 -0
  57. package/dist/service.d.ts +49 -0
  58. package/dist/service.mjs +1 -0
  59. package/dist/ssr/index.d.mts +45 -15
  60. package/dist/ssr/index.d.ts +45 -15
  61. package/dist/ssr/index.mjs +1 -4
  62. package/dist/upload.d.mts +35 -0
  63. package/dist/upload.d.ts +35 -0
  64. package/dist/upload.mjs +1 -0
  65. package/package.json +15 -2
  66. package/dist/packem_shared/CONFLICT_ERROR_CODE-B8gQ8tyU.mjs +0 -33
  67. package/dist/packem_shared/ClientServiceWorker-C3PAFwy0.mjs +0 -100
  68. package/dist/packem_shared/DEFAULT_MAX_BUFFER-7hFnzNk9.mjs +0 -110
  69. package/dist/packem_shared/LunoraClient-D3h4P7hg.mjs +0 -3613
  70. package/dist/packem_shared/OfflineQueue-BgarnAub.mjs +0 -1
  71. package/dist/packem_shared/SKIP-vItZChkw.mjs +0 -50
  72. package/dist/packem_shared/SubscriptionRegistry-CxS_Inha.mjs +0 -31
  73. package/dist/packem_shared/TabCoordinator-D_5oNTTt.mjs +0 -258
  74. package/dist/packem_shared/applyDelta-CRKZ1PBt.mjs +0 -81
  75. package/dist/packem_shared/createAsyncStoragePersistence-1Z5BZ8RC.mjs +0 -45
  76. package/dist/packem_shared/createClientQuery-dJZg1ohm.mjs +0 -80
  77. package/dist/packem_shared/createInMemoryBookmarkStorage-BoN7a7TH.mjs +0 -11
  78. package/dist/packem_shared/createInMemoryPersistence-DZ2VHWgm.mjs +0 -79
  79. package/dist/packem_shared/createInMemoryQueryCache-DiaGZkA2.mjs +0 -112
  80. package/dist/packem_shared/createLocalStore-BtqUmOQA.mjs +0 -2
  81. package/dist/packem_shared/createMutationRunner-BqsavzvG.mjs +0 -21
  82. package/dist/packem_shared/createMutatorRunner-BETvCd0p.mjs +0 -31
  83. package/dist/packem_shared/createReconnect-Di_-oHH7.mjs +0 -22
  84. package/dist/packem_shared/createReply-lI4tVS2w.mjs +0 -36
  85. package/dist/packem_shared/createServerClient-DzeC2J3A.mjs +0 -11
  86. package/dist/packem_shared/createSnapshotPrecondition-CxQ1T4ZP.mjs +0 -18
  87. package/dist/packem_shared/deserializePreloaded-C0eJTY_W.mjs +0 -4
  88. package/dist/packem_shared/getServerSession-8jXewqxd.mjs +0 -13
  89. package/dist/packem_shared/httpStream-DIdL8NEw.mjs +0 -168
  90. package/dist/packem_shared/idb-utility-DrSVX43Q.mjs +0 -48
  91. package/dist/packem_shared/local-store-DIq-UWfD.mjs +0 -106
  92. package/dist/packem_shared/lunora-client.d-C4ud8bej.d.mts +0 -2834
  93. package/dist/packem_shared/lunora-client.d-C4ud8bej.d.ts +0 -2834
  94. package/dist/packem_shared/offline-queue-N-1JvYb4.mjs +0 -211
  95. package/dist/packem_shared/preloadQuery-lobFkD2Z.mjs +0 -13
  96. package/dist/packem_shared/wire-key-Djie6aaR.mjs +0 -266
@@ -0,0 +1 @@
1
+ let a=0;const d=()=>{if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();a+=1;const o=typeof crypto<"u"&&typeof crypto.getRandomValues=="function"?Array.from(crypto.getRandomValues(new Uint8Array(8)),e=>e.toString(16).padStart(2,"0")).join(""):Math.random().toString(16).slice(2,12);return`id_${Date.now().toString(36)}_${a.toString(36)}_${o}`},l=(o,e)=>o!==void 0&&e!==o,f=d,h=(o,e,t,i)=>{if(o)try{o({error:t,mutationId:i,operation:e});return}catch{}console.warn(`[lunora] offline-queue persistence ${e} failed`,t)};class p{queueBeforeFirstConnect;maxItems;onPersistenceError;persistence;onEvict;onSizeChange;onReplayingChange;version;items=[];replayingIds=new Set;appending=new Map;unsettled=new Map;unpersisted=new Set;constructor(e={},t={}){this.maxItems=e.maxItems??1e3,this.queueBeforeFirstConnect=e.queueBeforeFirstConnect??!1,this.onPersistenceError=e.onPersistenceError,this.persistence=t.persistence,this.onEvict=t.onEvict,this.onSizeChange=t.onSizeChange,this.onReplayingChange=t.onReplayingChange,this.version=t.version}get size(){return this.items.length}get replaying(){return this.replayingIds.size}enqueue(e){const t=e;t.id??=f();let i=this.items.length;for(;t.issueSeq!==void 0&&i>0&&(this.items[i-1]?.issueSeq??-1)>t.issueSeq;)i-=1;this.items.splice(i,0,t),this.unsettled.set(t.id,t),this.persist(this.recordOf(t,t.id)),this.evictOverflow(),this.notifySize()}discard(e){this.unsettled.delete(e),this.unpersisted.delete(e),this.replayingIds.delete(e)&&this.onReplayingChange?.();const{persistence:t}=this;t&&(this.appending.get(e)??Promise.resolve()).then(async()=>t.remove(e)).catch(i=>{h(this.onPersistenceError,"remove",i,e)})}flushUnpersisted(){for(const e of this.unpersisted){const t=this.unsettled.get(e);t&&!this.appending.has(e)&&this.persist(this.recordOf(t,e))}}async hydrate(){if(!this.persistence)return[];let e;try{e=await this.persistence.load()}catch(s){throw h(this.onPersistenceError,"load",s),s}const t=[],i=new Set(this.items.map(s=>s.id));for(const s of e)if(!i.has(s.id)){if(l(this.version,s.version)){this.persistence.remove(s.id).catch(c=>{h(this.onPersistenceError,"remove",c,s.id)});continue}i.add(s.id),t.push({args:s.args,baselineSeq:s.baselineSeq,clientId:s.clientId,functionPath:s.functionPath,id:s.id,identity:s.identity,reject:()=>{},resolve:()=>{},shardKey:s.shardKey})}this.items.unshift(...t),this.evictOverflow(),this.notifySize();const n=new Set(this.items),r=new Set;for(const s of t)n.has(s)&&r.add(s.shardKey);return[...r]}restampIdentity(e,t){for(const i of this.items){if(i.identity!==e)continue;i.identity=t;const{id:n}=i;!this.persistence||n===void 0||this.rewriteStamp(n,this.recordOf(i,n)).catch(r=>{h(this.onPersistenceError,"replace",r,n)})}}hasPending(e){return this.items.some(t=>e(t))}drain(e){if(!e){const n=[...this.items];return this.items.length=0,this.markReplaying(n),this.notifySize(),n}const t=[],i=[];for(const n of this.items)(e(n)?t:i).push(n);return this.items.length=0,this.items.push(...i),this.markReplaying(t),this.notifySize(),t}requeue(e){if(e.length!==0){for(const t of e)t.id!==void 0&&this.replayingIds.delete(t.id);this.items.unshift(...e),this.notifySize()}}drainConflict(){const e=[],t=[];for(const i of this.items){let n=!0,r;if(i.precondition!==void 0)try{n=i.precondition()}catch(s){n=!1,r=s}if(n)t.push(i);else{const s=new Error("offline mutation skipped: precondition failed before replay",r===void 0?void 0:{cause:r});s.code="OFFLINE_PRECONDITION_FAILED",i.reject(s),e.push(i)}}return e.length>0&&(this.items.length=0,this.items.push(...t),this.notifySize()),e}clear(){for(const e of new Set([...this.items,...this.unsettled.values()])){const t=new Error("CLIENT_CLOSED"),i=e.id??"",n=s=>{t.code="CLIENT_CLOSED",t.persisted=s,e.reject(t)},r=this.appending.get(i);this.replayingIds.has(i)?n(!1):r===void 0?n(this.persistence!==void 0&&!this.unpersisted.has(i)):r.catch(()=>!1).then(n).catch(()=>{})}this.items.length=0,this.replayingIds.clear(),this.unsettled.clear(),this.unpersisted.clear(),this.notifySize()}recordOf(e,t){return{args:e.args,...e.baselineSeq===void 0?{}:{baselineSeq:e.baselineSeq},clientId:e.clientId,functionPath:e.functionPath,id:t,identity:e.identity,shardKey:e.shardKey,...this.version===void 0?{}:{version:this.version}}}persist(e){const{persistence:t}=this;if(!t)return;const i=(async()=>{try{return await t.append(e),this.unpersisted.delete(e.id),!0}catch(n){return this.unsettled.has(e.id)&&this.unpersisted.add(e.id),h(this.onPersistenceError,"append",n,e.id),!1}})();this.appending.set(e.id,i),i.finally(()=>{this.appending.get(e.id)===i&&this.appending.delete(e.id)}).catch(()=>{})}async rewriteStamp(e,t){const i=this.persistence;if(i)try{await this.appending.get(e),await i.replace(t)}catch(n){h(this.onPersistenceError,"replace",n,e)}}evictOverflow(){for(;this.items.length>this.maxItems;){const e=this.items.shift();if(e){e.id&&this.discard(e.id);const t=new Error("offline queue overflow");t.code="OFFLINE_QUEUE_OVERFLOW",e.reject(t),this.onEvict?.(e,t)}}}markReplaying(e){for(const t of e)t.id!==void 0&&this.replayingIds.add(t.id)}notifySize(){this.onSizeChange?.(this.items.length)}}export{p as O,l as i,f as n,h as r};
@@ -1,4 +1,5 @@
1
- import { F as FunctionReference, L as LunoraClient, A as ArgsOf, R as ReturnOf, P as Preloaded } from "./lunora-client.d-C4ud8bej.js";
1
+ import { L as LunoraClient, P as Preloaded } from "./lunora-client.d-7WaMRZUK.js";
2
+ import { F as FunctionReference, A as ArgsOf, R as ReturnOf } from "./function-reference.d-Br_hsKje.js";
2
3
  /**
3
4
  * Run a query once on the server (during SSR) and capture its result in a
4
5
  * serializable {@link Preloaded} token. Embed the token in the rendered HTML and
@@ -1,4 +1,5 @@
1
- import { F as FunctionReference, L as LunoraClient, A as ArgsOf, R as ReturnOf, P as Preloaded } from "./lunora-client.d-C4ud8bej.mjs";
1
+ import { L as LunoraClient, P as Preloaded } from "./lunora-client.d-DtTKDhtw.mjs";
2
+ import { F as FunctionReference, A as ArgsOf, R as ReturnOf } from "./function-reference.d-Br_hsKje.mjs";
2
3
  /**
3
4
  * Run a query once on the server (during SSR) and capture its result in a
4
5
  * serializable {@link Preloaded} token. Embed the token in the rendered HTML and
@@ -0,0 +1 @@
1
+ const t=async(e,r,a,u={})=>{const l=await e.query(r,a,u);return{__lunoraPreloaded:!0,args:a??{},functionPath:r.__lunoraRef,shardKey:u.shardKey,value:l}},d=e=>e.value;export{t as preloadQuery,d as preloadedQueryResult};
@@ -0,0 +1 @@
1
+ import{encodeWire as s,decodeWire as a}from"@lunora/wire";const c=Symbol("lunora.corrupt-blob"),m=(r,t)=>{let n=Promise.resolve();const o=e=>{const i=n.then(e,e);return n=i.then(()=>{},()=>{}),i};return{clear:()=>o(()=>r.removeItem(t)),read:async()=>{const e=await r.getItem(t);if(e!==null)try{return a(JSON.parse(e))}catch{return c}},serialize:o,write:async e=>{await r.setItem(t,JSON.stringify(s(e)))}}};export{c as C,m as s};
@@ -0,0 +1 @@
1
+ import{stableWireKey as p}from"@lunora/wire";const u=new WeakMap,i=(e,t)=>{u.set(e,t)},d=e=>e===void 0?void 0:u.get(e),h=(e,t,s,n)=>{const o=e.peekActiveQuerySnapshot(t.__lunoraRef,s,n),a=o.present&&o.answered?p(o.value):void 0,c=()=>{const r=e.peekActiveQuerySnapshot(t.__lunoraRef,s,n);return!o.present||!o.answered||!r.present||!r.answered?!0:p(r.value)===a};return a!==void 0&&i(c,{args:s,functionPath:t.__lunoraRef,shardKey:n}),c};export{h as c,i as r,d as s};
@@ -0,0 +1 @@
1
+ import{LunoraError as v}from"@lunora/errors";import{TransportError as f}from"./CONFLICT_ERROR_CODE-B7qNZMMk.mjs";const c=t=>t.reason??Object.assign(new Error("The operation was aborted"),{name:"AbortError"}),m=async(t,r,o,i=()=>new f(`LunoraClient: request timed out after ${t.toString()}ms`))=>{if(r?.aborted)throw c(r);const n=new AbortController,e=[],u=new Promise((b,d)=>{if(t>0){const a=setTimeout(()=>{d(i()),n.abort()},t);e.push(()=>{clearTimeout(a)})}if(r){const a=()=>{n.abort(),d(c(r))};r.addEventListener("abort",a,{once:!0}),e.push(()=>{r.removeEventListener("abort",a)})}}),s=o(n.signal);s.catch(()=>{});try{return await Promise.race([s,u])}finally{for(const b of e)b()}},E=async(t,r)=>{if(r===void 0)return t;if(r.aborted)throw t.catch(()=>{}),c(r);let o=()=>{};const i=new Promise((n,e)=>{o=()=>{e(c(r))},r.addEventListener("abort",o,{once:!0})});t.catch(()=>{});try{return await Promise.race([t,i])}finally{r.removeEventListener("abort",o)}},y=async(t,r)=>!Number.isFinite(r)||r<=0?t.read():m(r,void 0,async()=>t.read(),()=>new v("STREAM_IDLE",`stream received nothing for ${r.toString()}ms`));export{E as a,c as b,y as r,m as w};
@@ -0,0 +1 @@
1
+ import{LunoraError as n}from"@lunora/errors";import{decodeWire as d}from"@lunora/wire";import{TransportError as u,getRetryAfterMs as f}from"./CONFLICT_ERROR_CODE-B7qNZMMk.mjs";const l=t=>{if(t===null)return;const e=Number(t);if(Number.isFinite(e))return e>0?e*1e3:void 0;const r=Date.parse(t);if(Number.isNaN(r))return;const o=r-Date.now();return o>0?o:void 0},v=(t,e)=>{const r=l(e);if(!(r===void 0||f(t)!==void 0))return t.data===void 0?{retryAfterMs:r}:typeof t.data=="object"&&t.data!==null&&!Array.isArray(t.data)?{...t.data,retryAfterMs:r}:void 0},p=t=>{const e=t?.error;if(typeof e!="object"||e===null||Array.isArray(e))return;const{why:r,...o}=e;return typeof r=="string"?{...o,why:r}:o},E=()=>new u("LunoraClient: batch slot carried no error envelope"),i=(t,e)=>{const r=t.error,o=typeof r?.code=="string"?r.code:void 0,s=typeof r?.message=="string"?r.message:void 0;return{code:o,messageText:(typeof t.message=="string"?t.message:void 0)??s??e}},A=t=>{const{code:e,messageText:r}=i(t,"stream error"),o=t.error?.why,s=e===void 0?new Error(r):new n(e,r);return typeof o=="string"&&(s.why=o),s},R=t=>{const{code:e,messageText:r}=i(t,"subscription error"),o=t.error?.why;return{message:r,...e===void 0?{}:{code:e},...typeof o=="string"?{why:o}:{}}},y=Symbol.for("lunora.serverVerdict"),a=t=>{const e=new Error(t.message??"request failed");if(e.code=t.code,e[y]=!0,t.data!==void 0)try{e.data=d(t.data)}catch{}return t.hint!==void 0&&(e.hint=t.hint),t.docsUrl!==void 0&&(e.docsUrl=t.docsUrl),typeof t.why=="string"&&(e.why=t.why),e},m=t=>Object.freeze(Object.fromEntries([...t].filter(([e])=>e!=="set-cookie"))),b=(t,e)=>Object.defineProperty(t,"headers",{value:m(e)}),S=(t,e)=>{const r=a(t),o=v(r,e.get("retry-after"));return o!==void 0&&(r.data=o),b(r,e)},D=t=>{const e=p(t);return e===void 0?E():a(e)},c=new WeakSet,j=t=>{const e=new n("WIRE_DECODE_FAILED",`LunoraClient: the call succeeded but its result could not be decoded (a mutation has still committed) — ${t instanceof Error?t.message:String(t)}`,{cause:t});return c.add(e),e},M=t=>t instanceof Error&&c.has(t);export{l as a,S as b,A as c,R as d,p as e,E as f,M as i,a as r,D as s,j as u,b as w};
@@ -1,61 +1 @@
1
- const SPLIT_FACTOR = 2;
2
- const JOIN_FACTOR = 0.5;
3
- const initialPages = (numberItems) => [
4
- // eslint-disable-next-line unicorn/no-null -- `lower: null` is the feed head, `upper: null` the open-ended tail — both are wire-shape cursors.
5
- { lower: null, numItems: numberItems, upper: null }
6
- ];
7
- const rebalance = (pages, results) => {
8
- for (const [index, page] of pages.entries()) {
9
- if (page.upper === null) {
10
- continue;
11
- }
12
- const result = results[index];
13
- if (!result) {
14
- continue;
15
- }
16
- const size = result.page.length;
17
- if (size > SPLIT_FACTOR * page.numItems && result.splitCursor) {
18
- const split = result.splitCursor;
19
- const next = [...pages];
20
- next.splice(index, 1, { lower: page.lower, numItems: page.numItems, upper: split }, { lower: split, numItems: page.numItems, upper: page.upper });
21
- return next;
22
- }
23
- if (size < JOIN_FACTOR * page.numItems && index + 1 < pages.length) {
24
- const neighbour = pages[index + 1];
25
- if (!neighbour) {
26
- continue;
27
- }
28
- const next = [...pages];
29
- next.splice(index, 2, { lower: page.lower, numItems: page.numItems, upper: neighbour.upper });
30
- return next;
31
- }
32
- }
33
- return void 0;
34
- };
35
- const derivePaginationStatus = (skipped, pageResults) => {
36
- if (skipped || !pageResults[0]) {
37
- return { nextCursor: void 0, status: "LoadingFirstPage" };
38
- }
39
- const tail = pageResults.at(-1);
40
- if (!tail) {
41
- return { nextCursor: void 0, status: "LoadingMore" };
42
- }
43
- if (tail.isDone || tail.continueCursor === null) {
44
- return { nextCursor: void 0, status: "Exhausted" };
45
- }
46
- return { nextCursor: tail.continueCursor, status: "CanLoadMore" };
47
- };
48
- const applyLoadMore = (pages, cursor, numberItems) => {
49
- if (cursor === void 0 || cursor === null) {
50
- return void 0;
51
- }
52
- const next = [...pages];
53
- const tail = next.at(-1);
54
- if (tail) {
55
- next[next.length - 1] = { lower: tail.lower, numItems: tail.numItems, upper: cursor };
56
- }
57
- next.push({ lower: cursor, numItems: numberItems, upper: null });
58
- return next;
59
- };
60
-
61
- export { JOIN_FACTOR, SPLIT_FACTOR, applyLoadMore, derivePaginationStatus, initialPages, rebalance };
1
+ const l=2,m=.5,p=e=>[{lower:null,numItems:e,upper:null}],c=(e,r)=>{for(const[n,t]of e.entries()){if(t.upper===null)continue;const o=r[n];if(!o)continue;const i=o.page.length;if(i>2*t.numItems&&o.splitCursor){const u=o.splitCursor,s=[...e];return s.splice(n,1,{lower:t.lower,numItems:t.numItems,upper:u},{lower:u,numItems:t.numItems,upper:t.upper}),s}if(i<.5*t.numItems&&n+1<e.length){const u=e[n+1];if(!u)continue;const s=[...e];return s.splice(n,2,{lower:t.lower,numItems:t.numItems,upper:u.upper}),s}}},a=(e,r)=>{if(e||!r[0])return{nextCursor:void 0,status:"LoadingFirstPage"};const n=r.at(-1);return n?n.isDone||n.continueCursor===null?{nextCursor:void 0,status:"Exhausted"}:{nextCursor:n.continueCursor,status:"CanLoadMore"}:{nextCursor:void 0,status:"LoadingMore"}},I=(e,r,n)=>{if(r==null)return;const t=[...e],o=t.at(-1);return o&&(t[t.length-1]={lower:o.lower,numItems:o.numItems,upper:r}),t.push({lower:r,numItems:n,upper:null}),t};export{m as JOIN_FACTOR,l as SPLIT_FACTOR,I as applyLoadMore,a as derivePaginationStatus,p as initialPages,c as rebalance};
@@ -1,5 +1,18 @@
1
- import { S as SubscriptionError, F as FunctionReference, A as ArgsOf, R as ReturnOf, L as LunoraClient, a as Unsubscribe } from "../packem_shared/lunora-client.d-C4ud8bej.mjs";
2
- export type { b as SubscriptionErrorCallback } from "../packem_shared/lunora-client.d-C4ud8bej.mjs";
1
+ import { S as SubscriptionError, L as LunoraClient, a as Unsubscribe } from "../packem_shared/lunora-client.d-DtTKDhtw.mjs";
2
+ export type {
3
+ /**
4
+ * `@lunora/client/query` — the framework-neutral live-query state machine shared
5
+ * by every Lunora UI adapter (React, Vue, Svelte, Solid). It owns the seam
6
+ * between a `LunoraClient` subscription and a framework's reactivity primitive:
7
+ * the subscribe → snapshot → error/reset → cleanup lifecycle, with the
8
+ * skip-handling, value/error fan-out, attach-throw normalisation, and
9
+ * cancellation-guarded teardown all in one place. Nothing here imports a UI
10
+ * framework — each adapter supplies thin sinks that write into its own ref /
11
+ * store / signal / cache.
12
+ */
13
+ b as SubscriptionErrorCallback } from "../packem_shared/lunora-client.d-DtTKDhtw.mjs";
14
+ import { F as FunctionReference, A as ArgsOf, R as ReturnOf } from "../packem_shared/function-reference.d-Br_hsKje.mjs";
15
+ import '@lunora/errors';
3
16
  import '@lunora/runtime';
4
17
  /**
5
18
  * The sentinel a framework adapter resolves its reactive args to when it wants
@@ -59,4 +72,59 @@ declare const toSubscriptionError: (error: unknown) => SubscriptionError;
59
72
  * in-flight push reaches the sinks.
60
73
  */
61
74
  declare const createQuerySubscription: <F extends FunctionReference, T = ReturnOf<F>>(client: LunoraClient, function_: F, args: ResolvedArgs<F>, sinks: QuerySubscriptionSinks<T>, options?: QuerySubscriptionOptions) => Unsubscribe;
62
- export { type ArgsOf, type FunctionReference, type QuerySubscriptionOptions, type QuerySubscriptionSinks, type ResolvedArgs, type ReturnOf, SKIP, type SubscriptionError, type Unsubscribe, createQuerySubscription, toSubscriptionError };
75
+ export {
76
+ /**
77
+ * `@lunora/client/query` — the framework-neutral live-query state machine shared
78
+ * by every Lunora UI adapter (React, Vue, Svelte, Solid). It owns the seam
79
+ * between a `LunoraClient` subscription and a framework's reactivity primitive:
80
+ * the subscribe → snapshot → error/reset → cleanup lifecycle, with the
81
+ * skip-handling, value/error fan-out, attach-throw normalisation, and
82
+ * cancellation-guarded teardown all in one place. Nothing here imports a UI
83
+ * framework — each adapter supplies thin sinks that write into its own ref /
84
+ * store / signal / cache.
85
+ */
86
+ type ArgsOf,
87
+ /**
88
+ * `@lunora/client/query` — the framework-neutral live-query state machine shared
89
+ * by every Lunora UI adapter (React, Vue, Svelte, Solid). It owns the seam
90
+ * between a `LunoraClient` subscription and a framework's reactivity primitive:
91
+ * the subscribe → snapshot → error/reset → cleanup lifecycle, with the
92
+ * skip-handling, value/error fan-out, attach-throw normalisation, and
93
+ * cancellation-guarded teardown all in one place. Nothing here imports a UI
94
+ * framework — each adapter supplies thin sinks that write into its own ref /
95
+ * store / signal / cache.
96
+ */
97
+ type FunctionReference, type QuerySubscriptionOptions, type QuerySubscriptionSinks, type ResolvedArgs,
98
+ /**
99
+ * `@lunora/client/query` — the framework-neutral live-query state machine shared
100
+ * by every Lunora UI adapter (React, Vue, Svelte, Solid). It owns the seam
101
+ * between a `LunoraClient` subscription and a framework's reactivity primitive:
102
+ * the subscribe → snapshot → error/reset → cleanup lifecycle, with the
103
+ * skip-handling, value/error fan-out, attach-throw normalisation, and
104
+ * cancellation-guarded teardown all in one place. Nothing here imports a UI
105
+ * framework — each adapter supplies thin sinks that write into its own ref /
106
+ * store / signal / cache.
107
+ */
108
+ type ReturnOf, SKIP,
109
+ /**
110
+ * `@lunora/client/query` — the framework-neutral live-query state machine shared
111
+ * by every Lunora UI adapter (React, Vue, Svelte, Solid). It owns the seam
112
+ * between a `LunoraClient` subscription and a framework's reactivity primitive:
113
+ * the subscribe → snapshot → error/reset → cleanup lifecycle, with the
114
+ * skip-handling, value/error fan-out, attach-throw normalisation, and
115
+ * cancellation-guarded teardown all in one place. Nothing here imports a UI
116
+ * framework — each adapter supplies thin sinks that write into its own ref /
117
+ * store / signal / cache.
118
+ */
119
+ type SubscriptionError,
120
+ /**
121
+ * `@lunora/client/query` — the framework-neutral live-query state machine shared
122
+ * by every Lunora UI adapter (React, Vue, Svelte, Solid). It owns the seam
123
+ * between a `LunoraClient` subscription and a framework's reactivity primitive:
124
+ * the subscribe → snapshot → error/reset → cleanup lifecycle, with the
125
+ * skip-handling, value/error fan-out, attach-throw normalisation, and
126
+ * cancellation-guarded teardown all in one place. Nothing here imports a UI
127
+ * framework — each adapter supplies thin sinks that write into its own ref /
128
+ * store / signal / cache.
129
+ */
130
+ type Unsubscribe, createQuerySubscription, toSubscriptionError };
@@ -1,5 +1,18 @@
1
- import { S as SubscriptionError, F as FunctionReference, A as ArgsOf, R as ReturnOf, L as LunoraClient, a as Unsubscribe } from "../packem_shared/lunora-client.d-C4ud8bej.js";
2
- export type { b as SubscriptionErrorCallback } from "../packem_shared/lunora-client.d-C4ud8bej.js";
1
+ import { S as SubscriptionError, L as LunoraClient, a as Unsubscribe } from "../packem_shared/lunora-client.d-7WaMRZUK.js";
2
+ export type {
3
+ /**
4
+ * `@lunora/client/query` — the framework-neutral live-query state machine shared
5
+ * by every Lunora UI adapter (React, Vue, Svelte, Solid). It owns the seam
6
+ * between a `LunoraClient` subscription and a framework's reactivity primitive:
7
+ * the subscribe → snapshot → error/reset → cleanup lifecycle, with the
8
+ * skip-handling, value/error fan-out, attach-throw normalisation, and
9
+ * cancellation-guarded teardown all in one place. Nothing here imports a UI
10
+ * framework — each adapter supplies thin sinks that write into its own ref /
11
+ * store / signal / cache.
12
+ */
13
+ b as SubscriptionErrorCallback } from "../packem_shared/lunora-client.d-7WaMRZUK.js";
14
+ import { F as FunctionReference, A as ArgsOf, R as ReturnOf } from "../packem_shared/function-reference.d-Br_hsKje.js";
15
+ import '@lunora/errors';
3
16
  import '@lunora/runtime';
4
17
  /**
5
18
  * The sentinel a framework adapter resolves its reactive args to when it wants
@@ -59,4 +72,59 @@ declare const toSubscriptionError: (error: unknown) => SubscriptionError;
59
72
  * in-flight push reaches the sinks.
60
73
  */
61
74
  declare const createQuerySubscription: <F extends FunctionReference, T = ReturnOf<F>>(client: LunoraClient, function_: F, args: ResolvedArgs<F>, sinks: QuerySubscriptionSinks<T>, options?: QuerySubscriptionOptions) => Unsubscribe;
62
- export { type ArgsOf, type FunctionReference, type QuerySubscriptionOptions, type QuerySubscriptionSinks, type ResolvedArgs, type ReturnOf, SKIP, type SubscriptionError, type Unsubscribe, createQuerySubscription, toSubscriptionError };
75
+ export {
76
+ /**
77
+ * `@lunora/client/query` — the framework-neutral live-query state machine shared
78
+ * by every Lunora UI adapter (React, Vue, Svelte, Solid). It owns the seam
79
+ * between a `LunoraClient` subscription and a framework's reactivity primitive:
80
+ * the subscribe → snapshot → error/reset → cleanup lifecycle, with the
81
+ * skip-handling, value/error fan-out, attach-throw normalisation, and
82
+ * cancellation-guarded teardown all in one place. Nothing here imports a UI
83
+ * framework — each adapter supplies thin sinks that write into its own ref /
84
+ * store / signal / cache.
85
+ */
86
+ type ArgsOf,
87
+ /**
88
+ * `@lunora/client/query` — the framework-neutral live-query state machine shared
89
+ * by every Lunora UI adapter (React, Vue, Svelte, Solid). It owns the seam
90
+ * between a `LunoraClient` subscription and a framework's reactivity primitive:
91
+ * the subscribe → snapshot → error/reset → cleanup lifecycle, with the
92
+ * skip-handling, value/error fan-out, attach-throw normalisation, and
93
+ * cancellation-guarded teardown all in one place. Nothing here imports a UI
94
+ * framework — each adapter supplies thin sinks that write into its own ref /
95
+ * store / signal / cache.
96
+ */
97
+ type FunctionReference, type QuerySubscriptionOptions, type QuerySubscriptionSinks, type ResolvedArgs,
98
+ /**
99
+ * `@lunora/client/query` — the framework-neutral live-query state machine shared
100
+ * by every Lunora UI adapter (React, Vue, Svelte, Solid). It owns the seam
101
+ * between a `LunoraClient` subscription and a framework's reactivity primitive:
102
+ * the subscribe → snapshot → error/reset → cleanup lifecycle, with the
103
+ * skip-handling, value/error fan-out, attach-throw normalisation, and
104
+ * cancellation-guarded teardown all in one place. Nothing here imports a UI
105
+ * framework — each adapter supplies thin sinks that write into its own ref /
106
+ * store / signal / cache.
107
+ */
108
+ type ReturnOf, SKIP,
109
+ /**
110
+ * `@lunora/client/query` — the framework-neutral live-query state machine shared
111
+ * by every Lunora UI adapter (React, Vue, Svelte, Solid). It owns the seam
112
+ * between a `LunoraClient` subscription and a framework's reactivity primitive:
113
+ * the subscribe → snapshot → error/reset → cleanup lifecycle, with the
114
+ * skip-handling, value/error fan-out, attach-throw normalisation, and
115
+ * cancellation-guarded teardown all in one place. Nothing here imports a UI
116
+ * framework — each adapter supplies thin sinks that write into its own ref /
117
+ * store / signal / cache.
118
+ */
119
+ type SubscriptionError,
120
+ /**
121
+ * `@lunora/client/query` — the framework-neutral live-query state machine shared
122
+ * by every Lunora UI adapter (React, Vue, Svelte, Solid). It owns the seam
123
+ * between a `LunoraClient` subscription and a framework's reactivity primitive:
124
+ * the subscribe → snapshot → error/reset → cleanup lifecycle, with the
125
+ * skip-handling, value/error fan-out, attach-throw normalisation, and
126
+ * cancellation-guarded teardown all in one place. Nothing here imports a UI
127
+ * framework — each adapter supplies thin sinks that write into its own ref /
128
+ * store / signal / cache.
129
+ */
130
+ type Unsubscribe, createQuerySubscription, toSubscriptionError };
@@ -1 +1 @@
1
- export { SKIP, createQuerySubscription, toSubscriptionError } from '../packem_shared/SKIP-vItZChkw.mjs';
1
+ import{SKIP as t,createQuerySubscription as e,toSubscriptionError as i}from"../packem_shared/SKIP-d7LeP-sY.mjs";export{t as SKIP,e as createQuerySubscription,i as toSubscriptionError};
@@ -0,0 +1,49 @@
1
+ import { F as FunctionReference, A as ArgsOf, R as ReturnOf } from "./packem_shared/function-reference.d-Br_hsKje.mjs";
2
+ /**
3
+ * The wire endpoint every Lunora Worker serves. Matches `createWorker`'s RPC
4
+ * route; the envelope shape below is that route's documented contract.
5
+ */
6
+ declare const RPC_PATH = "/_lunora/rpc";
7
+ /**
8
+ * The slice of a Cloudflare service binding this module uses.
9
+ *
10
+ * Structural on purpose: `env.BACKEND` satisfies it, and so does a one-method
11
+ * fake in a test. Declaring the full `Fetcher` would drag
12
+ * `@cloudflare/workers-types` into every consumer for a single method.
13
+ */
14
+ interface ServiceBindingLike {
15
+ fetch: (request: Request) => Promise<Response>;
16
+ }
17
+ interface ServiceCallOptions {
18
+ /**
19
+ * Route to a specific shard. Omitted, the callee routes to its default shard
20
+ * — the same rule the HTTP path follows, so a sharded app must pass the key
21
+ * it would have passed there.
22
+ */
23
+ shardKey?: string;
24
+ }
25
+ /**
26
+ * A typed caller bound to one Lunora Worker.
27
+ *
28
+ * The three methods are separate rather than one `call` so a reader can tell a
29
+ * read from a write at the call site, and so the reference's `Kind` is checked:
30
+ * passing a mutation reference to `query` is a compile error, matching how
31
+ * `ctx.runQuery`/`ctx.runMutation` behave inside an app.
32
+ */
33
+ interface LunoraServiceClient {
34
+ action: <F extends FunctionReference<"action">>(reference: F, args?: ArgsOf<F>, options?: ServiceCallOptions) => Promise<ReturnOf<F>>;
35
+ mutation: <F extends FunctionReference<"mutation">>(reference: F, args?: ArgsOf<F>, options?: ServiceCallOptions) => Promise<ReturnOf<F>>;
36
+ query: <F extends FunctionReference<"query">>(reference: F, args?: ArgsOf<F>, options?: ServiceCallOptions) => Promise<ReturnOf<F>>;
37
+ }
38
+ /**
39
+ * Build a typed caller for the Lunora Worker behind `binding`.
40
+ *
41
+ * Only PUBLIC functions are reachable. An `internal*` procedure is deliberately
42
+ * absent from the generated `api` object and rejected by the callee, because a
43
+ * service binding is a trust boundary between deployments, not the intra-app
44
+ * `ctx.run*` seam.
45
+ * @param binding The service binding, e.g. `env.BACKEND`.
46
+ * @returns a client whose methods type-check against the generated `api`.
47
+ */
48
+ declare const createServiceClient: (binding: ServiceBindingLike) => LunoraServiceClient;
49
+ export { type LunoraServiceClient, RPC_PATH, type ServiceBindingLike, type ServiceCallOptions, createServiceClient };
@@ -0,0 +1,49 @@
1
+ import { F as FunctionReference, A as ArgsOf, R as ReturnOf } from "./packem_shared/function-reference.d-Br_hsKje.js";
2
+ /**
3
+ * The wire endpoint every Lunora Worker serves. Matches `createWorker`'s RPC
4
+ * route; the envelope shape below is that route's documented contract.
5
+ */
6
+ declare const RPC_PATH = "/_lunora/rpc";
7
+ /**
8
+ * The slice of a Cloudflare service binding this module uses.
9
+ *
10
+ * Structural on purpose: `env.BACKEND` satisfies it, and so does a one-method
11
+ * fake in a test. Declaring the full `Fetcher` would drag
12
+ * `@cloudflare/workers-types` into every consumer for a single method.
13
+ */
14
+ interface ServiceBindingLike {
15
+ fetch: (request: Request) => Promise<Response>;
16
+ }
17
+ interface ServiceCallOptions {
18
+ /**
19
+ * Route to a specific shard. Omitted, the callee routes to its default shard
20
+ * — the same rule the HTTP path follows, so a sharded app must pass the key
21
+ * it would have passed there.
22
+ */
23
+ shardKey?: string;
24
+ }
25
+ /**
26
+ * A typed caller bound to one Lunora Worker.
27
+ *
28
+ * The three methods are separate rather than one `call` so a reader can tell a
29
+ * read from a write at the call site, and so the reference's `Kind` is checked:
30
+ * passing a mutation reference to `query` is a compile error, matching how
31
+ * `ctx.runQuery`/`ctx.runMutation` behave inside an app.
32
+ */
33
+ interface LunoraServiceClient {
34
+ action: <F extends FunctionReference<"action">>(reference: F, args?: ArgsOf<F>, options?: ServiceCallOptions) => Promise<ReturnOf<F>>;
35
+ mutation: <F extends FunctionReference<"mutation">>(reference: F, args?: ArgsOf<F>, options?: ServiceCallOptions) => Promise<ReturnOf<F>>;
36
+ query: <F extends FunctionReference<"query">>(reference: F, args?: ArgsOf<F>, options?: ServiceCallOptions) => Promise<ReturnOf<F>>;
37
+ }
38
+ /**
39
+ * Build a typed caller for the Lunora Worker behind `binding`.
40
+ *
41
+ * Only PUBLIC functions are reachable. An `internal*` procedure is deliberately
42
+ * absent from the generated `api` object and rejected by the callee, because a
43
+ * service binding is a trust boundary between deployments, not the intra-app
44
+ * `ctx.run*` seam.
45
+ * @param binding The service binding, e.g. `env.BACKEND`.
46
+ * @returns a client whose methods type-check against the generated `api`.
47
+ */
48
+ declare const createServiceClient: (binding: ServiceBindingLike) => LunoraServiceClient;
49
+ export { type LunoraServiceClient, RPC_PATH, type ServiceBindingLike, type ServiceCallOptions, createServiceClient };
@@ -0,0 +1 @@
1
+ import{LunoraError as c}from"@lunora/errors";import{encodeArgsOrThrow as d,decodeWire as y}from"@lunora/wire";import{e as f,r as w}from"./packem_shared/wire-errors-BgFi7ONA.mjs";const v="/_lunora/rpc",N="https://lunora.internal",i=async(n,t,r,o,u)=>{const a=r.__lunoraRef,p=JSON.stringify({args:d("@lunora/client/service",a,o??{}),functionPath:a,...u?.shardKey===void 0?{}:{shardKey:u.shardKey}}),e=await n.fetch(new Request(`${N}${v}`,{body:p,headers:{"content-type":"application/json"},method:"POST"}));let s;try{s=await e.json()}catch{throw new c("INTERNAL",`@lunora/client/service: ${t} "${a}" got a non-JSON response (status ${e.status.toString()}). Check the service binding points at the Lunora Worker that declares this function.`,{status:e.status})}if(s===null||typeof s!="object")throw new c("INTERNAL",`@lunora/client/service: ${t} "${a}" returned a JSON body that is not an object (status ${e.status.toString()}). Check the service binding points at the Lunora Worker that declares this function.`,{status:e.status});const h=s,l=f(h);if(l!==void 0)throw w(l);if(!e.ok)throw new c("INTERNAL",`@lunora/client/service: ${t} "${a}" failed with status ${e.status.toString()} and no error envelope.`,{status:e.status});return y(h.result)},R=n=>({action:async(t,r,o)=>await i(n,"action",t,r,o),mutation:async(t,r,o)=>await i(n,"mutation",t,r,o),query:async(t,r,o)=>await i(n,"query",t,r,o)});export{v as RPC_PATH,R as createServiceClient};
@@ -1,6 +1,27 @@
1
- import { P as Preloaded, L as LunoraClient } from "../packem_shared/lunora-client.d-C4ud8bej.mjs";
2
- export type { A as ArgsOf, F as FunctionReference, R as ReturnOf } from "../packem_shared/lunora-client.d-C4ud8bej.mjs";
3
- export { p as preloadQuery, a as preloadedQueryResult } from "../packem_shared/preload.d-Dvk8zg6m.mjs";
1
+ import { P as Preloaded, L as LunoraClient } from "../packem_shared/lunora-client.d-DtTKDhtw.mjs";
2
+ export type { A as ArgsOf, F as FunctionReference, R as ReturnOf } from "../packem_shared/function-reference.d-Br_hsKje.mjs";
3
+ export {
4
+ /**
5
+ * `@lunora/client/ssr` — the framework-neutral server contract that every Lunora
6
+ * meta-framework adapter (React, Solid, Svelte, Vue) depends on. It owns the
7
+ * server-side seam: a request-scoped HTTP RPC client, session resolution from
8
+ * the inbound request, query preloading, and the dehydrate/serialize helpers
9
+ * for handing a preloaded snapshot to the client. Nothing here opens a
10
+ * WebSocket or touches a UI framework, so it is safe to import from any SSR
11
+ * loader.
12
+ */
13
+ p as preloadQuery,
14
+ /**
15
+ * `@lunora/client/ssr` — the framework-neutral server contract that every Lunora
16
+ * meta-framework adapter (React, Solid, Svelte, Vue) depends on. It owns the
17
+ * server-side seam: a request-scoped HTTP RPC client, session resolution from
18
+ * the inbound request, query preloading, and the dehydrate/serialize helpers
19
+ * for handing a preloaded snapshot to the client. Nothing here opens a
20
+ * WebSocket or touches a UI framework, so it is safe to import from any SSR
21
+ * loader.
22
+ */
23
+ a as preloadedQueryResult } from "../packem_shared/preload.d-CT_9YaL9.mjs";
24
+ import '@lunora/errors';
4
25
  import '@lunora/runtime';
5
26
  /**
6
27
  * Structural shape of a better-auth `getSession` call's resolved value.
@@ -55,25 +76,34 @@ type HeadersSource = Headers | Request | {
55
76
  declare const getServerSession: <Result>(request: HeadersSource, auth: AuthLike<Result>) => Promise<NonNullable<Result> | null>;
56
77
  /**
57
78
  * Serialize a {@link Preloaded} token to a JSON string for embedding in the
58
- * rendered HTML (e.g. a `&lt;script>` payload the client
59
- * reads on hydration). Every field of `Preloaded` is JSON-serializable by
60
- * construction — `preloadQuery` only captures the query args, function path,
61
- * optional shard key, and the resolved value — so this is a thin, explicit
62
- * `JSON.stringify` that documents the dehydration seam and keeps callers from
63
- * accidentally stringifying a non-serializable wrapper.
79
+ * rendered HTML (e.g. a `<script>` payload the client
80
+ * reads on hydration).
81
+ *
82
+ * The payload is **wire-encoded** first, exactly as the RPC transport encodes
83
+ * its own bodies ({@link file://../service.ts}). `preloadQuery` captures
84
+ * `await client.query(...)`, whose RPC path ends at `decodeWire(body.result)` —
85
+ * so a `v.bigint()` column arrives here as a real `bigint` (which
86
+ * `JSON.stringify` **throws** on) and a `v.bytes()` column as a real
87
+ * `ArrayBuffer` (which `JSON.stringify` silently degrades to an index-keyed
88
+ * object). The query `args` are user-supplied and carry the same kinds.
89
+ * `encodeWire` is identity for JSON-safe data, so a pure-JSON snapshot
90
+ * serializes byte-for-byte as it did before.
64
91
  *
65
- * The `&lt;` is escaped to `&lt;` so the payload is safe to inline inside a
66
- * `&lt;script>` tag without a stray `&lt;/script>` (or `&lt;!--`) prematurely closing
92
+ * The `<` is escaped to `<` so the payload is safe to inline inside a
93
+ * `<script>` tag without a stray `<\/script>` (or `<!--`) prematurely closing
67
94
  * it — the standard XSS-safe script-embedding precaution. This escaping is NOT
68
- * sufficient for an HTML *attribute* sink (which also needs the quote and `&amp;`
95
+ * sufficient for an HTML *attribute* sink (which also needs the quote and `&`
69
96
  * characters escaped); embed the output in a raw-text script element, not a
70
97
  * data attribute.
71
98
  */
72
99
  declare const serializePreloaded: <T>(preloaded: Preloaded<T>) => string;
73
100
  /**
74
101
  * Inverse of {@link serializePreloaded}: parse a serialized token back into a
75
- * {@link Preloaded} value on the client. The `&lt;` escape from serialization
76
- * is transparent to `JSON.parse`, so no un-escaping step is needed.
102
+ * {@link Preloaded} value on the client, running the parsed payload back
103
+ * through {@link decodeWire} so `bigint` / `ArrayBuffer` / typed-array leaves
104
+ * are restored rather than left in their tagged form. The `<` escape from
105
+ * serialization is transparent to `JSON.parse`, so no un-escaping step is
106
+ * needed.
77
107
  */
78
108
  declare const deserializePreloaded: <T = unknown>(serialized: string) => Preloaded<T>;
79
109
  /** Options accepted by {@link createServerClient}. */
@@ -86,7 +116,7 @@ interface ServerClientOptions {
86
116
  */
87
117
  fetch?: typeof fetch;
88
118
  /**
89
- * Bearer token sent as `Authorization: Bearer &lt;token>` on every RPC. In an
119
+ * Bearer token sent as `Authorization: Bearer <token>` on every RPC. In an
90
120
  * SSR loader you typically read this from the request (e.g. the session
91
121
  * resolved by `getServerSession`) and pass it here so the server-side
92
122
  * load runs as the signed-in user — and so the client subscription that
@@ -1,6 +1,27 @@
1
- import { P as Preloaded, L as LunoraClient } from "../packem_shared/lunora-client.d-C4ud8bej.js";
2
- export type { A as ArgsOf, F as FunctionReference, R as ReturnOf } from "../packem_shared/lunora-client.d-C4ud8bej.js";
3
- export { p as preloadQuery, a as preloadedQueryResult } from "../packem_shared/preload.d-B6-lqUf2.js";
1
+ import { P as Preloaded, L as LunoraClient } from "../packem_shared/lunora-client.d-7WaMRZUK.js";
2
+ export type { A as ArgsOf, F as FunctionReference, R as ReturnOf } from "../packem_shared/function-reference.d-Br_hsKje.js";
3
+ export {
4
+ /**
5
+ * `@lunora/client/ssr` — the framework-neutral server contract that every Lunora
6
+ * meta-framework adapter (React, Solid, Svelte, Vue) depends on. It owns the
7
+ * server-side seam: a request-scoped HTTP RPC client, session resolution from
8
+ * the inbound request, query preloading, and the dehydrate/serialize helpers
9
+ * for handing a preloaded snapshot to the client. Nothing here opens a
10
+ * WebSocket or touches a UI framework, so it is safe to import from any SSR
11
+ * loader.
12
+ */
13
+ p as preloadQuery,
14
+ /**
15
+ * `@lunora/client/ssr` — the framework-neutral server contract that every Lunora
16
+ * meta-framework adapter (React, Solid, Svelte, Vue) depends on. It owns the
17
+ * server-side seam: a request-scoped HTTP RPC client, session resolution from
18
+ * the inbound request, query preloading, and the dehydrate/serialize helpers
19
+ * for handing a preloaded snapshot to the client. Nothing here opens a
20
+ * WebSocket or touches a UI framework, so it is safe to import from any SSR
21
+ * loader.
22
+ */
23
+ a as preloadedQueryResult } from "../packem_shared/preload.d-B26QlpOB.js";
24
+ import '@lunora/errors';
4
25
  import '@lunora/runtime';
5
26
  /**
6
27
  * Structural shape of a better-auth `getSession` call's resolved value.
@@ -55,25 +76,34 @@ type HeadersSource = Headers | Request | {
55
76
  declare const getServerSession: <Result>(request: HeadersSource, auth: AuthLike<Result>) => Promise<NonNullable<Result> | null>;
56
77
  /**
57
78
  * Serialize a {@link Preloaded} token to a JSON string for embedding in the
58
- * rendered HTML (e.g. a `&lt;script>` payload the client
59
- * reads on hydration). Every field of `Preloaded` is JSON-serializable by
60
- * construction — `preloadQuery` only captures the query args, function path,
61
- * optional shard key, and the resolved value — so this is a thin, explicit
62
- * `JSON.stringify` that documents the dehydration seam and keeps callers from
63
- * accidentally stringifying a non-serializable wrapper.
79
+ * rendered HTML (e.g. a `<script>` payload the client
80
+ * reads on hydration).
81
+ *
82
+ * The payload is **wire-encoded** first, exactly as the RPC transport encodes
83
+ * its own bodies ({@link file://../service.ts}). `preloadQuery` captures
84
+ * `await client.query(...)`, whose RPC path ends at `decodeWire(body.result)` —
85
+ * so a `v.bigint()` column arrives here as a real `bigint` (which
86
+ * `JSON.stringify` **throws** on) and a `v.bytes()` column as a real
87
+ * `ArrayBuffer` (which `JSON.stringify` silently degrades to an index-keyed
88
+ * object). The query `args` are user-supplied and carry the same kinds.
89
+ * `encodeWire` is identity for JSON-safe data, so a pure-JSON snapshot
90
+ * serializes byte-for-byte as it did before.
64
91
  *
65
- * The `&lt;` is escaped to `&lt;` so the payload is safe to inline inside a
66
- * `&lt;script>` tag without a stray `&lt;/script>` (or `&lt;!--`) prematurely closing
92
+ * The `<` is escaped to `<` so the payload is safe to inline inside a
93
+ * `<script>` tag without a stray `<\/script>` (or `<!--`) prematurely closing
67
94
  * it — the standard XSS-safe script-embedding precaution. This escaping is NOT
68
- * sufficient for an HTML *attribute* sink (which also needs the quote and `&amp;`
95
+ * sufficient for an HTML *attribute* sink (which also needs the quote and `&`
69
96
  * characters escaped); embed the output in a raw-text script element, not a
70
97
  * data attribute.
71
98
  */
72
99
  declare const serializePreloaded: <T>(preloaded: Preloaded<T>) => string;
73
100
  /**
74
101
  * Inverse of {@link serializePreloaded}: parse a serialized token back into a
75
- * {@link Preloaded} value on the client. The `&lt;` escape from serialization
76
- * is transparent to `JSON.parse`, so no un-escaping step is needed.
102
+ * {@link Preloaded} value on the client, running the parsed payload back
103
+ * through {@link decodeWire} so `bigint` / `ArrayBuffer` / typed-array leaves
104
+ * are restored rather than left in their tagged form. The `<` escape from
105
+ * serialization is transparent to `JSON.parse`, so no un-escaping step is
106
+ * needed.
77
107
  */
78
108
  declare const deserializePreloaded: <T = unknown>(serialized: string) => Preloaded<T>;
79
109
  /** Options accepted by {@link createServerClient}. */
@@ -86,7 +116,7 @@ interface ServerClientOptions {
86
116
  */
87
117
  fetch?: typeof fetch;
88
118
  /**
89
- * Bearer token sent as `Authorization: Bearer &lt;token>` on every RPC. In an
119
+ * Bearer token sent as `Authorization: Bearer <token>` on every RPC. In an
90
120
  * SSR loader you typically read this from the request (e.g. the session
91
121
  * resolved by `getServerSession`) and pass it here so the server-side
92
122
  * load runs as the signed-in user — and so the client subscription that
@@ -1,4 +1 @@
1
- export { getServerSession } from '../packem_shared/getServerSession-8jXewqxd.mjs';
2
- export { deserializePreloaded, serializePreloaded } from '../packem_shared/deserializePreloaded-C0eJTY_W.mjs';
3
- export { createServerClient } from '../packem_shared/createServerClient-DzeC2J3A.mjs';
4
- export { preloadQuery, preloadedQueryResult } from '../packem_shared/preloadQuery-lobFkD2Z.mjs';
1
+ import{getServerSession as o}from"../packem_shared/getServerSession-BaOoo1p6.mjs";import{deserializePreloaded as l,serializePreloaded as t}from"../packem_shared/deserializePreloaded-CyFK_cv6.mjs";import{createServerClient as i}from"../packem_shared/createServerClient-kd9cUs8g.mjs";import{preloadQuery as s,preloadedQueryResult as f}from"../packem_shared/preloadQuery-uFy24PCR.mjs";export{i as createServerClient,l as deserializePreloaded,o as getServerSession,s as preloadQuery,f as preloadedQueryResult,t as serializePreloaded};
@@ -0,0 +1,35 @@
1
+ import { UploadControl, HeadersResolver, UploadRestrictions, ChunkedRestAdapter, MultipartAdapter, TusAdapter } from '@visulima/storage-client';
2
+ export { type ChunkedRestAdapter, type ChunkedRestAdapterOptions, type FingerprintFunction, type HeadersResolver, LocalStorageUrlStorage, MemoryUrlStorage, type MultipartAdapter, type MultipartAdapterOptions, type OnBeforeRequest, type RequestOptions, RestrictionError, type TusAdapter, type TusAdapterOptions, type UploadControl, UploadError, type UploadMethod, type UploadRestrictions, type UploadResult, type Uploader, type UrlStorage, createChunkedRestAdapter, createMultipartAdapter, createTusAdapter, putFile, validateFile, validateFiles } from '@visulima/storage-client';
3
+ /** Resumable upload wire protocols {@link createUpload} can drive. */
4
+ type UploadProtocol = "chunked-rest" | "multipart" | "tus";
5
+ /** The adapter shape {@link createUpload} returns — a `.upload(file)` driver plus lifecycle callbacks. */
6
+ type UploadAdapter = ChunkedRestAdapter | MultipartAdapter | TusAdapter;
7
+ /** Options for {@link createUpload}. */
8
+ interface CreateUploadOptions {
9
+ /** Chunk size in bytes (TUS / chunked-REST only). */
10
+ chunkSize?: number;
11
+ /** A shared {@link UploadControl} for pause/resume/cancel (TUS / chunked-REST). */
12
+ control?: UploadControl;
13
+ /** The upload endpoint — a route backed by `@lunora/storage/upload`'s handler. */
14
+ endpoint: string;
15
+ /** Static or dynamically-resolved request headers (e.g. an `Authorization` token). */
16
+ headers?: HeadersResolver;
17
+ /** Maximum retry attempts (TUS / chunked-REST, when `retry` is on). */
18
+ maxRetries?: number;
19
+ /** Extra metadata sent with the upload. */
20
+ metadata?: Record<string, string>;
21
+ /** Which protocol to speak. Default `"tus"` (resumable, pause/resume-capable). */
22
+ protocol?: UploadProtocol;
23
+ /** Client-side size/type restrictions, validated before any network request. */
24
+ restrictions?: UploadRestrictions;
25
+ /** Enable automatic retry on failure (TUS / chunked-REST). */
26
+ retry?: boolean;
27
+ }
28
+ /**
29
+ * Create a protocol-appropriate upload adapter against an RLS-gated endpoint.
30
+ * Defaults to TUS — the resumable path that survives pause/resume and a dropped
31
+ * connection. Call `.upload(file)` to start; use the shared {@link UploadControl}
32
+ * (or the adapter's `pause`/`resume`/`abort`) to steer it.
33
+ */
34
+ declare const createUpload: (options: CreateUploadOptions) => UploadAdapter;
35
+ export { CreateUploadOptions, UploadAdapter, UploadProtocol, createUpload };