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
@@ -0,0 +1,80 @@
1
+ import { StoreFeatureMeta, FeatureName, StoreFeatureRuntime } from './feature.js';
2
+ import { A as AsyncRegistry } from './registry.js';
3
+
4
+ /**
5
+ * @module store-registry
6
+ *
7
+ * LAYER: Store runtime
8
+ * OWNS: Module-level behavior and exports for store-registry.
9
+ *
10
+ * Consumers: Internal imports and public API.
11
+ */
12
+
13
+ type RegistryStoreValue = unknown;
14
+ type RegistrySubscriber = (value: RegistryStoreValue | null) => void;
15
+ type RegistrySnapshotEntry = {
16
+ version: number;
17
+ snapshot: RegistryStoreValue | null;
18
+ source?: RegistryStoreValue | null;
19
+ mode?: "deep" | "shallow" | "ref";
20
+ };
21
+ type StoreLifecycleEvent = {
22
+ type: "created";
23
+ name: string;
24
+ isGlobal: boolean;
25
+ isTemp: boolean;
26
+ } | {
27
+ type: "deleted";
28
+ name: string;
29
+ };
30
+ type StoreLifecycleListener = (event: StoreLifecycleEvent) => void;
31
+ type TransactionState = {
32
+ depth: number;
33
+ pending: Array<() => void>;
34
+ stagedValues: Map<string, RegistryStoreValue>;
35
+ snapshotCache: Map<string, TransactionSnapshotEntry>;
36
+ failed: boolean;
37
+ error?: Error;
38
+ };
39
+ type TransactionSnapshotMode = "deep" | "shallow" | "ref";
40
+ type TransactionSnapshotEntry = {
41
+ source: RegistryStoreValue | null | undefined;
42
+ snapshot: RegistryStoreValue | null;
43
+ mode: TransactionSnapshotMode;
44
+ };
45
+ type ComputedEntry = {
46
+ deps: string[];
47
+ compute: (...args: unknown[]) => unknown;
48
+ stale: boolean;
49
+ };
50
+ type NotifyState = {
51
+ pendingNotifications: Set<string>;
52
+ pendingBuffer: string[];
53
+ orderedNames: string[];
54
+ subscriberBuffer: RegistrySubscriber[];
55
+ notifyScheduled: boolean;
56
+ batchDepth: number;
57
+ flushId: number;
58
+ isFlushing: boolean;
59
+ };
60
+ type RegistryScope = "default" | "request";
61
+ type StoreRegistry = {
62
+ scope: RegistryScope;
63
+ stores: Record<string, RegistryStoreValue>;
64
+ subscribers: Record<string, Set<RegistrySubscriber>>;
65
+ initialStates: Record<string, RegistryStoreValue>;
66
+ initialFactories: Record<string, (() => RegistryStoreValue) | undefined>;
67
+ metaEntries: Record<string, StoreFeatureMeta>;
68
+ snapshotCache: Record<string, RegistrySnapshotEntry>;
69
+ featureRuntimes: Map<FeatureName, StoreFeatureRuntime>;
70
+ deletingStores: Set<string>;
71
+ computedEntries: Record<string, ComputedEntry>;
72
+ computedDependents: Record<string, Set<string>>;
73
+ computedCleanups: Map<string, () => void>;
74
+ transaction: TransactionState;
75
+ async: AsyncRegistry;
76
+ notify: NotifyState;
77
+ lifecycleListener: StoreLifecycleListener | null;
78
+ };
79
+
80
+ export type { StoreRegistry as S };
package/dist/sync.d.ts CHANGED
@@ -1 +1 @@
1
- export { installSync_alias_1 as installSync } from './_tsup-dts-rollup.js';
1
+ export { installSync } from './install.js';
package/dist/sync.js CHANGED
@@ -1,2 +1,2 @@
1
- var ie=new Map,U=(e,t)=>{ie.set(e,t);};var H=({value:e,sanitize:t,validate:r,onSanitizeError:a})=>{let i;if(t)try{i=t(e);}catch(d){return a?.(d),{ok:false}}else i=e;let l=r(i);return l.ok?{ok:true,value:l.value??i}:{ok:false}},R=({value:e,fallbackMs:t=Date.now(),onInvalid:r})=>{if(typeof e=="number")return Number.isFinite(e)?e:(r?.(),t);if(typeof e=="string"){let a=Date.parse(e);return Number.isFinite(a)?a:(r?.(),t)}return r?.(),t};var ue=new Map,k=(e,t,r=0)=>{!e||typeof t!="function"||ue.set(e,{name:e,order:r,fn:t});};var B=()=>({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 M=new Map,le=typeof __STROID_REGISTRY_ID__<"u"&&__STROID_REGISTRY_ID__||typeof process<"u"&&process.env?.STROID_REGISTRY_ID||void 0,L,q=e=>(L||le||e).replace(/\.ts(\?|$)/,".js$1"),de=q(new URL("./store.js",import.meta.url).href);var pe=()=>{L=void 0,M.clear();};k("registry.scope-override",pe,110);var ge=()=>({pendingNotifications:new Set,pendingBuffer:[],orderedNames:[],notifyScheduled:false,batchDepth:0});var fe=()=>({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:B(),notify:ge()}),ye=e=>{let t=q(e),r=M.get(t);if(r)return r;let a=fe();return M.set(t,a),a};var Y=e=>e||ye(de);var me={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}`));}},G={logSink:me,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},F=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}),C=new WeakMap,K=F(G),he=e=>{let t=C.get(e);return t||(t=F(K),C.set(e,t)),t};var A=()=>he(Y());var Re=()=>{C=new WeakMap,K=F(G);};k("config.reset",Re,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 ke=(e,t)=>{typeof console<"u"&&typeof console.warn=="function"&&(t?console.warn(`[stroid] ${e}`,t):console.warn(`[stroid] ${e}`));};var E=(e,t)=>{if((A().logSink.warn??ke)(e,t),A().assertRuntime)throw new Error(e)};var J=false,b=1,we=e=>typeof e?.v=="number"?e.v:typeof e?.protocol=="number"?e.protocol:void 0,V=new Set,T=new Set,Me=e=>typeof TextEncoder<"u"?new TextEncoder().encode(e).length:typeof Buffer<"u"?Buffer.byteLength(e):e.length,Ce=({incoming:e,accepted:t})=>{let r=t?.clock??0,a=typeof e.clock=="number"?e.clock:0;if(a!==r)return a-r;let i=e.source??"",l=t?.source??"";return i===l?0:i.localeCompare(l,"en",{sensitivity:"variant"})},Fe=e=>e?.updatedAtMs??R({value:e?.updatedAt,fallbackMs:0}),Ae=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"},Q=({name:e,syncChannels:t,instanceId:r,authToken:a,reportStoreError:i})=>{let l=t[e];if(l)try{let d={v:b,protocol:b,type:"sync-request",source:r,name:e,clock:0,requestedAt:Date.now()};a&&(d.token=a),l.postMessage(d);}catch(d){i(e,`Failed to request sync snapshot for "${e}": ${d?.message??d}`);}},Ee=(e,t)=>(t[e]=(t[e]??0)+1,t[e]),Ve=(e,t,r)=>(r[e]=Math.max(r[e]??0,t)+1,r[e]),Te=({name:e,syncChannels:t,syncWindowCleanup:r,syncClocks:a,syncVersions:i})=>{t[e]?.close(),delete t[e],r[e]?.(),delete r[e],delete a[e],delete i[e];},xe=({syncChannels:e,syncWindowCleanup:t})=>{Object.values(t).forEach(r=>{try{r();}catch{}}),Object.values(e).forEach(r=>{try{r.close();}catch{}});},_e=({name:e,syncOption:t,syncChannels:r,syncClocks:a,syncVersions:i,syncWindowCleanup:l,instanceId:d,getMeta:n,getAcceptedSyncVersion:o,getStoreValue:c,hasStoreEntry:u,notify:p,validate:w,reportStoreError:g,warn:f,setStoreValue:x,normalizeIncomingState:_,acceptIncomingSyncVersion:te,resolveSyncVersion:ne,broadcastSync:O})=>{if(!t)return;if(typeof window>"u"||typeof BroadcastChannel>"u"){g(e,`Sync enabled for "${e}" but BroadcastChannel not available in this environment.`);return}let re=typeof t=="object"&&typeof t.authToken=="string"&&t.authToken.length>0,j=typeof t=="object"&&typeof t.verify=="function",oe=typeof t=="object"&&typeof t.sign=="function";!re&&!j&&!V.has(e)&&(V.add(e),E(`Sync for "${e}" is unauthenticated. Any same-origin tab can forge sync messages. Provide sync.authToken or sync.verify to enforce authentication.`)),oe&&!j&&!T.has(e)&&(T.add(e),f(`Sync for "${e}" is configured with "sign" but no "verify". "sign" has no effect unless incoming messages are verified.`));let v=typeof t=="object"?t.authToken:void 0,D=false,se=typeof t=="object"&&t.channel?t.channel:`stroid_sync_${e}`;try{let y=new BroadcastChannel(se);if(r[e]=y,y.onmessage=S=>{let s=S.data;if(!s||s.source===d||s.name!==e||r[e]!==y||!u(e)||!n(e))return;if(!Ae(s)){g(e,`Sync message for "${e}" is malformed; ignoring.`);return}if(v&&s.token!==v){D||(g(e,`Sync message for "${e}" failed auth token verification; ignoring.`),D=!0);return}let N=we(s);if(N!==b){g(e,`Sync protocol mismatch for "${e}". Expected v${b} but received ${String(N??"unknown")}. Ignoring message.`);return}if(s.type==="sync-state"&&(typeof s.data>"u"||typeof s.clock!="number")){g(e,`Sync message for "${e}" is malformed; ignoring.`);return}if(typeof t=="object"&&typeof t.verify=="function"){let m=!1;try{m=!!t.verify(s);}catch(h){g(e,`Sync message verification failed for "${e}": ${h?.message??h}`);return}if(!m){g(e,`Sync message for "${e}" failed verification; ignoring.`);return}}if(s.type==="sync-request"){O(e);return}let $=typeof t=="object"?t.conflictResolver:null;if(Ce({incoming:{clock:s.clock,source:s.source},accepted:o(e)})<=0){let m=Fe(n(e)),h=typeof s.updatedAt=="number"?s.updatedAt:Date.now();if($){let I=$({local:c(e),incoming:s.data,localUpdated:m,incomingUpdated:h});if(I!==void 0){let W=_(e,I);if(W===null)return;x(e,W);let z=typeof t=="object"?t.resolveUpdatedAt:null,ae=z?z({localUpdated:m,incomingUpdated:h,now:Date.now()}):Math.max(Date.now(),m,h);ne(e,ae,typeof s.clock=="number"?s.clock:0),p(e),O(e);}}return}let P=_(e,s.data);P!==null&&(x(e,P),te(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"){l[e]?.();let S=window,s=()=>{Q({name:e,syncChannels:r,instanceId:d,authToken:v,reportStoreError:g});};S.addEventListener("focus",s),S.addEventListener("online",s),l[e]=()=>{S.removeEventListener("focus",s),S.removeEventListener("online",s);};}queueMicrotask(()=>{Q({name:e,syncChannels:r,instanceId:d,authToken:v,reportStoreError:g});});}catch(y){f(`Failed to setup sync for "${e}": ${y?.message||y}`);}},X=({name:e,syncOption:t,syncChannels:r,syncClocks:a,instanceId:i,updatedAt:l,data:d,hashState:n,reportStoreError:o})=>{let c=r[e];if(c)try{let u=typeof t=="object"&&t.checksum==="none"?"none":"hash",p={v:b,protocol:b,type:"sync-state",source:i,name:e,clock:a[e]??0,updatedAt:R({value:l,fallbackMs:Date.now()}),data:d,checksum:u==="hash"?n(d):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"){o(e,`Sync signer for "${e}" returned a Promise. "sign" must be synchronous.`);return}f!==void 0&&(p.auth=f);}catch(f){o(e,`Failed to sign sync payload for "${e}": ${f?.message??f}`);return}let w=typeof t=="object"&&typeof t.maxPayloadBytes=="number"?t.maxPayloadBytes:64*1024,g=Me(JSON.stringify(p));if(g>w){o(e,`Sync payload for "${e}" exceeds ${w} bytes (${g} bytes). Skipping BroadcastChannel sync.`);return}c.postMessage(p);}catch(u){o(e,`Failed to broadcast sync for "${e}": ${u?.message??u}`);}},Oe=()=>{let e=Object.create(null),t=Object.create(null),r=Object.create(null),a=Object.create(null),i=`stroid_${Math.random().toString(16).slice(2)}`,l=(n,o)=>{r[n]={clock:t[n]??0,updatedAt:R({value:o,fallbackMs:Date.now()}),source:i};},d=(n,o)=>{Ee(n,t),l(n,o);};return {onStoreCreate(n){if(n.options.sync&&(_e({name:n.name,syncOption:n.options.sync,syncChannels:e,syncClocks:t,syncVersions:r,syncWindowCleanup:a,instanceId:i,getMeta:n.getMeta,getAcceptedSyncVersion:o=>r[o],getStoreValue:o=>n.getStoreValue(),hasStoreEntry:()=>n.hasStore(),notify:()=>n.notify(),validate:(o,c)=>n.validate(c),reportStoreError:(o,c)=>n.reportStoreError(c),warn:n.warn,setStoreValue:(o,c)=>n.setStoreValue(c),normalizeIncomingState:(o,c)=>{let u=H({value:c,sanitize:n.sanitize,validate:n.validate,onSanitizeError:p=>{n.reportStoreError(`Sanitize failed for incoming sync "${o}": ${p?.message??p}`);}});return u.ok?u.value:null},acceptIncomingSyncVersion:(o,c,u,p)=>{n.applyFeatureState(n.getStoreValue(),c),t[n.name]=Math.max(t[n.name]??0,u),r[n.name]={clock:u,updatedAt:c,source:p};},resolveSyncVersion:(o,c,u)=>{n.applyFeatureState(n.getStoreValue(),c);let p=Ve(n.name,u,t);return r[n.name]={clock:p,updatedAt:c,source:i},p},broadcastSync:()=>{let o=n.getMeta();o&&X({name:n.name,syncOption:n.options.sync,syncChannels:e,syncClocks:t,instanceId:i,updatedAt:o.updatedAtMs??o.updatedAt,data:n.getStoreValue(),hashState:n.hashState,reportStoreError:(c,u)=>n.reportStoreError(u)});}}),e[n.name])){let o=n.getMeta();l(n.name,o?.updatedAtMs??o?.updatedAt??new Date().toISOString());}},onStoreWrite(n){if(!n.options.sync)return;let o=n.getMeta();o&&(d(n.name,o.updatedAtMs??o.updatedAt),X({name:n.name,syncOption:n.options.sync,syncChannels:e,syncClocks:t,instanceId:i,updatedAt:o.updatedAtMs??o.updatedAt,data:n.next,hashState:n.hashState,reportStoreError:(c,u)=>n.reportStoreError(u)}));},beforeStoreDelete(n){Te({name:n.name,syncChannels:e,syncWindowCleanup:a,syncClocks:t,syncVersions:r});},resetAll(){xe({syncChannels:e,syncWindowCleanup:a}),Object.keys(e).forEach(n=>delete e[n]),Object.keys(t).forEach(n=>delete t[n]),Object.keys(r).forEach(n=>delete r[n]),Object.keys(a).forEach(n=>delete a[n]),V.clear(),T.clear();}}},Z=()=>{J||(J=true,U("sync",Oe));};var ee=()=>{Z();};ee();export{ee as installSync};//# sourceMappingURL=sync.js.map
1
+ var O=new Map,ee=(e,t)=>{O.set(e,t);};var te=e=>O.get(e),re=()=>Array.from(O.keys());var oe=({value:e,sanitize:t,validate:o,onSanitizeError:a})=>{let c;if(t)try{c=t(e);}catch(l){return a?.(l),{ok:false}}else c=e;let u=o(c);return u.ok?{ok:true,value:u.value??c}:{ok:false}},x=({value:e,fallbackMs:t=Date.now(),onInvalid:o})=>{if(typeof e=="number")return Number.isFinite(e)?e:(o?.(),t);if(typeof e=="string"){let a=Date.parse(e);return Number.isFinite(a)?a:(o?.(),t)}return o?.(),t};var Ce=new Map,V=(e,t,o=0)=>{!e||typeof t!="function"||Ce.set(e,{name:e,order:o,fn:t});};var we=()=>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:we(),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 _=new Map,se=new WeakSet,Me=e=>{se.has(e)||(se.add(e),re().forEach(t=>{if(!e.featureRuntimes.get(t)){let o=te(t);o&&e.featureRuntimes.set(t,o());}}));},Fe=typeof __STROID_REGISTRY_ID__<"u"&&__STROID_REGISTRY_ID__||typeof process<"u"&&process.env?.STROID_REGISTRY_ID||void 0,ae,ie=e=>(ae||Fe||e).replace(/\.ts(\?|$)/,".js$1"),Ee=ie(new URL("../../store.js",import.meta.url).href);var Te=()=>{ae=void 0,_.clear();};V("registry.scope-override",Te,110);var Ae=()=>({pendingNotifications:new Set,pendingBuffer:[],orderedNames:[],subscriberBuffer:[],notifyScheduled:false,batchDepth:0,flushId:0,isFlushing:false});var xe=()=>({depth:0,pending:[],stagedValues:new Map,snapshotCache:new Map,failed:false,error:void 0}),Ve=(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:Ae(),lifecycleListener:null};return Me(t),t},je=e=>{let t=ie(e),o=_.get(t);if(o)return o;let a=Ve();return _.set(t,a),a};var m=[],Oe={run:(e,t)=>{m.push(e);try{return t()}finally{m.pop();}},get:()=>m.length>0?m[m.length-1]:null,enterWith:e=>{if(m.length>0){m[m.length-1]=e;return}m.push(e);}};var ce=e=>(Oe).get()||e||je(Ee);var _e={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}`));}},le={logSink:_e,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},$=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}),N=new WeakMap,ue=$(le),Ne=e=>{let t=N.get(e);return t||(t=$(ue),N.set(e,t)),t};var P=()=>Ne(ce());var ze=()=>{N=new WeakMap,ue=$(le);};V("config.reset",ze,90);var Le=typeof process<"u"&&typeof process.env?.NODE_ENV=="string"?process.env.NODE_ENV:void 0,We=typeof import.meta<"u"&&import.meta?.env?.MODE?import.meta.env.MODE:void 0,de=typeof globalThis<"u"&&typeof globalThis.__STROID_DEV__=="boolean"?globalThis.__STROID_DEV__:void 0,He="production",Ue=Le??We??He,pe=typeof de=="boolean"?de:Ue!=="production",I=()=>pe,Be=(e,t)=>{typeof console<"u"&&typeof console.warn=="function"&&(t?console.warn(`[stroid] ${e}`,t):console.warn(`[stroid] ${e}`));};var z=(e,t)=>{if((P().logSink.warn??Be)(e,t),P().assertRuntime)throw new Error(e)};var fe=false,F=1,qe=e=>typeof e?.v=="number"?e.v:typeof e?.protocol=="number"?e.protocol:void 0,L=new Set,W=new Set,j=100,Se=e=>{if(!e)return null;if(e===true)return j;if(typeof e!="object")return null;let t=e.loopGuard;if(t===false)return null;if(t===true||t===void 0)return j;if(typeof t=="object"){let o=t.windowMs;return typeof o=="number"&&Number.isFinite(o)&&o>0?o:j}return j},Ge=e=>typeof TextEncoder<"u"?new TextEncoder().encode(e).length:typeof Buffer<"u"?Buffer.byteLength(e):e.length,Ke=({incoming:e,accepted:t})=>{let o=t?.clock??0,a=typeof e.clock=="number"?e.clock:0;if(a!==o)return a-o;let c=e.source??"",u=t?.source??"";return c===u?0:c.localeCompare(u,"en",{sensitivity:"variant"})},Ye=e=>e?.updatedAtMs??x({value:e?.updatedAt,fallbackMs:0}),Je=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"},ge=({name:e,syncChannels:t,instanceId:o,authToken:a,reportStoreError:c})=>{let u=t[e];if(u)try{let l={v:F,protocol:F,type:"sync-request",source:o,name:e,clock:0,requestedAt:Date.now()};a&&(l.token=a),u.postMessage(l);}catch(l){c(e,`Failed to request sync snapshot for "${e}": ${l?.message??l}`);}},Qe=(e,t)=>(t[e]=(t[e]??0)+1,t[e]),Xe=(e,t,o)=>(o[e]=Math.max(o[e]??0,t)+1,o[e]),Ze=({name:e,syncChannels:t,syncWindowCleanup:o,syncClocks:a,syncVersions:c})=>{t[e]?.close(),delete t[e],o[e]?.(),delete o[e],delete a[e],delete c[e];},et=({syncChannels:e,syncWindowCleanup:t})=>{Object.values(t).forEach(o=>{try{o();}catch{}}),Object.values(e).forEach(o=>{try{o.close();}catch{}});},tt=({name:e,syncOption:t,syncChannels:o,syncClocks:a,syncVersions:c,syncWindowCleanup:u,instanceId:l,getMeta:b,getAcceptedSyncVersion:S,getStoreValue:v,hasStoreEntry:h,notify:r,validate:n,reportStoreError:i,warn:d,setStoreValue:R,normalizeIncomingState:E,acceptIncomingSyncVersion:H,resolveSyncVersion:p,broadcastSync:f,markLoopGuard:g})=>{if(!t)return;if(typeof window>"u"||typeof BroadcastChannel>"u"){i(e,`Sync enabled for "${e}" but BroadcastChannel not available in this environment.`);return}let y=typeof t=="object"?t.policy:void 0,U=y==="insecure"||y!=="strict"&&typeof t=="object"&&t.insecure===true,B=typeof t=="object"&&typeof t.authToken=="string"&&t.authToken.length>0,D=typeof t=="object"&&typeof t.verify=="function",be=typeof t=="object"&&typeof t.sign=="function",q=y==="strict"||!I()&&y!=="insecure";if(q&&!U&&!B&&!D){i(e,`Sync for "${e}" requires authToken or verify in strict mode. Use sync: { policy: "insecure" } to acknowledge the risk.`);return}!q&&!U&&!B&&!D&&!L.has(e)&&(L.add(e),z(`Sync for "${e}" is unauthenticated. Any same-origin tab can forge sync messages. Provide sync.authToken or sync.verify to enforce authentication.`)),be&&!D&&!W.has(e)&&(W.add(e),d(`Sync for "${e}" is configured with "sign" but no "verify". "sign" has no effect unless incoming messages are verified.`));let T=typeof t=="object"?t.authToken:void 0,A=Se(t),G=false,ve=typeof t=="object"&&t.channel?t.channel:`stroid_sync_${e}`;try{let k=new BroadcastChannel(ve);if(o[e]=k,k.onmessage=C=>{let s=C.data;if(!s||s.source===l||s.name!==e||o[e]!==k||!h(e)||!b(e))return;if(!Je(s)){i(e,`Sync message for "${e}" is malformed; ignoring.`);return}if(T&&s.token!==T){G||(i(e,`Sync message for "${e}" failed auth token verification; ignoring.`),G=!0);return}let K=qe(s);if(K!==F){i(e,`Sync protocol mismatch for "${e}". Expected v${F} but received ${String(K??"unknown")}. Ignoring message.`);return}if(s.type==="sync-state"&&(typeof s.data>"u"||typeof s.clock!="number")){i(e,`Sync message for "${e}" is malformed; ignoring.`);return}if(typeof t=="object"&&typeof t.verify=="function"){let w=!1;try{w=!!t.verify(s);}catch(M){i(e,`Sync message verification failed for "${e}": ${M?.message??M}`);return}if(!w){i(e,`Sync message for "${e}" failed verification; ignoring.`);return}}if(s.type==="sync-request"){f(e);return}let Y=typeof t=="object"?t.conflictResolver:null;if(Ke({incoming:{clock:s.clock,source:s.source},accepted:S(e)})<=0){let w=Ye(b(e)),M=typeof s.updatedAt=="number"?s.updatedAt:Date.now();if(Y){let Q=Y({local:v(e),incoming:s.data,localUpdated:w,incomingUpdated:M});if(Q!==void 0){let X=E(e,Q);if(X===null)return;R(e,X);let Z=typeof t=="object"?t.resolveUpdatedAt:null,Re=Z?Z({localUpdated:w,incomingUpdated:M,now:Date.now()}):Math.max(Date.now(),w,M);p(e,Re,typeof s.clock=="number"?s.clock:0),A&&g(e,A),r(e),f(e);}}return}let J=E(e,s.data);J!==null&&(R(e,J),H(e,typeof s.updatedAt=="number"?s.updatedAt:Date.now(),typeof s.clock=="number"?s.clock:0,typeof s.source=="string"?s.source:""),A&&g(e,A),r(e));},typeof window<"u"&&typeof window.addEventListener=="function"){u[e]?.();let C=window,s=()=>{ge({name:e,syncChannels:o,instanceId:l,authToken:T,reportStoreError:i});};C.addEventListener("focus",s),C.addEventListener("online",s),u[e]=()=>{C.removeEventListener("focus",s),C.removeEventListener("online",s);};}queueMicrotask(()=>{ge({name:e,syncChannels:o,instanceId:l,authToken:T,reportStoreError:i});});}catch(k){d(`Failed to setup sync for "${e}": ${k?.message||k}`);}},ye=({name:e,syncOption:t,syncChannels:o,syncClocks:a,instanceId:c,updatedAt:u,data:l,hashState:b,reportStoreError:S})=>{let v=o[e];if(v)try{let h=typeof t=="object"&&t.checksum==="none"?"none":"hash",r={v:F,protocol:F,type:"sync-state",source:c,name:e,clock:a[e]??0,updatedAt:x({value:u,fallbackMs:Date.now()}),data:l,checksum:h==="hash"?b(l):null};if(typeof t=="object"&&t.authToken&&(r.token=t.authToken),typeof t=="object"&&typeof t.sign=="function")try{let d=t.sign(r);if(d&&typeof d.then=="function"){S(e,`Sync signer for "${e}" returned a Promise. "sign" must be synchronous.`);return}d!==void 0&&(r.auth=d);}catch(d){S(e,`Failed to sign sync payload for "${e}": ${d?.message??d}`);return}let n=typeof t=="object"&&typeof t.maxPayloadBytes=="number"?t.maxPayloadBytes:64*1024,i=Ge(JSON.stringify(r));if(i>n){S(e,`Sync payload for "${e}" exceeds ${n} bytes (${i} bytes). Skipping BroadcastChannel sync.`);return}try{v.postMessage(r);}catch(d){if(d&&typeof d=="object"&&d.name==="DataCloneError"){S(e,`Sync payload for "${e}" could not be cloned (DataCloneError). Remove non-serializable values or provide a custom serializer. Payload size ~${i} bytes.`);return}throw d}}catch(h){S(e,`Failed to broadcast sync for "${e}": ${h?.message??h}`);}},rt=()=>{let e=Object.create(null),t=Object.create(null),o=Object.create(null),a=Object.create(null),c=Object.create(null),u=new Set,l=`stroid_${Math.random().toString(16).slice(2)}`,b=(r,n)=>{o[r]={clock:t[r]??0,updatedAt:x({value:n,fallbackMs:Date.now()}),source:l};},S=(r,n)=>{Qe(r,t),b(r,n);},v=(r,n)=>{!n||!Number.isFinite(n)||(c[r]=Date.now()+n);},h=(r,n)=>{if(!n)return false;let i=c[r];return i?Date.now()>=i?(delete c[r],false):true:false};return {onStoreCreate(r){if(!r.options.sync)return;let n=r.options.sync,i=typeof n=="object"?n.policy:void 0,d=i==="insecure"||i!=="strict"&&typeof n=="object"&&n.insecure===true,R=typeof n=="object"&&typeof n.authToken=="string"&&n.authToken.length>0,E=typeof n=="object"&&typeof n.verify=="function";if((i==="strict"||!r.isDev()&&i!=="insecure")&&n&&!d&&!R&&!E){r.reportStoreError(`Sync for "${r.name}" requires authToken or verify in strict mode. Use sync: { policy: "insecure" } to acknowledge the risk.`),r.options.sync=false;return}if(tt({name:r.name,syncOption:n,syncChannels:e,syncClocks:t,syncVersions:o,syncWindowCleanup:a,instanceId:l,getMeta:r.getMeta,getAcceptedSyncVersion:p=>o[p],getStoreValue:p=>r.getStoreValue(),hasStoreEntry:()=>r.hasStore(),notify:()=>r.notify(),validate:(p,f)=>r.validate(f),reportStoreError:(p,f)=>r.reportStoreError(f),warn:r.warn,setStoreValue:(p,f)=>r.setStoreValue(f),normalizeIncomingState:(p,f)=>{let g=oe({value:f,sanitize:r.sanitize,validate:r.validate,onSanitizeError:y=>{r.reportStoreError(`Sanitize failed for incoming sync "${p}": ${y?.message??y}`);}});return g.ok?g.value:null},acceptIncomingSyncVersion:(p,f,g,y)=>{r.applyFeatureState(r.getStoreValue(),f),t[r.name]=Math.max(t[r.name]??0,g),o[r.name]={clock:g,updatedAt:f,source:y};},resolveSyncVersion:(p,f,g)=>{r.applyFeatureState(r.getStoreValue(),f);let y=Xe(r.name,g,t);return o[r.name]={clock:y,updatedAt:f,source:l},y},broadcastSync:()=>{let p=r.getMeta();p&&ye({name:r.name,syncOption:r.options.sync,syncChannels:e,syncClocks:t,instanceId:l,updatedAt:p.updatedAtMs??p.updatedAt,data:r.getStoreValue(),hashState:r.hashState,reportStoreError:(f,g)=>r.reportStoreError(g)});},markLoopGuard:v}),e[r.name]){let p=r.getMeta();b(r.name,p?.updatedAtMs??p?.updatedAt??new Date().toISOString());}},onStoreWrite(r){if(!r.options.sync)return;let n=r.getMeta();if(!n)return;let i=Se(r.options.sync);if(h(r.name,i)){S(r.name,n.updatedAtMs??n.updatedAt),u.has(r.name)||(u.add(r.name),r.warn(`Sync broadcast for "${r.name}" suppressed by loopGuard to prevent feedback loops.`));return}S(r.name,n.updatedAtMs??n.updatedAt),ye({name:r.name,syncOption:r.options.sync,syncChannels:e,syncClocks:t,instanceId:l,updatedAt:n.updatedAtMs??n.updatedAt,data:r.next,hashState:r.hashState,reportStoreError:(d,R)=>r.reportStoreError(R)});},beforeStoreDelete(r){Ze({name:r.name,syncChannels:e,syncWindowCleanup:a,syncClocks:t,syncVersions:o}),delete c[r.name],u.delete(r.name);},resetAll(){et({syncChannels:e,syncWindowCleanup:a}),Object.keys(e).forEach(r=>delete e[r]),Object.keys(t).forEach(r=>delete t[r]),Object.keys(o).forEach(r=>delete o[r]),Object.keys(a).forEach(r=>delete a[r]),Object.keys(c).forEach(r=>delete c[r]),L.clear(),W.clear(),u.clear();}}},me=()=>{fe||(fe=true,ee("sync",rt));};var he=()=>{me();};he();export{he as installSync};//# sourceMappingURL=sync.js.map
2
2
  //# sourceMappingURL=sync.js.map