stroid 0.1.1 → 0.1.2

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 (180) hide show
  1. package/CHANGELOG.md +210 -119
  2. package/README.md +104 -431
  3. package/dist/async.d.ts +42 -9
  4. package/dist/async.js +26 -26
  5. package/dist/async.js.map +1 -1
  6. package/dist/cache.d.ts +12 -0
  7. package/dist/computed.d.ts +40 -7
  8. package/dist/computed.js +11 -11
  9. package/dist/computed.js.map +1 -1
  10. package/dist/core.d.ts +5 -15
  11. package/dist/core.js +14 -15
  12. package/dist/core.js.map +1 -1
  13. package/dist/devtools.d.ts +30 -5
  14. package/dist/devtools.js +1 -1
  15. package/dist/devtools.js.map +1 -1
  16. package/dist/feature.d.ts +92 -14
  17. package/dist/feature.js +1 -1
  18. package/dist/feature.js.map +1 -1
  19. package/dist/helpers.d.ts +37 -3
  20. package/dist/helpers.js +14 -15
  21. package/dist/helpers.js.map +1 -1
  22. package/dist/index-internal.d.ts +44 -0
  23. package/dist/index.d.cts +169 -33
  24. package/dist/index.d.ts +169 -33
  25. package/dist/index.js +24 -23
  26. package/dist/index.js.map +1 -1
  27. package/dist/install.d.ts +6 -4
  28. package/dist/install.js +1 -1
  29. package/dist/install.js.map +1 -1
  30. package/dist/options.d.ts +295 -0
  31. package/dist/persist.d.ts +1 -1
  32. package/dist/persist.js +1 -1
  33. package/dist/persist.js.map +1 -1
  34. package/dist/react/index.d.ts +70 -0
  35. package/dist/react/index.js +38 -0
  36. package/dist/react/index.js.map +1 -0
  37. package/dist/registry.d.ts +117 -0
  38. package/dist/runtime-admin.d.ts +4 -2
  39. package/dist/runtime-admin.js +1 -1
  40. package/dist/runtime-admin.js.map +1 -1
  41. package/dist/runtime-tools.d.ts +66 -9
  42. package/dist/runtime-tools.js +2 -2
  43. package/dist/runtime-tools.js.map +1 -1
  44. package/dist/selectors.d.ts +4 -2
  45. package/dist/selectors.js +1 -1
  46. package/dist/selectors.js.map +1 -1
  47. package/dist/server.d.ts +30 -2
  48. package/dist/server.js +11 -10
  49. package/dist/server.js.map +1 -1
  50. package/dist/store-registry.d.ts +80 -0
  51. package/dist/sync.d.ts +1 -1
  52. package/dist/sync.js +1 -1
  53. package/dist/sync.js.map +1 -1
  54. package/dist/testing.d.ts +16 -4
  55. package/dist/testing.js +14 -15
  56. package/dist/testing.js.map +1 -1
  57. package/dist/tsdoc-metadata.json +11 -0
  58. package/dist/types/adapters/options.d.ts +335 -0
  59. package/dist/types/async/cache.d.ts +39 -0
  60. package/dist/types/async/clone.d.ts +10 -0
  61. package/dist/types/async/errors.d.ts +3 -0
  62. package/dist/types/async/fetch.d.ts +37 -0
  63. package/dist/types/async/inflight.d.ts +13 -0
  64. package/dist/types/async/rate.d.ts +5 -0
  65. package/dist/types/async/registry.d.ts +116 -0
  66. package/dist/types/async/request.d.ts +11 -0
  67. package/dist/types/async/retry.d.ts +10 -0
  68. package/dist/types/async.d.ts +10 -0
  69. package/dist/types/computed/computed-graph.d.ts +29 -0
  70. package/dist/types/computed/index.d.ts +16 -0
  71. package/dist/types/config.d.ts +10 -0
  72. package/dist/types/core/index.d.ts +11 -0
  73. package/dist/types/core/lifecycle-hooks.d.ts +16 -0
  74. package/dist/types/core/store-admin-impl.d.ts +9 -0
  75. package/dist/types/core/store-admin.d.ts +9 -0
  76. package/dist/types/core/store-core.d.ts +13 -0
  77. package/dist/types/core/store-create.d.ts +16 -0
  78. package/dist/types/core/store-hydrate-impl.d.ts +35 -0
  79. package/dist/types/core/store-hydrate.d.ts +9 -0
  80. package/dist/types/core/store-lifecycle/hooks.d.ts +19 -0
  81. package/dist/types/core/store-lifecycle/identity.d.ts +23 -0
  82. package/dist/types/core/store-lifecycle/registry.d.ts +53 -0
  83. package/dist/types/core/store-lifecycle/types.d.ts +67 -0
  84. package/dist/types/core/store-lifecycle/validation.d.ts +53 -0
  85. package/dist/types/core/store-name.d.ts +28 -0
  86. package/dist/types/core/store-notify.d.ts +12 -0
  87. package/dist/types/core/store-read.d.ts +18 -0
  88. package/dist/types/core/store-registry.d.ts +108 -0
  89. package/dist/types/core/store-replace-impl.d.ts +11 -0
  90. package/dist/types/core/store-replace.d.ts +9 -0
  91. package/dist/types/core/store-set-impl.d.ts +13 -0
  92. package/dist/types/core/store-set.d.ts +9 -0
  93. package/dist/types/core/store-shared/core.d.ts +13 -0
  94. package/dist/types/core/store-shared/notify.d.ts +12 -0
  95. package/dist/types/core/store-transaction.d.ts +26 -0
  96. package/dist/types/core/store-write-shared.d.ts +19 -0
  97. package/dist/types/core/store-write.d.ts +13 -0
  98. package/dist/types/features/feature-registry.d.ts +91 -0
  99. package/dist/types/features/lifecycle.d.ts +40 -0
  100. package/dist/types/index.d.ts +17 -0
  101. package/dist/types/integrations/query.d.ts +8 -0
  102. package/dist/types/internals/computed-order.d.ts +3 -0
  103. package/dist/types/internals/config.d.ts +116 -0
  104. package/dist/types/internals/diagnostics.d.ts +21 -0
  105. package/dist/types/internals/reporting.d.ts +9 -0
  106. package/dist/types/internals/store-admin.d.ts +7 -0
  107. package/dist/types/internals/store-ops.d.ts +13 -0
  108. package/dist/types/internals/test-reset.d.ts +2 -0
  109. package/dist/types/internals/write-context.d.ts +15 -0
  110. package/dist/types/notification/delivery.d.ts +3 -0
  111. package/dist/types/notification/index.d.ts +10 -0
  112. package/dist/types/notification/metrics.d.ts +12 -0
  113. package/dist/types/notification/priority.d.ts +9 -0
  114. package/dist/types/notification/scheduler.d.ts +11 -0
  115. package/dist/types/notification/snapshot.d.ts +8 -0
  116. package/dist/types/runtime-admin/index.d.ts +2 -0
  117. package/dist/types/runtime-tools/index.d.ts +58 -0
  118. package/dist/types/store.d.ts +16 -0
  119. package/dist/types/types/utility.d.ts +17 -0
  120. package/dist/types/utils/clone.d.ts +4 -0
  121. package/dist/types/utils/devfreeze.d.ts +2 -0
  122. package/dist/types/utils/hash.d.ts +8 -0
  123. package/dist/types/utils/path.d.ts +5 -0
  124. package/dist/types/utils/validation.d.ts +14 -0
  125. package/dist/types/utils.d.ts +13 -0
  126. package/dist/types.d.ts +65 -0
  127. package/dist/utility.d.ts +15 -0
  128. package/package.json +26 -11
  129. package/dist/_tsup-dts-rollup.d.cts +0 -2411
  130. package/dist/_tsup-dts-rollup.d.ts +0 -2411
  131. package/dist/async.cjs +0 -34
  132. package/dist/async.cjs.map +0 -1
  133. package/dist/async.d.cts +0 -9
  134. package/dist/computed.cjs +0 -13
  135. package/dist/computed.cjs.map +0 -1
  136. package/dist/computed.d.cts +0 -7
  137. package/dist/core.cjs +0 -24
  138. package/dist/core.cjs.map +0 -1
  139. package/dist/core.d.cts +0 -15
  140. package/dist/devtools.cjs +0 -2
  141. package/dist/devtools.cjs.map +0 -1
  142. package/dist/devtools.d.cts +0 -5
  143. package/dist/feature.cjs +0 -2
  144. package/dist/feature.cjs.map +0 -1
  145. package/dist/feature.d.cts +0 -14
  146. package/dist/helpers.cjs +0 -24
  147. package/dist/helpers.cjs.map +0 -1
  148. package/dist/helpers.d.cts +0 -3
  149. package/dist/index.cjs +0 -35
  150. package/dist/index.cjs.map +0 -1
  151. package/dist/install.cjs +0 -2
  152. package/dist/install.cjs.map +0 -1
  153. package/dist/install.d.cts +0 -4
  154. package/dist/persist.cjs +0 -2
  155. package/dist/persist.cjs.map +0 -1
  156. package/dist/persist.d.cts +0 -1
  157. package/dist/react.cjs +0 -36
  158. package/dist/react.cjs.map +0 -1
  159. package/dist/react.d.cts +0 -7
  160. package/dist/react.d.ts +0 -7
  161. package/dist/react.js +0 -36
  162. package/dist/react.js.map +0 -1
  163. package/dist/runtime-admin.cjs +0 -2
  164. package/dist/runtime-admin.cjs.map +0 -1
  165. package/dist/runtime-admin.d.cts +0 -2
  166. package/dist/runtime-tools.cjs +0 -4
  167. package/dist/runtime-tools.cjs.map +0 -1
  168. package/dist/runtime-tools.d.cts +0 -9
  169. package/dist/selectors.cjs +0 -2
  170. package/dist/selectors.cjs.map +0 -1
  171. package/dist/selectors.d.cts +0 -2
  172. package/dist/server.cjs +0 -12
  173. package/dist/server.cjs.map +0 -1
  174. package/dist/server.d.cts +0 -2
  175. package/dist/sync.cjs +0 -2
  176. package/dist/sync.cjs.map +0 -1
  177. package/dist/sync.d.cts +0 -1
  178. package/dist/testing.cjs +0 -24
  179. package/dist/testing.cjs.map +0 -1
  180. package/dist/testing.d.cts +0 -4
package/dist/install.d.ts CHANGED
@@ -1,4 +1,6 @@
1
- export { installPersist } from './_tsup-dts-rollup.js';
2
- export { installSync } from './_tsup-dts-rollup.js';
3
- export { installDevtools_alias_1 as installDevtools } from './_tsup-dts-rollup.js';
4
- export { installAllFeatures } from './_tsup-dts-rollup.js';
1
+ declare const installPersist: () => void;
2
+ declare const installSync: () => void;
3
+ declare const installDevtools: () => void;
4
+ declare const installAllFeatures: () => void;
5
+
6
+ export { installAllFeatures, installDevtools, installPersist, installSync };
package/dist/install.js CHANGED
@@ -1,2 +1,2 @@
1
- var De=new Map,O=(e,t)=>{De.set(e,t);};var Ne=typeof Symbol=="function"?Symbol.for("stroid.persist.defaultCrypto"):"__stroid_persist_defaultCrypto__",U=e=>!!e?.[Ne],z=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}},ie=(e,t,n)=>{let o="__stroid_persist_roundtrip_probe__",a;try{a=t(o);}catch(u){return {ok:false,reason:`persist: encrypt failed for store "${e}" (${u?.message??u})`}}if(typeof a!="string")return {ok:false,reason:`persist: encrypt must return a string for store "${e}".`};let c;try{c=n(a);}catch(u){return {ok:false,reason:`persist: decrypt failed for store "${e}" (${u?.message??u})`}}return typeof c!="string"?{ok:false,reason:`persist: decrypt must return a string for store "${e}".`}:c!==o?{ok:false,reason:`persist: encrypt/decrypt must round-trip for store "${e}".`}:{ok:true}};var ce=(e,t,n)=>{e[t]&&(e[t].lastPresent=n);},ue=({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 a=window,c=()=>{try{return t.driver.getItem?.(t.key)!=null}catch{return false}},u=i=>{let g=n[e],p=c();if(g){if(!g.lastPresent||p){g.lastPresent=p;return}g.lastPresent=false,o({name:e,key:t.key,reason:i});}},r=i=>{if(i.key===null){u("clear");return}i.key===t.key&&i.newValue===null&&u("remove");},s=()=>{u("missing");};a.addEventListener("storage",r),a.addEventListener("focus",s),n[e]={lastPresent:c(),dispose:()=>{a.removeEventListener("storage",r),a.removeEventListener("focus",s);}};};var W=({value:e,sanitize:t,validate:n,onSanitizeError:o})=>{let a;if(t)try{a=t(e);}catch(u){return o?.(u),{ok:false}}else a=e;let c=n(a);return c.ok?{ok:true,value:c.value??a}:{ok:false}},P=({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 We=new Map,H=(e,t,n=0)=>{!e||typeof t!="function"||We.set(e,{name:e,order:n,fn:t});};var le=()=>({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,noSignalWarned:new Set,shapeWarned:new Set,autoCreateWarned:new Set,mutableResultWarned:new Set,cleanupSubs:Object.create(null),storeCleanupFns: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 q=new Map,Ie=typeof __STROID_REGISTRY_ID__<"u"&&__STROID_REGISTRY_ID__||typeof process<"u"&&process.env?.STROID_REGISTRY_ID||void 0,de,fe=e=>(de||Ie||e).replace(/\.ts(\?|$)/,".js$1"),xe=fe(new URL("./store.js",import.meta.url).href);var ze=()=>{de=void 0,q.clear();};H("registry.scope-override",ze,110);var He=()=>({pendingNotifications:new Set,pendingBuffer:[],orderedNames:[],notifyScheduled:false,batchDepth:0});var Le=()=>({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:{depth:0,pending:[],stagedValues:new Map,snapshotCache:new Map,failed:false,error:void 0},async:le(),notify:He()}),Be=e=>{let t=fe(e),n=q.get(t);if(n)return n;let o=Le();return q.set(t,o),o};var pe=e=>e||Be(xe);var qe={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}`));}},ge={logSink:qe,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",defaultSnapshotMode:"deep",strictAsyncUsageErrors:false,middleware:[],allowUntrustedHydration:false,mutatorProduce:void 0},J=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,defaultSnapshotMode:e.defaultSnapshotMode,strictAsyncUsageErrors:e.strictAsyncUsageErrors,middleware:[...e.middleware],allowUntrustedHydration:e.allowUntrustedHydration,mutatorProduce:e.mutatorProduce}),Y=new WeakMap,ye=J(ge),Ye=e=>{let t=Y.get(e);return t||(t=J(ye),Y.set(e,t)),t};var K=()=>Ye(pe());var Ge=()=>{Y=new WeakMap,ye=J(ge);};H("config.reset",Ge,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 Xe=(e,t)=>{typeof console<"u"&&typeof console.warn=="function"&&(t?console.warn(`[stroid] ${e}`,t):console.warn(`[stroid] ${e}`));};var I=(e,t)=>{if((K().logSink.warn??Xe)(e,t),K().assertRuntime)throw new Error(e)};var me=new Set(["__proto__","constructor","prototype"]);var G=null,Qe=()=>{if(G)return G;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 G=t,t},he=e=>{let t=Qe(),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},Ze=2166136261,et=2654435761,tt=1e5,E=(e,t)=>{let n=t>>>0;e.h1=Math.imul(e.h1^n,2246822507),e.h2=Math.imul(e.h2^n,3266489909);},_=(e,t)=>{E(e,t.length);for(let n=0;n<t.length;n++)E(e,t.charCodeAt(n));},k=(e,t)=>{_(e,t);},Se=(e,t)=>{if(Number.isNaN(t)){k(e,"NaN");return}if(!Number.isFinite(t)){k(e,t>0?"Infinity":"-Infinity");return}if(Object.is(t,-0)){k(e,"-0");return}let n=t|0;if(t===n){k(e,"int"),E(e,n);return}k(e,"num"),_(e,String(t));},D=(e,t)=>{if(e.nodes++>tt){k(e,"[max]");return}if(t===null){k(e,"null");return}let n=typeof t;if(n==="string"){k(e,"string"),_(e,t);return}if(n==="number"){k(e,"number"),Se(e,t);return}if(n==="boolean"){k(e,t?"true":"false");return}if(n==="undefined"){k(e,"undefined");return}if(n==="bigint"){k(e,"bigint"),_(e,t.toString());return}if(n==="symbol"){k(e,"symbol");let s=t;_(e,Symbol.keyFor(s)??s.description??String(s));return}if(n==="function"){k(e,"function"),_(e,t.name||"anonymous");return}let o=t,a=e.seen.get(o);if(a!==void 0){k(e,"ref"),E(e,a);return}let c=e.nextId++;if(e.seen.set(o,c),Array.isArray(o)){k(e,"array"),E(e,o.length);for(let s=0;s<o.length;s++)Object.prototype.hasOwnProperty.call(o,s)?D(e,o[s]):k(e,"hole");return}if(o instanceof Date){k(e,"date"),Se(e,o.getTime());return}if(o instanceof Map){k(e,"map"),E(e,o.size),o.forEach((s,i)=>{D(e,i),D(e,s);});return}if(o instanceof Set){k(e,"set"),E(e,o.size),o.forEach(s=>{D(e,s);});return}k(e,"object");let u=Object.getOwnPropertyDescriptors(o),r=[];Object.entries(u).forEach(([s,i])=>{i?.enumerable&&(me.has(s)||"get"in i||"set"in i||r.push([s,i]));}),E(e,r.length);for(let[s,i]of r)_(e,s),D(e,i.value);},X=e=>{if(typeof e=="string")return he(JSON.stringify(e));let t={h1:Ze,h2:et,seen:new WeakMap,nextId:1,nodes:0};D(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 rt=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},nt=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 rt(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")}},L=async(e,t,n=X)=>e==="none"?null:e==="sha256"?nt(t):n(t);var Q=({name:e,persisted:t,reason:n,persistConfig:o,initialState:a,reportStoreError:c,sanitize:u,deepClone:r})=>{c(e,n);let s=o?.onMigrationFail??"reset";if(s==="keep")return {state:t,requiresValidation:true};if(typeof s=="function")try{let i=s(r(t));if(i!==void 0)return {state:u(i),requiresValidation:!0};c(e,`onMigrationFail for "${e}" returned undefined. Falling back to initial state.`);}catch(i){c(e,`onMigrationFail for "${e}" failed: ${i?.message??i}`);}return {state:r(a),requiresValidation:true}},be=e=>{let n=e.getMeta()?.options?.persist;return n?!!n.decryptAsync||n.checksum==="sha256"?st(e):ot(e):false},ot=({name:e,silent:t=false,getMeta:n,getInitialState:o,applyFeatureState:a,reportStoreError:c,validate:u,log:r,hashState:s,deepClone:i,sanitize:g,shouldApply:p})=>{let y=n(),l=y?.options?.persist;if(!l)return false;let f=d=>W({value:d,validate:u});try{let d=l.driver.getItem?.(l.key)??null;if(!d)return !1;if(typeof d!="string")return c(e,`Persist driver for "${e}" returned an async value during sync hydration. Provide async decrypt hooks or use an async-capable persist driver.`),!0;let m=l.decrypt(d),b=JSON.parse(m),{v:h=1,checksum:v,data:w,updatedAt:A,updatedAtMs:F}=b||{};if(!w)return !0;let M=P({value:typeof F=="number"?F:A,fallbackMs:Date.now(),onInvalid:()=>{r(`persist: corrupt updatedAt in stored data for "${e}". Using current time to prevent sync overwrite.`);}});if(l.checksum!=="none"&&v!==s(w))return c(e,`Checksum mismatch loading store "${e}". Falling back to initial state.`),(!p||p())&&a(i(o()),Date.now()),!0;let V=l.deserialize(w),N=y?.version??1,R=ke({name:e,parsed:V,v:h,targetVersion:N,cfg:l,migrations:y?.options?.migrations??{},getInitialState:o,reportStoreError:c,sanitize:g,deepClone:i,validateState:f,safeUpdatedAt:M,applyFeatureState:a,shouldApply:p});return R.ok&&(V=R.state,(!p||p())&&(a(R.state,M),t||r(`Store "${e}" loaded from persistence`))),!0}catch(d){return c(e,`Could not load store "${e}" (${d?.message||d})`),true}},st=async({name:e,silent:t=false,getMeta:n,getInitialState:o,applyFeatureState:a,reportStoreError:c,validate:u,log:r,hashState:s,deepClone:i,sanitize:g,shouldApply:p})=>{let y=n(),l=y?.options?.persist;if(!l)return false;let f=d=>W({value:d,validate:u});try{let d=await Promise.resolve(l.driver.getItem?.(l.key)??null);if(!d)return !1;let m=l.decryptAsync?await l.decryptAsync(d):l.decrypt(d),b=JSON.parse(m),{v:h=1,checksum:v,data:w,updatedAt:A,updatedAtMs:F}=b||{};if(!w)return !0;let M=P({value:typeof F=="number"?F:A,fallbackMs:Date.now(),onInvalid:()=>{r(`persist: corrupt updatedAt in stored data for "${e}". Using current time to prevent sync overwrite.`);}}),V=await L(l.checksum,w,s);if(l.checksum!=="none"&&v!==V)return c(e,`Checksum mismatch loading store "${e}". Falling back to initial state.`),(!p||p())&&a(i(o()),Date.now()),!0;let N=l.deserialize(w),R=y?.version??1,C=ke({name:e,parsed:N,v:h,targetVersion:R,cfg:l,migrations:y?.options?.migrations??{},getInitialState:o,reportStoreError:c,sanitize:g,deepClone:i,validateState:f,safeUpdatedAt:M,applyFeatureState:a,shouldApply:p});return C.ok&&(!p||p())&&(a(C.state,M),t||r(`Store "${e}" loaded from persistence`)),!0}catch(d){return c(e,`Could not load store "${e}" (${d?.message||d})`),true}},ke=({name:e,parsed:t,v:n,targetVersion:o,cfg:a,migrations:c,getInitialState:u,reportStoreError:r,sanitize:s,deepClone:i,validateState:g,safeUpdatedAt:p,applyFeatureState:y,shouldApply:l})=>{if(n!==o){let d=Object.keys(c).map(h=>Number(h)).filter(h=>h>n&&h<=o).sort((h,v)=>h-v);if(d.length===0){let h=Q({name:e,persisted:t,reason:`No migration path from v${n} to v${o} for "${e}". Applying onMigrationFail strategy.`,persistConfig:a,initialState:u(),reportStoreError:r,sanitize:s,deepClone:i});if(t=h.state,!h.requiresValidation)return (!l||l())&&y(t,p),{ok:false,state:t}}let m=false,b=true;if(d.forEach(h=>{if(!m)try{let v=c[h](t);v!==void 0&&(t=v);}catch(v){let w=Q({name:e,persisted:t,reason:`Migration to v${h} failed for "${e}": ${v?.message||v}`,persistConfig:a,initialState:u(),reportStoreError:r,sanitize:s,deepClone:i});t=w.state,b=w.requiresValidation,m=true;}}),m){if(!b)return (!l||l())&&y(t,p),{ok:false,state:t};let h=g(t);return h.ok?{ok:true,state:h.value??t}:((!l||l())&&y(i(u()),Date.now()),{ok:false,state:t})}}let f=g(t);if(!f.ok){if(n!==o){let d=Q({name:e,persisted:t,reason:`Persisted state for "${e}" failed schema after version change. Applying onMigrationFail strategy.`,persistConfig:a,initialState:u(),reportStoreError:r,sanitize:s,deepClone:i});if(!d.requiresValidation)return (!l||l())&&y(d.state,p),{ok:false,state:d.state};let m=g(d.state);if(m.ok)return {ok:true,state:m.value??d.state}}return r(e,`Persisted state for "${e}" failed schema; resetting to initial.`),(!l||l())&&y(i(u()),Date.now()),{ok:false,state:t}}return {ok:true,state:f.value??t}};var ve=({name:e,persistTimers:t,persistInFlight:n,persistSequence:o,persistWatchState:a,plaintextWarningsIssued:c,exists:u,getMeta:r,getStoreValue:s,reportStoreError:i,hashState:g},p=false)=>{let y=r()?.options?.persist;if(!y)return;let l=async()=>{let m=r();if(!(!m?.options?.persist||m.options.persist!==y||!u())){if(!y.allowPlaintext&&!c.has(e)&&U(y.encrypt)&&U(y.decrypt)){c.add(e);let b=`[stroid/persist] Store '${e}' is persisted in plaintext. Provide encrypt/decrypt hooks to protect sensitive data.`;m.options.onError?.(b),I(b);}try{let b=y.serialize(s()),h=await L(y.checksum,b,g),v=JSON.stringify({v:m.version??1,updatedAt:m.updatedAt,updatedAtMs:m.updatedAtMs??Date.now(),checksum:h,data:b}),w=y.encryptAsync?await y.encryptAsync(v):y.encrypt(v);await Promise.resolve(y.driver.setItem?.(y.key,w)),ce(a,e,!0);}catch(b){i(e,`Could not persist store "${e}" (${b?.message||b})`);}}},f=m=>{let b=n[e],h=(o[e]??0)+1;o[e]=h;let w=(async()=>{b&&await b,!(m&&t[e]!==m)&&o[e]===h&&await l();})().finally(()=>{n[e]===w&&(n[e]=null),m&&t[e]===m&&delete t[e];});n[e]=w;};if(p){t[e]&&(clearTimeout(t[e]),delete t[e]),f();return}t[e]&&clearTimeout(t[e]);let d=setTimeout(()=>{t[e]===d&&f(d);},0);t[e]=d;},x=e=>ve(e),we=(e,t)=>ve({...t,name:e},true);var Re=false,at=typeof process<"u"&&typeof process.env?.NODE_ENV=="string"?process.env.NODE_ENV:void 0,it=typeof import.meta<"u"&&import.meta?.env?.MODE?import.meta.env.MODE:void 0,ct=at??it,ut=()=>ct==="production",lt=()=>{let e={},t={},n=Object.create(null),o=Object.create(null),a=Object.create(null),c=new Set,u=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&&z(s.encrypt)&&z(s.decrypt)&&!s.allowPlaintext){let f=`[stroid/persist] Store "${r.name}" is configured for plaintext persistence. Provide encrypt/decrypt hooks or set persist.allowPlaintext: true to acknowledge.`;if(ut()){r.reportStoreError(f),r.options.persist=null;return}r.warn(f);}if(s.sensitiveData&&!s.encryptAsync&&z(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 g=ie(r.name,s.encrypt,s.decrypt);if(!g.ok){r.reportStoreError(g.reason??`persist: encrypt/decrypt validation failed for store "${r.name}".`),r.options.persist=null;return}if(s.key){let f=o[s.key];f&&f!==r.name&&r.isDev()?r.warn(`Persist key collision: "${s.key}" already used by store "${f}". Store "${r.name}" will overwrite the same storage key.`):o[s.key]=r.name;}let p=r.getMeta()?.updateCount??0,y=()=>{let f=r.getMeta();return f?(f.updateCount??0)===p:false},l=be({name:r.name,silent:true,getMeta:r.getMeta,getInitialState:r.getInitialState,applyFeatureState:r.applyFeatureState,reportStoreError:(f,d)=>r.reportStoreError(d),validate:r.validate,log:r.log,hashState:r.hashState,deepClone:r.deepClone,sanitize:r.sanitize,shouldApply:y});if(typeof l?.then=="function"?(u[r.name]={loading:true,pendingSave:false},l.then(f=>{let d=u[r.name];d&&(d.loading=false,(!f||d.pendingSave)&&x({name:r.name,persistTimers:e,persistInFlight:t,persistSequence:n,persistWatchState:a,plaintextWarningsIssued:c,exists:()=>r.hasStore(),getMeta:r.getMeta,getStoreValue:r.getStoreValue,reportStoreError:(m,b)=>r.reportStoreError(b),hashState:r.hashState}),delete u[r.name]);}).catch(()=>{let f=u[r.name];f&&(f.loading=false,f.pendingSave&&x({name:r.name,persistTimers:e,persistInFlight:t,persistSequence:n,persistWatchState:a,plaintextWarningsIssued:c,exists:()=>r.hasStore(),getMeta:r.getMeta,getStoreValue:r.getStoreValue,reportStoreError:(d,m)=>r.reportStoreError(m),hashState:r.hashState}),delete u[r.name]);})):l||x({name:r.name,persistTimers:e,persistInFlight:t,persistSequence:n,persistWatchState:a,plaintextWarningsIssued:c,exists:()=>r.hasStore(),getMeta:r.getMeta,getStoreValue:r.getStoreValue,reportStoreError:(f,d)=>r.reportStoreError(d),hashState:r.hashState}),typeof window<"u"&&typeof window.addEventListener=="function"){let f=()=>{we(r.name,{name:r.name,persistTimers:e,persistInFlight:t,persistSequence:n,persistWatchState:a,plaintextWarningsIssued:c,exists:()=>r.hasStore(),getMeta:r.getMeta,getStoreValue:r.getStoreValue,reportStoreError:(d,m)=>r.reportStoreError(m),hashState:r.hashState});};window.addEventListener("pagehide",f,{once:true}),window.addEventListener("beforeunload",f,{once:true});}ue({name:r.name,persistConfig:s,persistWatchState:a});},onStoreWrite(r){if(!r.options.persist)return;let s=u[r.name];if(s?.loading){s.pendingSave=true;return}x({name:r.name,persistTimers:e,persistInFlight:t,persistSequence:n,persistWatchState:a,plaintextWarningsIssued:c,exists:()=>r.hasStore(),getMeta:r.getMeta,getStoreValue:r.getStoreValue,reportStoreError:(i,g)=>r.reportStoreError(g),hashState:r.hashState});},beforeStoreDelete(r){let s=r.options.persist;if(s){delete u[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],a[r.name]?.dispose(),delete a[r.name];}},resetAll(){Object.values(e).forEach(r=>clearTimeout(r)),Object.values(a).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(a).forEach(r=>delete a[r]),Object.keys(u).forEach(r=>delete u[r]),c.clear();}}},Me=()=>{Re||(Re=true,O("persist",lt));};var Ce=false,$=1,dt=e=>typeof e?.v=="number"?e.v:typeof e?.protocol=="number"?e.protocol:void 0,Z=new Set,ee=new Set,ft=e=>typeof TextEncoder<"u"?new TextEncoder().encode(e).length:typeof Buffer<"u"?Buffer.byteLength(e):e.length,pt=({incoming:e,accepted:t})=>{let n=t?.clock??0,o=typeof e.clock=="number"?e.clock:0;if(o!==n)return o-n;let a=e.source??"",c=t?.source??"";return a===c?0:a.localeCompare(c,"en",{sensitivity:"variant"})},gt=e=>e?.updatedAtMs??P({value:e?.updatedAt,fallbackMs:0}),yt=e=>{if(typeof e!="object"||e===null)return false;let t=e;return (typeof t.v=="number"||typeof t.protocol=="number")&&typeof t.type=="string"&&typeof t.name=="string"&&typeof t.clock=="number"&&typeof t.source=="string"},Ee=({name:e,syncChannels:t,instanceId:n,authToken:o,reportStoreError:a})=>{let c=t[e];if(c)try{let u={v:$,protocol:$,type:"sync-request",source:n,name:e,clock:0,requestedAt:Date.now()};o&&(u.token=o),c.postMessage(u);}catch(u){a(e,`Failed to request sync snapshot for "${e}": ${u?.message??u}`);}},mt=(e,t)=>(t[e]=(t[e]??0)+1,t[e]),St=(e,t,n)=>(n[e]=Math.max(n[e]??0,t)+1,n[e]),ht=({name:e,syncChannels:t,syncWindowCleanup:n,syncClocks:o,syncVersions:a})=>{t[e]?.close(),delete t[e],n[e]?.(),delete n[e],delete o[e],delete a[e];},bt=({syncChannels:e,syncWindowCleanup:t})=>{Object.values(t).forEach(n=>{try{n();}catch{}}),Object.values(e).forEach(n=>{try{n.close();}catch{}});},kt=({name:e,syncOption:t,syncChannels:n,syncClocks:o,syncVersions:a,syncWindowCleanup:c,instanceId:u,getMeta:r,getAcceptedSyncVersion:s,getStoreValue:i,hasStoreEntry:g,notify:p,validate:y,reportStoreError:l,warn:f,setStoreValue:d,normalizeIncomingState:m,acceptIncomingSyncVersion:b,resolveSyncVersion:h,broadcastSync:v})=>{if(!t)return;if(typeof window>"u"||typeof BroadcastChannel>"u"){l(e,`Sync enabled for "${e}" but BroadcastChannel not available in this environment.`);return}let w=typeof t=="object"&&typeof t.authToken=="string"&&t.authToken.length>0,A=typeof t=="object"&&typeof t.verify=="function",F=typeof t=="object"&&typeof t.sign=="function";!w&&!A&&!Z.has(e)&&(Z.add(e),I(`Sync for "${e}" is unauthenticated. Any same-origin tab can forge sync messages. Provide sync.authToken or sync.verify to enforce authentication.`)),F&&!A&&!ee.has(e)&&(ee.add(e),f(`Sync for "${e}" is configured with "sign" but no "verify". "sign" has no effect unless incoming messages are verified.`));let M=typeof t=="object"?t.authToken:void 0,V=false,N=typeof t=="object"&&t.channel?t.channel:`stroid_sync_${e}`;try{let R=new BroadcastChannel(N);if(n[e]=R,R.onmessage=C=>{let S=C.data;if(!S||S.source===u||S.name!==e||n[e]!==R||!g(e)||!r(e))return;if(!yt(S)){l(e,`Sync message for "${e}" is malformed; ignoring.`);return}if(M&&S.token!==M){V||(l(e,`Sync message for "${e}" failed auth token verification; ignoring.`),V=!0);return}let te=dt(S);if(te!==$){l(e,`Sync protocol mismatch for "${e}". Expected v${$} but received ${String(te??"unknown")}. Ignoring message.`);return}if(S.type==="sync-state"&&(typeof S.data>"u"||typeof S.clock!="number")){l(e,`Sync message for "${e}" is malformed; ignoring.`);return}if(typeof t=="object"&&typeof t.verify=="function"){let j=!1;try{j=!!t.verify(S);}catch(T){l(e,`Sync message verification failed for "${e}": ${T?.message??T}`);return}if(!j){l(e,`Sync message for "${e}" failed verification; ignoring.`);return}}if(S.type==="sync-request"){v(e);return}let re=typeof t=="object"?t.conflictResolver:null;if(pt({incoming:{clock:S.clock,source:S.source},accepted:s(e)})<=0){let j=gt(r(e)),T=typeof S.updatedAt=="number"?S.updatedAt:Date.now();if(re){let oe=re({local:i(e),incoming:S.data,localUpdated:j,incomingUpdated:T});if(oe!==void 0){let se=m(e,oe);if(se===null)return;d(e,se);let ae=typeof t=="object"?t.resolveUpdatedAt:null,Oe=ae?ae({localUpdated:j,incomingUpdated:T,now:Date.now()}):Math.max(Date.now(),j,T);h(e,Oe,typeof S.clock=="number"?S.clock:0),p(e),v(e);}}return}let ne=m(e,S.data);ne!==null&&(d(e,ne),b(e,typeof S.updatedAt=="number"?S.updatedAt:Date.now(),typeof S.clock=="number"?S.clock:0,typeof S.source=="string"?S.source:""),p(e));},typeof window<"u"&&typeof window.addEventListener=="function"){c[e]?.();let C=window,S=()=>{Ee({name:e,syncChannels:n,instanceId:u,authToken:M,reportStoreError:l});};C.addEventListener("focus",S),C.addEventListener("online",S),c[e]=()=>{C.removeEventListener("focus",S),C.removeEventListener("online",S);};}queueMicrotask(()=>{Ee({name:e,syncChannels:n,instanceId:u,authToken:M,reportStoreError:l});});}catch(R){f(`Failed to setup sync for "${e}": ${R?.message||R}`);}},Fe=({name:e,syncOption:t,syncChannels:n,syncClocks:o,instanceId:a,updatedAt:c,data:u,hashState:r,reportStoreError:s})=>{let i=n[e];if(i)try{let g=typeof t=="object"&&t.checksum==="none"?"none":"hash",p={v:$,protocol:$,type:"sync-state",source:a,name:e,clock:o[e]??0,updatedAt:P({value:c,fallbackMs:Date.now()}),data:u,checksum:g==="hash"?r(u):null};if(typeof t=="object"&&t.authToken&&(p.token=t.authToken),typeof t=="object"&&typeof t.sign=="function")try{let f=t.sign(p);if(f&&typeof f.then=="function"){s(e,`Sync signer for "${e}" returned a Promise. "sign" must be synchronous.`);return}f!==void 0&&(p.auth=f);}catch(f){s(e,`Failed to sign sync payload for "${e}": ${f?.message??f}`);return}let y=typeof t=="object"&&typeof t.maxPayloadBytes=="number"?t.maxPayloadBytes:64*1024,l=ft(JSON.stringify(p));if(l>y){s(e,`Sync payload for "${e}" exceeds ${y} bytes (${l} bytes). Skipping BroadcastChannel sync.`);return}i.postMessage(p);}catch(g){s(e,`Failed to broadcast sync for "${e}": ${g?.message??g}`);}},vt=()=>{let e=Object.create(null),t=Object.create(null),n=Object.create(null),o=Object.create(null),a=`stroid_${Math.random().toString(16).slice(2)}`,c=(r,s)=>{n[r]={clock:t[r]??0,updatedAt:P({value:s,fallbackMs:Date.now()}),source:a};},u=(r,s)=>{mt(r,t),c(r,s);};return {onStoreCreate(r){if(r.options.sync&&(kt({name:r.name,syncOption:r.options.sync,syncChannels:e,syncClocks:t,syncVersions:n,syncWindowCleanup:o,instanceId:a,getMeta:r.getMeta,getAcceptedSyncVersion:s=>n[s],getStoreValue:s=>r.getStoreValue(),hasStoreEntry:()=>r.hasStore(),notify:()=>r.notify(),validate:(s,i)=>r.validate(i),reportStoreError:(s,i)=>r.reportStoreError(i),warn:r.warn,setStoreValue:(s,i)=>r.setStoreValue(i),normalizeIncomingState:(s,i)=>{let g=W({value:i,sanitize:r.sanitize,validate:r.validate,onSanitizeError:p=>{r.reportStoreError(`Sanitize failed for incoming sync "${s}": ${p?.message??p}`);}});return g.ok?g.value:null},acceptIncomingSyncVersion:(s,i,g,p)=>{r.applyFeatureState(r.getStoreValue(),i),t[r.name]=Math.max(t[r.name]??0,g),n[r.name]={clock:g,updatedAt:i,source:p};},resolveSyncVersion:(s,i,g)=>{r.applyFeatureState(r.getStoreValue(),i);let p=St(r.name,g,t);return n[r.name]={clock:p,updatedAt:i,source:a},p},broadcastSync:()=>{let s=r.getMeta();s&&Fe({name:r.name,syncOption:r.options.sync,syncChannels:e,syncClocks:t,instanceId:a,updatedAt:s.updatedAtMs??s.updatedAt,data:r.getStoreValue(),hashState:r.hashState,reportStoreError:(i,g)=>r.reportStoreError(g)});}}),e[r.name])){let s=r.getMeta();c(r.name,s?.updatedAtMs??s?.updatedAt??new Date().toISOString());}},onStoreWrite(r){if(!r.options.sync)return;let s=r.getMeta();s&&(u(r.name,s.updatedAtMs??s.updatedAt),Fe({name:r.name,syncOption:r.options.sync,syncChannels:e,syncClocks:t,instanceId:a,updatedAt:s.updatedAtMs??s.updatedAt,data:r.next,hashState:r.hashState,reportStoreError:(i,g)=>r.reportStoreError(g)}));},beforeStoreDelete(r){ht({name:r.name,syncChannels:e,syncWindowCleanup:o,syncClocks:t,syncVersions:n});},resetAll(){bt({syncChannels:e,syncWindowCleanup:o}),Object.keys(e).forEach(r=>delete e[r]),Object.keys(t).forEach(r=>delete t[r]),Object.keys(n).forEach(r=>delete n[r]),Object.keys(o).forEach(r=>delete o[r]),Z.clear(),ee.clear();}}},Ve=()=>{Ce||(Ce=true,O("sync",vt));};var Pe=false,_e=e=>{try{return typeof structuredClone=="function"?structuredClone(e):JSON.parse(JSON.stringify(e))}catch{return e}},wt=({name:e,useDevtools:t,existingDevtools:n,stores:o,warn:a})=>{if(!t||typeof window>"u")return n;let c=window.__REDUX_DEVTOOLS_EXTENSION__||window.__REDUX_DEVTOOLS_EXTENSION__;if(!c||typeof c.connect!="function")return a(`DevTools requested for "${e}" but Redux DevTools extension not found.`),n;if(n)return n;let u=c.connect({name:"stroid"});return u.init(o),u},B=({data:e,redactor:t,deepClone:n})=>{if(typeof t=="function")try{return t(n(e))}catch{return e}return e},Rt=(e,t)=>{if(typeof e!="object"||typeof t!="object"||e===null||t===null)return null;let n=e,o=t,a=[],c=[],u=[],r=new Set(Object.keys(n)),s=new Set(Object.keys(o));return s.forEach(i=>{r.has(i)?Object.is(n[i],o[i])||u.push(i):a.push(i);}),r.forEach(i=>{s.has(i)||c.push(i);}),{added:a,removed:c,changed:u}},Ae=({name:e,action:t,prev:n,next:o,history:a,historyLimit:c,applyRedactor:u,deepClone:r})=>{if(c===0)return;a[e]||(a[e]=[]);let s={ts:Date.now(),action:t,prev:r(u(n)),next:r(u(o)),diff:Rt(n,o)};a[e].push(s),a[e].length>c&&a[e].splice(0,a[e].length-c);},je=({name:e,action:t,force:n=false,devtools:o,enabled:a,stores:c,applyRedactor:u})=>{if(!(!o||!n&&!a))try{let r={...c,[e]:u(c[e])};o.send({type:`${e}/${t}`},r);}catch{}},Mt=()=>{let e=Object.create(null),t;return {onStoreCreate(n){t=wt({name:n.name,useDevtools:!!n.options.devtools,existingDevtools:t,stores:n.getAllStores(),warn:n.warn}),Ae({name:n.name,action:"create",prev:null,next:n.getStoreValue(),history:e,historyLimit:n.options.historyLimit??50,applyRedactor:o=>B({data:o,redactor:n.options.redactor,deepClone:n.deepClone}),deepClone:n.deepClone});},onStoreWrite(n){Ae({name:n.name,action:n.action,prev:n.prev,next:n.next,history:e,historyLimit:n.options.historyLimit??50,applyRedactor:o=>B({data:o,redactor:n.options.redactor,deepClone:n.deepClone}),deepClone:n.deepClone}),je({name:n.name,action:n.action,devtools:t,enabled:!!n.options.devtools,stores:n.getAllStores(),applyRedactor:o=>B({data:o,redactor:n.options.redactor,deepClone:n.deepClone})});},afterStoreDelete(n){n.options.devtools&&je({name:n.name,action:"delete",force:true,devtools:t,enabled:true,stores:n.getAllStores(),applyRedactor:o=>B({data:o,redactor:n.options.redactor,deepClone:n.deepClone})}),delete e[n.name];},resetAll(){Object.keys(e).forEach(n=>{delete e[n];}),t=void 0;},api:{getHistory(n,o){if(!e[n])return [];let a=e[n];return o&&o>0?_e(a.slice(-o)):_e(a)},clearHistory(n){if(n){delete e[n];return}Object.keys(e).forEach(o=>{delete e[o];});}}}},Te=()=>{Pe||(Pe=true,O("devtools",Mt));};var Ct=()=>{Me();},Et=()=>{Ve();},Ft=()=>{Te();},Or=()=>{Ct(),Et(),Ft();};export{Or as installAllFeatures,Ft as installDevtools,Ct as installPersist,Et as installSync};//# sourceMappingURL=install.js.map
1
+ var X=new Map,z=(e,t)=>{X.set(e,t);};var ye=e=>X.get(e),me=()=>Array.from(X.keys());var et=typeof Symbol=="function"?Symbol.for("stroid.persist.defaultCrypto"):"__stroid_persist_defaultCrypto__",Q=e=>!!e?.[et],q=e=>{try{let t=`__stroid_plaintext_probe_${Math.random().toString(36).slice(2)}__`,r=`__stroid_plaintext_probe_${Math.random().toString(36).slice(2)}__`;return e(t)!==t?!1:e(r)===r}catch{return false}},Se=(e,t,r)=>{let o="__stroid_persist_roundtrip_probe__",a;try{a=t(o);}catch(l){return {ok:false,reason:`persist: encrypt failed for store "${e}" (${l?.message??l})`}}if(typeof a!="string")return {ok:false,reason:`persist: encrypt must return a string for store "${e}".`};let c;try{c=r(a);}catch(l){return {ok:false,reason:`persist: decrypt failed for store "${e}" (${l?.message??l})`}}return typeof c!="string"?{ok:false,reason:`persist: decrypt must return a string for store "${e}".`}:c!==o?{ok:false,reason:`persist: encrypt/decrypt must round-trip for store "${e}".`}:{ok:true}};var he=(e,t,r)=>{e[t]&&(e[t].lastPresent=r);},be=({name:e,persistConfig:t,persistWatchState:r})=>{let o=t?.onStorageCleared;if(!t||typeof o!="function"||typeof window>"u"||typeof window.addEventListener!="function")return;r[e]?.dispose();let a=window,c=()=>{try{return t.driver.getItem?.(t.key)!=null}catch{return false}},l=i=>{let k=r[e],s=c();if(k){if(!k.lastPresent||s){k.lastPresent=s;return}k.lastPresent=false,o({name:e,key:t.key,reason:i});}},g=i=>{if(i.key===null){l("clear");return}i.key===t.key&&i.newValue===null&&l("remove");},n=()=>{l("missing");};a.addEventListener("storage",g),a.addEventListener("focus",n),r[e]={lastPresent:c(),dispose:()=>{a.removeEventListener("storage",g),a.removeEventListener("focus",n);}};};var U=({value:e,sanitize:t,validate:r,onSanitizeError:o})=>{let a;if(t)try{a=t(e);}catch(l){return o?.(l),{ok:false}}else a=e;let c=r(a);return c.ok?{ok:true,value:c.value??a}:{ok:false}},j=({value:e,fallbackMs:t=Date.now(),onInvalid:r})=>{if(typeof e=="number")return Number.isFinite(e)?e:(r?.(),t);if(typeof e=="string"){let o=Date.parse(e);return Number.isFinite(o)?o:(r?.(),t)}return r?.(),t};var tt=new Map,G=(e,t,r=0)=>{!e||typeof t!="function"||tt.set(e,{name:e,order:r,fn:t});};var rt=()=>new Map([["noSignal",new Set],["shape",new Set],["autoCreate",new Set],["mutableResult",new Set]]),ke=()=>({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:rt(),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 Z=new Map,ve=new WeakSet,nt=e=>{ve.has(e)||(ve.add(e),me().forEach(t=>{if(!e.featureRuntimes.get(t)){let r=ye(t);r&&e.featureRuntimes.set(t,r());}}));},ot=typeof __STROID_REGISTRY_ID__<"u"&&__STROID_REGISTRY_ID__||typeof process<"u"&&process.env?.STROID_REGISTRY_ID||void 0,we,Re=e=>(we||ot||e).replace(/\.ts(\?|$)/,".js$1"),st=Re(new URL("../../store.js",import.meta.url).href);var at=()=>{we=void 0,Z.clear();};G("registry.scope-override",at,110);var it=()=>({pendingNotifications:new Set,pendingBuffer:[],orderedNames:[],subscriberBuffer:[],notifyScheduled:false,batchDepth:0,flushId:0,isFlushing:false});var ct=()=>({depth:0,pending:[],stagedValues:new Map,snapshotCache:new Map,failed:false,error:void 0}),ut=(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:ct(),async:ke(),notify:it(),lifecycleListener:null};return nt(t),t},lt=e=>{let t=Re(e),r=Z.get(t);if(r)return r;let o=ut();return Z.set(t,o),o};var F=[],ft={run:(e,t)=>{F.push(e);try{return t()}finally{F.pop();}},get:()=>F.length>0?F[F.length-1]:null,enterWith:e=>{if(F.length>0){F[F.length-1]=e;return}F.push(e);}};var Ce=e=>(ft).get()||e||lt(st);var pt={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}`));}},Me={logSink:pt,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},te=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}),ee=new WeakMap,Ee=te(Me),gt=e=>{let t=ee.get(e);return t||(t=te(Ee),ee.set(e,t)),t};var re=()=>gt(Ce());var ht=()=>{ee=new WeakMap,Ee=te(Me);};G("config.reset",ht,90);var bt=typeof process<"u"&&typeof process.env?.NODE_ENV=="string"?process.env.NODE_ENV:void 0,kt=typeof import.meta<"u"&&import.meta?.env?.MODE?import.meta.env.MODE:void 0,Fe=typeof globalThis<"u"&&typeof globalThis.__STROID_DEV__=="boolean"?globalThis.__STROID_DEV__:void 0,vt="production",wt=bt??kt??vt,Pe=typeof Fe=="boolean"?Fe:wt!=="production",ne=()=>Pe,Rt=(e,t)=>{typeof console<"u"&&typeof console.warn=="function"&&(t?console.warn(`[stroid] ${e}`,t):console.warn(`[stroid] ${e}`));};var _=(e,t)=>{if((re().logSink.warn??Rt)(e,t),re().assertRuntime)throw new Error(e)};var Te=new Set(["__proto__","constructor","prototype"]);var oe=null,Ct=()=>{if(oe)return oe;let e,t=[];for(let r=0;r<256;r++){e=r;for(let o=0;o<8;o++)e=e&1?3988292384^e>>>1:e>>>1;t[r]=e>>>0;}return oe=t,t},Ae=e=>{let t=Ct(),r=-1;for(let o=0;o<e.length;o++)r=r>>>0,r=r>>>8^t[(r^e.charCodeAt(o))&255];return (r^-1)>>>0},Mt=2166136261,Et=2654435761,Ft=1e5,T=(e,t)=>{let r=t>>>0;e.h1=Math.imul(e.h1^r,2246822507),e.h2=Math.imul(e.h2^r,3266489909);},D=(e,t)=>{T(e,t.length);for(let r=0;r<t.length;r++)T(e,t.charCodeAt(r));},w=(e,t)=>{D(e,t);},Ve=(e,t)=>{if(Number.isNaN(t)){w(e,"NaN");return}if(!Number.isFinite(t)){w(e,t>0?"Infinity":"-Infinity");return}if(Object.is(t,-0)){w(e,"-0");return}let r=t|0;if(t===r){w(e,"int"),T(e,r);return}w(e,"num"),D(e,String(t));},W=(e,t)=>{if(e.nodes++>Ft){w(e,"[max]");return}if(t===null){w(e,"null");return}let r=typeof t;if(r==="string"){w(e,"string"),D(e,t);return}if(r==="number"){w(e,"number"),Ve(e,t);return}if(r==="boolean"){w(e,t?"true":"false");return}if(r==="undefined"){w(e,"undefined");return}if(r==="bigint"){w(e,"bigint"),D(e,t.toString());return}if(r==="symbol"){w(e,"symbol");let n=t;D(e,Symbol.keyFor(n)??n.description??String(n));return}if(r==="function"){w(e,"function"),D(e,t.name||"anonymous");return}let o=t,a=e.seen.get(o);if(a!==void 0){w(e,"ref"),T(e,a);return}let c=e.nextId++;if(e.seen.set(o,c),Array.isArray(o)){w(e,"array"),T(e,o.length);for(let n=0;n<o.length;n++)Object.prototype.hasOwnProperty.call(o,n)?W(e,o[n]):w(e,"hole");return}if(o instanceof Date){w(e,"date"),Ve(e,o.getTime());return}if(o instanceof Map){w(e,"map"),T(e,o.size),o.forEach((n,i)=>{W(e,i),W(e,n);});return}if(o instanceof Set){w(e,"set"),T(e,o.size),o.forEach(n=>{W(e,n);});return}w(e,"object");let l=Object.getOwnPropertyDescriptors(o),g=[];Object.entries(l).forEach(([n,i])=>{i?.enumerable&&(Te.has(n)||"get"in i||"set"in i||g.push([n,i]));}),T(e,g.length);for(let[n,i]of g)D(e,n),W(e,i.value);},se=e=>{if(typeof e=="string")return Ae(JSON.stringify(e));let t={h1:Mt,h2:Et,seen:new WeakMap,nextId:1,nodes:0};W(t,e);let r=t.h1>>>0,o=t.h2>>>0;return r^=r>>>16,r=Math.imul(r,2246822507),r^=r>>>13,r=Math.imul(r,3266489909),r^=r>>>16,o^=o>>>16,o=Math.imul(o,668265261),o^=o>>>15,o=Math.imul(o,374761393),o^=o>>>16,(r&2097151)*4294967296+(o>>>0)};var Vt=e=>{let t=new Uint8Array(e),r="";for(let o=0;o<t.length;o++)r+=t[o].toString(16).padStart(2,"0");return r},At=async e=>{if(typeof globalThis<"u"&&globalThis.crypto?.subtle){let t=typeof TextEncoder<"u"?new TextEncoder:null,r=t?t.encode(e):new Uint8Array(Buffer.from(e)),o=await globalThis.crypto.subtle.digest("SHA-256",r);return Vt(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")}},K=async(e,t,r=se)=>e==="none"?null:e==="sha256"?At(t):r(t);var je=1e6,_e=(e,t)=>{let r=e?.options?.migrations??{};if(Object.keys(r).length>0)return r;let o=t?.migrate;if(typeof o!="function")return r;let a=e?.version??1;return !Number.isFinite(a)||a<=1?r:{[a]:o}},ae=({name:e,persisted:t,reason:r,persistConfig:o,initialState:a,reportStoreError:c,sanitize:l,deepClone:g})=>{c(e,r);let n=o?.onMigrationFail??"reset";if(n==="keep")return {state:t,requiresValidation:true};if(typeof n=="function")try{let i=n(g(t));if(i!==void 0)return {state:l(i),requiresValidation:!0};c(e,`onMigrationFail for "${e}" returned undefined. Falling back to initial state.`);}catch(i){c(e,`onMigrationFail for "${e}" failed: ${i?.message??i}`);}return {state:g(a),requiresValidation:true}},De=e=>{let r=e.getMeta()?.options?.persist;return r?!!r.decryptAsync||r.checksum==="sha256"?_t(e):jt(e):false},jt=({name:e,silent:t=false,getMeta:r,getInitialState:o,applyFeatureState:a,reportStoreError:c,warnMissingMaxSize:l,validate:g,log:n,hashState:i,deepClone:k,sanitize:s,shouldApply:u})=>{let y=r(),d=y?.options?.persist;if(!d)return false;let m=_e(y,d),S=p=>U({value:p,validate:g});try{let p=d.driver.getItem?.(d.key)??null;if(!p)return !1;if(typeof p!="string")return c(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 d.maxSize!="number"&&p.length>je&&l?.(p.length),typeof d.maxSize=="number"&&p.length>d.maxSize)return c(e,`Persist payload for "${e}" exceeds maxSize (${p.length} > ${d.maxSize}). Skipping hydration.`),!0;let f=d.decrypt(p),h=JSON.parse(f),{v=1,checksum:R,data:C,updatedAt:O,updatedAtMs:E}=h||{};if(!C)return !0;let V=j({value:typeof E=="number"?E:O,fallbackMs:Date.now(),onInvalid:()=>{n(`persist: corrupt updatedAt in stored data for "${e}". Using current time to prevent sync overwrite.`);}});if(d.checksum!=="none"&&R!==i(C))return c(e,`Checksum mismatch loading store "${e}". Falling back to initial state.`),(!u||u())&&a(k(o()),Date.now()),!0;let A=d.deserialize(C),P=y?.version??1,M=Oe({name:e,parsed:A,v,targetVersion:P,cfg:d,migrations:m,getInitialState:o,reportStoreError:c,sanitize:s,deepClone:k,validateState:S,safeUpdatedAt:V,applyFeatureState:a,shouldApply:u});return M.ok&&(A=M.state,(!u||u())&&(a(M.state,V),t||n(`Store "${e}" loaded from persistence`))),!0}catch(p){return c(e,`Could not load store "${e}" (${p?.message||p})`),true}},_t=async({name:e,silent:t=false,getMeta:r,getInitialState:o,applyFeatureState:a,reportStoreError:c,warnMissingMaxSize:l,validate:g,log:n,hashState:i,deepClone:k,sanitize:s,shouldApply:u})=>{let y=r(),d=y?.options?.persist;if(!d)return false;let m=_e(y,d),S=p=>U({value:p,validate:g});try{let p=await Promise.resolve(d.driver.getItem?.(d.key)??null);if(!p)return !1;if(typeof d.maxSize!="number"&&typeof p=="string"&&p.length>je&&l?.(p.length),typeof d.maxSize=="number"&&typeof p=="string"&&p.length>d.maxSize)return c(e,`Persist payload for "${e}" exceeds maxSize (${p.length} > ${d.maxSize}). Skipping hydration.`),!0;let f=d.decryptAsync?await d.decryptAsync(p):d.decrypt(p),h=JSON.parse(f),{v=1,checksum:R,data:C,updatedAt:O,updatedAtMs:E}=h||{};if(!C)return !0;let V=j({value:typeof E=="number"?E:O,fallbackMs:Date.now(),onInvalid:()=>{n(`persist: corrupt updatedAt in stored data for "${e}". Using current time to prevent sync overwrite.`);}}),A=await K(d.checksum,C,i);if(d.checksum!=="none"&&R!==A)return c(e,`Checksum mismatch loading store "${e}". Falling back to initial state.`),(!u||u())&&a(k(o()),Date.now()),!0;let P=d.deserialize(C),M=y?.version??1,H=Oe({name:e,parsed:P,v,targetVersion:M,cfg:d,migrations:m,getInitialState:o,reportStoreError:c,sanitize:s,deepClone:k,validateState:S,safeUpdatedAt:V,applyFeatureState:a,shouldApply:u});return H.ok&&(!u||u())&&(a(H.state,V),t||n(`Store "${e}" loaded from persistence`)),!0}catch(p){return c(e,`Could not load store "${e}" (${p?.message||p})`),true}},Oe=({name:e,parsed:t,v:r,targetVersion:o,cfg:a,migrations:c,getInitialState:l,reportStoreError:g,sanitize:n,deepClone:i,validateState:k,safeUpdatedAt:s,applyFeatureState:u,shouldApply:y})=>{if(r!==o){let m=Object.keys(c).map(f=>Number(f)).filter(f=>f>r&&f<=o).sort((f,h)=>f-h);if(m.length===0){let f=ae({name:e,persisted:t,reason:`No migration path from v${r} to v${o} for "${e}". Applying onMigrationFail strategy.`,persistConfig:a,initialState:l(),reportStoreError:g,sanitize:n,deepClone:i});if(t=f.state,!f.requiresValidation)return (!y||y())&&u(t,s),{ok:false,state:t}}let S=false,p=true;if(m.forEach(f=>{if(!S)try{let h=c[f](t);h!==void 0&&(t=h);}catch(h){let v=ae({name:e,persisted:t,reason:`Migration to v${f} failed for "${e}": ${h?.message||h}`,persistConfig:a,initialState:l(),reportStoreError:g,sanitize:n,deepClone:i});t=v.state,p=v.requiresValidation,S=true;}}),S){if(!p)return (!y||y())&&u(t,s),{ok:false,state:t};let f=k(t);return f.ok?{ok:true,state:f.value??t}:((!y||y())&&u(i(l()),Date.now()),{ok:false,state:t})}}let d=k(t);if(!d.ok){if(r!==o){let m=a?.onMigrationFail??"reset",S=ae({name:e,persisted:t,reason:`Persisted state for "${e}" failed schema after version change. Applying onMigrationFail strategy.`,persistConfig:a,initialState:l(),reportStoreError:g,sanitize:n,deepClone:i});if(!S.requiresValidation)return (!y||y())&&u(S.state,s),{ok:false,state:S.state};let p=k(S.state);if(p.ok)return m==="reset"&&g(e,`Persisted state for "${e}" failed schema; resetting to initial.`),{ok:true,state:p.value??S.state}}return g(e,`Persisted state for "${e}" failed schema; resetting to initial.`),(!y||y())&&u(i(l()),Date.now()),{ok:false,state:t}}return {ok:true,state:d.value??t}};var $e=(e,t,...r)=>{if(typeof e=="function")try{e(...r);}catch(o){let a=o?.message??o;_(`${t} callback threw: ${String(a)}`);}};var Ne=({name:e,persistTimers:t,persistInFlight:r,persistSequence:o,persistWatchState:a,plaintextWarningsIssued:c,exists:l,getMeta:g,getStoreValue:n,reportStoreError:i,hashState:k},s=false)=>{let u=g()?.options?.persist;if(!u)return;let y=async S=>{let p=g();if(!(!p?.options?.persist||p.options.persist!==u||!l())&&!(S!==void 0&&o[e]!==S)){if(!u.allowPlaintext&&!c.has(e)&&Q(u.encrypt)&&Q(u.decrypt)){c.add(e);let f=`[stroid/persist] Store '${e}' is persisted in plaintext. Provide encrypt/decrypt hooks to protect sensitive data.`;$e(p.options.onError,`onError(${e})`,f),_(f);}try{let f=u.serialize(n()),h=await K(u.checksum,f,k),v=JSON.stringify({v:p.version??1,updatedAt:p.updatedAt,updatedAtMs:p.updatedAtMs??Date.now(),checksum:h,data:f}),R=u.encryptAsync?await u.encryptAsync(v):u.encrypt(v);if(S!==void 0&&o[e]!==S)return;await Promise.resolve(u.driver.setItem?.(u.key,R)),he(a,e,!0);}catch(f){i(e,`Could not persist store "${e}" (${f?.message||f})`);}}},d=S=>{let p=r[e],f=(o[e]??0)+1;o[e]=f;let v=(async()=>{p&&await p,!(S&&t[e]!==S)&&o[e]===f&&await y(f);})().finally(()=>{r[e]===v&&(r[e]=null),S&&t[e]===S&&delete t[e];});r[e]=v;};if(s){t[e]&&(clearTimeout(t[e]),delete t[e]),d();return}t[e]&&clearTimeout(t[e]);let m=setTimeout(()=>{t[e]===m&&d(m);},0);t[e]=m;},B=e=>Ne(e),Ie=(e,t)=>Ne({...t,name:e},true);var xe=false,Dt=typeof process<"u"&&typeof process.env?.NODE_ENV=="string"?process.env.NODE_ENV:void 0,Ot=typeof import.meta<"u"&&import.meta?.env?.MODE?import.meta.env.MODE:void 0,$t=Dt??Ot,Nt=()=>$t==="production",It=()=>{let e={},t={},r=Object.create(null),o=Object.create(null),a=Object.create(null),c=new Set,l=new Set,g=Object.create(null);return {api:{getPersistQueueDepth(n){return e[n]?1:0}},onStoreCreate(n){let i=n.options.persist;if(!i)return;if(!i.encryptAsync&&q(i.encrypt)&&q(i.decrypt)&&!i.allowPlaintext){let m=`[stroid/persist] Store "${n.name}" is configured for plaintext persistence. Provide encrypt/decrypt hooks or set persist.allowPlaintext: true to acknowledge.`;if(Nt()){n.reportStoreError(m),n.options.persist=null;return}n.warn(m);}if(i.sensitiveData&&!i.encryptAsync&&q(i.encrypt)){n.reportStoreError(`persist: store "${n.name}" is marked sensitiveData but has no encrypt function. Plaintext data will be written to storage.`);return}let s=Se(n.name,i.encrypt,i.decrypt);if(!s.ok){n.reportStoreError(s.reason??`persist: encrypt/decrypt validation failed for store "${n.name}".`),n.options.persist=null;return}if(i.key){let m=o[i.key];m&&m!==n.name&&n.isDev()?n.warn(`Persist key collision: "${i.key}" already used by store "${m}". Store "${n.name}" will overwrite the same storage key.`):o[i.key]=n.name;}let u=n.getMeta()?.updateCount??0,y=()=>{let m=n.getMeta();return m?(m.updateCount??0)===u:false},d=De({name:n.name,silent:true,getMeta:n.getMeta,getInitialState:n.getInitialState,applyFeatureState:n.applyFeatureState,reportStoreError:(m,S)=>n.reportStoreError(S),warnMissingMaxSize:m=>{l.has(n.name)||(l.add(n.name),n.warnAlways(`[stroid/persist] Store "${n.name}" loaded ${m} bytes without a maxSize guard. Set persist.maxSize to prevent oversized payloads.`));},validate:n.validate,log:n.log,hashState:n.hashState,deepClone:n.deepClone,sanitize:n.sanitize,shouldApply:y});if(typeof d?.then=="function"?(g[n.name]={loading:true,pendingSave:false},d.then(m=>{let S=g[n.name];S&&(S.loading=false,(!m||S.pendingSave)&&B({name:n.name,persistTimers:e,persistInFlight:t,persistSequence:r,persistWatchState:a,plaintextWarningsIssued:c,exists:()=>n.hasStore(),getMeta:n.getMeta,getStoreValue:n.getStoreValue,reportStoreError:(p,f)=>n.reportStoreError(f),hashState:n.hashState}),delete g[n.name]);}).catch(()=>{let m=g[n.name];m&&(m.loading=false,m.pendingSave&&B({name:n.name,persistTimers:e,persistInFlight:t,persistSequence:r,persistWatchState:a,plaintextWarningsIssued:c,exists:()=>n.hasStore(),getMeta:n.getMeta,getStoreValue:n.getStoreValue,reportStoreError:(S,p)=>n.reportStoreError(p),hashState:n.hashState}),delete g[n.name]);})):d||B({name:n.name,persistTimers:e,persistInFlight:t,persistSequence:r,persistWatchState:a,plaintextWarningsIssued:c,exists:()=>n.hasStore(),getMeta:n.getMeta,getStoreValue:n.getStoreValue,reportStoreError:(m,S)=>n.reportStoreError(S),hashState:n.hashState}),typeof window<"u"&&typeof window.addEventListener=="function"){let m=()=>{Ie(n.name,{name:n.name,persistTimers:e,persistInFlight:t,persistSequence:r,persistWatchState:a,plaintextWarningsIssued:c,exists:()=>n.hasStore(),getMeta:n.getMeta,getStoreValue:n.getStoreValue,reportStoreError:(S,p)=>n.reportStoreError(p),hashState:n.hashState});};window.addEventListener("pagehide",m,{once:true}),window.addEventListener("beforeunload",m,{once:true});}be({name:n.name,persistConfig:i,persistWatchState:a});},onStoreWrite(n){if(!n.options.persist)return;let i=g[n.name];if(i?.loading){i.pendingSave=true;return}B({name:n.name,persistTimers:e,persistInFlight:t,persistSequence:r,persistWatchState:a,plaintextWarningsIssued:c,exists:()=>n.hasStore(),getMeta:n.getMeta,getStoreValue:n.getStoreValue,reportStoreError:(k,s)=>n.reportStoreError(s),hashState:n.hashState});},beforeStoreDelete(n){let i=n.options.persist;if(i){delete g[n.name],l.delete(n.name),e[n.name]&&(clearTimeout(e[n.name]),delete e[n.name]),t[n.name]=null,delete r[n.name];try{i.driver.removeItem?.(i.key);}catch{}i.key&&o[i.key]===n.name&&delete o[i.key],a[n.name]?.dispose(),delete a[n.name];}},resetAll(){Object.values(e).forEach(n=>clearTimeout(n)),Object.values(a).forEach(n=>{try{n.dispose();}catch{}}),Object.keys(e).forEach(n=>delete e[n]),Object.keys(t).forEach(n=>{t[n]=null,delete t[n];}),Object.keys(r).forEach(n=>delete r[n]),Object.keys(o).forEach(n=>delete o[n]),Object.keys(a).forEach(n=>delete a[n]),Object.keys(g).forEach(n=>delete g[n]),c.clear(),l.clear();}}},ze=()=>{xe||(xe=true,z("persist",It));};var We=false,L=1,xt=e=>typeof e?.v=="number"?e.v:typeof e?.protocol=="number"?e.protocol:void 0,ie=new Set,ce=new Set,Y=100,Ue=e=>{if(!e)return null;if(e===true)return Y;if(typeof e!="object")return null;let t=e.loopGuard;if(t===false)return null;if(t===true||t===void 0)return Y;if(typeof t=="object"){let r=t.windowMs;return typeof r=="number"&&Number.isFinite(r)&&r>0?r:Y}return Y},zt=e=>typeof TextEncoder<"u"?new TextEncoder().encode(e).length:typeof Buffer<"u"?Buffer.byteLength(e):e.length,Wt=({incoming:e,accepted:t})=>{let r=t?.clock??0,o=typeof e.clock=="number"?e.clock:0;if(o!==r)return o-r;let a=e.source??"",c=t?.source??"";return a===c?0:a.localeCompare(c,"en",{sensitivity:"variant"})},Lt=e=>e?.updatedAtMs??j({value:e?.updatedAt,fallbackMs:0}),Ht=e=>{if(typeof e!="object"||e===null)return false;let t=e;return (typeof t.v=="number"||typeof t.protocol=="number")&&typeof t.type=="string"&&typeof t.name=="string"&&typeof t.clock=="number"&&typeof t.source=="string"},Le=({name:e,syncChannels:t,instanceId:r,authToken:o,reportStoreError:a})=>{let c=t[e];if(c)try{let l={v:L,protocol:L,type:"sync-request",source:r,name:e,clock:0,requestedAt:Date.now()};o&&(l.token=o),c.postMessage(l);}catch(l){a(e,`Failed to request sync snapshot for "${e}": ${l?.message??l}`);}},Ut=(e,t)=>(t[e]=(t[e]??0)+1,t[e]),Bt=(e,t,r)=>(r[e]=Math.max(r[e]??0,t)+1,r[e]),qt=({name:e,syncChannels:t,syncWindowCleanup:r,syncClocks:o,syncVersions:a})=>{t[e]?.close(),delete t[e],r[e]?.(),delete r[e],delete o[e],delete a[e];},Gt=({syncChannels:e,syncWindowCleanup:t})=>{Object.values(t).forEach(r=>{try{r();}catch{}}),Object.values(e).forEach(r=>{try{r.close();}catch{}});},Kt=({name:e,syncOption:t,syncChannels:r,syncClocks:o,syncVersions:a,syncWindowCleanup:c,instanceId:l,getMeta:g,getAcceptedSyncVersion:n,getStoreValue:i,hasStoreEntry:k,notify:s,validate:u,reportStoreError:y,warn:d,setStoreValue:m,normalizeIncomingState:S,acceptIncomingSyncVersion:p,resolveSyncVersion:f,broadcastSync:h,markLoopGuard:v})=>{if(!t)return;if(typeof window>"u"||typeof BroadcastChannel>"u"){y(e,`Sync enabled for "${e}" but BroadcastChannel not available in this environment.`);return}let R=typeof t=="object"?t.policy:void 0,C=R==="insecure"||R!=="strict"&&typeof t=="object"&&t.insecure===true,O=typeof t=="object"&&typeof t.authToken=="string"&&t.authToken.length>0,E=typeof t=="object"&&typeof t.verify=="function",V=typeof t=="object"&&typeof t.sign=="function",A=R==="strict"||!ne()&&R!=="insecure";if(A&&!C&&!O&&!E){y(e,`Sync for "${e}" requires authToken or verify in strict mode. Use sync: { policy: "insecure" } to acknowledge the risk.`);return}!A&&!C&&!O&&!E&&!ie.has(e)&&(ie.add(e),_(`Sync for "${e}" is unauthenticated. Any same-origin tab can forge sync messages. Provide sync.authToken or sync.verify to enforce authentication.`)),V&&!E&&!ce.has(e)&&(ce.add(e),d(`Sync for "${e}" is configured with "sign" but no "verify". "sign" has no effect unless incoming messages are verified.`));let P=typeof t=="object"?t.authToken:void 0,M=Ue(t),H=false,Xe=typeof t=="object"&&t.channel?t.channel:`stroid_sync_${e}`;try{let $=new BroadcastChannel(Xe);if(r[e]=$,$.onmessage=N=>{let b=N.data;if(!b||b.source===l||b.name!==e||r[e]!==$||!k(e)||!g(e))return;if(!Ht(b)){y(e,`Sync message for "${e}" is malformed; ignoring.`);return}if(P&&b.token!==P){H||(y(e,`Sync message for "${e}" failed auth token verification; ignoring.`),H=!0);return}let ue=xt(b);if(ue!==L){y(e,`Sync protocol mismatch for "${e}". Expected v${L} but received ${String(ue??"unknown")}. Ignoring message.`);return}if(b.type==="sync-state"&&(typeof b.data>"u"||typeof b.clock!="number")){y(e,`Sync message for "${e}" is malformed; ignoring.`);return}if(typeof t=="object"&&typeof t.verify=="function"){let I=!1;try{I=!!t.verify(b);}catch(x){y(e,`Sync message verification failed for "${e}": ${x?.message??x}`);return}if(!I){y(e,`Sync message for "${e}" failed verification; ignoring.`);return}}if(b.type==="sync-request"){h(e);return}let le=typeof t=="object"?t.conflictResolver:null;if(Wt({incoming:{clock:b.clock,source:b.source},accepted:n(e)})<=0){let I=Lt(g(e)),x=typeof b.updatedAt=="number"?b.updatedAt:Date.now();if(le){let fe=le({local:i(e),incoming:b.data,localUpdated:I,incomingUpdated:x});if(fe!==void 0){let pe=S(e,fe);if(pe===null)return;m(e,pe);let ge=typeof t=="object"?t.resolveUpdatedAt:null,Qe=ge?ge({localUpdated:I,incomingUpdated:x,now:Date.now()}):Math.max(Date.now(),I,x);f(e,Qe,typeof b.clock=="number"?b.clock:0),M&&v(e,M),s(e),h(e);}}return}let de=S(e,b.data);de!==null&&(m(e,de),p(e,typeof b.updatedAt=="number"?b.updatedAt:Date.now(),typeof b.clock=="number"?b.clock:0,typeof b.source=="string"?b.source:""),M&&v(e,M),s(e));},typeof window<"u"&&typeof window.addEventListener=="function"){c[e]?.();let N=window,b=()=>{Le({name:e,syncChannels:r,instanceId:l,authToken:P,reportStoreError:y});};N.addEventListener("focus",b),N.addEventListener("online",b),c[e]=()=>{N.removeEventListener("focus",b),N.removeEventListener("online",b);};}queueMicrotask(()=>{Le({name:e,syncChannels:r,instanceId:l,authToken:P,reportStoreError:y});});}catch($){d(`Failed to setup sync for "${e}": ${$?.message||$}`);}},He=({name:e,syncOption:t,syncChannels:r,syncClocks:o,instanceId:a,updatedAt:c,data:l,hashState:g,reportStoreError:n})=>{let i=r[e];if(i)try{let k=typeof t=="object"&&t.checksum==="none"?"none":"hash",s={v:L,protocol:L,type:"sync-state",source:a,name:e,clock:o[e]??0,updatedAt:j({value:c,fallbackMs:Date.now()}),data:l,checksum:k==="hash"?g(l):null};if(typeof t=="object"&&t.authToken&&(s.token=t.authToken),typeof t=="object"&&typeof t.sign=="function")try{let d=t.sign(s);if(d&&typeof d.then=="function"){n(e,`Sync signer for "${e}" returned a Promise. "sign" must be synchronous.`);return}d!==void 0&&(s.auth=d);}catch(d){n(e,`Failed to sign sync payload for "${e}": ${d?.message??d}`);return}let u=typeof t=="object"&&typeof t.maxPayloadBytes=="number"?t.maxPayloadBytes:64*1024,y=zt(JSON.stringify(s));if(y>u){n(e,`Sync payload for "${e}" exceeds ${u} bytes (${y} bytes). Skipping BroadcastChannel sync.`);return}try{i.postMessage(s);}catch(d){if(d&&typeof d=="object"&&d.name==="DataCloneError"){n(e,`Sync payload for "${e}" could not be cloned (DataCloneError). Remove non-serializable values or provide a custom serializer. Payload size ~${y} bytes.`);return}throw d}}catch(k){n(e,`Failed to broadcast sync for "${e}": ${k?.message??k}`);}},Yt=()=>{let e=Object.create(null),t=Object.create(null),r=Object.create(null),o=Object.create(null),a=Object.create(null),c=new Set,l=`stroid_${Math.random().toString(16).slice(2)}`,g=(s,u)=>{r[s]={clock:t[s]??0,updatedAt:j({value:u,fallbackMs:Date.now()}),source:l};},n=(s,u)=>{Ut(s,t),g(s,u);},i=(s,u)=>{!u||!Number.isFinite(u)||(a[s]=Date.now()+u);},k=(s,u)=>{if(!u)return false;let y=a[s];return y?Date.now()>=y?(delete a[s],false):true:false};return {onStoreCreate(s){if(!s.options.sync)return;let u=s.options.sync,y=typeof u=="object"?u.policy:void 0,d=y==="insecure"||y!=="strict"&&typeof u=="object"&&u.insecure===true,m=typeof u=="object"&&typeof u.authToken=="string"&&u.authToken.length>0,S=typeof u=="object"&&typeof u.verify=="function";if((y==="strict"||!s.isDev()&&y!=="insecure")&&u&&!d&&!m&&!S){s.reportStoreError(`Sync for "${s.name}" requires authToken or verify in strict mode. Use sync: { policy: "insecure" } to acknowledge the risk.`),s.options.sync=false;return}if(Kt({name:s.name,syncOption:u,syncChannels:e,syncClocks:t,syncVersions:r,syncWindowCleanup:o,instanceId:l,getMeta:s.getMeta,getAcceptedSyncVersion:f=>r[f],getStoreValue:f=>s.getStoreValue(),hasStoreEntry:()=>s.hasStore(),notify:()=>s.notify(),validate:(f,h)=>s.validate(h),reportStoreError:(f,h)=>s.reportStoreError(h),warn:s.warn,setStoreValue:(f,h)=>s.setStoreValue(h),normalizeIncomingState:(f,h)=>{let v=U({value:h,sanitize:s.sanitize,validate:s.validate,onSanitizeError:R=>{s.reportStoreError(`Sanitize failed for incoming sync "${f}": ${R?.message??R}`);}});return v.ok?v.value:null},acceptIncomingSyncVersion:(f,h,v,R)=>{s.applyFeatureState(s.getStoreValue(),h),t[s.name]=Math.max(t[s.name]??0,v),r[s.name]={clock:v,updatedAt:h,source:R};},resolveSyncVersion:(f,h,v)=>{s.applyFeatureState(s.getStoreValue(),h);let R=Bt(s.name,v,t);return r[s.name]={clock:R,updatedAt:h,source:l},R},broadcastSync:()=>{let f=s.getMeta();f&&He({name:s.name,syncOption:s.options.sync,syncChannels:e,syncClocks:t,instanceId:l,updatedAt:f.updatedAtMs??f.updatedAt,data:s.getStoreValue(),hashState:s.hashState,reportStoreError:(h,v)=>s.reportStoreError(v)});},markLoopGuard:i}),e[s.name]){let f=s.getMeta();g(s.name,f?.updatedAtMs??f?.updatedAt??new Date().toISOString());}},onStoreWrite(s){if(!s.options.sync)return;let u=s.getMeta();if(!u)return;let y=Ue(s.options.sync);if(k(s.name,y)){n(s.name,u.updatedAtMs??u.updatedAt),c.has(s.name)||(c.add(s.name),s.warn(`Sync broadcast for "${s.name}" suppressed by loopGuard to prevent feedback loops.`));return}n(s.name,u.updatedAtMs??u.updatedAt),He({name:s.name,syncOption:s.options.sync,syncChannels:e,syncClocks:t,instanceId:l,updatedAt:u.updatedAtMs??u.updatedAt,data:s.next,hashState:s.hashState,reportStoreError:(d,m)=>s.reportStoreError(m)});},beforeStoreDelete(s){qt({name:s.name,syncChannels:e,syncWindowCleanup:o,syncClocks:t,syncVersions:r}),delete a[s.name],c.delete(s.name);},resetAll(){Gt({syncChannels:e,syncWindowCleanup:o}),Object.keys(e).forEach(s=>delete e[s]),Object.keys(t).forEach(s=>delete t[s]),Object.keys(r).forEach(s=>delete r[s]),Object.keys(o).forEach(s=>delete o[s]),Object.keys(a).forEach(s=>delete a[s]),ie.clear(),ce.clear(),c.clear();}}},Be=()=>{We||(We=true,z("sync",Yt));};var qe=false,Ge=e=>{try{return typeof structuredClone=="function"?structuredClone(e):JSON.parse(JSON.stringify(e))}catch{return e}},Jt=({name:e,useDevtools:t,existingDevtools:r,stores:o,warn:a})=>{if(!t||typeof window>"u")return r;let c=window.__REDUX_DEVTOOLS_EXTENSION__||window.__REDUX_DEVTOOLS_EXTENSION__;if(!c||typeof c.connect!="function")return a(`DevTools requested for "${e}" but Redux DevTools extension not found.`),r;if(r)return r;let l=c.connect({name:"stroid"});return l.init(o),l},J=({data:e,redactor:t,deepClone:r})=>{if(typeof t=="function")try{return t(r(e))}catch{return e}return e},Xt=(e,t)=>{if(typeof e!="object"||typeof t!="object"||e===null||t===null)return null;let r=e,o=t,a=[],c=[],l=[],g=new Set(Object.keys(r)),n=new Set(Object.keys(o));return n.forEach(i=>{g.has(i)?Object.is(r[i],o[i])||l.push(i):a.push(i);}),g.forEach(i=>{n.has(i)||c.push(i);}),{added:a,removed:c,changed:l}},Ke=({name:e,action:t,prev:r,next:o,history:a,historyLimit:c,applyRedactor:l,deepClone:g})=>{if(c===0)return;a[e]||(a[e]=[]);let n={ts:Date.now(),action:t,prev:g(l(r)),next:g(l(o)),diff:Xt(r,o)};a[e].push(n),a[e].length>c&&a[e].splice(0,a[e].length-c);},Ye=({name:e,action:t,force:r=false,devtools:o,enabled:a,stores:c,applyRedactor:l})=>{if(!(!o||!r&&!a))try{let g={...c,[e]:l(c[e])};o.send({type:`${e}/${t}`},g);}catch{}},Qt=()=>{let e=Object.create(null),t;return {onStoreCreate(r){t=Jt({name:r.name,useDevtools:!!r.options.devtools,existingDevtools:t,stores:r.getAllStores(),warn:r.warn}),Ke({name:r.name,action:"create",prev:null,next:r.getStoreValue(),history:e,historyLimit:r.options.historyLimit??50,applyRedactor:o=>J({data:o,redactor:r.options.redactor,deepClone:r.deepClone}),deepClone:r.deepClone});},onStoreWrite(r){Ke({name:r.name,action:r.action,prev:r.prev,next:r.next,history:e,historyLimit:r.options.historyLimit??50,applyRedactor:o=>J({data:o,redactor:r.options.redactor,deepClone:r.deepClone}),deepClone:r.deepClone}),Ye({name:r.name,action:r.action,devtools:t,enabled:!!r.options.devtools,stores:r.getAllStores(),applyRedactor:o=>J({data:o,redactor:r.options.redactor,deepClone:r.deepClone})});},afterStoreDelete(r){r.options.devtools&&Ye({name:r.name,action:"delete",force:true,devtools:t,enabled:true,stores:r.getAllStores(),applyRedactor:o=>J({data:o,redactor:r.options.redactor,deepClone:r.deepClone})}),delete e[r.name];},resetAll(){Object.keys(e).forEach(r=>{delete e[r];}),t=void 0;},api:{getHistory(r,o){if(!e[r])return [];let a=e[r];return o&&o>0?Ge(a.slice(-o)):Ge(a)},clearHistory(r){if(r){delete e[r];return}Object.keys(e).forEach(o=>{delete e[o];});}}}},Je=()=>{qe||(qe=true,z("devtools",Qt));};var Zt=()=>{ze();},er=()=>{Be();},tr=()=>{Je();},sn=()=>{Zt(),er(),tr();};export{sn as installAllFeatures,tr as installDevtools,Zt as installPersist,er as installSync};//# sourceMappingURL=install.js.map
2
2
  //# sourceMappingURL=install.js.map