sinho 0.2.1 → 0.2.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.
- package/dist/bundle.d.ts +3 -2
- package/dist/bundle.js +61 -54
- package/dist/bundle.min.js +1 -1
- package/dist/scope.d.ts +3 -2
- package/dist/scope.js +61 -54
- package/dist/scope.js.map +1 -1
- package/package.json +1 -1
- package/src/scope.ts +63 -65
package/dist/bundle.d.ts
CHANGED
|
@@ -40,9 +40,10 @@ interface SubscopeOptions {
|
|
|
40
40
|
details?: object;
|
|
41
41
|
}
|
|
42
42
|
interface Effect {
|
|
43
|
+
_scope: Scope;
|
|
44
|
+
_pure: boolean;
|
|
43
45
|
_clean?: Cleanup;
|
|
44
46
|
_deps: Set<Signal<unknown>>;
|
|
45
|
-
_scope: Scope;
|
|
46
47
|
_run(): void;
|
|
47
48
|
}
|
|
48
49
|
/**
|
|
@@ -71,7 +72,7 @@ declare const useSignal: (<T>(value: T, opts?: SetSignalOptions) => readonly [Si
|
|
|
71
72
|
* and updated at the same time.
|
|
72
73
|
*/
|
|
73
74
|
declare const useBatch: <T>(fn: () => T) => T;
|
|
74
|
-
declare
|
|
75
|
+
declare const flushBatch: () => void;
|
|
75
76
|
/**
|
|
76
77
|
* Creates a memoized signal.
|
|
77
78
|
*
|
package/dist/bundle.js
CHANGED
|
@@ -61,11 +61,12 @@ const useSignal = (value, opts) => {
|
|
|
61
61
|
if (innerOpts?.force) {
|
|
62
62
|
value = newValue;
|
|
63
63
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
else {
|
|
65
|
+
currBatch._setters.push(() => (value = newValue));
|
|
66
|
+
}
|
|
67
|
+
if (!innerOpts?.silent) {
|
|
68
|
+
signal._effects.forEach((effect) => currBatch._effects.add(effect));
|
|
69
|
+
}
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
72
|
else {
|
|
@@ -81,50 +82,42 @@ const useSignal = (value, opts) => {
|
|
|
81
82
|
* and updated at the same time.
|
|
82
83
|
*/
|
|
83
84
|
const useBatch = (fn) => {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
85
|
+
if (currBatch)
|
|
86
|
+
return fn();
|
|
87
|
+
currBatch = { _setters: [], _effects: new Set() };
|
|
88
|
+
try {
|
|
89
|
+
const result = fn();
|
|
89
90
|
flushBatch();
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
finally {
|
|
90
94
|
currBatch = undefined;
|
|
91
95
|
}
|
|
92
|
-
return result;
|
|
93
96
|
};
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
while (currBatch &&
|
|
97
|
+
const flushBatch = () => {
|
|
98
|
+
a: while (currBatch &&
|
|
97
99
|
(currBatch._setters.length > 0 || currBatch._effects.size > 0)) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
currBatch._effects = new Set();
|
|
101
|
-
// Collect and clean effects
|
|
102
|
-
for (const [signal, , silent] of currBatch._setters) {
|
|
103
|
-
if (!silent) {
|
|
104
|
-
signal._effects.forEach((effect) => {
|
|
105
|
-
effect._clean?.();
|
|
106
|
-
effects.add(effect);
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
}
|
|
100
|
+
// Clean effect subscope
|
|
101
|
+
currBatch._effects.forEach((effect) => effect._clean?.());
|
|
110
102
|
// Run signal updates
|
|
111
|
-
|
|
112
|
-
setter();
|
|
113
|
-
mutatedSignals.add(signal);
|
|
114
|
-
}
|
|
103
|
+
currBatch._setters.forEach((setter) => setter());
|
|
115
104
|
currBatch._setters = [];
|
|
116
|
-
// Run
|
|
117
|
-
for (const effect of
|
|
118
|
-
if (
|
|
119
|
-
[...effect._deps].every((dep) => mutatedSignals.has(dep))) {
|
|
105
|
+
// Run next effect
|
|
106
|
+
for (const effect of currBatch._effects) {
|
|
107
|
+
if (effect._pure) {
|
|
120
108
|
effect._run();
|
|
109
|
+
currBatch._effects.delete(effect);
|
|
110
|
+
continue a;
|
|
121
111
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
112
|
+
}
|
|
113
|
+
for (const effect of currBatch._effects) {
|
|
114
|
+
effect._run();
|
|
115
|
+
currBatch._effects.delete(effect);
|
|
116
|
+
break;
|
|
125
117
|
}
|
|
126
118
|
}
|
|
127
|
-
}
|
|
119
|
+
};
|
|
120
|
+
let pureEffectFlag = false;
|
|
128
121
|
/**
|
|
129
122
|
* Creates an effect which will rerun when any accessed signal changes.
|
|
130
123
|
*
|
|
@@ -134,6 +127,7 @@ const useEffect = (fn, deps) => {
|
|
|
134
127
|
const untracked = !!deps;
|
|
135
128
|
const effect = {
|
|
136
129
|
_scope: currScope,
|
|
130
|
+
_pure: pureEffectFlag,
|
|
137
131
|
_deps: new Set(),
|
|
138
132
|
_run() {
|
|
139
133
|
const prevEffect = currEffect;
|
|
@@ -182,10 +176,16 @@ const useEffect = (fn, deps) => {
|
|
|
182
176
|
const useMemo = (fn, opts) => {
|
|
183
177
|
const [memo, setMemo] = useSignal();
|
|
184
178
|
let firstTime = true;
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
179
|
+
pureEffectFlag = true;
|
|
180
|
+
try {
|
|
181
|
+
useEffect(() => {
|
|
182
|
+
setMemo(fn, firstTime ? { ...opts, force: true } : opts);
|
|
183
|
+
firstTime = false;
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
finally {
|
|
187
|
+
pureEffectFlag = false;
|
|
188
|
+
}
|
|
189
189
|
return memo;
|
|
190
190
|
};
|
|
191
191
|
/**
|
|
@@ -195,21 +195,28 @@ const useMemo = (fn, opts) => {
|
|
|
195
195
|
* @returns A function to manually destroy the subscope.
|
|
196
196
|
*/
|
|
197
197
|
const useSubscope = (fn, opts) => {
|
|
198
|
+
const prevBatch = currBatch;
|
|
199
|
+
currBatch = undefined;
|
|
198
200
|
const parent = currScope;
|
|
199
201
|
const scope = createScope(parent);
|
|
200
202
|
Object.assign(scope._details, opts?.details);
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
203
|
+
try {
|
|
204
|
+
parent._subscopes.push(scope);
|
|
205
|
+
const result = scope._run(fn);
|
|
206
|
+
return [
|
|
207
|
+
result,
|
|
208
|
+
() => {
|
|
209
|
+
const index = parent._subscopes.indexOf(scope);
|
|
210
|
+
if (index >= 0) {
|
|
211
|
+
parent._subscopes.splice(index, 1);
|
|
212
|
+
}
|
|
213
|
+
scope._cleanup();
|
|
214
|
+
},
|
|
215
|
+
];
|
|
216
|
+
}
|
|
217
|
+
finally {
|
|
218
|
+
currBatch = prevBatch;
|
|
219
|
+
}
|
|
213
220
|
};
|
|
214
221
|
/**
|
|
215
222
|
* Creates a new signal with write capabilities.
|
package/dist/bundle.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const t=t=>({t:t,o:[],i:[],l:{...t?.l},u(t){const n=o;o=this;try{return t()}finally{o=n}},h(){for(let t=this.i.length-1;t>=0;t--)this.i[t].h();this.i=[];for(let t=this.o.length-1;t>=0;t--){const n=this.o[t];n._?.(),n.u=()=>{},n.p.forEach((t=>t.o.delete(n))),n.p.clear()}this.o=[]}});let n,e,o=t(),s=!1;const r=()=>o,c=(t,o)=>{const r=()=>(!s&&n&&(n.p.add(r),r.o.add(n)),r.peek());r.o=new Set,r.peek=()=>t;const c=(n,s)=>{if(s={...o,...s},e){const o="function"==typeof n?n(r.peek()):n;(s?.force||o!==r.peek())&&(s?.force
|
|
1
|
+
const t=t=>({t:t,o:[],i:[],l:{...t?.l},u(t){const n=o;o=this;try{return t()}finally{o=n}},h(){for(let t=this.i.length-1;t>=0;t--)this.i[t].h();this.i=[];for(let t=this.o.length-1;t>=0;t--){const n=this.o[t];n._?.(),n.u=()=>{},n.p.forEach((t=>t.o.delete(n))),n.p.clear()}this.o=[]}});let n,e,o=t(),s=!1;const r=()=>o,c=(t,o)=>{const r=()=>(!s&&n&&(n.p.add(r),r.o.add(n)),r.peek());r.o=new Set,r.peek=()=>t;const c=(n,s)=>{if(s={...o,...s},e){const o="function"==typeof n?n(r.peek()):n;(s?.force||o!==r.peek())&&(s?.force?t=o:e.m.push((()=>t=o)),s?.silent||r.o.forEach((t=>e.o.add(t))))}else i((()=>c(n,s)))};return[r,c]},i=t=>{if(e)return t();e={m:[],o:new Set};try{const n=t();return l(),n}finally{e=void 0}},l=()=>{t:for(;e&&(e.m.length>0||e.o.size>0);){e.o.forEach((t=>t._?.())),e.m.forEach((t=>t())),e.m=[];for(const t of e.o)if(t.v){t.u(),e.o.delete(t);continue t}for(const t of e.o){t.u(),e.o.delete(t);break}}};let u=!1;const f=(t,e)=>{const r=!!e,c={S:o,v:u,p:new Set,u(){const o=n,c=s;n=this;try{this.p.forEach((t=>t.o.delete(this))),this.p.clear(),e&&(s=!1,e.forEach((t=>t()))),s=r,this._?.();const n=this.S.u((()=>i(t)));this._=n?()=>{this.S.u((()=>i(n))),this._=null}:null}finally{n=o,s=c}}};o.o.push(c),c.u(),c.p.size||c._||o.o.pop()},a=(t,n)=>{const[e,o]=c();let s=!0;u=!0;try{f((()=>{o(t,s?{...n,force:!0}:n),s=!1}))}finally{u=!1}return e},d=(n,s)=>{const r=e;e=void 0;const c=o,i=t(c);Object.assign(i.l,s?.details);try{c.i.push(i);return[i.u(n),()=>{const t=c.i.indexOf(i);t>=0&&c.i.splice(t,1),i.h()}]}finally{e=r}},h=(t,n)=>{const[e,o]=c(t,n);return e.set=o,e},_={upgrade:t=>()=>_.get(t),get:t=>"function"==typeof t?t():t,peek(t){const n=s;s=!0;try{return this.get(t)}finally{s=n}}},p=(t={})=>({M:[],k(t){return this.C?.next().value??t()},...t}),m=()=>{const t=r();return t.l.N??=p()},y=(t,n)=>{const e=m(),o=p({...e,...t}),[s,r]=d(n,{details:{N:o}});return f((()=>r)),s},w=t=>(t[0]??"").toLowerCase()+t.slice(1).replace(/[A-Z]/g,(t=>"-"+t.toLowerCase())),b=t=>t.startsWith("on:")?t.slice(3):w(t.slice(2)),g=Symbol(),v=(t,n)=>({[g]:Math.random().toString(36).slice(2),j:t,H:n}),x=t=>!!t?.[g],S=(t,n,e)=>{n.addEventListener(t[g],(t=>{const n=_.get(e);void 0!==n&&(t.stopPropagation(),t.detail(n))}))},M=t=>{const n=m();return a((()=>{let e=t.j;return n.L?.dispatchEvent(new CustomEvent(t[g],{detail:t=>e=t,bubbles:!0,composed:!0})),e}))},k=(t,n)=>({T:"p",A:t,...n}),C=(t=CustomEvent)=>({T:"e",O:t}),E=Symbol();let N;const j=(t,n)=>{N?N.push([t,n]):f(t,n)},H=(t,n={},e={})=>{const o=[],s=new Map;for(const t in n){const e=n[t];if("p"==e.T&&e.attribute){"function"==typeof e.attribute&&(e.attribute={transform:e.attribute});const n=e.attribute={name:w(t),static:!1,transform:t=>t,...e.attribute};s.set(n.name,{name:t,meta:e}),n.static||o.push(n.name)}}e.shadow??={mode:"open"};class i extends HTMLElement{static[E]={D:t};static observedAttributes=o;props={};events={};[E]={};constructor(){super();for(const t in n){const e=n[t];if("p"==e.T){const n=x(e.A)?e.A:null,[o,s]=c(n?void 0:e.A);this.props[t]=o,n&&S(n,this,o),Object.defineProperty(this,t,{get:o.peek,set:t=>s((()=>t),{force:!0})})}else if("e"==e.T&&t.startsWith("on")){const n=b(t);this.events[t]=t=>this.dispatchEvent(new e.O(n,t))}}}connectedCallback(){const t=(n=this,e.shadow?n.shadowRoot??n.attachShadow(e.shadow):n);var n;this[E].I=d((()=>y({$:!1,L:this,C:t.childNodes.values()},(()=>{this[E].S=r();const n=N;N=[];try{t?.append(...this.render().build()),N.forEach((([t,n])=>f(t,n)))}finally{N=n}}))))[1]}disconnectedCallback(){this[E].I?.()}attributeChangedCallback(t,n,e){const o=s.get(t);o&&(this[o.name]=null!=e?o.meta.attribute.transform.call(this,e):x(o.meta.A)?void 0:o.meta.A)}}return i},L=t=>!!t?.[E],T=(...t)=>{const[n,e]="string"==typeof t[0]?[t[0],t.slice(1)]:["",t];for(const t of e)customElements.define(n+t[E].D,t)},A=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,O=(t,n,e)=>{"-"==n[0]?t.style.setProperty(n,""+e):t.style[n]=null==e?"":"number"!=typeof e||A.test(n)?""+e:e+"px"},D=(t,n,e,o)=>{const s=null==e||!1===e&&!n.includes("-");if(n.startsWith("prop:"))t[n.slice(5)]=e;else if(n.startsWith("attr:"))n=n.slice(5),s?t.removeAttribute(n):t.setAttribute(n,e);else if(!["innerHTML","outerHTML"].includes(n)){if(!["tabIndex","role",...o?["width","height","href","list","form","download","rowSpan","colSpan"]:[]].includes(n)&&n in t)try{return void(t[n]=e)}catch(t){}"function"==typeof e||(s?t.removeAttribute(n):t.setAttribute(n,e))}},I=t=>({build(){const n=t();return n.build?.()??n}}),$=({text:t,marker:n})=>I((()=>{const e=m(),o=n&&e.k((()=>document.createComment(""))),s=e.k((()=>document.createTextNode("")));return f((()=>{const n=""+(_.get(t)??"");s.textContent!=n&&(s.textContent=n)})),o?[o,s]:[s]})),z=({children:t})=>I((()=>Array.isArray(t)?t.flatMap((t=>z({children:t}).build())):null==t?[]:"object"==typeof t?t:$({text:t}))),P=(t,n,e,o)=>{const{ref:s,style:c,children:l,dangerouslySetInnerHTML:u,...a}=e;for(const n in c??{}){const e=c[n];f((()=>{O(t,n,_.get(e))}))}for(const n in a){const e=a[n];if(n.startsWith("on")){const o=r(),s=t=>{o.u((()=>i((()=>e(t)))))},c=b(n);f((()=>(t.addEventListener(c,s),()=>t.removeEventListener(c,s))))}else f((()=>{D(t,n,_.get(e),o)}))}return u&&f((()=>{const n=_.get(u).__html;t.innerHTML!=n&&(t.innerHTML=n)})),s&&f((()=>(s.set(t),()=>s.set(void 0)))),null!=e.children&&t.append(...y({$:n,C:t.childNodes.values()},(()=>z({children:e.children}).build()))),t},V=(t,n={},e)=>(null!=e&&(n.children=e),L(t)?((t,n)=>I((()=>{const e=m().k((()=>new t));return customElements.upgrade(e),P(e,!1,n),[e]})))(t,n):"function"==typeof t?I((()=>t(n))):((t,n={})=>I((()=>{const e=m(),o="svg"==t||!!e.$;return[P(e.k((()=>o?document.createElementNS("http://www.w3.org/2000/svg",t):document.createElement(t))),o,n,!0)]})))(t,n)),Z=new Proxy(V,{get:(t,n)=>(e,o)=>t(n,e,o)}),q=(t,n)=>{const[e,o]=c({P:[],V:new Map});let s=new Map;return f((()=>{const e=[],r=s,c=((t,n)=>{const e=new Map;for(let o=0;o<t.length;o++){const s=n(t[o],o);if(e.has(s))throw Error(`Duplicate key '${s}'`);e.set(s,o)}return e})(t(),n),i=(t=NaN)=>e.map((t=>"r"==t.Z?n=>n<t.q?n:n==t.q?NaN:n-1:"a"==t.Z?n=>n<t.q?n:n+1:"m"==t.Z?n=>t.B<=n&&n<t.F?n+1:n==t.F?t.B:n:t=>t)).reduce(((t,n)=>n(t)),t);for(const t of r.keys()){const n=i(r.get(t));c.has(t)||e.push({Z:"r",G:t,q:n})}for(let o=0;o<t().length;o++){const s=n(t()[o],o),c=i(r.get(s));isNaN(c)?e.push({Z:"a",G:s,q:o}):c!=o&&e.push({Z:"m",G:s,F:c,B:o})}e.length>0&&o({P:e,V:c}),s=c})),e},B=t=>I((()=>{const n=m(),e=_.upgrade(t.each??[]),o=n.k((()=>document.createComment(""))),s=t.key??((t,n)=>n),r=[o],i=new Map,l=q(e,s),u=t=>{for(let n=t-1;n>=0;n--){const n=s(e()[t-1],t-1),o=i.get(n)?.J??[];if(o.length>0)return o[o.length-1]}return o};return f((()=>{for(const n of l().P)if("r"==n.Z){const{J:t=[],I:e}=i.get(n.G)??{};e?.();const o=r.indexOf(t[0]);o>0&&r.splice(o,t.length),t.forEach((t=>t.parentNode?.removeChild(t))),i.delete(n.G)}else if("a"==n.Z){let o=[];const[,s]=d((()=>{const[s,i]=c(n.q),[a,d]=c(e()[n.q]);f((()=>{0<=s()&&s()<e().length&&d((()=>e()[s()]))})),f((()=>{const t=l().V.get(n.G);null!=t&&i(t)})),o=t.children?.(a,s,e).build()??[];const h=u(n.q),_=r.indexOf(h);_>=0&&r.splice(_+1,0,...o),o.forEach((t=>h.parentNode?.insertBefore(t,h.nextSibling)))}));i.set(n.G,{J:o,I:s})}else if("m"==n.Z){const{J:t=[]}=i.get(n.G)??{},e=r.indexOf(t[0]);e>=0&&r.splice(e,t.length);const o=u(n.B),s=r.indexOf(o);s>=0&&r.splice(s+1,0,...t),t.forEach((t=>o.parentNode?.insertBefore(t,o.nextSibling)))}}),[l]),r})),F=t=>(m().M=[],G({condition:t.condition,children:t.children})),G=t=>{const n=m(),e=n.M,o=a((()=>e.every((t=>!t()))&&_.get(t.condition)));return n.M=[...e,o],y({M:[]},(()=>I((()=>{const e=n.k((()=>document.createComment(""))),s=[e],r=a((()=>o()?z({children:t.children}):null));let c=[];return f((()=>{c.forEach((t=>t.parentNode?.removeChild(t))),s.length=1;const[,t]=d((()=>{c=r()?.build()??[],e.after(...c),s.push(...c)}));return t}),[r]),s}))))},J=({children:t})=>G({condition:!0,children:t}),K=({mount:t,children:n})=>I((()=>y({C:void 0},(()=>{const e=z({children:n}).build();return f((()=>(e.forEach((n=>t.appendChild(n))),()=>{e.forEach((t=>t.parentNode?.removeChild(t)))}))),[]})))),Q=Symbol(),R=new Map,U=t=>{const n=t.children;if("function"==typeof n){const e=V("style",{},$({text:n,marker:!1}));return t.light?K({mount:document.head,children:e}):e}if(n){const o=m(),s=t.light?document:o.L?.shadowRoot??document,r=((t,n,e)=>{if(!R.has(n)){const t=new CSSStyleSheet;t.replaceSync(n),R.set(n,{K:t,R:0})}const o=R.get(n);o.R++,t.has(n)||t.set(n,{K:o.K,R:0});const s=t.get(n);return s.R++,f((()=>()=>{--s.R||(t.delete(n),e()),--o.R||R.delete(n)})),s.K})((e=s,e[Q]??=new Map),n,(()=>{s.adoptedStyleSheets=s.adoptedStyleSheets.filter((t=>t!=r))}));s.adoptedStyleSheets.push(r)}var e;return z({})},W=(t,...n)=>{const e=()=>t.reduce(((t,e,o)=>t+e+(_.get(n[o])??"")),"");return n.some((t=>"function"==typeof t))?e:e()},X=(t,n,e)=>(n&&null!=e&&(n.key=e),V(t,n));export{H as Component,J as Else,G as ElseIf,B as For,z as Fragment,F as If,_ as MaybeSignal,K as Portal,U as Style,v as createContext,V as createElement,W as css,T as defineComponents,C as event,l as flushBatch,Z as h,L as isComponent,X as jsx,X as jsxDEV,X as jsxs,k as prop,i as useBatch,M as useContext,j as useEffect,a as useMemo,h as useRef,c as useSignal,d as useSubscope};
|
package/dist/scope.d.ts
CHANGED
|
@@ -40,9 +40,10 @@ export interface SubscopeOptions {
|
|
|
40
40
|
details?: object;
|
|
41
41
|
}
|
|
42
42
|
interface Effect {
|
|
43
|
+
_scope: Scope;
|
|
44
|
+
_pure: boolean;
|
|
43
45
|
_clean?: Cleanup;
|
|
44
46
|
_deps: Set<Signal<unknown>>;
|
|
45
|
-
_scope: Scope;
|
|
46
47
|
_run(): void;
|
|
47
48
|
}
|
|
48
49
|
/**
|
|
@@ -71,7 +72,7 @@ export declare const useSignal: (<T>(value: T, opts?: SetSignalOptions) => reado
|
|
|
71
72
|
* and updated at the same time.
|
|
72
73
|
*/
|
|
73
74
|
export declare const useBatch: <T>(fn: () => T) => T;
|
|
74
|
-
export declare
|
|
75
|
+
export declare const flushBatch: () => void;
|
|
75
76
|
/**
|
|
76
77
|
* Creates an effect which will rerun when any accessed signal changes.
|
|
77
78
|
*
|
package/dist/scope.js
CHANGED
|
@@ -61,11 +61,12 @@ export const useSignal = (value, opts) => {
|
|
|
61
61
|
if (innerOpts?.force) {
|
|
62
62
|
value = newValue;
|
|
63
63
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
else {
|
|
65
|
+
currBatch._setters.push(() => (value = newValue));
|
|
66
|
+
}
|
|
67
|
+
if (!innerOpts?.silent) {
|
|
68
|
+
signal._effects.forEach((effect) => currBatch._effects.add(effect));
|
|
69
|
+
}
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
72
|
else {
|
|
@@ -81,50 +82,42 @@ export const useSignal = (value, opts) => {
|
|
|
81
82
|
* and updated at the same time.
|
|
82
83
|
*/
|
|
83
84
|
export const useBatch = (fn) => {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
85
|
+
if (currBatch)
|
|
86
|
+
return fn();
|
|
87
|
+
currBatch = { _setters: [], _effects: new Set() };
|
|
88
|
+
try {
|
|
89
|
+
const result = fn();
|
|
89
90
|
flushBatch();
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
finally {
|
|
90
94
|
currBatch = undefined;
|
|
91
95
|
}
|
|
92
|
-
return result;
|
|
93
96
|
};
|
|
94
|
-
export
|
|
95
|
-
|
|
96
|
-
while (currBatch &&
|
|
97
|
+
export const flushBatch = () => {
|
|
98
|
+
a: while (currBatch &&
|
|
97
99
|
(currBatch._setters.length > 0 || currBatch._effects.size > 0)) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
currBatch._effects = new Set();
|
|
101
|
-
// Collect and clean effects
|
|
102
|
-
for (const [signal, , silent] of currBatch._setters) {
|
|
103
|
-
if (!silent) {
|
|
104
|
-
signal._effects.forEach((effect) => {
|
|
105
|
-
effect._clean?.();
|
|
106
|
-
effects.add(effect);
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
}
|
|
100
|
+
// Clean effect subscope
|
|
101
|
+
currBatch._effects.forEach((effect) => effect._clean?.());
|
|
110
102
|
// Run signal updates
|
|
111
|
-
|
|
112
|
-
setter();
|
|
113
|
-
mutatedSignals.add(signal);
|
|
114
|
-
}
|
|
103
|
+
currBatch._setters.forEach((setter) => setter());
|
|
115
104
|
currBatch._setters = [];
|
|
116
|
-
// Run
|
|
117
|
-
for (const effect of
|
|
118
|
-
if (
|
|
119
|
-
[...effect._deps].every((dep) => mutatedSignals.has(dep))) {
|
|
105
|
+
// Run next effect
|
|
106
|
+
for (const effect of currBatch._effects) {
|
|
107
|
+
if (effect._pure) {
|
|
120
108
|
effect._run();
|
|
109
|
+
currBatch._effects.delete(effect);
|
|
110
|
+
continue a;
|
|
121
111
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
112
|
+
}
|
|
113
|
+
for (const effect of currBatch._effects) {
|
|
114
|
+
effect._run();
|
|
115
|
+
currBatch._effects.delete(effect);
|
|
116
|
+
break;
|
|
125
117
|
}
|
|
126
118
|
}
|
|
127
|
-
}
|
|
119
|
+
};
|
|
120
|
+
let pureEffectFlag = false;
|
|
128
121
|
/**
|
|
129
122
|
* Creates an effect which will rerun when any accessed signal changes.
|
|
130
123
|
*
|
|
@@ -134,6 +127,7 @@ export const useEffect = (fn, deps) => {
|
|
|
134
127
|
const untracked = !!deps;
|
|
135
128
|
const effect = {
|
|
136
129
|
_scope: currScope,
|
|
130
|
+
_pure: pureEffectFlag,
|
|
137
131
|
_deps: new Set(),
|
|
138
132
|
_run() {
|
|
139
133
|
const prevEffect = currEffect;
|
|
@@ -182,10 +176,16 @@ export const useEffect = (fn, deps) => {
|
|
|
182
176
|
export const useMemo = (fn, opts) => {
|
|
183
177
|
const [memo, setMemo] = useSignal();
|
|
184
178
|
let firstTime = true;
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
179
|
+
pureEffectFlag = true;
|
|
180
|
+
try {
|
|
181
|
+
useEffect(() => {
|
|
182
|
+
setMemo(fn, firstTime ? { ...opts, force: true } : opts);
|
|
183
|
+
firstTime = false;
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
finally {
|
|
187
|
+
pureEffectFlag = false;
|
|
188
|
+
}
|
|
189
189
|
return memo;
|
|
190
190
|
};
|
|
191
191
|
/**
|
|
@@ -195,21 +195,28 @@ export const useMemo = (fn, opts) => {
|
|
|
195
195
|
* @returns A function to manually destroy the subscope.
|
|
196
196
|
*/
|
|
197
197
|
export const useSubscope = (fn, opts) => {
|
|
198
|
+
const prevBatch = currBatch;
|
|
199
|
+
currBatch = undefined;
|
|
198
200
|
const parent = currScope;
|
|
199
201
|
const scope = createScope(parent);
|
|
200
202
|
Object.assign(scope._details, opts?.details);
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
203
|
+
try {
|
|
204
|
+
parent._subscopes.push(scope);
|
|
205
|
+
const result = scope._run(fn);
|
|
206
|
+
return [
|
|
207
|
+
result,
|
|
208
|
+
() => {
|
|
209
|
+
const index = parent._subscopes.indexOf(scope);
|
|
210
|
+
if (index >= 0) {
|
|
211
|
+
parent._subscopes.splice(index, 1);
|
|
212
|
+
}
|
|
213
|
+
scope._cleanup();
|
|
214
|
+
},
|
|
215
|
+
];
|
|
216
|
+
}
|
|
217
|
+
finally {
|
|
218
|
+
currBatch = prevBatch;
|
|
219
|
+
}
|
|
213
220
|
};
|
|
214
221
|
/**
|
|
215
222
|
* Creates a new signal with write capabilities.
|
package/dist/scope.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/scope.ts
CHANGED
|
@@ -46,9 +46,10 @@ export interface SubscopeOptions {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
interface Effect {
|
|
49
|
+
_scope: Scope;
|
|
50
|
+
_pure: boolean;
|
|
49
51
|
_clean?: Cleanup;
|
|
50
52
|
_deps: Set<Signal<unknown>>;
|
|
51
|
-
_scope: Scope;
|
|
52
53
|
|
|
53
54
|
_run(): void;
|
|
54
55
|
}
|
|
@@ -113,11 +114,7 @@ let currUntracked: boolean = false;
|
|
|
113
114
|
let currEffect: Effect | undefined;
|
|
114
115
|
let currBatch:
|
|
115
116
|
| {
|
|
116
|
-
_setters: [
|
|
117
|
-
signal: Signal<unknown>,
|
|
118
|
-
setter: () => void,
|
|
119
|
-
silent?: boolean,
|
|
120
|
-
][];
|
|
117
|
+
_setters: (() => void)[];
|
|
121
118
|
_effects: Set<Effect>;
|
|
122
119
|
}
|
|
123
120
|
| undefined;
|
|
@@ -164,13 +161,13 @@ export const useSignal: (<T>(
|
|
|
164
161
|
if (innerOpts?.force || newValue !== signal.peek()) {
|
|
165
162
|
if (innerOpts?.force) {
|
|
166
163
|
value = newValue;
|
|
164
|
+
} else {
|
|
165
|
+
currBatch._setters.push(() => (value = newValue));
|
|
167
166
|
}
|
|
168
167
|
|
|
169
|
-
|
|
170
|
-
signal
|
|
171
|
-
|
|
172
|
-
innerOpts?.silent,
|
|
173
|
-
]);
|
|
168
|
+
if (!innerOpts?.silent) {
|
|
169
|
+
signal._effects.forEach((effect) => currBatch!._effects.add(effect));
|
|
170
|
+
}
|
|
174
171
|
}
|
|
175
172
|
} else {
|
|
176
173
|
useBatch(() => setter(arg, innerOpts));
|
|
@@ -187,64 +184,52 @@ export const useSignal: (<T>(
|
|
|
187
184
|
* and updated at the same time.
|
|
188
185
|
*/
|
|
189
186
|
export const useBatch = <T>(fn: () => T): T => {
|
|
190
|
-
|
|
191
|
-
if (createBatch) currBatch = { _setters: [], _effects: new Set() };
|
|
187
|
+
if (currBatch) return fn();
|
|
192
188
|
|
|
193
|
-
|
|
189
|
+
currBatch = { _setters: [], _effects: new Set() };
|
|
194
190
|
|
|
195
|
-
|
|
191
|
+
try {
|
|
192
|
+
const result = fn();
|
|
196
193
|
flushBatch();
|
|
194
|
+
return result;
|
|
195
|
+
} finally {
|
|
197
196
|
currBatch = undefined;
|
|
198
197
|
}
|
|
199
|
-
|
|
200
|
-
return result;
|
|
201
198
|
};
|
|
202
199
|
|
|
203
|
-
export
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
while (
|
|
200
|
+
export const flushBatch = (): void => {
|
|
201
|
+
a: while (
|
|
207
202
|
currBatch &&
|
|
208
203
|
(currBatch._setters.length > 0 || currBatch._effects.size > 0)
|
|
209
204
|
) {
|
|
210
|
-
|
|
211
|
-
const effects = currBatch._effects;
|
|
212
|
-
currBatch._effects = new Set();
|
|
213
|
-
|
|
214
|
-
// Collect and clean effects
|
|
215
|
-
|
|
216
|
-
for (const [signal, , silent] of currBatch._setters) {
|
|
217
|
-
if (!silent) {
|
|
218
|
-
signal._effects.forEach((effect) => {
|
|
219
|
-
effect._clean?.();
|
|
220
|
-
effects.add(effect);
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
}
|
|
205
|
+
// Clean effect subscope
|
|
224
206
|
|
|
225
|
-
|
|
207
|
+
currBatch._effects.forEach((effect) => effect._clean?.());
|
|
226
208
|
|
|
227
|
-
|
|
228
|
-
setter();
|
|
229
|
-
mutatedSignals.add(signal);
|
|
230
|
-
}
|
|
209
|
+
// Run signal updates
|
|
231
210
|
|
|
211
|
+
currBatch._setters.forEach((setter) => setter());
|
|
232
212
|
currBatch._setters = [];
|
|
233
213
|
|
|
234
|
-
// Run
|
|
214
|
+
// Run next effect
|
|
235
215
|
|
|
236
|
-
for (const effect of
|
|
237
|
-
if (
|
|
238
|
-
!settersCount ||
|
|
239
|
-
[...effect._deps].every((dep) => mutatedSignals.has(dep))
|
|
240
|
-
) {
|
|
216
|
+
for (const effect of currBatch._effects) {
|
|
217
|
+
if (effect._pure) {
|
|
241
218
|
effect._run();
|
|
242
|
-
|
|
243
|
-
|
|
219
|
+
currBatch._effects.delete(effect);
|
|
220
|
+
continue a;
|
|
244
221
|
}
|
|
245
222
|
}
|
|
223
|
+
|
|
224
|
+
for (const effect of currBatch._effects) {
|
|
225
|
+
effect._run();
|
|
226
|
+
currBatch._effects.delete(effect);
|
|
227
|
+
break;
|
|
228
|
+
}
|
|
246
229
|
}
|
|
247
|
-
}
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
let pureEffectFlag: boolean = false;
|
|
248
233
|
|
|
249
234
|
/**
|
|
250
235
|
* Creates an effect which will rerun when any accessed signal changes.
|
|
@@ -259,6 +244,7 @@ export const useEffect = (
|
|
|
259
244
|
|
|
260
245
|
const effect: Effect = {
|
|
261
246
|
_scope: currScope,
|
|
247
|
+
_pure: pureEffectFlag,
|
|
262
248
|
_deps: new Set(),
|
|
263
249
|
|
|
264
250
|
_run(): void {
|
|
@@ -323,12 +309,17 @@ export const useMemo = <T>(fn: () => T, opts?: SetSignalOptions): Signal<T> => {
|
|
|
323
309
|
const [memo, setMemo] = useSignal<T>();
|
|
324
310
|
|
|
325
311
|
let firstTime = true;
|
|
312
|
+
pureEffectFlag = true;
|
|
326
313
|
|
|
327
|
-
|
|
328
|
-
|
|
314
|
+
try {
|
|
315
|
+
useEffect(() => {
|
|
316
|
+
setMemo(fn, firstTime ? { ...opts, force: true } : opts);
|
|
329
317
|
|
|
330
|
-
|
|
331
|
-
|
|
318
|
+
firstTime = false;
|
|
319
|
+
});
|
|
320
|
+
} finally {
|
|
321
|
+
pureEffectFlag = false;
|
|
322
|
+
}
|
|
332
323
|
|
|
333
324
|
return memo as Signal<T>;
|
|
334
325
|
};
|
|
@@ -343,24 +334,31 @@ export const useSubscope = <T>(
|
|
|
343
334
|
fn: () => T,
|
|
344
335
|
opts?: SubscopeOptions,
|
|
345
336
|
): [T, () => void] => {
|
|
337
|
+
const prevBatch = currBatch;
|
|
338
|
+
currBatch = undefined;
|
|
339
|
+
|
|
346
340
|
const parent = currScope;
|
|
347
341
|
const scope = createScope(parent);
|
|
348
342
|
Object.assign(scope._details, opts?.details);
|
|
349
343
|
|
|
350
|
-
|
|
351
|
-
|
|
344
|
+
try {
|
|
345
|
+
parent._subscopes.push(scope);
|
|
346
|
+
const result = scope._run(fn);
|
|
352
347
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
348
|
+
return [
|
|
349
|
+
result,
|
|
350
|
+
() => {
|
|
351
|
+
const index = parent._subscopes.indexOf(scope);
|
|
352
|
+
if (index >= 0) {
|
|
353
|
+
parent._subscopes.splice(index, 1);
|
|
354
|
+
}
|
|
360
355
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
356
|
+
scope._cleanup();
|
|
357
|
+
},
|
|
358
|
+
];
|
|
359
|
+
} finally {
|
|
360
|
+
currBatch = prevBatch;
|
|
361
|
+
}
|
|
364
362
|
};
|
|
365
363
|
|
|
366
364
|
/**
|