@lunora/replica 1.0.0-alpha.81 → 1.0.0-alpha.82
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/better-sqlite3.d.mts +1 -0
- package/dist/adapters/better-sqlite3.d.ts +1 -0
- package/dist/adapters/better-sqlite3.mjs +1 -1
- package/dist/adapters/sqlite-wasm.mjs +1 -1
- package/dist/adapters/sqljs.d.mts +3 -1
- package/dist/adapters/sqljs.d.ts +3 -1
- package/dist/adapters/sqljs.mjs +1 -1
- package/dist/index.d.mts +7 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.mjs +1 -1
- package/dist/packem_shared/EventLog-SuC_BKwj.mjs +1 -0
- package/dist/packem_shared/EventSource-Bg6zNmRn.mjs +1 -0
- package/dist/packem_shared/LocalMirror-Cc4FE1Le.mjs +4 -0
- package/dist/packem_shared/{MaterializerRuntime-DdszLF-h.mjs → MaterializerRuntime-DFXi-aqd.mjs} +1 -1
- package/dist/packem_shared/{applyDiff-BaUgblCl.mjs → applyDiff-C4pbSYUT.mjs} +1 -1
- package/dist/packem_shared/{applyDiffToDb-DiSnjR45.mjs → applyDiffToDb-zb4sHy-6.mjs} +1 -1
- package/dist/packem_shared/int64-CCVxepl4.mjs +1 -0
- package/dist/packem_shared/{local-mirror.d-CHCqFAg9.d.mts → local-mirror.d-DzREvGNM.d.mts} +23 -8
- package/dist/packem_shared/{local-mirror.d-CvNV3_gk.d.ts → local-mirror.d-wbGXkXaE.d.ts} +23 -8
- package/dist/packem_shared/subscribeToMirror-uA3ZCsLa.mjs +1 -0
- package/dist/packem_shared/wire-key-2vOZ0mPa.mjs +1 -0
- package/dist/react.d.mts +1 -1
- package/dist/react.d.ts +1 -1
- package/package.json +1 -1
- package/dist/packem_shared/EventLog-B1-yhArT.mjs +0 -1
- package/dist/packem_shared/EventSource-BC0hKJSA.mjs +0 -1
- package/dist/packem_shared/LocalMirror-DP6flo3R.mjs +0 -4
- package/dist/packem_shared/subscribeToMirror-Cv24WiWj.mjs +0 -1
- package/dist/packem_shared/wire-key-CU8KEXPo.mjs +0 -1
|
@@ -22,6 +22,7 @@ declare const createBetterSqlite3Adapter: (database: {
|
|
|
22
22
|
run: (params?: unknown[]) => {
|
|
23
23
|
lastInsertRowid: number | bigint;
|
|
24
24
|
};
|
|
25
|
+
safeIntegers: (toggle?: boolean) => unknown;
|
|
25
26
|
};
|
|
26
27
|
transaction: (function_: () => void) => () => void;
|
|
27
28
|
}) => SqliteAdapter;
|
|
@@ -22,6 +22,7 @@ declare const createBetterSqlite3Adapter: (database: {
|
|
|
22
22
|
run: (params?: unknown[]) => {
|
|
23
23
|
lastInsertRowid: number | bigint;
|
|
24
24
|
};
|
|
25
|
+
safeIntegers: (toggle?: boolean) => unknown;
|
|
25
26
|
};
|
|
26
27
|
transaction: (function_: () => void) => () => void;
|
|
27
28
|
}) => SqliteAdapter;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
import{n as c}from"../packem_shared/int64-CCVxepl4.mjs";const p=t=>({exec(r,e){e&&e.length>0?t.prepare(r).run([...e]):t.exec(r)},query(r,e){const n=t.prepare(r);n.safeIntegers(!0);const o=e&&e.length>0?n.all([...e]):n.all();return c(o)},transaction(r){t.transaction(r)()},close(){t.close()}});export{p as createBetterSqlite3Adapter};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
import{n}from"../packem_shared/int64-CCVxepl4.mjs";const x=r=>({exec(o,e){e&&e.length>0?r.exec(o,{bind:[...e]}):r.exec(o)},query(o,e){const c=r.exec(o,{bind:e&&e.length>0?[...e]:void 0,returnValue:"resultRows",rowMode:"object"});return n(c??[])},transaction(o){r.exec("BEGIN");try{o(),r.exec("COMMIT")}catch(e){throw r.exec("ROLLBACK"),e}},close(){r.close()}});export{x as createSqliteWasmAdapter};
|
|
@@ -11,7 +11,9 @@ import { S as SqliteAdapter } from "../packem_shared/types.d-BuLTPLaQ.mjs";
|
|
|
11
11
|
*/
|
|
12
12
|
declare const createSqlJsAdapter: (database: {
|
|
13
13
|
close: () => void;
|
|
14
|
-
exec: (sql: string, params?: unknown[]
|
|
14
|
+
exec: (sql: string, params?: unknown[], config?: {
|
|
15
|
+
useBigInt?: boolean;
|
|
16
|
+
}) => {
|
|
15
17
|
columns: string[];
|
|
16
18
|
values: unknown[][];
|
|
17
19
|
}[];
|
package/dist/adapters/sqljs.d.ts
CHANGED
|
@@ -11,7 +11,9 @@ import { S as SqliteAdapter } from "../packem_shared/types.d-BuLTPLaQ.js";
|
|
|
11
11
|
*/
|
|
12
12
|
declare const createSqlJsAdapter: (database: {
|
|
13
13
|
close: () => void;
|
|
14
|
-
exec: (sql: string, params?: unknown[]
|
|
14
|
+
exec: (sql: string, params?: unknown[], config?: {
|
|
15
|
+
useBigInt?: boolean;
|
|
16
|
+
}) => {
|
|
15
17
|
columns: string[];
|
|
16
18
|
values: unknown[][];
|
|
17
19
|
}[];
|
package/dist/adapters/sqljs.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
import{n as i}from"../packem_shared/int64-CCVxepl4.mjs";const w=o=>({exec(e,r){r&&r.length>0?o.run(e,[...r]):o.exec(e)},query(e,r){const n=o.exec(e,r&&r.length>0?[...r]:void 0,{useBigInt:!0})[0];if(!n)return[];const u=n.columns,t=[];for(const s of n.values){const c={};for(const[l,f]of u.entries())c[f]=s[l];t.push(c)}return i(t)},transaction(e){o.run("BEGIN");try{e(),o.run("COMMIT")}catch(r){throw o.run("ROLLBACK"),r}},close(){o.close()}});export{w as createSqlJsAdapter};
|
package/dist/index.d.mts
CHANGED
|
@@ -17,8 +17,8 @@ createBetterSqlite3Adapter } from "./adapters/better-sqlite3.mjs";
|
|
|
17
17
|
export { createSqliteWasmAdapter } from "./adapters/sqlite-wasm.mjs";
|
|
18
18
|
export { createSqlJsAdapter } from "./adapters/sqljs.mjs";
|
|
19
19
|
import { S as SqliteAdapter } from "./packem_shared/types.d-BuLTPLaQ.mjs";
|
|
20
|
-
import { T as TableDiff, I as InputEvent, S as Seq, E as EventLogEntry, a as EventLog, A as AppendOptions, L as LocalMirror } from "./packem_shared/local-mirror.d-
|
|
21
|
-
export { type C as ClientSeq, type b as EventLogOptions, type c as EventLogSnapshot, type G as GlobalSeq, type d as LocalMirrorOptions, type M as MirrorTableDef, type R as RowChange, e as classifyChanges, f as createTableDiff, g as diffSize, i as isClientSeq, h as isDiffEmpty, j as isGlobalSeq, k as isInputEvent, m as mergeDiffs } from "./packem_shared/local-mirror.d-
|
|
20
|
+
import { T as TableDiff, I as InputEvent, S as Seq, E as EventLogEntry, a as EventLog, A as AppendOptions, L as LocalMirror } from "./packem_shared/local-mirror.d-DzREvGNM.mjs";
|
|
21
|
+
export { type C as ClientSeq, type b as EventLogOptions, type c as EventLogSnapshot, type G as GlobalSeq, type d as LocalMirrorOptions, type M as MirrorTableDef, type R as RowChange, e as classifyChanges, f as createTableDiff, g as diffSize, i as isClientSeq, h as isDiffEmpty, j as isGlobalSeq, k as isInputEvent, m as mergeDiffs } from "./packem_shared/local-mirror.d-DzREvGNM.mjs";
|
|
22
22
|
/**
|
|
23
23
|
* Apply a single {@link TableDiff} to an in-memory row map and return
|
|
24
24
|
* the updated map.
|
|
@@ -861,6 +861,11 @@ interface SubscriptionClient {
|
|
|
861
861
|
* into the same mirror: they'd share one table and the snapshot-delete pass of
|
|
862
862
|
* one could remove rows still live in the other.
|
|
863
863
|
*
|
|
864
|
+
* `mirror.clearData()` resets the remembered frame. Without that reset the next
|
|
865
|
+
* identical frame diffed clean against a mirror that no longer held the rows —
|
|
866
|
+
* no changes, no `applyDiff` — and the table stayed empty until some row's
|
|
867
|
+
* content happened to change or the page reloaded.
|
|
868
|
+
*
|
|
864
869
|
* Call the returned unsubscribe function to tear down both the client
|
|
865
870
|
* subscription and future mirror writes.
|
|
866
871
|
* @example
|
package/dist/index.d.ts
CHANGED
|
@@ -17,8 +17,8 @@ createBetterSqlite3Adapter } from "./adapters/better-sqlite3.js";
|
|
|
17
17
|
export { createSqliteWasmAdapter } from "./adapters/sqlite-wasm.js";
|
|
18
18
|
export { createSqlJsAdapter } from "./adapters/sqljs.js";
|
|
19
19
|
import { S as SqliteAdapter } from "./packem_shared/types.d-BuLTPLaQ.js";
|
|
20
|
-
import { T as TableDiff, I as InputEvent, S as Seq, E as EventLogEntry, a as EventLog, A as AppendOptions, L as LocalMirror } from "./packem_shared/local-mirror.d-
|
|
21
|
-
export { type C as ClientSeq, type b as EventLogOptions, type c as EventLogSnapshot, type G as GlobalSeq, type d as LocalMirrorOptions, type M as MirrorTableDef, type R as RowChange, e as classifyChanges, f as createTableDiff, g as diffSize, i as isClientSeq, h as isDiffEmpty, j as isGlobalSeq, k as isInputEvent, m as mergeDiffs } from "./packem_shared/local-mirror.d-
|
|
20
|
+
import { T as TableDiff, I as InputEvent, S as Seq, E as EventLogEntry, a as EventLog, A as AppendOptions, L as LocalMirror } from "./packem_shared/local-mirror.d-wbGXkXaE.js";
|
|
21
|
+
export { type C as ClientSeq, type b as EventLogOptions, type c as EventLogSnapshot, type G as GlobalSeq, type d as LocalMirrorOptions, type M as MirrorTableDef, type R as RowChange, e as classifyChanges, f as createTableDiff, g as diffSize, i as isClientSeq, h as isDiffEmpty, j as isGlobalSeq, k as isInputEvent, m as mergeDiffs } from "./packem_shared/local-mirror.d-wbGXkXaE.js";
|
|
22
22
|
/**
|
|
23
23
|
* Apply a single {@link TableDiff} to an in-memory row map and return
|
|
24
24
|
* the updated map.
|
|
@@ -861,6 +861,11 @@ interface SubscriptionClient {
|
|
|
861
861
|
* into the same mirror: they'd share one table and the snapshot-delete pass of
|
|
862
862
|
* one could remove rows still live in the other.
|
|
863
863
|
*
|
|
864
|
+
* `mirror.clearData()` resets the remembered frame. Without that reset the next
|
|
865
|
+
* identical frame diffed clean against a mirror that no longer held the rows —
|
|
866
|
+
* no changes, no `applyDiff` — and the table stayed empty until some row's
|
|
867
|
+
* content happened to change or the page reloaded.
|
|
868
|
+
*
|
|
864
869
|
* Call the returned unsubscribe function to tear down both the client
|
|
865
870
|
* subscription and future mirror writes.
|
|
866
871
|
* @example
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createBetterSqlite3Adapter as o}from"./adapters/better-sqlite3.mjs";import{createSqliteWasmAdapter as f}from"./adapters/sqlite-wasm.mjs";import{createSqlJsAdapter as i}from"./adapters/sqljs.mjs";import{applyDiff as m,applyDiffToSnapshot as n,applyDiffs as x}from"./packem_shared/applyDiff-
|
|
1
|
+
import{createBetterSqlite3Adapter as o}from"./adapters/better-sqlite3.mjs";import{createSqliteWasmAdapter as f}from"./adapters/sqlite-wasm.mjs";import{createSqlJsAdapter as i}from"./adapters/sqljs.mjs";import{applyDiff as m,applyDiffToSnapshot as n,applyDiffs as x}from"./packem_shared/applyDiff-C4pbSYUT.mjs";import{defineEvents as l}from"./packem_shared/defineEvents-DHo-VK7G.mjs";import{MaterializerRuntime as S,defineMaterializer as E}from"./packem_shared/MaterializerRuntime-DFXi-aqd.mjs";import{applyDiffToDb as v,applyDiffsToDb as y}from"./packem_shared/applyDiffToDb-zb4sHy-6.mjs";import{EventEmitter as d}from"./packem_shared/EventEmitter-uo75adUL.mjs";import{EventLog as M}from"./packem_shared/EventLog-SuC_BKwj.mjs";import{EventLogDO as u}from"./packem_shared/EventLogDO-BgUx2GGL.mjs";import{EventLogDOClient as T}from"./packem_shared/EventLogDOClient-DWerZ3_n.mjs";import{EventSource as C,UNHANDLED as h}from"./packem_shared/EventSource-Bg6zNmRn.mjs";import{eventsContext as I}from"./packem_shared/eventsContext-Dxow9Y7S.mjs";import{LocalMirror as O}from"./packem_shared/LocalMirror-Cc4FE1Le.mjs";import{isClientSeq as G,isGlobalSeq as H,isInputEvent as J}from"./packem_shared/isClientSeq-D2Xm0_lj.mjs";import{InMemorySnapshotStore as U}from"./packem_shared/InMemorySnapshotStore-C4taIG5K.mjs";import{subscribeToMirror as j}from"./packem_shared/subscribeToMirror-uA3ZCsLa.mjs";import{SubscriptionManager as w}from"./packem_shared/SubscriptionManager-AhPw3lFc.mjs";import{EventsSync as K}from"./packem_shared/EventsSync-B3wzXm-b.mjs";import{classifyChanges as Q,createTableDiff as V,diffSize as X,isDiffEmpty as Y,mergeDiffs as Z}from"./packem_shared/classifyChanges-BBc0-770.mjs";export{d as EventEmitter,M as EventLog,u as EventLogDO,T as EventLogDOClient,C as EventSource,K as EventsSync,U as InMemorySnapshotStore,O as LocalMirror,S as MaterializerRuntime,w as SubscriptionManager,h as UNHANDLED,m as applyDiff,v as applyDiffToDb,n as applyDiffToSnapshot,x as applyDiffs,y as applyDiffsToDb,Q as classifyChanges,o as createBetterSqlite3Adapter,i as createSqlJsAdapter,f as createSqliteWasmAdapter,V as createTableDiff,l as defineEvents,E as defineMaterializer,X as diffSize,I as eventsContext,G as isClientSeq,Y as isDiffEmpty,H as isGlobalSeq,J as isInputEvent,Z as mergeDiffs,j as subscribeToMirror};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
class f{#e=[];#t=0;#i=0;#s=null;#n;constructor(t){this.#n=f.#o(t?.maxEntries)}static#o(t){if(t!==void 0){if(!Number.isSafeInteger(t)||t<0)throw new RangeError("maxEntries must be a non-negative safe integer");return t}}#r(){return this.#e.slice(this.#t)}#h(){if(this.#n===void 0)return;const e=this.#e.length-this.#t-this.#n;e>0&&(this.#t+=e),this.#t>0&&this.#t>=this.#e.length-this.#t&&(this.#e=this.#e.slice(this.#t),this.#t=0)}append(t,e,s,n){const r=typeof t=="string"?t:t.type,o=typeof t=="string"?e:t.payload;let h,i;typeof t=="string"?(h=s,i=n):(h=void 0,i=e);const a=i?.parentSeqNum??this.#s??void 0,l=this.#i;this.#i+=1;const c={seq:l,type:r,payload:o,timestamp:i?.timestamp??(typeof t=="string"?void 0:t.timestamp)??Date.now(),tableDiffs:h,clientId:i?.clientId,sessionId:i?.sessionId,parentSeqNum:a};return this.#e.push(c),this.#s=c.seq,this.#h(),c}commitAll(t){if(t.length===0)return[];const e=[];for(const s of t){const{type:n}=s,r="payload"in s?s.payload:void 0,o="timestamp"in s?s.timestamp:Date.now(),h=e.at(-1)?.seq??this.#s??void 0,i=this.#i;this.#i+=1;const a={seq:i,type:n,payload:r,timestamp:o,parentSeqNum:h};this.#e.push(a),e.push(a)}return this.#s=e.at(-1)?.seq??this.#s,this.#h(),e}load(t){this.#e=[...t.entries],this.#t=0,this.#i=t.nextSeq,this.#s=t.headSeq,this.#h()}getSince(t){const e=this.#r();if(t<=0)return e;const s=e.findIndex(n=>n.seq>=t);return s===-1?[]:e.slice(s)}getFrom(t,e=50){if(!Number.isSafeInteger(e)||e<1)throw new RangeError("limit must be a positive safe integer");const s=this.#e,n=this.#t,r=s.findIndex((h,i)=>i>=n&&h.seq>=t);if(r===-1)return{entries:[],hasMore:!1};const o=Math.min(r+e,s.length);return{entries:s.slice(r,o),hasMore:o<s.length}}snapshot(){return{entries:this.#r(),nextSeq:this.#i,headSeq:this.#s}}get size(){return this.#e.length-this.#t}get nextSeq(){return this.#i}get isEmpty(){return this.size===0}get headSeq(){return this.#s}clear(){this.#e=[],this.#t=0,this.#i=0,this.#s=null}truncateBelow(t){if(!Number.isSafeInteger(t)||t<0)throw new RangeError("floorSeq must be a non-negative safe integer");const e=this.#r(),s=e.findIndex(n=>n.seq>=t);this.#e=s===-1?[]:e.slice(s),this.#t=0}async*events(t=0){const e=this.getSince(t);for(const s of e)yield s}}export{f as EventLog};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{EventEmitter as m}from"./EventEmitter-uo75adUL.mjs";import{EventLog as u}from"./EventLog-SuC_BKwj.mjs";const d=Symbol("lunora.replica.event-source.unhandled");class w{emitter=new m;log;#e;#t;#n=!1;#i;#r=-1;constructor(e,n,t){this.#e={...e},this.#t=n,this.#i=t?.unknownEventHandling??"warn",this.log=new u({maxEntries:t?.maxLogEntries})}get state(){return this.#e}get replayed(){return this.#n}applyEvent(e,n,t){let r,o,i;typeof e=="string"?(r=e,o=n,i=t):(r=e.type,o=e.payload,i=n);const s={seq:this.log.nextSeq,type:r,payload:o,timestamp:Date.now(),clientId:i?.clientId,sessionId:i?.sessionId,parentSeqNum:i?.parentSeqNum??this.log.headSeq??void 0};let a;try{a=this.#t(this.#e,s)}catch(l){const p=l instanceof Error?l:new Error(String(l));throw this.emitter.emit("replay-error",{entry:s,error:p}),p}let c=!0;a===d&&(c=this.#s(s));const h=this.log.append(r,o,void 0,{...i,timestamp:s.timestamp});return a===d?(c&&this.emitter.emit("state-changed",{state:this.#e,entry:h}),h):(this.#e=a,this.emitter.emit("state-changed",{state:this.#e,entry:h}),h)}replayFromLog(e){const n=e.getSince(this.#r+1);for(const t of n)try{const r=this.#t(this.#e,t);r!==d&&(this.#e=r);const o=this.log.append(t.type,t.payload,t.tableDiffs,{clientId:t.clientId,sessionId:t.sessionId,parentSeqNum:t.parentSeqNum,timestamp:t.timestamp});this.emitter.emit("state-changed",{state:this.#e,entry:o})}catch(r){this.emitter.emit("replay-error",{entry:t,error:r instanceof Error?r:new Error(String(r))})}finally{this.#r=t.seq}this.#n=!0,this.emitter.emit("ready",{entryCount:this.log.size})}reset(e,n=-1){this.#e={...e},this.#r=n,this.#n=n>=0}async*events(e){const n=[];let t;const r=this.emitter.on("state-changed",({entry:i})=>{n.push(i),t?.()}),o=()=>{t?.()};e?.addEventListener("abort",o,{once:!0});try{let i=0;for(;i<this.log.size;){if(e?.aborted)return;for(const s of this.log.getSince(i))yield s;i=this.log.nextSeq}for(;!e?.aborted;){for(;n.length>0;){const s=n.shift();s&&(yield s)}n.length===0&&await new Promise(s=>{t=s})}}finally{r(),e?.removeEventListener("abort",o)}}#s(e){const n=this.#i;if(typeof n=="function")return n(e);switch(n){case"ignore":return!1;case"fail":throw new Error(`EventSource: unhandled event type "${e.type}" (seq ${String(e.seq)}). Configure \`unknownEventHandling\` to handle this event or change the strategy.`);default:return console.warn(`[EventSource] unhandled event type "${e.type}" (seq ${String(e.seq)}). The event was skipped. Configure \`unknownEventHandling\` if this is expected.`),!1}}}export{w as EventSource,d as UNHANDLED};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{createSqlJsAdapter as m}from"../adapters/sqljs.mjs";import{applyDiffToDb as b,escapeIdentifier as o}from"./applyDiffToDb-zb4sHy-6.mjs";import{EventLog as p}from"./EventLog-SuC_BKwj.mjs";const A=1e3,f="__lunora_mirror_meta",R=a=>{a.exec(`CREATE TABLE IF NOT EXISTS ${f} (
|
|
2
|
+
key TEXT PRIMARY KEY NOT NULL,
|
|
3
|
+
value TEXT NOT NULL
|
|
4
|
+
)`)},T="schema_version",y=4,l=a=>typeof a=="bigint"||typeof a=="boolean"?"INTEGER":typeof a=="number"?Number.isInteger(a)?"INTEGER":"REAL":"TEXT",h=a=>a??"";class E{#e;#t;#n;#s=new Set;#i=0;static create(e,t){const n=m(e);return new E({db:n,tables:t?.tables})}constructor(e){this.#e=e.db,this.#t={...e.tables},this.#n=new p({maxEntries:e.maxEventLogEntries??A}),R(this.#e),this.#o()}onChange(e){return this.#s.add(e),()=>{this.#s.delete(e)}}get eventLog(){return this.#n}get db(){return this.#e}get version(){return this.#i}applyDiff(e){e.changes.length!==0&&(this.#h(e),b(this.#e,e,this.primaryKeyOf(e.table)),this.#n.append("table-diff",e,[e]),this.#r("diff"))}query(e,t){return this.#e.query(e,t)}clearData(){const e=this.#a();this.#e.transaction(()=>{for(const{name:t}of e)this.#e.exec(`DELETE FROM ${o(t)}`)}),this.#r("clear")}#r(e){this.#i+=1;for(const t of this.#s)try{t(e)}catch{}}close(){this.#e.close(),this.#n.clear(),this.#s.clear()}registerTable(e,t){this.#t[e]={...this.#t[e],...t}}primaryKeyOf(e){return this.#t[e]?.primaryKey??"id"}get mirroredTables(){return Object.keys(this.#t)}#a(){return this.#e.query(String.raw`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE '\_\_lunora\_%' ESCAPE '\' AND name NOT LIKE 'sqlite\_%' ESCAPE '\'`)}#o(){if(this.#e.query(`SELECT key, value FROM ${f}`).find(s=>s.key===T)?.value===String(y))return;const n=this.#a();this.#e.transaction(()=>{for(const{name:s}of n)this.#e.exec(`DROP TABLE IF EXISTS ${o(s)}`);this.#e.exec(`INSERT OR REPLACE INTO ${f} (key, value) VALUES (?, ?)`,[T,String(y)])})}static#c(e,t){const n=new Set;for(const s of e.changes)if(s.type!=="delete")for(const c of Object.keys(s.data))c!==t&&n.add(c);return n}static#E(e,t,n){const s=new Map;for(const c of e.changes)if(!(c.type==="delete"||s.size===n.size))for(const r of n){if(r===t||s.has(r))continue;const i=c.data[r];i!=null&&s.set(r,l(i))}return s}static#l(e,t){for(const n of e.changes){const s=n.type==="delete"?n.id:n.data[t];if(s!=null)return l(s);if(n.type==="update")return l(n.id)}}#h(e){const t=this.primaryKeyOf(e.table),n=E.#c(e,t),s=E.#E(e,t,n);if(this.#e.query("SELECT name FROM sqlite_master WHERE type='table' AND name=?",[e.table]).length===0){const r=E.#l(e,t);let i=`${o(t)} ${r==="INTEGER"?"INT":h(r)} PRIMARY KEY NOT NULL`;for(const u of n)i+=`, ${o(u)} ${h(s.get(u))}`;this.#e.exec(`CREATE TABLE IF NOT EXISTS ${o(e.table)} (${i})`)}else if(n.size>0){const r=new Set(this.#e.query(`PRAGMA table_info(${o(e.table)})`).map(i=>i.name));for(const i of n)r.has(i)||this.#e.exec(`ALTER TABLE ${o(e.table)} ADD COLUMN ${o(i)} ${h(s.get(i))}`)}}}export{E as LocalMirror};
|
package/dist/packem_shared/{MaterializerRuntime-DdszLF-h.mjs → MaterializerRuntime-DFXi-aqd.mjs}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{UNHANDLED as o}from"./EventSource-
|
|
1
|
+
import{UNHANDLED as o}from"./EventSource-Bg6zNmRn.mjs";const h=1e3,p=s=>{let e=s.initial();return{def:s,get state(){return Object.freeze(e)},setState(t){e=t},apply(t){const n=s.handle(e,t);return n===o?!1:(e=n,!0)},reset(){e=s.initial()}}};class c{#e;#n;#i;#r;#t;constructor(e,t={}){this.#e=[...e],this.#t=this.#e.map(()=>0),this.#n=t.snapshotStore,this.#i=t.doClient,this.#r=t.unknownEventHandling??"warn"}get appliedSeq(){return this.#t.length>0?Math.min(...this.#t):0}applyEntries(e){let t=0;for(const n of e){const{advancedIndices:r,anyHandled:i}=this.#a(n);if(r.length!==0){!i&&r.length===this.#e.length&&this.#o(n);for(const a of r)this.#t[a]=n.seq+1;t+=1}}return t}#a(e){const t=[];let n=!1;for(const[r,i]of this.#e.entries())e.seq<(this.#t[r]??0)||(i.apply(e)&&(n=!0),t.push(r));return{advancedIndices:t,anyHandled:n}}#o(e){const t=this.#r;if(typeof t=="function"){t(e);return}switch(t){case"ignore":return;case"fail":throw new Error(`MaterializerRuntime: unhandled event type "${e.type}" (seq ${String(e.seq)}). Configure \`unknownEventHandling\` to handle this event or change the strategy.`);default:console.warn(`[MaterializerRuntime] unhandled event type "${e.type}" (seq ${String(e.seq)}). The event was skipped. Configure \`unknownEventHandling\` if this is expected.`)}}async recoverFromSnapshots(){if(!this.#n)return 0;let e=0;for(const[t,n]of this.#e.entries()){const r=await this.#n.load(n.def.name);if(r!==null&&typeof r=="object"){const i=r;if(Number.isSafeInteger(i.appliedSeq)&&i.appliedSeq>=0&&i.state!==void 0){const a=i.appliedSeq;n.setState(i.state),this.#t[t]=a,a>e&&(e=a)}}}return e}async persistSnapshots(){if(this.#n)for(const[e,t]of this.#e.entries())await this.#n.save(t.def.name,{appliedSeq:this.#t[e]??0,state:t.state})}async initialize(){return this.#i?(await this.recoverFromSnapshots(),this.#s()):0}async#s(){const e=this.#i;if(!e)return 0;let t=this.appliedSeq,n=0;for(let r=0;r<h;r+=1){const i=await e.getSince(t);if(n+=this.applyEntries(i.entries),!i.truncated||i.cursor===void 0||i.cursor<=t)return n;t=i.cursor}return n}async appendEvent(e){if(!this.#i)throw new Error("MaterializerRuntime.appendEvent requires a doClient — pass one in the constructor options.");const n=(await this.#i.append([e]))[0];if(!n)throw new Error("MaterializerRuntime.appendEvent: DO returned empty result");return this.#e.length>0&&this.appliedSeq<n.seq&&(await this.#s(),this.appliedSeq<n.seq)||this.applyEntries([n]),n}reset(){for(const[e,t]of this.#e.entries())this.#t[e]=0,t.reset()}get materializers(){return this.#e}}export{c as MaterializerRuntime,p as defineMaterializer};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{f as r}from"./fnv1a-BNN96GYb.mjs";import{s as p}from"./wire-key-
|
|
1
|
+
import{f as r}from"./fnv1a-BNN96GYb.mjs";import{s as p}from"./wire-key-2vOZ0mPa.mjs";const c=(e,n)=>`row-${r(`${e.table}::${p(n)}`)}`,o=(e,n)=>{for(const t of n.changes)switch(t.type){case"delete":{e.delete(t.id);break}case"insert":{const a=t.data.id,s=typeof a=="bigint"||typeof a=="number"||typeof a=="string"?String(a):c(n,t.data);e.set(s,{...t.data,id:s});break}case"update":{const a=e.get(t.id);a&&e.set(t.id,{...a,...t.data});break}}},i=(e,n)=>{const t=new Map(e);return o(t,n),t},l=(e,n)=>{const t=new Map(e);for(const a of n)o(t,a);return t},b=(e,n)=>{const t=new Map(e),a=t.get(n.table)??new Map;return t.set(n.table,i(a,n)),t};export{i as applyDiff,b as applyDiffToSnapshot,l as applyDiffs,c as deriveInsertId,r as fnv1a64Hex};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{deriveInsertId as $}from"./applyDiff-
|
|
1
|
+
import{deriveInsertId as $}from"./applyDiff-C4pbSYUT.mjs";const p=t=>`\`${t.replaceAll("`","``")}\``,D=t=>t.map(n=>`${p(n)} = ?`).join(", "),h=t=>`(${t.map(n=>p(n)).join(", ")})`,T=t=>`(${Array.from({length:t}).fill("?").join(", ")})`,f=t=>t==null?null:typeof t=="number"||typeof t=="bigint"||typeof t=="string"?t:typeof t=="boolean"?t?1:0:t instanceof Uint8Array?t:typeof t=="object"?JSON.stringify(t):String(t),g=(t,n,o)=>{if(n.changes.length===0)return;const a=p(n.table),l=p(o);for(const i of n.changes)switch(i.type){case"delete":{t.exec(`DELETE FROM ${a} WHERE ${l} = ?`,[f(i.id)]);break}case"insert":{const{data:e}=i;if(Object.keys(e).length===0)continue;const s=e[o],c=typeof s=="bigint"||typeof s=="number"||typeof s=="string"?e:{...e,[o]:$(n,e)},r=Object.keys(c),y=`INSERT OR REPLACE INTO ${a} ${h(r)} VALUES ${T(r.length)}`,b=r.map(E=>f(c[E]));t.exec(y,b);break}case"update":{const{data:e}=i,s=Object.keys(e);if(s.length===0)continue;const c=`UPDATE ${a} SET ${D(s)} WHERE ${l} = ?`,r=[...s.map(y=>f(e[y])),f(i.id)];t.exec(c,r);break}}},d=(t,n,o)=>{t.transaction(()=>{g(t,n,o??"id")})},j=(t,n)=>{n.length!==0&&t.transaction(()=>{for(const o of n)g(t,o,"id")})};export{d as applyDiffToDb,j as applyDiffsToDb,p as escapeIdentifier,f as normalizeBindValue};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const I=n=>typeof n=="bigint"&&n>=BigInt(Number.MIN_SAFE_INTEGER)&&n<=BigInt(Number.MAX_SAFE_INTEGER)?Number(n):n,c=n=>n.map(t=>{let e;for(const[s,r]of Object.entries(t)){const o=I(r);o!==r&&(e??={...t},e[s]=o)}return e??t});export{c as n};
|
|
@@ -31,13 +31,14 @@ interface TableDiff {
|
|
|
31
31
|
/**
|
|
32
32
|
* Optional stable identity for this diff, distinct from `timestamp`
|
|
33
33
|
* (multiple diffs can legitimately share a millisecond, so `timestamp`
|
|
34
|
-
* alone is not a unique diff identity).
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
34
|
+
* alone is not a unique diff identity). `createTableDiff` auto-generates
|
|
35
|
+
* one when omitted.
|
|
36
|
+
*
|
|
37
|
+
* **Nothing in the apply path reads it.** `deriveInsertId` (`apply-diff.ts`)
|
|
38
|
+
* keys an id-less insert off the ROW'S OWN content — hashing the diff id
|
|
39
|
+
* into it is what made `subscribeToMirror`'s per-frame re-emission mint a
|
|
40
|
+
* fresh row every second, so that derivation is gone. This field is
|
|
41
|
+
* carried for consumers that want to recognise a diff they have seen.
|
|
41
42
|
*/
|
|
42
43
|
readonly id?: string;
|
|
43
44
|
/** Logical table name (matches the schema table name). */
|
|
@@ -312,6 +313,11 @@ declare class EventLog {
|
|
|
312
313
|
getSince(sinceSeq: number): ReadonlyArray<EventLogEntry>;
|
|
313
314
|
/**
|
|
314
315
|
* Paginated read starting at `fromSeq`.
|
|
316
|
+
*
|
|
317
|
+
* `limit` must be a positive safe integer, validated like
|
|
318
|
+
* {@link EventLog#truncateBelow}'s floor and the constructor's `maxEntries`:
|
|
319
|
+
* a `limit` of `0` returned an empty page with `hasMore: true`, which spins a
|
|
320
|
+
* paginating caller forever on a page it can never advance past.
|
|
315
321
|
* @returns `{ entries, hasMore }` where `hasMore` is `true` when more
|
|
316
322
|
* entries exist beyond the requested page.
|
|
317
323
|
*/
|
|
@@ -405,6 +411,15 @@ interface LocalMirrorOptions {
|
|
|
405
411
|
*/
|
|
406
412
|
readonly tables?: Record<string, MirrorTableDef>;
|
|
407
413
|
}
|
|
414
|
+
/**
|
|
415
|
+
* Why the mirror changed: `"diff"` for the rows an {@link LocalMirror.applyDiff}
|
|
416
|
+
* wrote, `"clear"` for the wholesale {@link LocalMirror.clearData} sweep.
|
|
417
|
+
*
|
|
418
|
+
* A subscriber that caches what it believes the mirror holds has to tell the two
|
|
419
|
+
* apart: `"diff"` reports a change it usually made itself, while `"clear"` means
|
|
420
|
+
* every row it was tracking is gone regardless of who wrote it.
|
|
421
|
+
*/
|
|
422
|
+
type MirrorChangeReason = "clear" | "diff";
|
|
408
423
|
/**
|
|
409
424
|
* Local SQLite mirror that maintains a client-side replica of server
|
|
410
425
|
* tables by applying {@link TableDiff} deltas.
|
|
@@ -429,7 +444,7 @@ interface LocalMirrorOptions {
|
|
|
429
444
|
* );
|
|
430
445
|
* ```
|
|
431
446
|
*/
|
|
432
|
-
type ChangeSubscriber = () => void;
|
|
447
|
+
type ChangeSubscriber = (reason: MirrorChangeReason) => void;
|
|
433
448
|
/**
|
|
434
449
|
* `LocalMirror` is part of the experimental `@lunora/replica` API and may change without a major version bump.
|
|
435
450
|
* @experimental
|
|
@@ -31,13 +31,14 @@ interface TableDiff {
|
|
|
31
31
|
/**
|
|
32
32
|
* Optional stable identity for this diff, distinct from `timestamp`
|
|
33
33
|
* (multiple diffs can legitimately share a millisecond, so `timestamp`
|
|
34
|
-
* alone is not a unique diff identity).
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
34
|
+
* alone is not a unique diff identity). `createTableDiff` auto-generates
|
|
35
|
+
* one when omitted.
|
|
36
|
+
*
|
|
37
|
+
* **Nothing in the apply path reads it.** `deriveInsertId` (`apply-diff.ts`)
|
|
38
|
+
* keys an id-less insert off the ROW'S OWN content — hashing the diff id
|
|
39
|
+
* into it is what made `subscribeToMirror`'s per-frame re-emission mint a
|
|
40
|
+
* fresh row every second, so that derivation is gone. This field is
|
|
41
|
+
* carried for consumers that want to recognise a diff they have seen.
|
|
41
42
|
*/
|
|
42
43
|
readonly id?: string;
|
|
43
44
|
/** Logical table name (matches the schema table name). */
|
|
@@ -312,6 +313,11 @@ declare class EventLog {
|
|
|
312
313
|
getSince(sinceSeq: number): ReadonlyArray<EventLogEntry>;
|
|
313
314
|
/**
|
|
314
315
|
* Paginated read starting at `fromSeq`.
|
|
316
|
+
*
|
|
317
|
+
* `limit` must be a positive safe integer, validated like
|
|
318
|
+
* {@link EventLog#truncateBelow}'s floor and the constructor's `maxEntries`:
|
|
319
|
+
* a `limit` of `0` returned an empty page with `hasMore: true`, which spins a
|
|
320
|
+
* paginating caller forever on a page it can never advance past.
|
|
315
321
|
* @returns `{ entries, hasMore }` where `hasMore` is `true` when more
|
|
316
322
|
* entries exist beyond the requested page.
|
|
317
323
|
*/
|
|
@@ -405,6 +411,15 @@ interface LocalMirrorOptions {
|
|
|
405
411
|
*/
|
|
406
412
|
readonly tables?: Record<string, MirrorTableDef>;
|
|
407
413
|
}
|
|
414
|
+
/**
|
|
415
|
+
* Why the mirror changed: `"diff"` for the rows an {@link LocalMirror.applyDiff}
|
|
416
|
+
* wrote, `"clear"` for the wholesale {@link LocalMirror.clearData} sweep.
|
|
417
|
+
*
|
|
418
|
+
* A subscriber that caches what it believes the mirror holds has to tell the two
|
|
419
|
+
* apart: `"diff"` reports a change it usually made itself, while `"clear"` means
|
|
420
|
+
* every row it was tracking is gone regardless of who wrote it.
|
|
421
|
+
*/
|
|
422
|
+
type MirrorChangeReason = "clear" | "diff";
|
|
408
423
|
/**
|
|
409
424
|
* Local SQLite mirror that maintains a client-side replica of server
|
|
410
425
|
* tables by applying {@link TableDiff} deltas.
|
|
@@ -429,7 +444,7 @@ interface LocalMirrorOptions {
|
|
|
429
444
|
* );
|
|
430
445
|
* ```
|
|
431
446
|
*/
|
|
432
|
-
type ChangeSubscriber = () => void;
|
|
447
|
+
type ChangeSubscriber = (reason: MirrorChangeReason) => void;
|
|
433
448
|
/**
|
|
434
449
|
* `LocalMirror` is part of the experimental `@lunora/replica` API and may change without a major version bump.
|
|
435
450
|
* @experimental
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{s as A}from"./wire-key-2vOZ0mPa.mjs";const _=e=>`fn_${e.replaceAll(/[/:.]/g,"_")}`,k=e=>Array.isArray(e)?e:e!==null&&typeof e=="object"?[e]:[],x=(e,o,l,y,g)=>{const a=_(l.__lunoraRef);o.registerTable(a,{});const d=o.primaryKeyOf(a);let r=new Map,f=0;const w=o.onChange(p=>{p==="clear"&&(f+=1,r=new Map)}),h=e.subscribe(l,y,p=>{const M=f,c=new Map,b=new Map,s=[];for(const t of k(p)){const n=t,i=n[d];if(typeof i!="string"&&typeof i!="number"&&typeof i!="bigint"){s.push({type:"insert",data:n});continue}const u=String(i),m=A(n);c.set(u,m),b.set(u,n)}for(const[t,n]of c)r.get(t)!==n&&s.push({data:b.get(t),type:"insert"});for(const t of r.keys())c.has(t)||s.push({type:"delete",id:t});s.length>0&&o.applyDiff({table:a,changes:s,timestamp:Date.now()}),M===f&&(r=c)},{shardKey:g});return()=>{w(),h()}};export{x as subscribeToMirror};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const m=/["\\\u0000-\u001F\uD800-\uDFFF]/,d=r=>m.test(r)?JSON.stringify(r):`"${r}"`,b=r=>{if(r===void 0)return"null";if(typeof r=="bigint")throw new TypeError("stableStringify: cannot use a bigint in a stable JSON cache key — pass it as a string, or use stableWireKey");if(typeof r=="number"){if(Number.isNaN(r))return"nan";if(r===1/0)return"inf";if(r===-1/0)return"-inf";if(Object.is(r,-0))return"-0"}if(typeof r=="string")return d(r);if(r===null||typeof r!="object")return JSON.stringify(r);if(Array.isArray(r)){let e="[";for(let i=0;i<r.length;i++)i>0&&(e+=","),e+=b(r[i]);return e+"]"}const n=Object.getPrototypeOf(r);if(n!==null&&n!==Object.prototype){const e=r.constructor?.name??"value";throw new TypeError(`stableStringify: cannot use a ${e} in a stable JSON cache key — only plain objects, arrays, and JSON primitives are supported (wire-typed values key via stableWireKey)`)}const y=r,s=Object.keys(y).sort();let f="{",t=!0;for(const e of s){const i=y[e];i!==void 0&&(t?t=!1:f+=",",f+=d(e),f+=":",f+=b(i))}return f+"}"},u=r=>{let n="";for(let s=0;s<r.length;s+=32768)n+=String.fromCharCode(...r.subarray(s,s+32768));return btoa(n)},o="$lunora.wire$";const g="__proto__",w=r=>{if(r===null||typeof r!="object")return!1;const n=Object.getPrototypeOf(r);return n===null||n===Object.prototype},c=(r,n=0)=>{if(n>64)throw new RangeError("wire-codec: value nesting exceeds the 64-level limit");if(r===void 0)return[o,"undefined"];if(r===null)return null;const y=typeof r;if(y==="bigint")return[o,"bigint",r.toString()];if(y==="number"){const t=r;return Number.isNaN(t)?[o,"nan"]:t===1/0?[o,"inf"]:t===-1/0?[o,"-inf"]:t}if(y!=="object")return r;if(r instanceof Date)return[o,"date",c(r.getTime(),n+1)];if(r instanceof Error){const t=r,e={};for(const a of Object.keys(t)){if(t[a]===void 0)continue;const p=c(t[a],n+1);a===g?Object.defineProperty(e,a,{configurable:!0,enumerable:!0,value:p,writable:!0}):e[a]=p}const i=[o,"error",t.name,t.message,e];return t.cause!==void 0&&i.push(c(t.cause,n+1)),i}if(r instanceof URL)return[o,"url",r.href];if(r instanceof Map)return[o,"map",[...r.entries()].map(([t,e])=>[c(t,n+1),c(e,n+1)])];if(r instanceof Set)return[o,"set",[...r].map(t=>c(t,n+1))];if(r instanceof ArrayBuffer)return[o,"bytes",u(new Uint8Array(r)),"ArrayBuffer"];if(ArrayBuffer.isView(r)){const t=r,e=t.constructor.name,i=new Uint8Array(t.buffer,t.byteOffset,t.byteLength);return e==="Uint8Array"?[o,"bytes",u(i)]:[o,"bytes",u(i),e]}if(Array.isArray(r)){const t=r.map(e=>c(e,n+1));return t.length>0&&t[0]===o?[o,"arr",t]:t}if(!w(r)){const t=r.constructor?.name??"value";throw new TypeError(`wire-codec: cannot encode a ${t} 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 s=r,f={};for(const t of Object.keys(s)){const e=s[t];if(e===void 0)continue;const i=c(e,n+1);t===g?Object.defineProperty(f,t,{configurable:!0,enumerable:!0,value:i,writable:!0}):f[t]=i}return f},O=r=>b(c(r));export{O as s};
|
package/dist/react.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { L as LocalMirror } from "./packem_shared/local-mirror.d-
|
|
1
|
+
import { L as LocalMirror } from "./packem_shared/local-mirror.d-DzREvGNM.mjs";
|
|
2
2
|
import "./packem_shared/types.d-BuLTPLaQ.mjs";
|
|
3
3
|
/**
|
|
4
4
|
* Result of {@link useLocalQuery} — a discriminated union so callers get a
|
package/dist/react.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { L as LocalMirror } from "./packem_shared/local-mirror.d-
|
|
1
|
+
import { L as LocalMirror } from "./packem_shared/local-mirror.d-wbGXkXaE.js";
|
|
2
2
|
import "./packem_shared/types.d-BuLTPLaQ.js";
|
|
3
3
|
/**
|
|
4
4
|
* Result of {@link useLocalQuery} — a discriminated union so callers get a
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
class l{#e=[];#t=0;#i=0;#s=null;#n;constructor(t){this.#n=l.#o(t?.maxEntries)}static#o(t){if(t!==void 0){if(!Number.isSafeInteger(t)||t<0)throw new RangeError("maxEntries must be a non-negative safe integer");return t}}#r(){return this.#e.slice(this.#t)}#h(){if(this.#n===void 0)return;const e=this.#e.length-this.#t-this.#n;e>0&&(this.#t+=e),this.#t>0&&this.#t>=this.#e.length-this.#t&&(this.#e=this.#e.slice(this.#t),this.#t=0)}append(t,e,s,n){const r=typeof t=="string"?t:t.type,o=typeof t=="string"?e:t.payload;let h,i;typeof t=="string"?(h=s,i=n):(h=void 0,i=e);const a=i?.parentSeqNum??this.#s??void 0,f=this.#i;this.#i+=1;const c={seq:f,type:r,payload:o,timestamp:i?.timestamp??Date.now(),tableDiffs:h,clientId:i?.clientId,sessionId:i?.sessionId,parentSeqNum:a};return this.#e.push(c),this.#s=c.seq,this.#h(),c}commitAll(t){if(t.length===0)return[];const e=[];for(const s of t){const{type:n}=s,r="payload"in s?s.payload:void 0,o="timestamp"in s?s.timestamp:Date.now(),h=e.at(-1)?.seq??this.#s??void 0,i=this.#i;this.#i+=1;const a={seq:i,type:n,payload:r,timestamp:o,parentSeqNum:h};this.#e.push(a),e.push(a)}return this.#s=e.at(-1)?.seq??this.#s,this.#h(),e}load(t){this.#e=[...t.entries],this.#t=0,this.#i=t.nextSeq,this.#s=t.headSeq,this.#h()}getSince(t){const e=this.#r();if(t<=0)return e;const s=e.findIndex(n=>n.seq>=t);return s===-1?[]:e.slice(s)}getFrom(t,e=50){const s=this.#e,n=this.#t,r=s.findIndex((h,i)=>i>=n&&h.seq>=t);if(r===-1)return{entries:[],hasMore:!1};const o=Math.min(r+e,s.length);return{entries:s.slice(r,o),hasMore:o<s.length}}snapshot(){return{entries:this.#r(),nextSeq:this.#i,headSeq:this.#s}}get size(){return this.#e.length-this.#t}get nextSeq(){return this.#i}get isEmpty(){return this.size===0}get headSeq(){return this.#s}clear(){this.#e=[],this.#t=0,this.#i=0,this.#s=null}truncateBelow(t){if(!Number.isSafeInteger(t)||t<0)throw new RangeError("floorSeq must be a non-negative safe integer");const e=this.#r(),s=e.findIndex(n=>n.seq>=t);this.#e=s===-1?[]:e.slice(s),this.#t=0}async*events(t=0){const e=this.getSince(t);for(const s of e)yield s}}export{l as EventLog};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{EventEmitter as p}from"./EventEmitter-uo75adUL.mjs";import{EventLog as f}from"./EventLog-B1-yhArT.mjs";const d=Symbol("lunora.replica.event-source.unhandled");class w{emitter=new p;log;#e;#t;#n=!1;#i;#r=-1;constructor(e,t,n){this.#e={...e},this.#t=t,this.#i=n?.unknownEventHandling??"warn",this.log=new f({maxEntries:n?.maxLogEntries})}get state(){return this.#e}get replayed(){return this.#n}applyEvent(e,t,n){let r,o,i;typeof e=="string"?(r=e,o=t,i=n):(r=e.type,o=e.payload,i=t);const s={seq:this.log.nextSeq,type:r,payload:o,timestamp:Date.now(),clientId:i?.clientId,sessionId:i?.sessionId,parentSeqNum:i?.parentSeqNum??this.log.headSeq??void 0};let a;try{a=this.#t(this.#e,s)}catch(h){const u=h instanceof Error?h:new Error(String(h));throw this.emitter.emit("replay-error",{entry:s,error:u}),u}let c=!0;a===d&&(c=this.#s(s));const l=this.log.append(r,o,void 0,{...i,timestamp:s.timestamp});return a===d?(c&&this.emitter.emit("state-changed",{state:this.#e,entry:l}),l):(this.#e=a,this.emitter.emit("state-changed",{state:this.#e,entry:l}),l)}replayFromLog(e){const t=e.getSince(this.#r+1);for(const n of t)try{const r=this.#t(this.#e,n);r!==d&&(this.#e=r),this.log.append(n.type,n.payload,n.tableDiffs,{clientId:n.clientId,sessionId:n.sessionId,parentSeqNum:n.parentSeqNum})}catch(r){this.emitter.emit("replay-error",{entry:n,error:r instanceof Error?r:new Error(String(r))})}finally{this.#r=n.seq}this.#n=!0,this.emitter.emit("ready",{entryCount:this.log.size})}reset(e,t=-1){this.#e={...e},this.#r=t,this.#n=t>=0}async*events(e){const t=[];let n;const r=this.emitter.on("state-changed",({entry:i})=>{t.push(i),n?.()}),o=()=>{n?.()};e?.addEventListener("abort",o,{once:!0});try{let i=0;for(;i<this.log.size;){if(e?.aborted)return;for(const s of this.log.getSince(i))yield s;i=this.log.nextSeq}for(;!e?.aborted;){for(;t.length>0;){const s=t.shift();s&&(yield s)}t.length===0&&await new Promise(s=>{n=s})}}finally{r(),e?.removeEventListener("abort",o)}}#s(e){const t=this.#i;if(typeof t=="function")return t(e);switch(t){case"ignore":return!1;case"fail":throw new Error(`EventSource: unhandled event type "${e.type}" (seq ${String(e.seq)}). Configure \`unknownEventHandling\` to handle this event or change the strategy.`);default:return console.warn(`[EventSource] unhandled event type "${e.type}" (seq ${String(e.seq)}). The event was skipped. Configure \`unknownEventHandling\` if this is expected.`),!1}}}export{w as EventSource,d as UNHANDLED};
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import{createSqlJsAdapter as y}from"../adapters/sqljs.mjs";import{applyDiffToDb as m,escapeIdentifier as a}from"./applyDiffToDb-DiSnjR45.mjs";import{EventLog as b}from"./EventLog-B1-yhArT.mjs";const A=1e3,l="__lunora_mirror_meta",R=o=>{o.exec(`CREATE TABLE IF NOT EXISTS ${l} (
|
|
2
|
-
key TEXT PRIMARY KEY NOT NULL,
|
|
3
|
-
value TEXT NOT NULL
|
|
4
|
-
)`)},u="schema_version",f=3,h=o=>typeof o=="bigint"||typeof o=="boolean"?"INTEGER":typeof o=="number"?Number.isInteger(o)?"INTEGER":"REAL":"TEXT";class E{#e;#t;#s;#n=new Set;#i=0;static create(e,s){const t=y(e);return new E({db:t,tables:s?.tables})}constructor(e){this.#e=e.db,this.#t={...e.tables},this.#s=new b({maxEntries:e.maxEventLogEntries??A}),R(this.#e),this.#o()}onChange(e){return this.#n.add(e),()=>{this.#n.delete(e)}}get eventLog(){return this.#s}get db(){return this.#e}get version(){return this.#i}applyDiff(e){e.changes.length!==0&&(this.#l(e),m(this.#e,e,this.primaryKeyOf(e.table)),this.#s.append("table-diff",e,[e]),this.#r())}query(e,s){return this.#e.query(e,s)}clearData(){const e=this.#a();this.#e.transaction(()=>{for(const{name:s}of e)this.#e.exec(`DELETE FROM ${a(s)}`)}),this.#r()}#r(){this.#i+=1;for(const e of this.#n)try{e()}catch{}}close(){this.#e.close(),this.#s.clear(),this.#n.clear()}registerTable(e,s){this.#t[e]={...this.#t[e],...s}}primaryKeyOf(e){return this.#t[e]?.primaryKey??"id"}get mirroredTables(){return Object.keys(this.#t)}#a(){return this.#e.query(String.raw`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE '\_\_lunora\_%' ESCAPE '\' AND name NOT LIKE 'sqlite\_%' ESCAPE '\'`)}#o(){if(this.#e.query(`SELECT key, value FROM ${l}`).find(n=>n.key===u)?.value===String(f))return;const t=this.#a();this.#e.transaction(()=>{for(const{name:n}of t)this.#e.exec(`DROP TABLE IF EXISTS ${a(n)}`);this.#e.exec(`INSERT OR REPLACE INTO ${l} (key, value) VALUES (?, ?)`,[u,String(f)])})}static#c(e,s){const t=new Set;for(const n of e.changes)if(n.type!=="delete")for(const c of Object.keys(n.data))c!==s&&t.add(c);return t}static#E(e,s,t){const n=new Map;for(const c of e.changes)if(!(c.type==="delete"||n.size===t.size))for(const r of t){if(r===s||n.has(r))continue;const i=c.data[r];i!=null&&n.set(r,h(i))}return n}static#h(e,s){for(const t of e.changes){const n=t.type==="delete"?t.id:t.data[s];if(n!=null)return h(n);if(t.type==="update")return h(t.id)}return"TEXT"}#l(e){const s=this.primaryKeyOf(e.table),t=E.#c(e,s),n=E.#E(e,s,t);if(this.#e.query("SELECT name FROM sqlite_master WHERE type='table' AND name=?",[e.table]).length===0){const r=E.#h(e,s);let i=`${a(s)} ${r==="INTEGER"?"INT":r} PRIMARY KEY NOT NULL`;for(const T of t)i+=`, ${a(T)} ${n.get(T)??"TEXT"}`;this.#e.exec(`CREATE TABLE IF NOT EXISTS ${a(e.table)} (${i})`)}else if(t.size>0){const r=new Set(this.#e.query(`PRAGMA table_info(${a(e.table)})`).map(i=>i.name));for(const i of t)r.has(i)||this.#e.exec(`ALTER TABLE ${a(e.table)} ADD COLUMN ${a(i)} ${n.get(i)??"TEXT"}`)}}}export{E as LocalMirror};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as w}from"./wire-key-CU8KEXPo.mjs";const h=e=>`fn_${e.replaceAll(/[/:.]/g,"_")}`,m=e=>Array.isArray(e)?e:e!==null&&typeof e=="object"?[e]:[],M=(e,c,a,y,b)=>{const i=h(a.__lunoraRef);c.registerTable(i,{});const u=c.primaryKeyOf(i);let p=new Map;return e.subscribe(a,y,d=>{const r=new Map,f=new Map,o=[];for(const t of m(d)){const n=t,s=n[u];if(typeof s!="string"&&typeof s!="number"&&typeof s!="bigint"){o.push({type:"insert",data:n});continue}const l=String(s),g=w(n);r.set(l,g),f.set(l,n)}for(const[t,n]of r)p.get(t)!==n&&o.push({data:f.get(t),type:"insert"});for(const t of p.keys())r.has(t)||o.push({type:"delete",id:t});o.length>0&&c.applyDiff({table:i,changes:o,timestamp:Date.now()}),p=r},{shardKey:b})};export{M as subscribeToMirror};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const d=/["\\\u0000-\u001F\uD800-\uDFFF]/,p=r=>d.test(r)?JSON.stringify(r):`"${r}"`,b=r=>{if(r===void 0)return"null";if(typeof r=="bigint")throw new TypeError("stableStringify: cannot use a bigint in a stable JSON cache key — pass it as a string, or use stableWireKey");if(typeof r=="number"){if(Number.isNaN(r))return"nan";if(r===1/0)return"inf";if(r===-1/0)return"-inf";if(Object.is(r,-0))return"-0"}if(typeof r=="string")return p(r);if(r===null||typeof r!="object")return JSON.stringify(r);if(Array.isArray(r)){let n="[";for(let i=0;i<r.length;i++)i>0&&(n+=","),n+=b(r[i]);return n+"]"}const e=Object.getPrototypeOf(r);if(e!==null&&e!==Object.prototype){const n=r.constructor?.name??"value";throw new TypeError(`stableStringify: cannot use a ${n} in a stable JSON cache key — only plain objects, arrays, and JSON primitives are supported (wire-typed values key via stableWireKey)`)}const y=r,s=Object.keys(y).sort();let f="{",t=!0;for(const n of s){const i=y[n];i!==void 0&&(t?t=!1:f+=",",f+=p(n),f+=":",f+=b(i))}return f+"}"},u=r=>{let e="";for(let s=0;s<r.length;s+=32768)e+=String.fromCharCode(...r.subarray(s,s+32768));return btoa(e)},o="$lunora.wire$";const g="__proto__",m=r=>{if(r===null||typeof r!="object")return!1;const e=Object.getPrototypeOf(r);return e===null||e===Object.prototype},c=(r,e=0)=>{if(e>64)throw new RangeError("wire-codec: value nesting exceeds the 64-level limit");if(r===void 0)return[o,"undefined"];if(r===null)return null;const y=typeof r;if(y==="bigint")return[o,"bigint",r.toString()];if(y==="number"){const t=r;return Number.isNaN(t)?[o,"nan"]:t===1/0?[o,"inf"]:t===-1/0?[o,"-inf"]:t}if(y!=="object")return r;if(r instanceof Date)return[o,"date",c(r.getTime(),e+1)];if(r instanceof Error){const t=r,n={};for(const a of Object.keys(t))t[a]!==void 0&&(n[a]=c(t[a],e+1));const i=[o,"error",t.name,t.message,n];return t.cause!==void 0&&i.push(c(t.cause,e+1)),i}if(r instanceof URL)return[o,"url",r.href];if(r instanceof Map)return[o,"map",[...r.entries()].map(([t,n])=>[c(t,e+1),c(n,e+1)])];if(r instanceof Set)return[o,"set",[...r].map(t=>c(t,e+1))];if(r instanceof ArrayBuffer)return[o,"bytes",u(new Uint8Array(r)),"ArrayBuffer"];if(ArrayBuffer.isView(r)){const t=r,n=t.constructor.name,i=new Uint8Array(t.buffer,t.byteOffset,t.byteLength);return n==="Uint8Array"?[o,"bytes",u(i)]:[o,"bytes",u(i),n]}if(Array.isArray(r)){const t=r.map(n=>c(n,e+1));return t.length>0&&t[0]===o?[o,"arr",t]:t}if(!m(r)){const t=r.constructor?.name??"value";throw new TypeError(`wire-codec: cannot encode a ${t} 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 s=r,f={};for(const t of Object.keys(s)){const n=s[t];if(n===void 0)continue;const i=c(n,e+1);t===g?Object.defineProperty(f,t,{configurable:!0,enumerable:!0,value:i,writable:!0}):f[t]=i}return f},w=r=>b(c(r));export{w as s};
|