stroid 0.1.2 → 0.1.3

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 (105) hide show
  1. package/CHANGELOG.md +27 -2
  2. package/dist/async.js +22 -22
  3. package/dist/async.js.map +1 -1
  4. package/dist/computed.d.ts +7 -1
  5. package/dist/computed.js +11 -11
  6. package/dist/computed.js.map +1 -1
  7. package/dist/core.js +14 -14
  8. package/dist/core.js.map +1 -1
  9. package/dist/devtools.js +1 -1
  10. package/dist/devtools.js.map +1 -1
  11. package/dist/feature.js.map +1 -1
  12. package/dist/helpers.js +14 -14
  13. package/dist/helpers.js.map +1 -1
  14. package/dist/index.d.cts +1 -0
  15. package/dist/index.d.ts +1 -0
  16. package/dist/index.js +24 -24
  17. package/dist/index.js.map +1 -1
  18. package/dist/install.js +1 -1
  19. package/dist/install.js.map +1 -1
  20. package/dist/persist.js +1 -1
  21. package/dist/persist.js.map +1 -1
  22. package/dist/react/index.js +25 -25
  23. package/dist/react/index.js.map +1 -1
  24. package/dist/runtime-admin.js +1 -1
  25. package/dist/runtime-admin.js.map +1 -1
  26. package/dist/runtime-tools.js +2 -2
  27. package/dist/runtime-tools.js.map +1 -1
  28. package/dist/selectors.js +1 -1
  29. package/dist/selectors.js.map +1 -1
  30. package/dist/server.js +11 -11
  31. package/dist/server.js.map +1 -1
  32. package/dist/store-registry.d.ts +0 -1
  33. package/dist/sync.js +1 -1
  34. package/dist/sync.js.map +1 -1
  35. package/dist/testing.js +14 -14
  36. package/dist/testing.js.map +1 -1
  37. package/package.json +4 -1
  38. package/dist/types/adapters/options.d.ts +0 -335
  39. package/dist/types/async/cache.d.ts +0 -39
  40. package/dist/types/async/clone.d.ts +0 -10
  41. package/dist/types/async/errors.d.ts +0 -3
  42. package/dist/types/async/fetch.d.ts +0 -37
  43. package/dist/types/async/inflight.d.ts +0 -13
  44. package/dist/types/async/rate.d.ts +0 -5
  45. package/dist/types/async/registry.d.ts +0 -116
  46. package/dist/types/async/request.d.ts +0 -11
  47. package/dist/types/async/retry.d.ts +0 -10
  48. package/dist/types/async.d.ts +0 -10
  49. package/dist/types/computed/computed-graph.d.ts +0 -29
  50. package/dist/types/computed/index.d.ts +0 -16
  51. package/dist/types/config.d.ts +0 -10
  52. package/dist/types/core/index.d.ts +0 -11
  53. package/dist/types/core/lifecycle-hooks.d.ts +0 -16
  54. package/dist/types/core/store-admin-impl.d.ts +0 -9
  55. package/dist/types/core/store-admin.d.ts +0 -9
  56. package/dist/types/core/store-core.d.ts +0 -13
  57. package/dist/types/core/store-create.d.ts +0 -16
  58. package/dist/types/core/store-hydrate-impl.d.ts +0 -35
  59. package/dist/types/core/store-hydrate.d.ts +0 -9
  60. package/dist/types/core/store-lifecycle/hooks.d.ts +0 -19
  61. package/dist/types/core/store-lifecycle/identity.d.ts +0 -23
  62. package/dist/types/core/store-lifecycle/registry.d.ts +0 -53
  63. package/dist/types/core/store-lifecycle/types.d.ts +0 -67
  64. package/dist/types/core/store-lifecycle/validation.d.ts +0 -53
  65. package/dist/types/core/store-name.d.ts +0 -28
  66. package/dist/types/core/store-notify.d.ts +0 -12
  67. package/dist/types/core/store-read.d.ts +0 -18
  68. package/dist/types/core/store-registry.d.ts +0 -108
  69. package/dist/types/core/store-replace-impl.d.ts +0 -11
  70. package/dist/types/core/store-replace.d.ts +0 -9
  71. package/dist/types/core/store-set-impl.d.ts +0 -13
  72. package/dist/types/core/store-set.d.ts +0 -9
  73. package/dist/types/core/store-shared/core.d.ts +0 -13
  74. package/dist/types/core/store-shared/notify.d.ts +0 -12
  75. package/dist/types/core/store-transaction.d.ts +0 -26
  76. package/dist/types/core/store-write-shared.d.ts +0 -19
  77. package/dist/types/core/store-write.d.ts +0 -13
  78. package/dist/types/features/feature-registry.d.ts +0 -91
  79. package/dist/types/features/lifecycle.d.ts +0 -40
  80. package/dist/types/index.d.ts +0 -17
  81. package/dist/types/integrations/query.d.ts +0 -8
  82. package/dist/types/internals/computed-order.d.ts +0 -3
  83. package/dist/types/internals/config.d.ts +0 -116
  84. package/dist/types/internals/diagnostics.d.ts +0 -21
  85. package/dist/types/internals/reporting.d.ts +0 -9
  86. package/dist/types/internals/store-admin.d.ts +0 -7
  87. package/dist/types/internals/store-ops.d.ts +0 -13
  88. package/dist/types/internals/test-reset.d.ts +0 -2
  89. package/dist/types/internals/write-context.d.ts +0 -15
  90. package/dist/types/notification/delivery.d.ts +0 -3
  91. package/dist/types/notification/index.d.ts +0 -10
  92. package/dist/types/notification/metrics.d.ts +0 -12
  93. package/dist/types/notification/priority.d.ts +0 -9
  94. package/dist/types/notification/scheduler.d.ts +0 -11
  95. package/dist/types/notification/snapshot.d.ts +0 -8
  96. package/dist/types/runtime-admin/index.d.ts +0 -2
  97. package/dist/types/runtime-tools/index.d.ts +0 -58
  98. package/dist/types/store.d.ts +0 -16
  99. package/dist/types/types/utility.d.ts +0 -17
  100. package/dist/types/utils/clone.d.ts +0 -4
  101. package/dist/types/utils/devfreeze.d.ts +0 -2
  102. package/dist/types/utils/hash.d.ts +0 -8
  103. package/dist/types/utils/path.d.ts +0 -5
  104. package/dist/types/utils/validation.d.ts +0 -14
  105. package/dist/types/utils.d.ts +0 -13
package/dist/persist.js CHANGED
@@ -1,2 +1,2 @@
1
- var $=new Map,X=(e,t)=>{$.set(e,t);};var Q=e=>$.get(e),Z=()=>Array.from($.keys());var Me=typeof Symbol=="function"?Symbol.for("stroid.persist.defaultCrypto"):"__stroid_persist_defaultCrypto__",z=e=>!!e?.[Me],j=e=>{try{let t=`__stroid_plaintext_probe_${Math.random().toString(36).slice(2)}__`,n=`__stroid_plaintext_probe_${Math.random().toString(36).slice(2)}__`;return e(t)!==t?!1:e(n)===n}catch{return false}},ee=(e,t,n)=>{let o="__stroid_persist_roundtrip_probe__",i;try{i=t(o);}catch(p){return {ok:false,reason:`persist: encrypt failed for store "${e}" (${p?.message??p})`}}if(typeof i!="string")return {ok:false,reason:`persist: encrypt must return a string for store "${e}".`};let u;try{u=n(i);}catch(p){return {ok:false,reason:`persist: decrypt failed for store "${e}" (${p?.message??p})`}}return typeof u!="string"?{ok:false,reason:`persist: decrypt must return a string for store "${e}".`}:u!==o?{ok:false,reason:`persist: encrypt/decrypt must round-trip for store "${e}".`}:{ok:true}};var te=(e,t,n)=>{e[t]&&(e[t].lastPresent=n);},re=({name:e,persistConfig:t,persistWatchState:n})=>{let o=t?.onStorageCleared;if(!t||typeof o!="function"||typeof window>"u"||typeof window.addEventListener!="function")return;n[e]?.dispose();let i=window,u=()=>{try{return t.driver.getItem?.(t.key)!=null}catch{return false}},p=s=>{let h=n[e],b=u();if(h){if(!h.lastPresent||b){h.lastPresent=b;return}h.lastPresent=false,o({name:e,key:t.key,reason:s});}},g=s=>{if(s.key===null){p("clear");return}s.key===t.key&&s.newValue===null&&p("remove");},r=()=>{p("missing");};i.addEventListener("storage",g),i.addEventListener("focus",r),n[e]={lastPresent:u(),dispose:()=>{i.removeEventListener("storage",g),i.removeEventListener("focus",r);}};};var W=({value:e,sanitize:t,validate:n,onSanitizeError:o})=>{let i;if(t)try{i=t(e);}catch(p){return o?.(p),{ok:false}}else i=e;let u=n(i);return u.ok?{ok:true,value:u.value??i}:{ok:false}},H=({value:e,fallbackMs:t=Date.now(),onInvalid:n})=>{if(typeof e=="number")return Number.isFinite(e)?e:(n?.(),t);if(typeof e=="string"){let o=Date.parse(e);return Number.isFinite(o)?o:(n?.(),t)}return n?.(),t};var Ce=new Map,D=(e,t,n=0)=>{!e||typeof t!="function"||Ce.set(e,{name:e,order:n,fn:t});};var Fe=()=>new Map([["noSignal",new Set],["shape",new Set],["autoCreate",new Set],["mutableResult",new Set]]),ne=()=>({fetchRegistry:Object.create(null),inflight:Object.create(null),requestVersion:Object.create(null),cacheMeta:Object.create(null),rateWindowStart:Object.create(null),rateCount:Object.create(null),ratePruneState:{lastAt:0},ratePruneTimer:null,warnedOnce:Fe(),storeCleanups:Object.create(null),revalidateKeys:new Set,revalidateHandlers:Object.create(null),asyncMetrics:{cacheHits:0,cacheMisses:0,dedupes:0,requests:0,failures:0,avgMs:0,lastMs:0}});var L=new Map,oe=new WeakSet,Ee=e=>{oe.has(e)||(oe.add(e),Z().forEach(t=>{if(!e.featureRuntimes.get(t)){let n=Q(t);n&&e.featureRuntimes.set(t,n());}}));},Pe=typeof __STROID_REGISTRY_ID__<"u"&&__STROID_REGISTRY_ID__||typeof process<"u"&&process.env?.STROID_REGISTRY_ID||void 0,se,ie=e=>(se||Pe||e).replace(/\.ts(\?|$)/,".js$1"),Te=ie(new URL("../../store.js",import.meta.url).href);var xe=()=>{se=void 0,L.clear();};D("registry.scope-override",xe,110);var Oe=()=>({pendingNotifications:new Set,pendingBuffer:[],orderedNames:[],subscriberBuffer:[],notifyScheduled:false,batchDepth:0,flushId:0,isFlushing:false});var _e=()=>({depth:0,pending:[],stagedValues:new Map,snapshotCache:new Map,failed:false,error:void 0}),Ae=(e="default")=>{let t={scope:e,stores:Object.create(null),subscribers:Object.create(null),initialStates:Object.create(null),initialFactories:Object.create(null),metaEntries:Object.create(null),snapshotCache:Object.create(null),featureRuntimes:new Map,deletingStores:new Set,computedEntries:Object.create(null),computedDependents:Object.create(null),computedCleanups:new Map,transaction:_e(),async:ne(),notify:Oe(),lifecycleListener:null};return Ee(t),t},je=e=>{let t=ie(e),n=L.get(t);if(n)return n;let o=Ae();return L.set(t,o),o};var v=[],Ve={run:(e,t)=>{v.push(e);try{return t()}finally{v.pop();}},get:()=>v.length>0?v[v.length-1]:null,enterWith:e=>{if(v.length>0){v[v.length-1]=e;return}v.push(e);}};var ae=e=>(Ve).get()||e||je(Te);var Ne={log:(e,t)=>{typeof console<"u"&&typeof console.log=="function"&&(t?console.log(`[stroid] ${e}`,t):console.log(`[stroid] ${e}`));},warn:(e,t)=>{typeof console<"u"&&typeof console.warn=="function"&&(t?console.warn(`[stroid] ${e}`,t):console.warn(`[stroid] ${e}`));},critical:(e,t)=>{typeof console<"u"&&typeof console.error=="function"&&(t?console.error(`[stroid] ${e}`,t):console.error(`[stroid] ${e}`));}},ue={logSink:Ne,flush:{chunkSize:Number.POSITIVE_INFINITY,chunkDelayMs:0,priorityStores:[]},revalidateOnFocus:{debounceMs:0,maxConcurrent:3,staggerMs:100},namespace:"",strictMissingFeatures:true,assertRuntime:false,strictMutatorReturns:true,asyncAutoCreate:false,asyncCloneResult:"none",autoCorrelationIds:false,acknowledgeLooseTypes:false,pathCacheSize:500,defaultSnapshotMode:"deep",strictAsyncUsageErrors:false,middleware:[],allowUntrustedHydration:false,mutatorProduce:void 0,selectorCloneFrozen:true},U=e=>({logSink:{...e.logSink},flush:{...e.flush},revalidateOnFocus:{...e.revalidateOnFocus},namespace:e.namespace,strictMissingFeatures:e.strictMissingFeatures,assertRuntime:e.assertRuntime,strictMutatorReturns:e.strictMutatorReturns,asyncAutoCreate:e.asyncAutoCreate,asyncCloneResult:e.asyncCloneResult,autoCorrelationIds:e.autoCorrelationIds,acknowledgeLooseTypes:e.acknowledgeLooseTypes,pathCacheSize:e.pathCacheSize,defaultSnapshotMode:e.defaultSnapshotMode,strictAsyncUsageErrors:e.strictAsyncUsageErrors,middleware:[...e.middleware],allowUntrustedHydration:e.allowUntrustedHydration,mutatorProduce:e.mutatorProduce,selectorCloneFrozen:e.selectorCloneFrozen}),B=new WeakMap,ce=U(ue),Ie=e=>{let t=B.get(e);return t||(t=U(ce),B.set(e,t)),t};var q=()=>Ie(ae());var He=()=>{B=new WeakMap,ce=U(ue);};D("config.reset",He,90);typeof process<"u"&&typeof process.env?.NODE_ENV=="string"?process.env.NODE_ENV:void 0;typeof import.meta<"u"&&import.meta?.env?.MODE?import.meta.env.MODE:void 0;var Le=(e,t)=>{typeof console<"u"&&typeof console.warn=="function"&&(t?console.warn(`[stroid] ${e}`,t):console.warn(`[stroid] ${e}`));};var O=(e,t)=>{if((q().logSink.warn??Le)(e,t),q().assertRuntime)throw new Error(e)};var le=new Set(["__proto__","constructor","prototype"]);var Y=null,Be=()=>{if(Y)return Y;let e,t=[];for(let n=0;n<256;n++){e=n;for(let o=0;o<8;o++)e=e&1?3988292384^e>>>1:e>>>1;t[n]=e>>>0;}return Y=t,t},fe=e=>{let t=Be(),n=-1;for(let o=0;o<e.length;o++)n=n>>>0,n=n>>>8^t[(n^e.charCodeAt(o))&255];return (n^-1)>>>0},Ue=2166136261,qe=2654435761,Ye=1e5,R=(e,t)=>{let n=t>>>0;e.h1=Math.imul(e.h1^n,2246822507),e.h2=Math.imul(e.h2^n,3266489909);},C=(e,t)=>{R(e,t.length);for(let n=0;n<t.length;n++)R(e,t.charCodeAt(n));},S=(e,t)=>{C(e,t);},de=(e,t)=>{if(Number.isNaN(t)){S(e,"NaN");return}if(!Number.isFinite(t)){S(e,t>0?"Infinity":"-Infinity");return}if(Object.is(t,-0)){S(e,"-0");return}let n=t|0;if(t===n){S(e,"int"),R(e,n);return}S(e,"num"),C(e,String(t));},F=(e,t)=>{if(e.nodes++>Ye){S(e,"[max]");return}if(t===null){S(e,"null");return}let n=typeof t;if(n==="string"){S(e,"string"),C(e,t);return}if(n==="number"){S(e,"number"),de(e,t);return}if(n==="boolean"){S(e,t?"true":"false");return}if(n==="undefined"){S(e,"undefined");return}if(n==="bigint"){S(e,"bigint"),C(e,t.toString());return}if(n==="symbol"){S(e,"symbol");let r=t;C(e,Symbol.keyFor(r)??r.description??String(r));return}if(n==="function"){S(e,"function"),C(e,t.name||"anonymous");return}let o=t,i=e.seen.get(o);if(i!==void 0){S(e,"ref"),R(e,i);return}let u=e.nextId++;if(e.seen.set(o,u),Array.isArray(o)){S(e,"array"),R(e,o.length);for(let r=0;r<o.length;r++)Object.prototype.hasOwnProperty.call(o,r)?F(e,o[r]):S(e,"hole");return}if(o instanceof Date){S(e,"date"),de(e,o.getTime());return}if(o instanceof Map){S(e,"map"),R(e,o.size),o.forEach((r,s)=>{F(e,s),F(e,r);});return}if(o instanceof Set){S(e,"set"),R(e,o.size),o.forEach(r=>{F(e,r);});return}S(e,"object");let p=Object.getOwnPropertyDescriptors(o),g=[];Object.entries(p).forEach(([r,s])=>{s?.enumerable&&(le.has(r)||"get"in s||"set"in s||g.push([r,s]));}),R(e,g.length);for(let[r,s]of g)C(e,r),F(e,s.value);},K=e=>{if(typeof e=="string")return fe(JSON.stringify(e));let t={h1:Ue,h2:qe,seen:new WeakMap,nextId:1,nodes:0};F(t,e);let n=t.h1>>>0,o=t.h2>>>0;return n^=n>>>16,n=Math.imul(n,2246822507),n^=n>>>13,n=Math.imul(n,3266489909),n^=n>>>16,o^=o>>>16,o=Math.imul(o,668265261),o^=o>>>15,o=Math.imul(o,374761393),o^=o>>>16,(n&2097151)*4294967296+(o>>>0)};var Ge=e=>{let t=new Uint8Array(e),n="";for(let o=0;o<t.length;o++)n+=t[o].toString(16).padStart(2,"0");return n},Xe=async e=>{if(typeof globalThis<"u"&&globalThis.crypto?.subtle){let t=typeof TextEncoder<"u"?new TextEncoder:null,n=t?t.encode(e):new Uint8Array(Buffer.from(e)),o=await globalThis.crypto.subtle.digest("SHA-256",n);return Ge(o)}try{let{createHash:t}=await import('crypto');return t("sha256").update(e).digest("hex")}catch{throw new Error("sha256 checksum is not supported in this environment")}},V=async(e,t,n=K)=>e==="none"?null:e==="sha256"?Xe(t):n(t);var pe=1e6,ge=(e,t)=>{let n=e?.options?.migrations??{};if(Object.keys(n).length>0)return n;let o=t?.migrate;if(typeof o!="function")return n;let i=e?.version??1;return !Number.isFinite(i)||i<=1?n:{[i]:o}},J=({name:e,persisted:t,reason:n,persistConfig:o,initialState:i,reportStoreError:u,sanitize:p,deepClone:g})=>{u(e,n);let r=o?.onMigrationFail??"reset";if(r==="keep")return {state:t,requiresValidation:true};if(typeof r=="function")try{let s=r(g(t));if(s!==void 0)return {state:p(s),requiresValidation:!0};u(e,`onMigrationFail for "${e}" returned undefined. Falling back to initial state.`);}catch(s){u(e,`onMigrationFail for "${e}" failed: ${s?.message??s}`);}return {state:g(i),requiresValidation:true}},ye=e=>{let n=e.getMeta()?.options?.persist;return n?!!n.decryptAsync||n.checksum==="sha256"?Ze(e):Qe(e):false},Qe=({name:e,silent:t=false,getMeta:n,getInitialState:o,applyFeatureState:i,reportStoreError:u,warnMissingMaxSize:p,validate:g,log:r,hashState:s,deepClone:h,sanitize:b,shouldApply:y})=>{let m=n(),c=m?.options?.persist;if(!c)return false;let l=ge(m,c),f=a=>W({value:a,validate:g});try{let a=c.driver.getItem?.(c.key)??null;if(!a)return !1;if(typeof a!="string")return u(e,`Persist driver for "${e}" returned an async value during sync hydration. Provide async decrypt hooks or use an async-capable persist driver.`),!0;if(typeof c.maxSize!="number"&&a.length>pe&&p?.(a.length),typeof c.maxSize=="number"&&a.length>c.maxSize)return u(e,`Persist payload for "${e}" exceeds maxSize (${a.length} > ${c.maxSize}). Skipping hydration.`),!0;let d=c.decrypt(a),k=JSON.parse(d),{v:w=1,checksum:E,data:M,updatedAt:N,updatedAtMs:P}=k||{};if(!M)return !0;let T=H({value:typeof P=="number"?P:N,fallbackMs:Date.now(),onInvalid:()=>{r(`persist: corrupt updatedAt in stored data for "${e}". Using current time to prevent sync overwrite.`);}});if(c.checksum!=="none"&&E!==s(M))return u(e,`Checksum mismatch loading store "${e}". Falling back to initial state.`),(!y||y())&&i(h(o()),Date.now()),!0;let A=c.deserialize(M),I=m?.version??1,x=me({name:e,parsed:A,v:w,targetVersion:I,cfg:c,migrations:l,getInitialState:o,reportStoreError:u,sanitize:b,deepClone:h,validateState:f,safeUpdatedAt:T,applyFeatureState:i,shouldApply:y});return x.ok&&(A=x.state,(!y||y())&&(i(x.state,T),t||r(`Store "${e}" loaded from persistence`))),!0}catch(a){return u(e,`Could not load store "${e}" (${a?.message||a})`),true}},Ze=async({name:e,silent:t=false,getMeta:n,getInitialState:o,applyFeatureState:i,reportStoreError:u,warnMissingMaxSize:p,validate:g,log:r,hashState:s,deepClone:h,sanitize:b,shouldApply:y})=>{let m=n(),c=m?.options?.persist;if(!c)return false;let l=ge(m,c),f=a=>W({value:a,validate:g});try{let a=await Promise.resolve(c.driver.getItem?.(c.key)??null);if(!a)return !1;if(typeof c.maxSize!="number"&&typeof a=="string"&&a.length>pe&&p?.(a.length),typeof c.maxSize=="number"&&typeof a=="string"&&a.length>c.maxSize)return u(e,`Persist payload for "${e}" exceeds maxSize (${a.length} > ${c.maxSize}). Skipping hydration.`),!0;let d=c.decryptAsync?await c.decryptAsync(a):c.decrypt(a),k=JSON.parse(d),{v:w=1,checksum:E,data:M,updatedAt:N,updatedAtMs:P}=k||{};if(!M)return !0;let T=H({value:typeof P=="number"?P:N,fallbackMs:Date.now(),onInvalid:()=>{r(`persist: corrupt updatedAt in stored data for "${e}". Using current time to prevent sync overwrite.`);}}),A=await V(c.checksum,M,s);if(c.checksum!=="none"&&E!==A)return u(e,`Checksum mismatch loading store "${e}". Falling back to initial state.`),(!y||y())&&i(h(o()),Date.now()),!0;let I=c.deserialize(M),x=m?.version??1,G=me({name:e,parsed:I,v:w,targetVersion:x,cfg:c,migrations:l,getInitialState:o,reportStoreError:u,sanitize:b,deepClone:h,validateState:f,safeUpdatedAt:T,applyFeatureState:i,shouldApply:y});return G.ok&&(!y||y())&&(i(G.state,T),t||r(`Store "${e}" loaded from persistence`)),!0}catch(a){return u(e,`Could not load store "${e}" (${a?.message||a})`),true}},me=({name:e,parsed:t,v:n,targetVersion:o,cfg:i,migrations:u,getInitialState:p,reportStoreError:g,sanitize:r,deepClone:s,validateState:h,safeUpdatedAt:b,applyFeatureState:y,shouldApply:m})=>{if(n!==o){let l=Object.keys(u).map(d=>Number(d)).filter(d=>d>n&&d<=o).sort((d,k)=>d-k);if(l.length===0){let d=J({name:e,persisted:t,reason:`No migration path from v${n} to v${o} for "${e}". Applying onMigrationFail strategy.`,persistConfig:i,initialState:p(),reportStoreError:g,sanitize:r,deepClone:s});if(t=d.state,!d.requiresValidation)return (!m||m())&&y(t,b),{ok:false,state:t}}let f=false,a=true;if(l.forEach(d=>{if(!f)try{let k=u[d](t);k!==void 0&&(t=k);}catch(k){let w=J({name:e,persisted:t,reason:`Migration to v${d} failed for "${e}": ${k?.message||k}`,persistConfig:i,initialState:p(),reportStoreError:g,sanitize:r,deepClone:s});t=w.state,a=w.requiresValidation,f=true;}}),f){if(!a)return (!m||m())&&y(t,b),{ok:false,state:t};let d=h(t);return d.ok?{ok:true,state:d.value??t}:((!m||m())&&y(s(p()),Date.now()),{ok:false,state:t})}}let c=h(t);if(!c.ok){if(n!==o){let l=i?.onMigrationFail??"reset",f=J({name:e,persisted:t,reason:`Persisted state for "${e}" failed schema after version change. Applying onMigrationFail strategy.`,persistConfig:i,initialState:p(),reportStoreError:g,sanitize:r,deepClone:s});if(!f.requiresValidation)return (!m||m())&&y(f.state,b),{ok:false,state:f.state};let a=h(f.state);if(a.ok)return l==="reset"&&g(e,`Persisted state for "${e}" failed schema; resetting to initial.`),{ok:true,state:a.value??f.state}}return g(e,`Persisted state for "${e}" failed schema; resetting to initial.`),(!m||m())&&y(s(p()),Date.now()),{ok:false,state:t}}return {ok:true,state:c.value??t}};var Se=(e,t,...n)=>{if(typeof e=="function")try{e(...n);}catch(o){let i=o?.message??o;O(`${t} callback threw: ${String(i)}`);}};var he=({name:e,persistTimers:t,persistInFlight:n,persistSequence:o,persistWatchState:i,plaintextWarningsIssued:u,exists:p,getMeta:g,getStoreValue:r,reportStoreError:s,hashState:h},b=false)=>{let y=g()?.options?.persist;if(!y)return;let m=async f=>{let a=g();if(!(!a?.options?.persist||a.options.persist!==y||!p())&&!(f!==void 0&&o[e]!==f)){if(!y.allowPlaintext&&!u.has(e)&&z(y.encrypt)&&z(y.decrypt)){u.add(e);let d=`[stroid/persist] Store '${e}' is persisted in plaintext. Provide encrypt/decrypt hooks to protect sensitive data.`;Se(a.options.onError,`onError(${e})`,d),O(d);}try{let d=y.serialize(r()),k=await V(y.checksum,d,h),w=JSON.stringify({v:a.version??1,updatedAt:a.updatedAt,updatedAtMs:a.updatedAtMs??Date.now(),checksum:k,data:d}),E=y.encryptAsync?await y.encryptAsync(w):y.encrypt(w);if(f!==void 0&&o[e]!==f)return;await Promise.resolve(y.driver.setItem?.(y.key,E)),te(i,e,!0);}catch(d){s(e,`Could not persist store "${e}" (${d?.message||d})`);}}},c=f=>{let a=n[e],d=(o[e]??0)+1;o[e]=d;let w=(async()=>{a&&await a,!(f&&t[e]!==f)&&o[e]===d&&await m(d);})().finally(()=>{n[e]===w&&(n[e]=null),f&&t[e]===f&&delete t[e];});n[e]=w;};if(b){t[e]&&(clearTimeout(t[e]),delete t[e]),c();return}t[e]&&clearTimeout(t[e]);let l=setTimeout(()=>{t[e]===l&&c(l);},0);t[e]=l;},_=e=>he(e),be=(e,t)=>he({...t,name:e},true);var ke=false,et=typeof process<"u"&&typeof process.env?.NODE_ENV=="string"?process.env.NODE_ENV:void 0,tt=typeof import.meta<"u"&&import.meta?.env?.MODE?import.meta.env.MODE:void 0,rt=et??tt,nt=()=>rt==="production",ot=()=>{let e={},t={},n=Object.create(null),o=Object.create(null),i=Object.create(null),u=new Set,p=new Set,g=Object.create(null);return {api:{getPersistQueueDepth(r){return e[r]?1:0}},onStoreCreate(r){let s=r.options.persist;if(!s)return;if(!s.encryptAsync&&j(s.encrypt)&&j(s.decrypt)&&!s.allowPlaintext){let l=`[stroid/persist] Store "${r.name}" is configured for plaintext persistence. Provide encrypt/decrypt hooks or set persist.allowPlaintext: true to acknowledge.`;if(nt()){r.reportStoreError(l),r.options.persist=null;return}r.warn(l);}if(s.sensitiveData&&!s.encryptAsync&&j(s.encrypt)){r.reportStoreError(`persist: store "${r.name}" is marked sensitiveData but has no encrypt function. Plaintext data will be written to storage.`);return}let b=ee(r.name,s.encrypt,s.decrypt);if(!b.ok){r.reportStoreError(b.reason??`persist: encrypt/decrypt validation failed for store "${r.name}".`),r.options.persist=null;return}if(s.key){let l=o[s.key];l&&l!==r.name&&r.isDev()?r.warn(`Persist key collision: "${s.key}" already used by store "${l}". Store "${r.name}" will overwrite the same storage key.`):o[s.key]=r.name;}let y=r.getMeta()?.updateCount??0,m=()=>{let l=r.getMeta();return l?(l.updateCount??0)===y:false},c=ye({name:r.name,silent:true,getMeta:r.getMeta,getInitialState:r.getInitialState,applyFeatureState:r.applyFeatureState,reportStoreError:(l,f)=>r.reportStoreError(f),warnMissingMaxSize:l=>{p.has(r.name)||(p.add(r.name),r.warnAlways(`[stroid/persist] Store "${r.name}" loaded ${l} bytes without a maxSize guard. Set persist.maxSize to prevent oversized payloads.`));},validate:r.validate,log:r.log,hashState:r.hashState,deepClone:r.deepClone,sanitize:r.sanitize,shouldApply:m});if(typeof c?.then=="function"?(g[r.name]={loading:true,pendingSave:false},c.then(l=>{let f=g[r.name];f&&(f.loading=false,(!l||f.pendingSave)&&_({name:r.name,persistTimers:e,persistInFlight:t,persistSequence:n,persistWatchState:i,plaintextWarningsIssued:u,exists:()=>r.hasStore(),getMeta:r.getMeta,getStoreValue:r.getStoreValue,reportStoreError:(a,d)=>r.reportStoreError(d),hashState:r.hashState}),delete g[r.name]);}).catch(()=>{let l=g[r.name];l&&(l.loading=false,l.pendingSave&&_({name:r.name,persistTimers:e,persistInFlight:t,persistSequence:n,persistWatchState:i,plaintextWarningsIssued:u,exists:()=>r.hasStore(),getMeta:r.getMeta,getStoreValue:r.getStoreValue,reportStoreError:(f,a)=>r.reportStoreError(a),hashState:r.hashState}),delete g[r.name]);})):c||_({name:r.name,persistTimers:e,persistInFlight:t,persistSequence:n,persistWatchState:i,plaintextWarningsIssued:u,exists:()=>r.hasStore(),getMeta:r.getMeta,getStoreValue:r.getStoreValue,reportStoreError:(l,f)=>r.reportStoreError(f),hashState:r.hashState}),typeof window<"u"&&typeof window.addEventListener=="function"){let l=()=>{be(r.name,{name:r.name,persistTimers:e,persistInFlight:t,persistSequence:n,persistWatchState:i,plaintextWarningsIssued:u,exists:()=>r.hasStore(),getMeta:r.getMeta,getStoreValue:r.getStoreValue,reportStoreError:(f,a)=>r.reportStoreError(a),hashState:r.hashState});};window.addEventListener("pagehide",l,{once:true}),window.addEventListener("beforeunload",l,{once:true});}re({name:r.name,persistConfig:s,persistWatchState:i});},onStoreWrite(r){if(!r.options.persist)return;let s=g[r.name];if(s?.loading){s.pendingSave=true;return}_({name:r.name,persistTimers:e,persistInFlight:t,persistSequence:n,persistWatchState:i,plaintextWarningsIssued:u,exists:()=>r.hasStore(),getMeta:r.getMeta,getStoreValue:r.getStoreValue,reportStoreError:(h,b)=>r.reportStoreError(b),hashState:r.hashState});},beforeStoreDelete(r){let s=r.options.persist;if(s){delete g[r.name],p.delete(r.name),e[r.name]&&(clearTimeout(e[r.name]),delete e[r.name]),t[r.name]=null,delete n[r.name];try{s.driver.removeItem?.(s.key);}catch{}s.key&&o[s.key]===r.name&&delete o[s.key],i[r.name]?.dispose(),delete i[r.name];}},resetAll(){Object.values(e).forEach(r=>clearTimeout(r)),Object.values(i).forEach(r=>{try{r.dispose();}catch{}}),Object.keys(e).forEach(r=>delete e[r]),Object.keys(t).forEach(r=>{t[r]=null,delete t[r];}),Object.keys(n).forEach(r=>delete n[r]),Object.keys(o).forEach(r=>delete o[r]),Object.keys(i).forEach(r=>delete i[r]),Object.keys(g).forEach(r=>delete g[r]),u.clear(),p.clear();}}},we=()=>{ke||(ke=true,X("persist",ot));};var ve=()=>{we();};ve();export{ve as installPersist};//# sourceMappingURL=persist.js.map
1
+ var $=new Map,X=(e,t)=>{$.set(e,t);};var Q=e=>$.get(e),Z=()=>Array.from($.keys());var Me=typeof Symbol=="function"?Symbol.for("stroid.persist.defaultCrypto"):"__stroid_persist_defaultCrypto__",z=e=>!!e?.[Me],j=e=>{try{let t=`__stroid_plaintext_probe_${Math.random().toString(36).slice(2)}__`,n=`__stroid_plaintext_probe_${Math.random().toString(36).slice(2)}__`;return e(t)!==t?!1:e(n)===n}catch{return false}},ee=(e,t,n)=>{let o="__stroid_persist_roundtrip_probe__",i;try{i=t(o);}catch(g){return {ok:false,reason:`persist: encrypt failed for store "${e}" (${g?.message??g})`}}if(typeof i!="string")return {ok:false,reason:`persist: encrypt must return a string for store "${e}".`};let l;try{l=n(i);}catch(g){return {ok:false,reason:`persist: decrypt failed for store "${e}" (${g?.message??g})`}}return typeof l!="string"?{ok:false,reason:`persist: decrypt must return a string for store "${e}".`}:l!==o?{ok:false,reason:`persist: encrypt/decrypt must round-trip for store "${e}".`}:{ok:true}};var te=(e,t,n)=>{e[t]&&(e[t].lastPresent=n);},re=({name:e,persistConfig:t,persistWatchState:n})=>{let o=t?.onStorageCleared;if(!t||typeof o!="function"||typeof window>"u"||typeof window.addEventListener!="function")return;n[e]?.dispose();let i=window,l=()=>{try{return t.driver.getItem?.(t.key)!=null}catch{return false}},g=r=>{let u=n[e],k=l();if(u){if(!u.lastPresent||k){u.lastPresent=k;return}u.lastPresent=false,o({name:e,key:t.key,reason:r});}},y=r=>{if(r.key===null){g("clear");return}r.key===t.key&&r.newValue===null&&g("remove");},c=()=>{g("missing");};i.addEventListener("storage",y),i.addEventListener("focus",c),n[e]={lastPresent:l(),dispose:()=>{i.removeEventListener("storage",y),i.removeEventListener("focus",c);}};};var W=({value:e,sanitize:t,validate:n,onSanitizeError:o})=>{let i;if(t)try{i=t(e);}catch(g){return o?.(g),{ok:false}}else i=e;let l=n(i);return l.ok?{ok:true,value:l.value??i}:{ok:false}},H=({value:e,fallbackMs:t=Date.now(),onInvalid:n})=>{if(typeof e=="number")return Number.isFinite(e)?e:(n?.(),t);if(typeof e=="string"){let o=Date.parse(e);return Number.isFinite(o)?o:(n?.(),t)}return n?.(),t};var Ce=new Map,D=(e,t,n=0)=>{!e||typeof t!="function"||Ce.set(e,{name:e,order:n,fn:t});};var Ee=()=>new Map([["noSignal",new Set],["shape",new Set],["autoCreate",new Set],["mutableResult",new Set]]),ne=()=>({fetchRegistry:Object.create(null),inflight:Object.create(null),requestVersion:Object.create(null),cacheMeta:Object.create(null),rateWindowStart:Object.create(null),rateCount:Object.create(null),ratePruneState:{lastAt:0},ratePruneTimer:null,warnedOnce:Ee(),storeCleanups:Object.create(null),revalidateKeys:new Set,revalidateHandlers:Object.create(null),asyncMetrics:{cacheHits:0,cacheMisses:0,dedupes:0,requests:0,failures:0,avgMs:0,lastMs:0}});var L=new Map,oe=new WeakSet,Fe=e=>{oe.has(e)||(oe.add(e),Z().forEach(t=>{if(!e.featureRuntimes.get(t)){let n=Q(t);n&&e.featureRuntimes.set(t,n());}}));},Pe=typeof __STROID_REGISTRY_ID__<"u"&&__STROID_REGISTRY_ID__||typeof process<"u"&&process.env?.STROID_REGISTRY_ID||void 0,se,ie=e=>(se||Pe||e).replace(/\.ts(\?|$)/,".js$1"),Te=ie("stroid:default-registry");var Oe=()=>{se=void 0,L.clear();};D("registry.scope-override",Oe,110);var _e=()=>({pendingNotifications:new Set,pendingBuffer:[],orderedNames:[],notifyScheduled:false,batchDepth:0,flushId:0,isFlushing:false});var xe=()=>({depth:0,pending:[],stagedValues:new Map,snapshotCache:new Map,failed:false,error:void 0}),Ae=(e="default")=>{let t={scope:e,stores:Object.create(null),subscribers:Object.create(null),initialStates:Object.create(null),initialFactories:Object.create(null),metaEntries:Object.create(null),snapshotCache:Object.create(null),featureRuntimes:new Map,deletingStores:new Set,computedEntries:Object.create(null),computedDependents:Object.create(null),computedCleanups:new Map,transaction:xe(),async:ne(),notify:_e(),lifecycleListener:null};return Fe(t),t},je=e=>{let t=ie(e),n=L.get(t);if(n)return n;let o=Ae();return L.set(t,o),o};var v=[],Ve={run:(e,t)=>{v.push(e);try{return t()}finally{v.pop();}},get:()=>v.length>0?v[v.length-1]:null,enterWith:e=>{if(v.length>0){v[v.length-1]=e;return}v.push(e);}};var ae=e=>(Ve).get()||e||je(Te);var Ne={log:(e,t)=>{typeof console<"u"&&typeof console.log=="function"&&(t?console.log(`[stroid] ${e}`,t):console.log(`[stroid] ${e}`));},warn:(e,t)=>{typeof console<"u"&&typeof console.warn=="function"&&(t?console.warn(`[stroid] ${e}`,t):console.warn(`[stroid] ${e}`));},critical:(e,t)=>{typeof console<"u"&&typeof console.error=="function"&&(t?console.error(`[stroid] ${e}`,t):console.error(`[stroid] ${e}`));}},ue={logSink:Ne,flush:{chunkSize:Number.POSITIVE_INFINITY,chunkDelayMs:0,priorityStores:[]},revalidateOnFocus:{debounceMs:0,maxConcurrent:3,staggerMs:100},namespace:"",strictMissingFeatures:true,assertRuntime:false,strictMutatorReturns:true,asyncAutoCreate:false,asyncCloneResult:"none",autoCorrelationIds:false,acknowledgeLooseTypes:false,pathCacheSize:500,defaultSnapshotMode:"deep",strictAsyncUsageErrors:false,middleware:[],allowUntrustedHydration:false,mutatorProduce:void 0,selectorCloneFrozen:true},B=e=>({logSink:{...e.logSink},flush:{...e.flush},revalidateOnFocus:{...e.revalidateOnFocus},namespace:e.namespace,strictMissingFeatures:e.strictMissingFeatures,assertRuntime:e.assertRuntime,strictMutatorReturns:e.strictMutatorReturns,asyncAutoCreate:e.asyncAutoCreate,asyncCloneResult:e.asyncCloneResult,autoCorrelationIds:e.autoCorrelationIds,acknowledgeLooseTypes:e.acknowledgeLooseTypes,pathCacheSize:e.pathCacheSize,defaultSnapshotMode:e.defaultSnapshotMode,strictAsyncUsageErrors:e.strictAsyncUsageErrors,middleware:[...e.middleware],allowUntrustedHydration:e.allowUntrustedHydration,mutatorProduce:e.mutatorProduce,selectorCloneFrozen:e.selectorCloneFrozen}),U=new WeakMap,ce=B(ue),Ie=e=>{let t=U.get(e);return t||(t=B(ce),U.set(e,t)),t};var q=()=>Ie(ae());var He=()=>{U=new WeakMap,ce=B(ue);};D("config.reset",He,90);typeof process<"u"&&typeof process.env?.NODE_ENV=="string"?process.env.NODE_ENV:void 0;typeof import.meta<"u"&&import.meta?.env?.MODE?import.meta.env.MODE:void 0;var Le=(e,t)=>{typeof console<"u"&&typeof console.warn=="function"&&(t?console.warn(`[stroid] ${e}`,t):console.warn(`[stroid] ${e}`));};var _=(e,t)=>{if((q().logSink.warn??Le)(e,t),q().assertRuntime)throw new Error(e)};var le=new Set(["__proto__","constructor","prototype"]);var Y=null,Ue=()=>{if(Y)return Y;let e,t=[];for(let n=0;n<256;n++){e=n;for(let o=0;o<8;o++)e=e&1?3988292384^e>>>1:e>>>1;t[n]=e>>>0;}return Y=t,t},fe=e=>{let t=Ue(),n=-1;for(let o=0;o<e.length;o++)n=n>>>0,n=n>>>8^t[(n^e.charCodeAt(o))&255];return (n^-1)>>>0},Be=2166136261,qe=2654435761,Ye=1e5,R=(e,t)=>{let n=t>>>0;e.h1=Math.imul(e.h1^n,2246822507),e.h2=Math.imul(e.h2^n,3266489909);},E=(e,t)=>{R(e,t.length);for(let n=0;n<t.length;n++)R(e,t.charCodeAt(n));},h=(e,t)=>{E(e,t);},de=(e,t)=>{if(Number.isNaN(t)){h(e,"NaN");return}if(!Number.isFinite(t)){h(e,t>0?"Infinity":"-Infinity");return}if(Object.is(t,-0)){h(e,"-0");return}let n=t|0;if(t===n){h(e,"int"),R(e,n);return}h(e,"num"),E(e,String(t));},F=(e,t)=>{if(e.nodes++>Ye){h(e,"[max]");return}if(t===null){h(e,"null");return}let n=typeof t;if(n==="string"){h(e,"string"),E(e,t);return}if(n==="number"){h(e,"number"),de(e,t);return}if(n==="boolean"){h(e,t?"true":"false");return}if(n==="undefined"){h(e,"undefined");return}if(n==="bigint"){h(e,"bigint"),E(e,t.toString());return}if(n==="symbol"){h(e,"symbol");let c=t;E(e,Symbol.keyFor(c)??c.description??String(c));return}if(n==="function"){h(e,"function"),E(e,t.name||"anonymous");return}let o=t,i=e.seen.get(o);if(i!==void 0){h(e,"ref"),R(e,i);return}let l=e.nextId++;if(e.seen.set(o,l),Array.isArray(o)){h(e,"array"),R(e,o.length);for(let c=0;c<o.length;c++)Object.prototype.hasOwnProperty.call(o,c)?F(e,o[c]):h(e,"hole");return}if(o instanceof Date){h(e,"date"),de(e,o.getTime());return}if(o instanceof Map){h(e,"map"),R(e,o.size),o.forEach((c,r)=>{F(e,r),F(e,c);});return}if(o instanceof Set){h(e,"set"),R(e,o.size),o.forEach(c=>{F(e,c);});return}h(e,"object");let g=Object.getOwnPropertyDescriptors(o),y=[];Object.entries(g).forEach(([c,r])=>{r?.enumerable&&(le.has(c)||"get"in r||"set"in r||y.push([c,r]));}),R(e,y.length);for(let[c,r]of y)E(e,c),F(e,r.value);},K=e=>{if(typeof e=="string")return fe(JSON.stringify(e));let t={h1:Be,h2:qe,seen:new WeakMap,nextId:1,nodes:0};F(t,e);let n=t.h1>>>0,o=t.h2>>>0;return n^=n>>>16,n=Math.imul(n,2246822507),n^=n>>>13,n=Math.imul(n,3266489909),n^=n>>>16,o^=o>>>16,o=Math.imul(o,668265261),o^=o>>>15,o=Math.imul(o,374761393),o^=o>>>16,(n&2097151)*4294967296+(o>>>0)};var Ge=e=>{let t=new Uint8Array(e),n="";for(let o=0;o<t.length;o++)n+=t[o].toString(16).padStart(2,"0");return n},Xe=async e=>{if(typeof globalThis<"u"&&globalThis.crypto?.subtle){let t=typeof TextEncoder<"u"?new TextEncoder:null,n=t?t.encode(e):new Uint8Array(Buffer.from(e)),o=await globalThis.crypto.subtle.digest("SHA-256",n);return Ge(o)}try{let{createHash:t}=await import('crypto');return t("sha256").update(e).digest("hex")}catch{throw new Error("sha256 checksum is not supported in this environment")}},V=async(e,t,n=K)=>e==="none"?null:e==="sha256"?Xe(t):n(t);var pe=1e6,ge=(e,t)=>{let n=e?.options?.migrations??{};if(Object.keys(n).length>0)return n;let o=t?.migrate;if(typeof o!="function")return n;let i=e?.version??1;return !Number.isFinite(i)||i<=1?n:{[i]:o}},J=({name:e,persisted:t,reason:n,persistConfig:o,initialState:i,reportStoreError:l,sanitize:g,deepClone:y})=>{l(e,n);let c=o?.onMigrationFail??"reset";if(c==="keep")return {state:t,requiresValidation:true};if(typeof c=="function")try{let r=c(y(t));if(r!==void 0)return {state:g(r),requiresValidation:!0};l(e,`onMigrationFail for "${e}" returned undefined. Falling back to initial state.`);}catch(r){l(e,`onMigrationFail for "${e}" failed: ${r?.message??r}`);}return {state:y(i),requiresValidation:true}},ye=e=>{let n=e.getMeta()?.options?.persist;return n?!!n.decryptAsync||n.checksum==="sha256"?Ze(e):Qe(e):false},Qe=({name:e,silent:t=false,getMeta:n,getInitialState:o,applyFeatureState:i,reportStoreError:l,warnMissingMaxSize:g,validate:y,log:c,hashState:r,deepClone:u,sanitize:k,shouldApply:p})=>{let m=n(),f=m?.options?.persist;if(!f)return false;let b=ge(m,f),a=s=>W({value:s,validate:y});try{let s=f.driver.getItem?.(f.key)??null;if(!s)return !1;if(typeof s!="string")return l(e,`Persist driver for "${e}" returned an async value during sync hydration. Provide async decrypt hooks or use an async-capable persist driver.`),!0;if(typeof f.maxSize!="number"&&s.length>pe&&g?.(s.length),typeof f.maxSize=="number"&&s.length>f.maxSize)return l(e,`Persist payload for "${e}" exceeds maxSize (${s.length} > ${f.maxSize}). Skipping hydration.`),!0;let d=f.decrypt(s),S=JSON.parse(d),{v:w=1,checksum:M,data:C,updatedAt:N,updatedAtMs:P}=S||{};if(!C)return !0;let T=H({value:typeof P=="number"?P:N,fallbackMs:Date.now(),onInvalid:()=>{c(`persist: corrupt updatedAt in stored data for "${e}". Using current time to prevent sync overwrite.`);}});if(f.checksum!=="none"&&M!==r(C))return l(e,`Checksum mismatch loading store "${e}". Falling back to initial state.`),(!p||p())&&i(u(o()),Date.now()),!0;let A=f.deserialize(C),I=m?.version??1,O=me({name:e,parsed:A,v:w,targetVersion:I,cfg:f,migrations:b,getInitialState:o,reportStoreError:l,sanitize:k,deepClone:u,validateState:a,safeUpdatedAt:T,applyFeatureState:i,shouldApply:p});return O.ok&&(A=O.state,(!p||p())&&(i(O.state,T),t||c(`Store "${e}" loaded from persistence`))),!0}catch(s){return l(e,`Could not load store "${e}" (${s?.message||s})`),true}},Ze=async({name:e,silent:t=false,getMeta:n,getInitialState:o,applyFeatureState:i,reportStoreError:l,warnMissingMaxSize:g,validate:y,log:c,hashState:r,deepClone:u,sanitize:k,shouldApply:p})=>{let m=n(),f=m?.options?.persist;if(!f)return false;let b=ge(m,f),a=s=>W({value:s,validate:y});try{let s=await Promise.resolve(f.driver.getItem?.(f.key)??null);if(!s)return !1;if(typeof f.maxSize!="number"&&typeof s=="string"&&s.length>pe&&g?.(s.length),typeof f.maxSize=="number"&&typeof s=="string"&&s.length>f.maxSize)return l(e,`Persist payload for "${e}" exceeds maxSize (${s.length} > ${f.maxSize}). Skipping hydration.`),!0;let d=f.decryptAsync?await f.decryptAsync(s):f.decrypt(s),S=JSON.parse(d),{v:w=1,checksum:M,data:C,updatedAt:N,updatedAtMs:P}=S||{};if(!C)return !0;let T=H({value:typeof P=="number"?P:N,fallbackMs:Date.now(),onInvalid:()=>{c(`persist: corrupt updatedAt in stored data for "${e}". Using current time to prevent sync overwrite.`);}}),A=await V(f.checksum,C,r);if(f.checksum!=="none"&&M!==A)return l(e,`Checksum mismatch loading store "${e}". Falling back to initial state.`),(!p||p())&&i(u(o()),Date.now()),!0;let I=f.deserialize(C),O=m?.version??1,G=me({name:e,parsed:I,v:w,targetVersion:O,cfg:f,migrations:b,getInitialState:o,reportStoreError:l,sanitize:k,deepClone:u,validateState:a,safeUpdatedAt:T,applyFeatureState:i,shouldApply:p});return G.ok&&(!p||p())&&(i(G.state,T),t||c(`Store "${e}" loaded from persistence`)),!0}catch(s){return l(e,`Could not load store "${e}" (${s?.message||s})`),true}},me=({name:e,parsed:t,v:n,targetVersion:o,cfg:i,migrations:l,getInitialState:g,reportStoreError:y,sanitize:c,deepClone:r,validateState:u,safeUpdatedAt:k,applyFeatureState:p,shouldApply:m})=>{if(n!==o){let b=Object.keys(l).map(d=>Number(d)).filter(d=>d>n&&d<=o).sort((d,S)=>d-S);if(b.length===0){let d=J({name:e,persisted:t,reason:`No migration path from v${n} to v${o} for "${e}". Applying onMigrationFail strategy.`,persistConfig:i,initialState:g(),reportStoreError:y,sanitize:c,deepClone:r});if(t=d.state,!d.requiresValidation)return (!m||m())&&p(t,k),{ok:false,state:t}}let a=false,s=true;if(b.forEach(d=>{if(!a)try{let S=l[d](t);S!==void 0&&(t=S);}catch(S){let w=J({name:e,persisted:t,reason:`Migration to v${d} failed for "${e}": ${S?.message||S}`,persistConfig:i,initialState:g(),reportStoreError:y,sanitize:c,deepClone:r});t=w.state,s=w.requiresValidation,a=true;}}),a){if(!s)return (!m||m())&&p(t,k),{ok:false,state:t};let d=u(t);return d.ok?{ok:true,state:d.value??t}:((!m||m())&&p(r(g()),Date.now()),{ok:false,state:t})}}let f=u(t);if(!f.ok){if(n!==o){let b=i?.onMigrationFail??"reset",a=J({name:e,persisted:t,reason:`Persisted state for "${e}" failed schema after version change. Applying onMigrationFail strategy.`,persistConfig:i,initialState:g(),reportStoreError:y,sanitize:c,deepClone:r});if(!a.requiresValidation)return (!m||m())&&p(a.state,k),{ok:false,state:a.state};let s=u(a.state);if(s.ok)return b==="reset"&&y(e,`Persisted state for "${e}" failed schema; resetting to initial.`),{ok:true,state:s.value??a.state}}return y(e,`Persisted state for "${e}" failed schema; resetting to initial.`),(!m||m())&&p(r(g()),Date.now()),{ok:false,state:t}}return {ok:true,state:f.value??t}};var Se=(e,t,...n)=>{if(typeof e=="function")try{e(...n);}catch(o){let i=o?.message??o;_(`${t} callback threw: ${String(i)}`);}};var he=({name:e,persistTimers:t,persistInFlight:n,persistSequence:o,persistWatchState:i,plaintextWarningsIssued:l,exists:g,getMeta:y,getStoreValue:c,reportStoreError:r,hashState:u},k=false)=>{let p=y()?.options?.persist;if(!p)return;let m=async a=>{let s=y();if(!(!s?.options?.persist||s.options.persist!==p||!g())&&!(a!==void 0&&o[e]!==a)){if(!p.allowPlaintext&&!l.has(e)&&z(p.encrypt)&&z(p.decrypt)){l.add(e);let d=`[stroid/persist] Store '${e}' is persisted in plaintext. Provide encrypt/decrypt hooks to protect sensitive data.`;Se(s.options.onError,`onError(${e})`,d),_(d);}try{let d=p.serialize(c()),S=await V(p.checksum,d,u),w=JSON.stringify({v:s.version??1,updatedAt:s.updatedAt,updatedAtMs:s.updatedAtMs??Date.now(),checksum:S,data:d}),M=p.encryptAsync?await p.encryptAsync(w):p.encrypt(w);if(a!==void 0&&o[e]!==a)return;await Promise.resolve(p.driver.setItem?.(p.key,M)),te(i,e,!0);}catch(d){r(e,`Could not persist store "${e}" (${d?.message||d})`);}}},f=a=>{let s=n[e],d=(o[e]??0)+1;o[e]=d;let w=(async()=>{s&&await s,!(a&&t[e]!==a)&&o[e]===d&&await m(d);})().finally(()=>{n[e]===w&&(n[e]=null),a&&t[e]===a&&delete t[e];});n[e]=w;};if(k){t[e]&&(clearTimeout(t[e]),delete t[e]),f();return}t[e]&&clearTimeout(t[e]);let b=setTimeout(()=>{t[e]===b&&f(b);},0);t[e]=b;},x=e=>he(e),be=(e,t)=>he({...t,name:e},true);var ke=false,et=typeof process<"u"&&typeof process.env?.NODE_ENV=="string"?process.env.NODE_ENV:void 0,tt=typeof import.meta<"u"&&import.meta?.env?.MODE?import.meta.env.MODE:void 0,rt=et??tt,nt=()=>rt==="production",ot=()=>{let e={},t={},n=Object.create(null),o=Object.create(null),i=Object.create(null),l=new Set,g=new Set,y=Object.create(null),c=Object.create(null);return {api:{getPersistQueueDepth(r){return e[r]?1:0}},onStoreCreate(r){let u=r.options.persist;if(!u)return;if(!u.encryptAsync&&j(u.encrypt)&&j(u.decrypt)&&!u.allowPlaintext){let a=`[stroid/persist] Store "${r.name}" is configured for plaintext persistence. Provide encrypt/decrypt hooks or set persist.allowPlaintext: true to acknowledge.`;if(nt()){r.reportStoreError(a),r.options.persist=null;return}r.warn(a);}if(u.sensitiveData&&!u.encryptAsync&&j(u.encrypt)){r.reportStoreError(`persist: store "${r.name}" is marked sensitiveData but has no encrypt function. Plaintext data will be written to storage.`);return}let p=ee(r.name,u.encrypt,u.decrypt);if(!p.ok){r.reportStoreError(p.reason??`persist: encrypt/decrypt validation failed for store "${r.name}".`),r.options.persist=null;return}if(u.key){let a=o[u.key];a&&a!==r.name&&r.isDev()?r.warn(`Persist key collision: "${u.key}" already used by store "${a}". Store "${r.name}" will overwrite the same storage key.`):o[u.key]=r.name;}let m=r.getMeta()?.updateCount??0,f=()=>{let a=r.getMeta();return a?(a.updateCount??0)===m:false},b=ye({name:r.name,silent:true,getMeta:r.getMeta,getInitialState:r.getInitialState,applyFeatureState:r.applyFeatureState,reportStoreError:(a,s)=>r.reportStoreError(s),warnMissingMaxSize:a=>{g.has(r.name)||(g.add(r.name),r.warnAlways(`[stroid/persist] Store "${r.name}" loaded ${a} bytes without a maxSize guard. Set persist.maxSize to prevent oversized payloads.`));},validate:r.validate,log:r.log,hashState:r.hashState,deepClone:r.deepClone,sanitize:r.sanitize,shouldApply:f});if(typeof b?.then=="function"?(y[r.name]={loading:true,pendingSave:false},b.then(a=>{let s=y[r.name];s&&(s.loading=false,(!a||s.pendingSave)&&x({name:r.name,persistTimers:e,persistInFlight:t,persistSequence:n,persistWatchState:i,plaintextWarningsIssued:l,exists:()=>r.hasStore(),getMeta:r.getMeta,getStoreValue:r.getStoreValue,reportStoreError:(d,S)=>r.reportStoreError(S),hashState:r.hashState}),delete y[r.name]);}).catch(()=>{let a=y[r.name];a&&(a.loading=false,a.pendingSave&&x({name:r.name,persistTimers:e,persistInFlight:t,persistSequence:n,persistWatchState:i,plaintextWarningsIssued:l,exists:()=>r.hasStore(),getMeta:r.getMeta,getStoreValue:r.getStoreValue,reportStoreError:(s,d)=>r.reportStoreError(d),hashState:r.hashState}),delete y[r.name]);})):b||x({name:r.name,persistTimers:e,persistInFlight:t,persistSequence:n,persistWatchState:i,plaintextWarningsIssued:l,exists:()=>r.hasStore(),getMeta:r.getMeta,getStoreValue:r.getStoreValue,reportStoreError:(a,s)=>r.reportStoreError(s),hashState:r.hashState}),typeof window<"u"&&typeof window.addEventListener=="function"){c[r.name]?.();let a=window,s=false,d=()=>{s||(s=true,a.removeEventListener("pagehide",S),a.removeEventListener("beforeunload",S),delete c[r.name]);},S=()=>{d(),be(r.name,{name:r.name,persistTimers:e,persistInFlight:t,persistSequence:n,persistWatchState:i,plaintextWarningsIssued:l,exists:()=>r.hasStore(),getMeta:r.getMeta,getStoreValue:r.getStoreValue,reportStoreError:(w,M)=>r.reportStoreError(M),hashState:r.hashState});};a.addEventListener("pagehide",S,{once:true}),a.addEventListener("beforeunload",S,{once:true}),c[r.name]=d;}re({name:r.name,persistConfig:u,persistWatchState:i});},onStoreWrite(r){if(!r.options.persist)return;let u=y[r.name];if(u?.loading){u.pendingSave=true;return}x({name:r.name,persistTimers:e,persistInFlight:t,persistSequence:n,persistWatchState:i,plaintextWarningsIssued:l,exists:()=>r.hasStore(),getMeta:r.getMeta,getStoreValue:r.getStoreValue,reportStoreError:(k,p)=>r.reportStoreError(p),hashState:r.hashState});},beforeStoreDelete(r){let u=r.options.persist;if(u){delete y[r.name],g.delete(r.name),e[r.name]&&(clearTimeout(e[r.name]),delete e[r.name]),t[r.name]=null,delete n[r.name];try{u.driver.removeItem?.(u.key);}catch{}u.key&&o[u.key]===r.name&&delete o[u.key],c[r.name]?.(),i[r.name]?.dispose(),delete c[r.name],delete i[r.name];}},resetAll(){Object.values(e).forEach(r=>clearTimeout(r)),Object.values(c).forEach(r=>{try{r();}catch{}}),Object.values(i).forEach(r=>{try{r.dispose();}catch{}}),Object.keys(e).forEach(r=>delete e[r]),Object.keys(t).forEach(r=>{t[r]=null,delete t[r];}),Object.keys(n).forEach(r=>delete n[r]),Object.keys(o).forEach(r=>delete o[r]),Object.keys(i).forEach(r=>delete i[r]),Object.keys(y).forEach(r=>delete y[r]),l.clear(),g.clear();}}},we=()=>{ke||(ke=true,X("persist",ot));};var ve=()=>{we();};ve();export{ve as installPersist};//# sourceMappingURL=persist.js.map
2
2
  //# sourceMappingURL=persist.js.map