UNPKG

@substrate-system/mergeparty

Version:
3 lines (2 loc) 5.73 kB
"use strict";var g=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var v=Object.prototype.hasOwnProperty;var d=(n,e)=>g(n,"name",{value:e,configurable:!0});var A=(n,e)=>{for(var s in e)g(n,s,{get:e[s],enumerable:!0})},_=(n,e,s,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of m(e))!v.call(n,r)&&r!==s&&g(n,r,{get:()=>e[r],enumerable:!(t=S(e,r))||t.enumerable});return n};var w=n=>_(g({},"__esModule",{value:!0}),n);var P={};A(P,{WithStorage:()=>k});module.exports=w(P);var h=require("@substrate-system/automerge-repo-slim"),y=require("cborg"),u=require("./relay.js"),T=require("./polyfill.js");class k extends u.Relay{static{d(this,"WithStorage")}isStorageServer=!0;_repo;constructor(e,s){super(e),s?this._repo=s:this._repo=new h.Repo({storage:this,network:[this],sharePolicy:d(async()=>!0,"sharePolicy"),peerId:`server:${this.room.id}`}),this.setupStoragePersistence(),this._log=this._baseLog.extend("storage"),this.connect(this.serverPeerId,{})}async onMessage(e,s){if(!this.byConn.get(s)?.joined)return super.onMessage(e,s);try{if(e instanceof ArrayBuffer){const t=(0,y.decode)(new Uint8Array(e));if(t&&t.type==="sync"&&t.documentId){const r=t.documentId;this._repo.handles[r]||this._repo.find(r)}}}catch{}await super.onMessage(e,s)}async load(e){const s=this.keyToString(e);this._log(`Loading from storage: key=${s}`);const t=await this.room.storage.get(s);if(!t){this._log(`No value found for key: ${s}`);return}if(this._log(`Found value for key: ${s}, type=${typeof t}`),t instanceof Uint8Array)return t;if(t instanceof ArrayBuffer)return new Uint8Array(t);if(typeof t=="object"&&t!==null&&Object.keys(t).every(r=>!isNaN(Number(r))))return new Uint8Array(Object.values(t));throw new Error("Unsupported value type from storage")}async save(e,s){const t=this.keyToString(e);this._log(`Saving to storage: key=${t}, valueLength=${s.length}`),await this.room.storage.put(t,s),this._log(`Successfully saved key: ${t}`)}async remove(e){await this.room.storage.delete(this.keyToString(e))}async loadRange(e){const s=this.keyToString(e),t=[],r=await this.room.storage.list({prefix:s});for(const[i,o]of[...r.entries()].sort(([a],[l])=>a.localeCompare(l))){let a;o instanceof Uint8Array?a=o:o instanceof ArrayBuffer?a=new Uint8Array(o):typeof o=="object"&&o!==null&&Object.keys(o).every(l=>!isNaN(Number(l)))?a=new Uint8Array(Object.values(o)):a=void 0,t.push({key:this.stringToKey(i),data:a})}return t}async removeRange(e){const s=this.keyToString(e),t=await this.room.storage.list({prefix:s});for(const r of t.keys())await this.room.storage.delete(r)}async onStart(){this._log("**Stateful sync server started (Automerge peer w/ PartyKit storage)**"),await this.save(["storage-adapter-id"],new TextEncoder().encode(this.peerId||"server")),this._log("Storage adapter initialized")}async onRequest(e){const s=new URL(e.url);if(s.pathname.includes("/debug/storage")){const t=await this.room.storage.list(),r={};for(const[i,o]of t)r[i]=o;return Response.json(r,{status:200,headers:{"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type"}})}if(s.pathname.includes("/test/storage")){this._log("[WithStorage] Storage test endpoint called");try{this._log("[WithStorage] Starting basic storage operations test...");const t="test-manual-storage",r=new TextEncoder().encode("test-value");this._log("[WithStorage] Calling save..."),await this.save([t],r),this._log("[WithStorage] Calling load...");const i=await this.load([t]);if(!i||new TextDecoder().decode(i)!=="test-value")throw new Error("Storage test failed");this._log("[WithStorage] Basic storage operations successful"),this._log("[WithStorage] Storage test: getting repo handles...");let o=0,a=0,l=[];try{if(l=Object.keys(this._repo.handles),o=l.length,this._log(`[WithStorage] Found ${o} handles`),o>0){const c=Object.values(this._repo.handles);this._log("[WithStorage] Checking readiness of handles..."),a=c.filter(p=>{try{return p.isReady()}catch(f){return this._log(`[WithStorage] Error checking handle readiness: ${f.message}`),!1}}).length}}catch(c){this._log(`[WithStorage] Error accessing repo handles: ${c.message}`)}return this._log(`[WithStorage] Storage test: found ${o} total handles, ${a} ready`),Response.json({success:!0,message:"Storage operations successful - Automerge handles persistence automatically",repoHandles:l,readyHandles:a,totalHandles:o,storageKeys:await this.room.storage.list().then(c=>[...c.keys()])},{status:200,headers:{"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type"}})}catch(t){return this._log(`[WithStorage] Storage test failed: ${t.message}`),Response.json({success:!1,error:t.message},{status:500,headers:{"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type"}})}}return super.onRequest(e)}async onConnect(e){super.onConnect(e);try{await this._repo.flush(),this._log("Flushed on client connect")}catch(s){this._log(`Failed to flush on connect: ${s}`)}}unicastByPeerId(e,s){const t=this.sockets[e];t&&t.send(s)}keyToString(e){return e.join(".")}stringToKey(e){return e.split(".")}setupStoragePersistence(){this._log("[WithStorage] Setting up storage persistence - Automerge should handle this automatically"),setInterval(()=>{const e=Object.keys(this._repo.handles).length;if(e>0){const t=Object.values(this._repo.handles).filter(r=>r.isReady());this._log(`[WithStorage] Repo state: ${e} total handles, ${t.length} ready`),this._log("[WithStorage] Handle IDs:",Object.keys(this._repo.handles))}},5e3)}} //# sourceMappingURL=with-storage.min.cjs.map