@storix-js/sync 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +512 -0
- package/package.json +24 -0
- package/src/index.ts +161 -0
- package/tsconfig.build.json +8 -0
- package/tsconfig.json +4 -0
- package/vite.config.ts +15 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var at=Symbol.for("preact-signals");function W(){if(k>1)k--;else{for(var e,t=!1;D!==void 0;){var o=D;for(D=void 0,B++;o!==void 0;){var l=o.o;if(o.o=void 0,o.f&=-3,!(8&o.f)&&nt(o))try{o.c()}catch(x){t||(e=x,t=!0)}o=l}}if(B=0,k--,t)throw e}}function Z(e){if(k>0)return e();k++;try{return e()}finally{W()}}var u=void 0;function tt(e){var t=u;u=void 0;try{return e()}finally{u=t}}var D=void 0,k=0,B=0,J=0;function et(e){if(u!==void 0){var t=e.n;if(t===void 0||t.t!==u)return t={i:0,S:e,p:u.s,n:void 0,t:u,e:void 0,x:void 0,r:t},u.s!==void 0&&(u.s.n=t),u.s=t,e.n=t,32&u.f&&e.S(t),t;if(t.i===-1)return t.i=0,t.n!==void 0&&(t.n.p=t.p,t.p!==void 0&&(t.p.n=t.n),t.p=u.s,t.n=void 0,u.s.n=t,u.s=t),t}}function m(e,t){this.v=e,this.i=0,this.n=void 0,this.t=void 0,this.W=t==null?void 0:t.watched,this.Z=t==null?void 0:t.unwatched,this.name=t==null?void 0:t.name}m.prototype.brand=at;m.prototype.h=function(){return!0};m.prototype.S=function(e){var t=this,o=this.t;o!==e&&e.e===void 0&&(e.x=o,this.t=e,o!==void 0?o.e=e:tt(function(){var l;(l=t.W)==null||l.call(t)}))};m.prototype.U=function(e){var t=this;if(this.t!==void 0){var o=e.e,l=e.x;o!==void 0&&(o.x=l,e.e=void 0),l!==void 0&&(l.e=o,e.x=void 0),e===this.t&&(this.t=l,l===void 0&&tt(function(){var x;(x=t.Z)==null||x.call(t)}))}};m.prototype.subscribe=function(e){var t=this;return ut(function(){var o=t.value,l=u;u=void 0;try{e(o)}finally{u=l}},{name:"sub"})};m.prototype.valueOf=function(){return this.value};m.prototype.toString=function(){return this.value+""};m.prototype.toJSON=function(){return this.value};m.prototype.peek=function(){var e=u;u=void 0;try{return this.value}finally{u=e}};Object.defineProperty(m.prototype,"value",{get:function(){var e=et(this);return e!==void 0&&(e.i=this.i),this.v},set:function(e){if(e!==this.v){if(B>100)throw new Error("Cycle detected");this.v=e,this.i++,J++,k++;try{for(var t=this.t;t!==void 0;t=t.x)t.t.N()}finally{W()}}}});function ft(e,t){return new m(e,t)}function nt(e){for(var t=e.s;t!==void 0;t=t.n)if(t.S.i!==t.i||!t.S.h()||t.S.i!==t.i)return!0;return!1}function it(e){for(var t=e.s;t!==void 0;t=t.n){var o=t.S.n;if(o!==void 0&&(t.r=o),t.S.n=t,t.i=-1,t.n===void 0){e.s=t;break}}}function ot(e){for(var t=e.s,o=void 0;t!==void 0;){var l=t.p;t.i===-1?(t.S.U(t),l!==void 0&&(l.n=t.n),t.n!==void 0&&(t.n.p=l)):o=t,t.S.n=t.r,t.r!==void 0&&(t.r=void 0),t=l}e.s=o}function R(e,t){m.call(this,void 0),this.x=e,this.s=void 0,this.g=J-1,this.f=4,this.W=t==null?void 0:t.watched,this.Z=t==null?void 0:t.unwatched,this.name=t==null?void 0:t.name}R.prototype=new m;R.prototype.h=function(){if(this.f&=-3,1&this.f)return!1;if((36&this.f)==32||(this.f&=-5,this.g===J))return!0;if(this.g=J,this.f|=1,this.i>0&&!nt(this))return this.f&=-2,!0;var e=u;try{it(this),u=this;var t=this.x();(16&this.f||this.v!==t||this.i===0)&&(this.v=t,this.f&=-17,this.i++)}catch(o){this.v=o,this.f|=16,this.i++}return u=e,ot(this),this.f&=-2,!0};R.prototype.S=function(e){if(this.t===void 0){this.f|=36;for(var t=this.s;t!==void 0;t=t.n)t.S.S(t)}m.prototype.S.call(this,e)};R.prototype.U=function(e){if(this.t!==void 0&&(m.prototype.U.call(this,e),this.t===void 0)){this.f&=-33;for(var t=this.s;t!==void 0;t=t.n)t.S.U(t)}};R.prototype.N=function(){if(!(2&this.f)){this.f|=6;for(var e=this.t;e!==void 0;e=e.x)e.t.N()}};Object.defineProperty(R.prototype,"value",{get:function(){if(1&this.f)throw new Error("Cycle detected");var e=et(this);if(this.h(),e!==void 0&&(e.i=this.i),16&this.f)throw this.v;return this.v}});function Y(e,t){return new R(e,t)}function st(e){var t=e.u;if(e.u=void 0,typeof t=="function"){k++;var o=u;u=void 0;try{t()}catch(l){throw e.f&=-2,e.f|=8,K(e),l}finally{u=o,W()}}}function K(e){for(var t=e.s;t!==void 0;t=t.n)t.S.U(t);e.x=void 0,e.s=void 0,st(e)}function ct(e){if(u!==this)throw new Error("Out-of-order effect");ot(this),u=e,this.f&=-2,8&this.f&&K(this),W()}function C(e,t){this.x=e,this.u=void 0,this.s=void 0,this.o=void 0,this.f=32,this.name=t==null?void 0:t.name}C.prototype.c=function(){var e=this.S();try{if(8&this.f||this.x===void 0)return;var t=this.x();typeof t=="function"&&(this.u=t)}finally{e()}};C.prototype.S=function(){if(1&this.f)throw new Error("Cycle detected");this.f|=1,this.f&=-9,st(this),it(this),k++;var e=u;return u=this,ct.bind(this,e)};C.prototype.N=function(){2&this.f||(this.f|=2,this.o=D,D=this)};C.prototype.d=function(){this.f|=8,1&this.f||K(this)};C.prototype.dispose=function(){this.d()};function ut(e,t){var o=new C(e,t);try{o.c()}catch(x){throw o.d(),x}var l=o.d.bind(o);return l[Symbol.dispose]=l,l}function lt(e={}){const t=(e.namespace??"default").trim()||"default",o=e.plugins??[],l=new Map;function x(S,j){return function(){var _;const N=`${t}:${S}`,E=l.get(S);if(E)return E;const U=j.state(),I=j.modules??{},H={...U};for(const[i,n]of Object.entries(I))H[i]=n.state();const h=ft(H),y=new Map,A=new Map,L=new Map,M=new Map,b=new Map,T=new Set,d=new Set(Object.keys(U)),a=new Set(Object.keys(j.getters??{})),p=new Set(Object.keys(j.actions??{})),w=i=>h.value[i]??{},q=(i,n)=>{h.value={...h.value,[i]:n}},rt=new Proxy({},{get(i,n){var r,f;if(y.has(n))return(r=y.get(n))==null?void 0:r.value;if(b.has(n))return(f=b.get(n))==null?void 0:f.value;if(d.has(n))return h.value[n];const v=M.get(n);return v?w(v.moduleName)[v.key]:h.value[n]}});for(const[i,n]of Object.entries(j.getters??{}))y.set(i,Y(()=>n(h.value,rt)));const F=(i,n)=>{var r;for(const f of T)f(i);for(const f of o)(r=f.onMutation)==null||r.call(f,n,i)},G=(i,n,r,f)=>{const v=h.value[i];Object.is(v,n)||(h.value={...h.value,[i]:n},F({namespace:t,scopeId:N,storeId:S,key:i,oldValue:v,newValue:n,origin:r},f))},z=(i,n,r,f,v)=>{const g=w(i),s=g[n];Object.is(s,r)||(q(i,{...g,[n]:r}),F({namespace:t,scopeId:N,storeId:S,key:`${i}.${n}`,oldValue:s,newValue:r,origin:f},v))},P={$id:S,$namespace:t,$scopeId:N,$subscribe(i){return T.add(i),()=>T.delete(i)},$dispose(){var i;T.clear();for(const n of o)(i=n.onDispose)==null||i.call(n,$);l.delete(S)},$patch(i,n="local"){Z(()=>{for(const[r,f]of Object.entries(i)){const v=M.get(r);if(v){z(v.moduleName,v.key,f,n,$);continue}if(r.includes(".")){const[g,s]=r.split(".",2);if(I[g]){z(g,s,f,n,$);continue}}if(I[r]&&f&&typeof f=="object"&&!Array.isArray(f)){for(const[g,s]of Object.entries(f))z(r,g,s,n,$);continue}G(r,f,n,$)}})},$snapshot(){return{...h.value}}};for(const[i,n]of Object.entries(I)){const r=new Map,f=new Map,v=new Proxy({},{get(s,c){var O,V,Q;if(r.has(c))return(O=r.get(c))==null?void 0:O.value;if(y.has(c))return(V=y.get(c))==null?void 0:V.value;if(b.has(c))return(Q=b.get(c))==null?void 0:Q.value;const X=w(i);if(c in X)return X[c];if(d.has(c))return h.value[c]}});for(const[s,c]of Object.entries(n.getters??{}))r.set(s,Y(()=>c(w(i),h.value,v)));let g;for(const[s,c]of Object.entries(n.actions??{}))f.set(s,(...O)=>Z(()=>c.apply(g,O)));g=new Proxy({},{get(s,c){var O;if(f.has(c))return f.get(c);if(r.has(c))return(O=r.get(c))==null?void 0:O.value;const V=w(i);return c in V?V[c]:$[c]},set(s,c,O){if(f.has(c)||r.has(c))return!1;const V=w(i);return c in V?z(i,c,O,"local",$):$[c]=O,!0}}),L.set(i,g),A.set(i,r);for(const s of Object.keys(w(i)))!(d.has(s)||a.has(s)||p.has(s)||Reflect.has(P,s)||I[s]!==void 0)&&!M.has(s)&&M.set(s,{moduleName:i,key:s});for(const[s,c]of r.entries())!(d.has(s)||a.has(s)||p.has(s)||Reflect.has(P,s)||I[s]!==void 0)&&!b.has(s)&&b.set(s,c);for(const[s,c]of f.entries())!(d.has(s)||a.has(s)||p.has(s)||Reflect.has(P,s)||I[s]!==void 0)&&!Reflect.has(P,s)&&(P[s]=c)}const $=new Proxy(P,{get(i,n,r){var f,v;if(Reflect.has(i,n))return Reflect.get(i,n,r);if(L.has(n))return L.get(n);if(y.has(n))return(f=y.get(n))==null?void 0:f.value;if(b.has(n))return(v=b.get(n))==null?void 0:v.value;if(d.has(n))return h.value[n];const g=M.get(n);return g?w(g.moduleName)[g.key]:h.value[n]},set(i,n,r,f){if(Reflect.has(i,n))return Reflect.set(i,n,r,f);const v=M.get(n);return v?(z(v.moduleName,v.key,r,"local",f),!0):(G(n,r,"local",f),!0)}});for(const[i,n]of Object.entries(j.actions??{}))P[i]=(...r)=>Z(()=>n.apply($,r));for(const i of o)(_=i.onInit)==null||_.call(i,$);return l.set(S,$),$}}return{defineStore:x,use(S){o.push(S)}}}lt();function dt(e={}){const t=e.channelName??"storix-sync",o=new Set(e.include??[]),l=new Set(e.exclude??[]),x=e.namespaces??[],S=x==="*"?null:new Set(x),j=e.debounce??16,_=crypto.randomUUID(),N=`__storix_sync__:${t}`,E=new Map,U=new Set,I=new Map,H=new Map;let h=null;const y=typeof window<"u"&&"BroadcastChannel"in window?new BroadcastChannel(t):null,A=d=>{const a=[d.$id,d.$scopeId];return!(a.some(p=>l.has(p))||o.size>0&&!a.some(p=>o.has(p)))},L=(d,a)=>a===d||S===null?!0:S.has(a),M=(d,a)=>{!a||a.originTabId===_||L(d.$namespace,a.namespace)&&a.storeId===d.$id&&A(d)&&d.$patch({[a.key]:a.newValue},"remote")},b=()=>{if(h=null,E.size===0)return;const d=Array.from(E.values());E.clear();for(const a of d){const p={...a,originTabId:_};if(y&&y.postMessage(p),typeof window<"u"&&"localStorage"in window)try{window.localStorage.setItem(N,JSON.stringify(p)),window.localStorage.removeItem(N)}catch{}}},T=d=>{if(E.set(`${d.scopeId}:${d.key}`,d),j<=0){b();return}h||(h=setTimeout(b,j))};return{name:"sync",onInit(d){const a=d;if(A(a)){if(U.add(a.$scopeId),y){const p=w=>{M(a,w.data)};I.set(a.$scopeId,p),y.addEventListener("message",p)}if(typeof window<"u"){const p=w=>{if(!(w.key!==N||!w.newValue))try{const q=JSON.parse(w.newValue);M(a,q)}catch{}};H.set(a.$scopeId,p),window.addEventListener("storage",p)}}},onMutation(d,a){a.origin!=="remote"&&A(d)&&T(a)},onDispose(d){const a=d;U.delete(a.$scopeId);const p=I.get(a.$scopeId);y&&p&&(y.removeEventListener("message",p),I.delete(a.$scopeId));const w=H.get(a.$scopeId);typeof window<"u"&&w&&(window.removeEventListener("storage",w),H.delete(a.$scopeId)),h&&(clearTimeout(h),h=null),b(),U.size===0&&(y==null||y.close())}}}exports.syncPlugin=dt;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface SyncPluginOptions {
|
|
2
|
+
channelName?: string;
|
|
3
|
+
include?: string[];
|
|
4
|
+
exclude?: string[];
|
|
5
|
+
namespaces?: string[] | '*';
|
|
6
|
+
conflict?: 'last-write-wins';
|
|
7
|
+
debounce?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function syncPlugin(options?: SyncPluginOptions): import("@storix-js/core").StorePlugin;
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IAC5B,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AASD,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,yCA8IzD"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
var at = Symbol.for("preact-signals");
|
|
2
|
+
function W() {
|
|
3
|
+
if (M > 1)
|
|
4
|
+
M--;
|
|
5
|
+
else {
|
|
6
|
+
for (var e, t = !1; D !== void 0; ) {
|
|
7
|
+
var o = D;
|
|
8
|
+
for (D = void 0, B++; o !== void 0; ) {
|
|
9
|
+
var l = o.o;
|
|
10
|
+
if (o.o = void 0, o.f &= -3, !(8 & o.f) && nt(o)) try {
|
|
11
|
+
o.c();
|
|
12
|
+
} catch (x) {
|
|
13
|
+
t || (e = x, t = !0);
|
|
14
|
+
}
|
|
15
|
+
o = l;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
if (B = 0, M--, t) throw e;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function Z(e) {
|
|
22
|
+
if (M > 0) return e();
|
|
23
|
+
M++;
|
|
24
|
+
try {
|
|
25
|
+
return e();
|
|
26
|
+
} finally {
|
|
27
|
+
W();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
var u = void 0;
|
|
31
|
+
function tt(e) {
|
|
32
|
+
var t = u;
|
|
33
|
+
u = void 0;
|
|
34
|
+
try {
|
|
35
|
+
return e();
|
|
36
|
+
} finally {
|
|
37
|
+
u = t;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
var D = void 0, M = 0, B = 0, J = 0;
|
|
41
|
+
function et(e) {
|
|
42
|
+
if (u !== void 0) {
|
|
43
|
+
var t = e.n;
|
|
44
|
+
if (t === void 0 || t.t !== u)
|
|
45
|
+
return t = { i: 0, S: e, p: u.s, n: void 0, t: u, e: void 0, x: void 0, r: t }, u.s !== void 0 && (u.s.n = t), u.s = t, e.n = t, 32 & u.f && e.S(t), t;
|
|
46
|
+
if (t.i === -1)
|
|
47
|
+
return t.i = 0, t.n !== void 0 && (t.n.p = t.p, t.p !== void 0 && (t.p.n = t.n), t.p = u.s, t.n = void 0, u.s.n = t, u.s = t), t;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function m(e, t) {
|
|
51
|
+
this.v = e, this.i = 0, this.n = void 0, this.t = void 0, this.W = t == null ? void 0 : t.watched, this.Z = t == null ? void 0 : t.unwatched, this.name = t == null ? void 0 : t.name;
|
|
52
|
+
}
|
|
53
|
+
m.prototype.brand = at;
|
|
54
|
+
m.prototype.h = function() {
|
|
55
|
+
return !0;
|
|
56
|
+
};
|
|
57
|
+
m.prototype.S = function(e) {
|
|
58
|
+
var t = this, o = this.t;
|
|
59
|
+
o !== e && e.e === void 0 && (e.x = o, this.t = e, o !== void 0 ? o.e = e : tt(function() {
|
|
60
|
+
var l;
|
|
61
|
+
(l = t.W) == null || l.call(t);
|
|
62
|
+
}));
|
|
63
|
+
};
|
|
64
|
+
m.prototype.U = function(e) {
|
|
65
|
+
var t = this;
|
|
66
|
+
if (this.t !== void 0) {
|
|
67
|
+
var o = e.e, l = e.x;
|
|
68
|
+
o !== void 0 && (o.x = l, e.e = void 0), l !== void 0 && (l.e = o, e.x = void 0), e === this.t && (this.t = l, l === void 0 && tt(function() {
|
|
69
|
+
var x;
|
|
70
|
+
(x = t.Z) == null || x.call(t);
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
m.prototype.subscribe = function(e) {
|
|
75
|
+
var t = this;
|
|
76
|
+
return ut(function() {
|
|
77
|
+
var o = t.value, l = u;
|
|
78
|
+
u = void 0;
|
|
79
|
+
try {
|
|
80
|
+
e(o);
|
|
81
|
+
} finally {
|
|
82
|
+
u = l;
|
|
83
|
+
}
|
|
84
|
+
}, { name: "sub" });
|
|
85
|
+
};
|
|
86
|
+
m.prototype.valueOf = function() {
|
|
87
|
+
return this.value;
|
|
88
|
+
};
|
|
89
|
+
m.prototype.toString = function() {
|
|
90
|
+
return this.value + "";
|
|
91
|
+
};
|
|
92
|
+
m.prototype.toJSON = function() {
|
|
93
|
+
return this.value;
|
|
94
|
+
};
|
|
95
|
+
m.prototype.peek = function() {
|
|
96
|
+
var e = u;
|
|
97
|
+
u = void 0;
|
|
98
|
+
try {
|
|
99
|
+
return this.value;
|
|
100
|
+
} finally {
|
|
101
|
+
u = e;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
Object.defineProperty(m.prototype, "value", { get: function() {
|
|
105
|
+
var e = et(this);
|
|
106
|
+
return e !== void 0 && (e.i = this.i), this.v;
|
|
107
|
+
}, set: function(e) {
|
|
108
|
+
if (e !== this.v) {
|
|
109
|
+
if (B > 100) throw new Error("Cycle detected");
|
|
110
|
+
this.v = e, this.i++, J++, M++;
|
|
111
|
+
try {
|
|
112
|
+
for (var t = this.t; t !== void 0; t = t.x) t.t.N();
|
|
113
|
+
} finally {
|
|
114
|
+
W();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
} });
|
|
118
|
+
function ft(e, t) {
|
|
119
|
+
return new m(e, t);
|
|
120
|
+
}
|
|
121
|
+
function nt(e) {
|
|
122
|
+
for (var t = e.s; t !== void 0; t = t.n) if (t.S.i !== t.i || !t.S.h() || t.S.i !== t.i) return !0;
|
|
123
|
+
return !1;
|
|
124
|
+
}
|
|
125
|
+
function it(e) {
|
|
126
|
+
for (var t = e.s; t !== void 0; t = t.n) {
|
|
127
|
+
var o = t.S.n;
|
|
128
|
+
if (o !== void 0 && (t.r = o), t.S.n = t, t.i = -1, t.n === void 0) {
|
|
129
|
+
e.s = t;
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function ot(e) {
|
|
135
|
+
for (var t = e.s, o = void 0; t !== void 0; ) {
|
|
136
|
+
var l = t.p;
|
|
137
|
+
t.i === -1 ? (t.S.U(t), l !== void 0 && (l.n = t.n), t.n !== void 0 && (t.n.p = l)) : o = t, t.S.n = t.r, t.r !== void 0 && (t.r = void 0), t = l;
|
|
138
|
+
}
|
|
139
|
+
e.s = o;
|
|
140
|
+
}
|
|
141
|
+
function U(e, t) {
|
|
142
|
+
m.call(this, void 0), this.x = e, this.s = void 0, this.g = J - 1, this.f = 4, this.W = t == null ? void 0 : t.watched, this.Z = t == null ? void 0 : t.unwatched, this.name = t == null ? void 0 : t.name;
|
|
143
|
+
}
|
|
144
|
+
U.prototype = new m();
|
|
145
|
+
U.prototype.h = function() {
|
|
146
|
+
if (this.f &= -3, 1 & this.f) return !1;
|
|
147
|
+
if ((36 & this.f) == 32 || (this.f &= -5, this.g === J)) return !0;
|
|
148
|
+
if (this.g = J, this.f |= 1, this.i > 0 && !nt(this))
|
|
149
|
+
return this.f &= -2, !0;
|
|
150
|
+
var e = u;
|
|
151
|
+
try {
|
|
152
|
+
it(this), u = this;
|
|
153
|
+
var t = this.x();
|
|
154
|
+
(16 & this.f || this.v !== t || this.i === 0) && (this.v = t, this.f &= -17, this.i++);
|
|
155
|
+
} catch (o) {
|
|
156
|
+
this.v = o, this.f |= 16, this.i++;
|
|
157
|
+
}
|
|
158
|
+
return u = e, ot(this), this.f &= -2, !0;
|
|
159
|
+
};
|
|
160
|
+
U.prototype.S = function(e) {
|
|
161
|
+
if (this.t === void 0) {
|
|
162
|
+
this.f |= 36;
|
|
163
|
+
for (var t = this.s; t !== void 0; t = t.n) t.S.S(t);
|
|
164
|
+
}
|
|
165
|
+
m.prototype.S.call(this, e);
|
|
166
|
+
};
|
|
167
|
+
U.prototype.U = function(e) {
|
|
168
|
+
if (this.t !== void 0 && (m.prototype.U.call(this, e), this.t === void 0)) {
|
|
169
|
+
this.f &= -33;
|
|
170
|
+
for (var t = this.s; t !== void 0; t = t.n) t.S.U(t);
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
U.prototype.N = function() {
|
|
174
|
+
if (!(2 & this.f)) {
|
|
175
|
+
this.f |= 6;
|
|
176
|
+
for (var e = this.t; e !== void 0; e = e.x) e.t.N();
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
Object.defineProperty(U.prototype, "value", { get: function() {
|
|
180
|
+
if (1 & this.f) throw new Error("Cycle detected");
|
|
181
|
+
var e = et(this);
|
|
182
|
+
if (this.h(), e !== void 0 && (e.i = this.i), 16 & this.f) throw this.v;
|
|
183
|
+
return this.v;
|
|
184
|
+
} });
|
|
185
|
+
function Y(e, t) {
|
|
186
|
+
return new U(e, t);
|
|
187
|
+
}
|
|
188
|
+
function st(e) {
|
|
189
|
+
var t = e.u;
|
|
190
|
+
if (e.u = void 0, typeof t == "function") {
|
|
191
|
+
M++;
|
|
192
|
+
var o = u;
|
|
193
|
+
u = void 0;
|
|
194
|
+
try {
|
|
195
|
+
t();
|
|
196
|
+
} catch (l) {
|
|
197
|
+
throw e.f &= -2, e.f |= 8, K(e), l;
|
|
198
|
+
} finally {
|
|
199
|
+
u = o, W();
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
function K(e) {
|
|
204
|
+
for (var t = e.s; t !== void 0; t = t.n) t.S.U(t);
|
|
205
|
+
e.x = void 0, e.s = void 0, st(e);
|
|
206
|
+
}
|
|
207
|
+
function ct(e) {
|
|
208
|
+
if (u !== this) throw new Error("Out-of-order effect");
|
|
209
|
+
ot(this), u = e, this.f &= -2, 8 & this.f && K(this), W();
|
|
210
|
+
}
|
|
211
|
+
function T(e, t) {
|
|
212
|
+
this.x = e, this.u = void 0, this.s = void 0, this.o = void 0, this.f = 32, this.name = t == null ? void 0 : t.name;
|
|
213
|
+
}
|
|
214
|
+
T.prototype.c = function() {
|
|
215
|
+
var e = this.S();
|
|
216
|
+
try {
|
|
217
|
+
if (8 & this.f || this.x === void 0) return;
|
|
218
|
+
var t = this.x();
|
|
219
|
+
typeof t == "function" && (this.u = t);
|
|
220
|
+
} finally {
|
|
221
|
+
e();
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
T.prototype.S = function() {
|
|
225
|
+
if (1 & this.f) throw new Error("Cycle detected");
|
|
226
|
+
this.f |= 1, this.f &= -9, st(this), it(this), M++;
|
|
227
|
+
var e = u;
|
|
228
|
+
return u = this, ct.bind(this, e);
|
|
229
|
+
};
|
|
230
|
+
T.prototype.N = function() {
|
|
231
|
+
2 & this.f || (this.f |= 2, this.o = D, D = this);
|
|
232
|
+
};
|
|
233
|
+
T.prototype.d = function() {
|
|
234
|
+
this.f |= 8, 1 & this.f || K(this);
|
|
235
|
+
};
|
|
236
|
+
T.prototype.dispose = function() {
|
|
237
|
+
this.d();
|
|
238
|
+
};
|
|
239
|
+
function ut(e, t) {
|
|
240
|
+
var o = new T(e, t);
|
|
241
|
+
try {
|
|
242
|
+
o.c();
|
|
243
|
+
} catch (x) {
|
|
244
|
+
throw o.d(), x;
|
|
245
|
+
}
|
|
246
|
+
var l = o.d.bind(o);
|
|
247
|
+
return l[Symbol.dispose] = l, l;
|
|
248
|
+
}
|
|
249
|
+
function lt(e = {}) {
|
|
250
|
+
const t = (e.namespace ?? "default").trim() || "default", o = e.plugins ?? [], l = /* @__PURE__ */ new Map();
|
|
251
|
+
function x(S, j) {
|
|
252
|
+
return function() {
|
|
253
|
+
var _;
|
|
254
|
+
const N = `${t}:${S}`, E = l.get(S);
|
|
255
|
+
if (E) return E;
|
|
256
|
+
const P = j.state(), I = j.modules ?? {}, H = { ...P };
|
|
257
|
+
for (const [i, n] of Object.entries(I))
|
|
258
|
+
H[i] = n.state();
|
|
259
|
+
const h = ft(H), y = /* @__PURE__ */ new Map(), A = /* @__PURE__ */ new Map(), L = /* @__PURE__ */ new Map(), k = /* @__PURE__ */ new Map(), b = /* @__PURE__ */ new Map(), C = /* @__PURE__ */ new Set(), d = new Set(Object.keys(P)), a = new Set(Object.keys(j.getters ?? {})), p = new Set(Object.keys(j.actions ?? {})), w = (i) => h.value[i] ?? {}, q = (i, n) => {
|
|
260
|
+
h.value = {
|
|
261
|
+
...h.value,
|
|
262
|
+
[i]: n
|
|
263
|
+
};
|
|
264
|
+
}, rt = new Proxy(
|
|
265
|
+
{},
|
|
266
|
+
{
|
|
267
|
+
get(i, n) {
|
|
268
|
+
var r, f;
|
|
269
|
+
if (y.has(n)) return (r = y.get(n)) == null ? void 0 : r.value;
|
|
270
|
+
if (b.has(n)) return (f = b.get(n)) == null ? void 0 : f.value;
|
|
271
|
+
if (d.has(n)) return h.value[n];
|
|
272
|
+
const v = k.get(n);
|
|
273
|
+
return v ? w(v.moduleName)[v.key] : h.value[n];
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
);
|
|
277
|
+
for (const [i, n] of Object.entries(j.getters ?? {}))
|
|
278
|
+
y.set(
|
|
279
|
+
i,
|
|
280
|
+
Y(() => n(h.value, rt))
|
|
281
|
+
);
|
|
282
|
+
const F = (i, n) => {
|
|
283
|
+
var r;
|
|
284
|
+
for (const f of C) f(i);
|
|
285
|
+
for (const f of o)
|
|
286
|
+
(r = f.onMutation) == null || r.call(f, n, i);
|
|
287
|
+
}, G = (i, n, r, f) => {
|
|
288
|
+
const v = h.value[i];
|
|
289
|
+
Object.is(v, n) || (h.value = {
|
|
290
|
+
...h.value,
|
|
291
|
+
[i]: n
|
|
292
|
+
}, F(
|
|
293
|
+
{
|
|
294
|
+
namespace: t,
|
|
295
|
+
scopeId: N,
|
|
296
|
+
storeId: S,
|
|
297
|
+
key: i,
|
|
298
|
+
oldValue: v,
|
|
299
|
+
newValue: n,
|
|
300
|
+
origin: r
|
|
301
|
+
},
|
|
302
|
+
f
|
|
303
|
+
));
|
|
304
|
+
}, z = (i, n, r, f, v) => {
|
|
305
|
+
const g = w(i), s = g[n];
|
|
306
|
+
Object.is(s, r) || (q(i, {
|
|
307
|
+
...g,
|
|
308
|
+
[n]: r
|
|
309
|
+
}), F(
|
|
310
|
+
{
|
|
311
|
+
namespace: t,
|
|
312
|
+
scopeId: N,
|
|
313
|
+
storeId: S,
|
|
314
|
+
key: `${i}.${n}`,
|
|
315
|
+
oldValue: s,
|
|
316
|
+
newValue: r,
|
|
317
|
+
origin: f
|
|
318
|
+
},
|
|
319
|
+
v
|
|
320
|
+
));
|
|
321
|
+
}, V = {
|
|
322
|
+
$id: S,
|
|
323
|
+
$namespace: t,
|
|
324
|
+
$scopeId: N,
|
|
325
|
+
$subscribe(i) {
|
|
326
|
+
return C.add(i), () => C.delete(i);
|
|
327
|
+
},
|
|
328
|
+
$dispose() {
|
|
329
|
+
var i;
|
|
330
|
+
C.clear();
|
|
331
|
+
for (const n of o)
|
|
332
|
+
(i = n.onDispose) == null || i.call(n, $);
|
|
333
|
+
l.delete(S);
|
|
334
|
+
},
|
|
335
|
+
$patch(i, n = "local") {
|
|
336
|
+
Z(() => {
|
|
337
|
+
for (const [r, f] of Object.entries(i)) {
|
|
338
|
+
const v = k.get(r);
|
|
339
|
+
if (v) {
|
|
340
|
+
z(v.moduleName, v.key, f, n, $);
|
|
341
|
+
continue;
|
|
342
|
+
}
|
|
343
|
+
if (r.includes(".")) {
|
|
344
|
+
const [g, s] = r.split(".", 2);
|
|
345
|
+
if (I[g]) {
|
|
346
|
+
z(g, s, f, n, $);
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
if (I[r] && f && typeof f == "object" && !Array.isArray(f)) {
|
|
351
|
+
for (const [g, s] of Object.entries(f))
|
|
352
|
+
z(r, g, s, n, $);
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
G(r, f, n, $);
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
},
|
|
359
|
+
$snapshot() {
|
|
360
|
+
return { ...h.value };
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
for (const [i, n] of Object.entries(I)) {
|
|
364
|
+
const r = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Map(), v = new Proxy(
|
|
365
|
+
{},
|
|
366
|
+
{
|
|
367
|
+
get(s, c) {
|
|
368
|
+
var O, R, Q;
|
|
369
|
+
if (r.has(c)) return (O = r.get(c)) == null ? void 0 : O.value;
|
|
370
|
+
if (y.has(c)) return (R = y.get(c)) == null ? void 0 : R.value;
|
|
371
|
+
if (b.has(c)) return (Q = b.get(c)) == null ? void 0 : Q.value;
|
|
372
|
+
const X = w(i);
|
|
373
|
+
if (c in X) return X[c];
|
|
374
|
+
if (d.has(c)) return h.value[c];
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
);
|
|
378
|
+
for (const [s, c] of Object.entries(n.getters ?? {}))
|
|
379
|
+
r.set(
|
|
380
|
+
s,
|
|
381
|
+
Y(() => c(w(i), h.value, v))
|
|
382
|
+
);
|
|
383
|
+
let g;
|
|
384
|
+
for (const [s, c] of Object.entries(n.actions ?? {}))
|
|
385
|
+
f.set(s, (...O) => Z(() => c.apply(g, O)));
|
|
386
|
+
g = new Proxy(
|
|
387
|
+
{},
|
|
388
|
+
{
|
|
389
|
+
get(s, c) {
|
|
390
|
+
var O;
|
|
391
|
+
if (f.has(c)) return f.get(c);
|
|
392
|
+
if (r.has(c)) return (O = r.get(c)) == null ? void 0 : O.value;
|
|
393
|
+
const R = w(i);
|
|
394
|
+
return c in R ? R[c] : $[c];
|
|
395
|
+
},
|
|
396
|
+
set(s, c, O) {
|
|
397
|
+
if (f.has(c) || r.has(c)) return !1;
|
|
398
|
+
const R = w(i);
|
|
399
|
+
return c in R ? z(i, c, O, "local", $) : $[c] = O, !0;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
), L.set(i, g), A.set(i, r);
|
|
403
|
+
for (const s of Object.keys(w(i)))
|
|
404
|
+
!(d.has(s) || a.has(s) || p.has(s) || Reflect.has(V, s) || I[s] !== void 0) && !k.has(s) && k.set(s, { moduleName: i, key: s });
|
|
405
|
+
for (const [s, c] of r.entries())
|
|
406
|
+
!(d.has(s) || a.has(s) || p.has(s) || Reflect.has(V, s) || I[s] !== void 0) && !b.has(s) && b.set(s, c);
|
|
407
|
+
for (const [s, c] of f.entries())
|
|
408
|
+
!(d.has(s) || a.has(s) || p.has(s) || Reflect.has(V, s) || I[s] !== void 0) && !Reflect.has(V, s) && (V[s] = c);
|
|
409
|
+
}
|
|
410
|
+
const $ = new Proxy(V, {
|
|
411
|
+
get(i, n, r) {
|
|
412
|
+
var f, v;
|
|
413
|
+
if (Reflect.has(i, n)) return Reflect.get(i, n, r);
|
|
414
|
+
if (L.has(n)) return L.get(n);
|
|
415
|
+
if (y.has(n)) return (f = y.get(n)) == null ? void 0 : f.value;
|
|
416
|
+
if (b.has(n)) return (v = b.get(n)) == null ? void 0 : v.value;
|
|
417
|
+
if (d.has(n)) return h.value[n];
|
|
418
|
+
const g = k.get(n);
|
|
419
|
+
return g ? w(g.moduleName)[g.key] : h.value[n];
|
|
420
|
+
},
|
|
421
|
+
set(i, n, r, f) {
|
|
422
|
+
if (Reflect.has(i, n))
|
|
423
|
+
return Reflect.set(i, n, r, f);
|
|
424
|
+
const v = k.get(n);
|
|
425
|
+
return v ? (z(v.moduleName, v.key, r, "local", f), !0) : (G(n, r, "local", f), !0);
|
|
426
|
+
}
|
|
427
|
+
});
|
|
428
|
+
for (const [i, n] of Object.entries(j.actions ?? {}))
|
|
429
|
+
V[i] = (...r) => Z(() => n.apply($, r));
|
|
430
|
+
for (const i of o)
|
|
431
|
+
(_ = i.onInit) == null || _.call(i, $);
|
|
432
|
+
return l.set(S, $), $;
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
return {
|
|
436
|
+
defineStore: x,
|
|
437
|
+
use(S) {
|
|
438
|
+
o.push(S);
|
|
439
|
+
}
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
lt();
|
|
443
|
+
function dt(e = {}) {
|
|
444
|
+
const t = e.channelName ?? "storix-sync", o = new Set(e.include ?? []), l = new Set(e.exclude ?? []), x = e.namespaces ?? [], S = x === "*" ? null : new Set(x), j = e.debounce ?? 16, _ = crypto.randomUUID(), N = `__storix_sync__:${t}`, E = /* @__PURE__ */ new Map(), P = /* @__PURE__ */ new Set(), I = /* @__PURE__ */ new Map(), H = /* @__PURE__ */ new Map();
|
|
445
|
+
let h = null;
|
|
446
|
+
const y = typeof window < "u" && "BroadcastChannel" in window ? new BroadcastChannel(t) : null, A = (d) => {
|
|
447
|
+
const a = [d.$id, d.$scopeId];
|
|
448
|
+
return !(a.some((p) => l.has(p)) || o.size > 0 && !a.some((p) => o.has(p)));
|
|
449
|
+
}, L = (d, a) => a === d || S === null ? !0 : S.has(a), k = (d, a) => {
|
|
450
|
+
!a || a.originTabId === _ || L(d.$namespace, a.namespace) && a.storeId === d.$id && A(d) && d.$patch({ [a.key]: a.newValue }, "remote");
|
|
451
|
+
}, b = () => {
|
|
452
|
+
if (h = null, E.size === 0) return;
|
|
453
|
+
const d = Array.from(E.values());
|
|
454
|
+
E.clear();
|
|
455
|
+
for (const a of d) {
|
|
456
|
+
const p = {
|
|
457
|
+
...a,
|
|
458
|
+
originTabId: _
|
|
459
|
+
};
|
|
460
|
+
if (y && y.postMessage(p), typeof window < "u" && "localStorage" in window)
|
|
461
|
+
try {
|
|
462
|
+
window.localStorage.setItem(N, JSON.stringify(p)), window.localStorage.removeItem(N);
|
|
463
|
+
} catch {
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}, C = (d) => {
|
|
467
|
+
if (E.set(`${d.scopeId}:${d.key}`, d), j <= 0) {
|
|
468
|
+
b();
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
h || (h = setTimeout(b, j));
|
|
472
|
+
};
|
|
473
|
+
return {
|
|
474
|
+
name: "sync",
|
|
475
|
+
onInit(d) {
|
|
476
|
+
const a = d;
|
|
477
|
+
if (A(a)) {
|
|
478
|
+
if (P.add(a.$scopeId), y) {
|
|
479
|
+
const p = (w) => {
|
|
480
|
+
k(a, w.data);
|
|
481
|
+
};
|
|
482
|
+
I.set(a.$scopeId, p), y.addEventListener("message", p);
|
|
483
|
+
}
|
|
484
|
+
if (typeof window < "u") {
|
|
485
|
+
const p = (w) => {
|
|
486
|
+
if (!(w.key !== N || !w.newValue))
|
|
487
|
+
try {
|
|
488
|
+
const q = JSON.parse(w.newValue);
|
|
489
|
+
k(a, q);
|
|
490
|
+
} catch {
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
H.set(a.$scopeId, p), window.addEventListener("storage", p);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
},
|
|
497
|
+
onMutation(d, a) {
|
|
498
|
+
a.origin !== "remote" && A(d) && C(a);
|
|
499
|
+
},
|
|
500
|
+
onDispose(d) {
|
|
501
|
+
const a = d;
|
|
502
|
+
P.delete(a.$scopeId);
|
|
503
|
+
const p = I.get(a.$scopeId);
|
|
504
|
+
y && p && (y.removeEventListener("message", p), I.delete(a.$scopeId));
|
|
505
|
+
const w = H.get(a.$scopeId);
|
|
506
|
+
typeof window < "u" && w && (window.removeEventListener("storage", w), H.delete(a.$scopeId)), h && (clearTimeout(h), h = null), b(), P.size === 0 && (y == null || y.close());
|
|
507
|
+
}
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
export {
|
|
511
|
+
dt as syncPlugin
|
|
512
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@storix-js/sync",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.cjs",
|
|
6
|
+
"module": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"require": "./dist/index.cjs"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "vite build && tsc -p tsconfig.build.json --emitDeclarationOnly",
|
|
17
|
+
"dev": "vite build --watch",
|
|
18
|
+
"test": "vitest run",
|
|
19
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@storix-js/core": "workspace:*"
|
|
23
|
+
}
|
|
24
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { definePlugin, type MutationPayload } from '@storix-js/core';
|
|
2
|
+
|
|
3
|
+
export interface SyncPluginOptions {
|
|
4
|
+
channelName?: string;
|
|
5
|
+
include?: string[];
|
|
6
|
+
exclude?: string[];
|
|
7
|
+
namespaces?: string[] | '*';
|
|
8
|
+
conflict?: 'last-write-wins';
|
|
9
|
+
debounce?: number;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
type ScopedStore = {
|
|
13
|
+
$id: string;
|
|
14
|
+
$namespace: string;
|
|
15
|
+
$scopeId: string;
|
|
16
|
+
$patch: (patch: Record<string, unknown>, origin?: 'local' | 'remote') => void;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export function syncPlugin(options: SyncPluginOptions = {}) {
|
|
20
|
+
const channelName = options.channelName ?? 'storix-sync';
|
|
21
|
+
const include = new Set(options.include ?? []);
|
|
22
|
+
const exclude = new Set(options.exclude ?? []);
|
|
23
|
+
const namespaceSelection = options.namespaces ?? [];
|
|
24
|
+
const allowedNamespaces = namespaceSelection === '*' ? null : new Set(namespaceSelection);
|
|
25
|
+
const debounceMs = options.debounce ?? 16;
|
|
26
|
+
const tabId = crypto.randomUUID();
|
|
27
|
+
const storageEventKey = `__storix_sync__:${channelName}`;
|
|
28
|
+
const queued = new Map<string, MutationPayload>();
|
|
29
|
+
const activeStoreIds = new Set<string>();
|
|
30
|
+
const messageHandlers = new Map<string, (event: MessageEvent<unknown>) => void>();
|
|
31
|
+
const storageHandlers = new Map<string, (event: StorageEvent) => void>();
|
|
32
|
+
|
|
33
|
+
let flushTimer: ReturnType<typeof setTimeout> | null = null;
|
|
34
|
+
const channel = typeof window !== 'undefined' && 'BroadcastChannel' in window
|
|
35
|
+
? new BroadcastChannel(channelName)
|
|
36
|
+
: null;
|
|
37
|
+
|
|
38
|
+
const shouldSyncStore = (store: ScopedStore) => {
|
|
39
|
+
const ids = [store.$id, store.$scopeId];
|
|
40
|
+
if (ids.some((value) => exclude.has(value))) return false;
|
|
41
|
+
if (include.size > 0 && !ids.some((value) => include.has(value))) return false;
|
|
42
|
+
return true;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const shouldAcceptNamespace = (targetNamespace: string, sourceNamespace: string) => {
|
|
46
|
+
if (sourceNamespace === targetNamespace) return true;
|
|
47
|
+
if (allowedNamespaces === null) return true;
|
|
48
|
+
return allowedNamespaces.has(sourceNamespace);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const processIncomingMessage = (store: ScopedStore, payload: MutationPayload & { originTabId?: string }) => {
|
|
52
|
+
if (!payload || payload.originTabId === tabId) return;
|
|
53
|
+
if (!shouldAcceptNamespace(store.$namespace, payload.namespace)) return;
|
|
54
|
+
if (payload.storeId !== store.$id) return;
|
|
55
|
+
if (!shouldSyncStore(store)) return;
|
|
56
|
+
store.$patch({ [payload.key]: payload.newValue }, 'remote');
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const flush = () => {
|
|
60
|
+
flushTimer = null;
|
|
61
|
+
if (queued.size === 0) return;
|
|
62
|
+
|
|
63
|
+
const payloads = Array.from(queued.values());
|
|
64
|
+
queued.clear();
|
|
65
|
+
|
|
66
|
+
for (const payload of payloads) {
|
|
67
|
+
const message = {
|
|
68
|
+
...payload,
|
|
69
|
+
originTabId: tabId
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
if (channel) {
|
|
73
|
+
channel.postMessage(message);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (typeof window !== 'undefined' && 'localStorage' in window) {
|
|
77
|
+
try {
|
|
78
|
+
window.localStorage.setItem(storageEventKey, JSON.stringify(message));
|
|
79
|
+
window.localStorage.removeItem(storageEventKey);
|
|
80
|
+
} catch {
|
|
81
|
+
// Ignore quota/security exceptions.
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const queue = (payload: MutationPayload) => {
|
|
88
|
+
queued.set(`${payload.scopeId}:${payload.key}`, payload);
|
|
89
|
+
|
|
90
|
+
if (debounceMs <= 0) {
|
|
91
|
+
flush();
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (!flushTimer) {
|
|
96
|
+
flushTimer = setTimeout(flush, debounceMs);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
return definePlugin({
|
|
101
|
+
name: 'sync',
|
|
102
|
+
onInit(store) {
|
|
103
|
+
const scopedStore = store as ScopedStore;
|
|
104
|
+
if (!shouldSyncStore(scopedStore)) return;
|
|
105
|
+
activeStoreIds.add(scopedStore.$scopeId);
|
|
106
|
+
|
|
107
|
+
if (channel) {
|
|
108
|
+
const messageHandler = (event: MessageEvent<unknown>) => {
|
|
109
|
+
processIncomingMessage(scopedStore, event.data as MutationPayload & { originTabId?: string });
|
|
110
|
+
};
|
|
111
|
+
messageHandlers.set(scopedStore.$scopeId, messageHandler);
|
|
112
|
+
channel.addEventListener('message', messageHandler);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (typeof window !== 'undefined') {
|
|
116
|
+
const storageHandler = (event: StorageEvent) => {
|
|
117
|
+
if (event.key !== storageEventKey || !event.newValue) return;
|
|
118
|
+
try {
|
|
119
|
+
const payload = JSON.parse(event.newValue) as MutationPayload & { originTabId?: string };
|
|
120
|
+
processIncomingMessage(scopedStore, payload);
|
|
121
|
+
} catch {
|
|
122
|
+
// Ignore malformed payloads.
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
storageHandlers.set(scopedStore.$scopeId, storageHandler);
|
|
126
|
+
window.addEventListener('storage', storageHandler);
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
onMutation(store, mutation) {
|
|
130
|
+
if (mutation.origin === 'remote') return;
|
|
131
|
+
if (!shouldSyncStore(store as ScopedStore)) return;
|
|
132
|
+
queue(mutation);
|
|
133
|
+
},
|
|
134
|
+
onDispose(store) {
|
|
135
|
+
const scopedStore = store as ScopedStore;
|
|
136
|
+
activeStoreIds.delete(scopedStore.$scopeId);
|
|
137
|
+
|
|
138
|
+
const messageHandler = messageHandlers.get(scopedStore.$scopeId);
|
|
139
|
+
if (channel && messageHandler) {
|
|
140
|
+
channel.removeEventListener('message', messageHandler);
|
|
141
|
+
messageHandlers.delete(scopedStore.$scopeId);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const storageHandler = storageHandlers.get(scopedStore.$scopeId);
|
|
145
|
+
if (typeof window !== 'undefined' && storageHandler) {
|
|
146
|
+
window.removeEventListener('storage', storageHandler);
|
|
147
|
+
storageHandlers.delete(scopedStore.$scopeId);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (flushTimer) {
|
|
151
|
+
clearTimeout(flushTimer);
|
|
152
|
+
flushTimer = null;
|
|
153
|
+
}
|
|
154
|
+
flush();
|
|
155
|
+
|
|
156
|
+
if (activeStoreIds.size === 0) {
|
|
157
|
+
channel?.close();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
package/tsconfig.json
ADDED
package/vite.config.ts
ADDED