nanoeffects 0.21.0 → 0.22.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/actions.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { H as PayloadOf, T as EventKey, W as Task, c as WithScope, h as Bus, n as Free, o as Scope, r as FreeActionCreator, t as ActionCreator, z as EventMap } from "./action-creator-Bpa8BUS9.js";
2
- import { r as Scoped, t as FieldsOfScope } from "./types-CbdJKC2z.js";
3
- import { a as createModule, c as CarryingCalls, d as commandsPlugin, f as createCommand, l as MadeCommand, n as ModuleApi, o as modulePlugin, r as ModuleContext, s as Binding, t as Module, u as bindHandler } from "./module-B0KVDNjY.js";
2
+ import { r as Scoped, t as FieldsOfScope } from "./types-DC-aLJit.js";
3
+ import { a as createModule, c as CarryingCalls, d as commandsPlugin, f as createCommand, l as MadeCommand, n as ModuleApi, o as modulePlugin, r as ModuleContext, s as Binding, t as Module, u as bindHandler } from "./module-1sUEXIcD.js";
4
4
  import { t as OriginOptions } from "./origin-key-CxK0SkeG.js";
5
5
  //#region src/actions/action.d.ts
6
6
  type ScopedCreator<P, T extends string, F> = [P] extends [Free] ? FreeActionCreator<T, F> & WithScope<F> : ActionCreator<P, T, PayloadOf<P>, F> & WithScope<F>;
package/dist/dev.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { J as UnsubscribeCallback, h as Bus, z as EventMap } from "./action-creator-Bpa8BUS9.js";
2
- import { i as WithApp, n as ModuleApi } from "./module-B0KVDNjY.js";
2
+ import { i as WithApp, n as ModuleApi } from "./module-1sUEXIcD.js";
3
3
  //#region src/dev/types.d.ts
4
4
  /** The parts of what `modulePlugin` returned that the diagnostics report. */
5
5
  type ReportedApp<E extends EventMap> = Pick<ModuleApi<E>, "mount" | "unmount" | "isMounted">;
package/dist/effects.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { P as WithSignal, W as Task, u as Effect, z as EventMap } from "./action-creator-Bpa8BUS9.js";
2
- import { a as RaceStarter, c as all, d as delay, i as take, l as EffectContext, n as effectsPlugin, o as race, r as TakeOptions, s as allSettled, u as Starter } from "./plugin-D9UTzGRG.js";
2
+ import { a as RaceStarter, c as all, d as delay, i as take, l as EffectContext, n as effectsPlugin, o as race, r as TakeOptions, s as allSettled, u as Starter } from "./plugin-BiGv84Xu.js";
3
3
  //#region src/utils/onAbort.d.ts
4
4
  export declare const onAbort: (ctx: {
5
5
  signal?: AbortSignal | undefined;
package/dist/effects.js CHANGED
@@ -1 +1 @@
1
- import{d as e,i as t,o as n,s as r,t as i,u as a}from"./context-CJGW6OWj.js";import{n as o,r as s,t as c}from"./delay-BnBdGPh7.js";const l=(e,t)=>t?.signal?new Promise((n,r)=>{let i=a(t,r);e.then(n,r).finally(i)}):e,u=async(e,n,o,s)=>{n?.signal?.throwIfAborted();let{ctx:c,unlink:u}=t(n??{}),d=i(c,e);r(c,e,`start`),a(c,()=>d(`cancel`));try{let e=await l(o(c),n);return d(`done`),s?.(!1),e}catch(e){throw d(`error`,e),s?.(!0),e}finally{u()}},d=async(e,r)=>{let{ctx:i,unlink:a}=t(e);try{return await n(i,`run`,()=>r(i))}finally{a()}},f=e=>e,p=(e,t)=>n=>e(t,f(n)),m=e=>Array.isArray(e)?Array(e.length):{},h=(e,r)=>{let i=Object.entries(r).map(([r,i])=>{let a=t(e),o={signal:a.ctx.signal,abort:a.ctx.abort},s=()=>i(o);return{key:r,task:new Promise(e=>e(n(a.ctx,`run`,s))).finally(a.unlink),cancel:a.ctx.abort}});return{tasks:i.map(({key:e,task:t})=>[e,t]),cancelAll:()=>{for(let e of i)e.cancel()}}},g=(e,t,n,r,i)=>{let a=()=>{};return u(e,t,async e=>{let t=h(e,n);return a=t.cancelAll,r(t.tasks)},e=>{(e||i===`end`)&&a()})};function _(e,t){return g(`all`,e,t,async e=>{let n=await Promise.all(e.map(([,e])=>e)),r=m(t);for(let[t,[i]]of e.entries())r[i]=n[t];return r},`failure`)}const v=e=>e.then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}));function y(e,t){return g(`allSettled`,e,t,async e=>{let n=await Promise.all(e.map(([,e])=>v(e))),r=m(t);for(let[t,[i]]of e.entries())r[i]=n[t];return r},`failure`)}const b=e=>e>0?e:0,x=(e={})=>{let t=b(e.base??100),n=e.factor??2,r=b(e.max??1/0),i=e.jitter??!1;return e=>{let a=b(Math.min(r,t*n**(e-1)));return i?Math.random()*a||0:a}},S=(t,n)=>t.signal.aborted?Promise.reject(t.signal.reason):new Promise((r,i)=>{let o=[],s=`pending`,c=t=>{try{t()}catch(t){e(`cancel cleanup failed`,t)}},l=a(t,e=>{s=`cancelled`;for(let e of o.reverse())c(e);i(e)}),u=e=>(...t)=>{s===`pending`&&(s=`settled`,l(),o.length=0,e(...t))},d=e=>{s===`pending`?o.push(e):s===`cancelled`&&c(e)};try{n({resolve:u(r),reject:u(i),onCancel:d})}catch(e){u(i)(e)}}),C=e=>t=>{let n=t.addContext,r=Object.entries(e);return t.addContext=e=>{n?.(e);for(let[t,n]of r)t in e||Object.assign(e,{[t]:(...t)=>n(e,...t)})},t},w=(e,t,n,r)=>{if(e.signal.aborted)return Promise.resolve();let i=r.leading??!1,c=r.waitForFn??!1;return u(`poll`,e,e=>new Promise((r,l)=>{let u=0,f=null,p=()=>{f!==null&&(o(f),f=null)},m=e=>{try{f=s(h,typeof n==`function`?n(e):n)}catch(e){p(),l(e)}},h=()=>{f=null,c||m(u+1),g()},g=()=>{let n=u++;d(e,e=>t(e,n)).then(()=>{c&&!e.signal.aborted&&m(u)},e=>{p(),l(e)})};a(e,p),i?(g(),c||m(u)):m(0)})).catch(t=>{if(!e.signal.aborted)throw t})};function T(e,t,n,r={}){if(typeof e!=`object`){let r=t,i=n??{};return(t,n)=>w(n,p(r,t),e,i)}let i=t;return w(e,(e,t)=>i(t),n,r)}function E(e,t){let n=m(t);return Object.keys(t).length===0?Promise.resolve(n):g(`race`,e,t,async e=>{let[t,r]=await Promise.race(e.map(([e,t])=>t.then(t=>[e,t])));return n[t]=r,n},`end`)}const D=(e,t,n)=>typeof e==`function`?e(t,n):e,O=e=>({times:e.times??3,delay:e.delay??0,shouldRetry:e.shouldRetry??(()=>!0)}),k=(e,t,n)=>u(`retry`,e,async e=>{let{times:r,delay:i,shouldRetry:a}=O(n);for(let n=1;;n++)try{return await d(e,e=>t(e,n))}catch(t){if(e.signal.throwIfAborted(),!(n<r)||!a(t,n))throw t;let o=D(i,n,t);o>0&&await c(e,o)}});function A(e,t,n={}){if(typeof e==`function`){let n=e;return(e,r)=>k(r,p(n,e),t??{})}let r=t;return k(e,(e,t)=>r(t),n)}function j(e,t,n={}){return u(`take`,e,r=>new Promise((i,o)=>{let{predicate:s}=n,c=[],l=()=>{for(let e of c)e()},u=e=>{l(),o(e)};c.push(e.on(t,e=>{(!s||s(e))&&(l(),i(e))})),c.push(a(r,u)),c.push(a({signal:n.signal},u))}))}const M=(e,r,i)=>u(`timeout`,e,async e=>{let a=t(e),c=s(()=>a.ctx.abort(new DOMException(`Timed out after ${r}ms`,`TimeoutError`)),r);try{return await l(Promise.resolve(n(a.ctx,`run`,()=>i(a.ctx))),a.ctx)}finally{o(c),a.unlink()}});function N(e,t,n){if(typeof e==`number`){let n=t;return(t,r)=>M(r,e,p(n,t))}let r=t,i=n;return M(e,r,e=>i({signal:e.signal,abort:e.abort}))}export{_ as all,y as allSettled,x as backoff,S as cancellable,c as delay,C as effectsPlugin,a as onAbort,T as poll,E as race,A as retry,j as take,N as timeout};
1
+ import{d as e,i as t,o as n,s as r,t as i,u as a}from"./context-CJGW6OWj.js";import{n as o,r as s,t as c}from"./delay-BnBdGPh7.js";const l=(e,t)=>t?.signal?new Promise((n,r)=>{let i=a(t,r);e.then(n,r).finally(i)}):e,u=async(e,n,o,s)=>{n?.signal?.throwIfAborted();let{ctx:c,unlink:u}=t(n??{}),d=i(c,e);r(c,e,`start`),a(c,()=>d(`cancel`));try{let e=await l(o(c),n);return d(`done`),s?.(!1),e}catch(e){throw d(`error`,e),s?.(!0),e}finally{u()}},d=async(e,r)=>{let{ctx:i,unlink:a}=t(e);try{return await n(i,`run`,()=>r(i))}finally{a()}},f=e=>e,p=(e,t)=>n=>e(t,f(n)),m=e=>Array.isArray(e)?Array(e.length):{},h=(e,r)=>{let i=Object.entries(r).map(([r,i])=>{let a=t(e),o={signal:a.ctx.signal,abort:a.ctx.abort},s=()=>i(o);return{key:r,task:new Promise(e=>e(n(a.ctx,`run`,s))).finally(a.unlink),cancel:a.ctx.abort}});return{tasks:i.map(({key:e,task:t})=>[e,t]),cancelAll:()=>{for(let e of i)e.cancel()}}},g=(e,t,n,r,i)=>{let a=()=>{};return u(e,t,async e=>{let t=h(e,n);return a=t.cancelAll,r(t.tasks)},e=>{(e||i===`end`)&&a()})};function _(e,t){return g(`all`,e,t,async e=>{let n=await Promise.all(e.map(([,e])=>e)),r=m(t);for(let[t,[i]]of e.entries())r[i]=n[t];return r},`failure`)}const v=e=>e.then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}));function y(e,t){return g(`allSettled`,e,t,async e=>{let n=await Promise.all(e.map(([,e])=>v(e))),r=m(t);for(let[t,[i]]of e.entries())r[i]=n[t];return r},`failure`)}const b=e=>e>0?e:0,x=(e={})=>{let t=b(e.base??100),n=e.factor??2,r=b(e.max??1/0),i=e.jitter??!1;return e=>{let a=b(Math.min(r,t*n**(e-1)));return i?Math.random()*a||0:a}},S=(t,n)=>t.signal.aborted?Promise.reject(t.signal.reason):new Promise((r,i)=>{let o=[],s=`pending`,c=t=>{try{t()}catch(t){e(`cancel cleanup failed`,t)}},l=a(t,e=>{s=`cancelled`;for(let e of o.reverse())c(e);i(e)}),u=e=>(...t)=>{s===`pending`&&(s=`settled`,l(),o.length=0,e(...t))},d=e=>{s===`pending`?o.push(e):s===`cancelled`&&c(e)};try{n({resolve:u(r),reject:u(i),onCancel:d})}catch(e){u(i)(e)}}),C=e=>t=>{let n=t.addContext,r=Object.entries(e);return t.addContext=e=>{n?.(e);for(let[t,n]of r)t in e||Object.assign(e,{[t]:(...t)=>n(e,...t)})},t},w=(e,t,n,r)=>{if(e.signal.aborted)return Promise.resolve();let i=r.leading??!1,c=r.waitForFn??!1;return u(`poll`,e,e=>new Promise((r,l)=>{let u=0,f=null,p=()=>{f!==null&&(o(f),f=null)},m=e=>{try{f=s(h,typeof n==`function`?n(e):n)}catch(e){p(),l(e)}},h=()=>{f=null,c||m(u+1),g()},g=()=>{let n=u++;d(e,e=>t(e,n)).then(()=>{c&&!e.signal.aborted&&m(u)},e=>{p(),l(e)})};a(e,p),i?(g(),c||m(u)):m(0)})).catch(t=>{if(!e.signal.aborted)throw t})};function T(e,t,n,r={}){if(typeof e!=`object`){let r=t,i=n??{};return(t,n)=>w(n,p(r,t),e,i)}let i=t;return w(e,(e,t)=>i(t),n,r)}function E(e,t){let n=m(t);return Object.keys(t).length===0?Promise.resolve(n):g(`race`,e,t,async e=>{let[t,r]=await Promise.race(e.map(([e,t])=>t.then(t=>[e,t])));return n[t]=r,n},`end`)}const D=(e,t,n)=>typeof e==`function`?e(t,n):e,O=e=>({times:e.times??3,delay:e.delay??0,shouldRetry:e.shouldRetry??(()=>!0)}),k=(e,t,n)=>u(`retry`,e,async e=>{let{times:r,delay:i,shouldRetry:a}=O(n);for(let n=1;;n++)try{return await d(e,e=>t(e,n))}catch(t){if(e.signal.throwIfAborted(),!(n<r)||!a(t,n))throw t;let o=D(i,n,t);o>0&&await c(e,o)}});function A(e,t,n={}){if(typeof e==`function`){let n=e;return(e,r)=>k(r,p(n,e),t??{})}let r=t;return k(e,(e,t)=>r(t),n)}function j(e,t,n={}){return u(`take`,e,r=>new Promise((i,o)=>{let{predicate:s}=n,c=[],l=()=>{for(let e of c)e()},u=e=>{l(),o(e)},d=t;c.push(e.on(d,e=>{(!s||s(e))&&(l(),i(e))})),c.push(a(r,u)),c.push(a({signal:n.signal},u))}))}const M=(e,r,i)=>u(`timeout`,e,async e=>{let a=t(e),c=s(()=>a.ctx.abort(new DOMException(`Timed out after ${r}ms`,`TimeoutError`)),r);try{return await l(Promise.resolve(n(a.ctx,`run`,()=>i(a.ctx))),a.ctx)}finally{o(c),a.unlink()}});function N(e,t,n){if(typeof e==`number`){let n=t;return(t,r)=>M(r,e,p(n,t))}let r=t,i=n;return M(e,r,e=>i({signal:e.signal,abort:e.abort}))}export{_ as all,y as allSettled,x as backoff,S as cancellable,c as delay,C as effectsPlugin,a as onAbort,T as poll,E as race,A as retry,j as take,N as timeout};
@@ -1,5 +1,5 @@
1
1
  import { H as PayloadOf, J as UnsubscribeCallback, W as Task, _ as Command, b as Context, c as WithScope, h as Bus, o as Scope, v as CommandCall, y as Commands, z as EventMap } from "./action-creator-Bpa8BUS9.js";
2
- import { n as ScopeSlots, r as Scoped, t as FieldsOfScope } from "./types-CbdJKC2z.js";
2
+ import { n as ScopeSlots, r as Scoped, t as FieldsOfScope } from "./types-DC-aLJit.js";
3
3
  //#region src/actions/command.d.ts
4
4
  /** What `createCommand` returns: a command that also tells whether an action is of its type. */
5
5
  type MadeCommand<P, R, T extends string> = Command<P, R> & {
@@ -1,5 +1,5 @@
1
1
  import { C as EventKey, F as EventMap, L as PayloadOf, R as Task, _ as Commands, a as Scope, g as CommandCall, h as Command, n as Free, o as WithFields, p as Bus, r as FreeActionCreator, s as WithScope, t as ActionCreator, u as Effects, v as Context, z as UnsubscribeCallback } from "./action-creator-D2CotugT.js";
2
- import { t as BoundOf } from "./plugin-C6KA4dX-.js";
2
+ import { t as BoundOf } from "./plugin-ByDuI8Vq.js";
3
3
  import { t as OriginOptions } from "./origin-key-CxK0SkeG.js";
4
4
  //#region src/scope/types.d.ts
5
5
  /**
@@ -1,5 +1,5 @@
1
1
  import { F as EventMap, M as WithSignal, R as Task, l as Effect } from "./action-creator-D2CotugT.js";
2
- import { a as RaceStarter, c as all, d as delay, i as take, l as EffectContext, n as effectsPlugin, o as race, r as TakeOptions, s as allSettled, u as Starter } from "./plugin-C6KA4dX-.js";
2
+ import { a as RaceStarter, c as all, d as delay, i as take, l as EffectContext, n as effectsPlugin, o as race, r as TakeOptions, s as allSettled, u as Starter } from "./plugin-ByDuI8Vq.js";
3
3
  //#region src/utils/onAbort.d.ts
4
4
  export declare const onAbort: (ctx: {
5
5
  signal?: AbortSignal | undefined;
@@ -1 +1 @@
1
- import{a as e,c as t,i as n,l as r,o as i,t as a}from"./context-yYU3_9lq.js";import{n as o,r as s,t as c}from"./delay-BosJKFjg.js";const l=(e,n)=>n?.signal?new Promise((r,i)=>{let a=t(n,i);e.then(r,i).finally(a)}):e,u=async(e,r,o,s)=>{r?.signal?.throwIfAborted();let{ctx:c,unlink:u}=n(r??{}),d=a(c,e);i(c,e,`start`),t(c,()=>d(`cancel`));try{let e=await l(o(c),r);return d(`done`),s?.(!1),e}catch(e){throw d(`error`,e),s?.(!0),e}finally{u()}},d=async(t,r)=>{let{ctx:i,unlink:a}=n(t);try{return await e(i,`run`,()=>r(i))}finally{a()}},f=e=>e,p=(e,t)=>n=>e(t,f(n)),m=e=>Array.isArray(e)?Array(e.length):{},h=(t,r)=>{let i=Object.entries(r).map(([r,i])=>{let a=n(t),o={signal:a.ctx.signal,abort:a.ctx.abort},s=()=>i(o);return{key:r,task:new Promise(t=>t(e(a.ctx,`run`,s))).finally(a.unlink),cancel:a.ctx.abort}});return{tasks:i.map(({key:e,task:t})=>[e,t]),cancelAll:()=>{for(let e of i)e.cancel()}}},g=(e,t,n,r,i)=>{let a=()=>{};return u(e,t,async e=>{let t=h(e,n);return a=t.cancelAll,r(t.tasks)},e=>{(e||i===`end`)&&a()})};function _(e,t){return g(`all`,e,t,async e=>{let n=await Promise.all(e.map(([,e])=>e)),r=m(t);for(let[t,[i]]of e.entries())r[i]=n[t];return r},`failure`)}const v=e=>e.then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}));function y(e,t){return g(`allSettled`,e,t,async e=>{let n=await Promise.all(e.map(([,e])=>v(e))),r=m(t);for(let[t,[i]]of e.entries())r[i]=n[t];return r},`failure`)}const b=e=>e>0?e:0,x=(e={})=>{let t=b(e.base??100),n=e.factor??2,r=b(e.max??1/0),i=e.jitter??!1;return e=>{let a=b(Math.min(r,t*n**(e-1)));return i?Math.random()*a||0:a}},S=(e,n)=>e.signal.aborted?Promise.reject(e.signal.reason):new Promise((i,a)=>{let o=[],s=`pending`,c=e=>{try{e()}catch(e){r(`cancel cleanup failed`,e)}},l=t(e,e=>{s=`cancelled`;for(let e of o.reverse())c(e);a(e)}),u=e=>(...t)=>{s===`pending`&&(s=`settled`,l(),o.length=0,e(...t))},d=e=>{s===`pending`?o.push(e):s===`cancelled`&&c(e)};try{n({resolve:u(i),reject:u(a),onCancel:d})}catch(e){u(a)(e)}}),C=e=>t=>{let n=t.addContext,r=Object.entries(e);return t.addContext=e=>{n?.(e);for(let[t,n]of r)t in e||Object.assign(e,{[t]:(...t)=>n(e,...t)})},t},w=(e,n,r,i)=>{if(e.signal.aborted)return Promise.resolve();let a=i.leading??!1,c=i.waitForFn??!1;return u(`poll`,e,e=>new Promise((i,l)=>{let u=0,f=null,p=()=>{f!==null&&(o(f),f=null)},m=e=>{try{f=s(h,typeof r==`function`?r(e):r)}catch(e){p(),l(e)}},h=()=>{f=null,c||m(u+1),g()},g=()=>{let t=u++;d(e,e=>n(e,t)).then(()=>{c&&!e.signal.aborted&&m(u)},e=>{p(),l(e)})};t(e,p),a?(g(),c||m(u)):m(0)})).catch(t=>{if(!e.signal.aborted)throw t})};function T(e,t,n,r={}){if(typeof e!=`object`){let r=t,i=n??{};return(t,n)=>w(n,p(r,t),e,i)}let i=t;return w(e,(e,t)=>i(t),n,r)}function E(e,t){let n=m(t);return Object.keys(t).length===0?Promise.resolve(n):g(`race`,e,t,async e=>{let[t,r]=await Promise.race(e.map(([e,t])=>t.then(t=>[e,t])));return n[t]=r,n},`end`)}const D=(e,t,n)=>typeof e==`function`?e(t,n):e,O=e=>({times:e.times??3,delay:e.delay??0,shouldRetry:e.shouldRetry??(()=>!0)}),k=(e,t,n)=>u(`retry`,e,async e=>{let{times:r,delay:i,shouldRetry:a}=O(n);for(let n=1;;n++)try{return await d(e,e=>t(e,n))}catch(t){if(e.signal.throwIfAborted(),!(n<r)||!a(t,n))throw t;let o=D(i,n,t);o>0&&await c(e,o)}});function A(e,t,n={}){if(typeof e==`function`){let n=e;return(e,r)=>k(r,p(n,e),t??{})}let r=t;return k(e,(e,t)=>r(t),n)}function j(e,n,r={}){return u(`take`,e,i=>new Promise((a,o)=>{let{predicate:s}=r,c=[],l=()=>{for(let e of c)e()},u=e=>{l(),o(e)};c.push(e.on(n,e=>{(!s||s(e))&&(l(),a(e))})),c.push(t(i,u)),c.push(t({signal:r.signal},u))}))}const M=(t,r,i)=>u(`timeout`,t,async t=>{let a=n(t),c=s(()=>a.ctx.abort(new DOMException(`Timed out after ${r}ms`,`TimeoutError`)),r);try{return await l(Promise.resolve(e(a.ctx,`run`,()=>i(a.ctx))),a.ctx)}finally{o(c),a.unlink()}});function N(e,t,n){if(typeof e==`number`){let n=t;return(t,r)=>M(r,e,p(n,t))}let r=t,i=n;return M(e,r,e=>i({signal:e.signal,abort:e.abort}))}export{_ as all,y as allSettled,x as backoff,S as cancellable,c as delay,C as effectsPlugin,t as onAbort,T as poll,E as race,A as retry,j as take,N as timeout};
1
+ import{a as e,c as t,i as n,l as r,o as i,t as a}from"./context-yYU3_9lq.js";import{n as o,r as s,t as c}from"./delay-BosJKFjg.js";const l=(e,n)=>n?.signal?new Promise((r,i)=>{let a=t(n,i);e.then(r,i).finally(a)}):e,u=async(e,r,o,s)=>{r?.signal?.throwIfAborted();let{ctx:c,unlink:u}=n(r??{}),d=a(c,e);i(c,e,`start`),t(c,()=>d(`cancel`));try{let e=await l(o(c),r);return d(`done`),s?.(!1),e}catch(e){throw d(`error`,e),s?.(!0),e}finally{u()}},d=async(t,r)=>{let{ctx:i,unlink:a}=n(t);try{return await e(i,`run`,()=>r(i))}finally{a()}},f=e=>e,p=(e,t)=>n=>e(t,f(n)),m=e=>Array.isArray(e)?Array(e.length):{},h=(t,r)=>{let i=Object.entries(r).map(([r,i])=>{let a=n(t),o={signal:a.ctx.signal,abort:a.ctx.abort},s=()=>i(o);return{key:r,task:new Promise(t=>t(e(a.ctx,`run`,s))).finally(a.unlink),cancel:a.ctx.abort}});return{tasks:i.map(({key:e,task:t})=>[e,t]),cancelAll:()=>{for(let e of i)e.cancel()}}},g=(e,t,n,r,i)=>{let a=()=>{};return u(e,t,async e=>{let t=h(e,n);return a=t.cancelAll,r(t.tasks)},e=>{(e||i===`end`)&&a()})};function _(e,t){return g(`all`,e,t,async e=>{let n=await Promise.all(e.map(([,e])=>e)),r=m(t);for(let[t,[i]]of e.entries())r[i]=n[t];return r},`failure`)}const v=e=>e.then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}));function y(e,t){return g(`allSettled`,e,t,async e=>{let n=await Promise.all(e.map(([,e])=>v(e))),r=m(t);for(let[t,[i]]of e.entries())r[i]=n[t];return r},`failure`)}const b=e=>e>0?e:0,x=(e={})=>{let t=b(e.base??100),n=e.factor??2,r=b(e.max??1/0),i=e.jitter??!1;return e=>{let a=b(Math.min(r,t*n**(e-1)));return i?Math.random()*a||0:a}},S=(e,n)=>e.signal.aborted?Promise.reject(e.signal.reason):new Promise((i,a)=>{let o=[],s=`pending`,c=e=>{try{e()}catch(e){r(`cancel cleanup failed`,e)}},l=t(e,e=>{s=`cancelled`;for(let e of o.reverse())c(e);a(e)}),u=e=>(...t)=>{s===`pending`&&(s=`settled`,l(),o.length=0,e(...t))},d=e=>{s===`pending`?o.push(e):s===`cancelled`&&c(e)};try{n({resolve:u(i),reject:u(a),onCancel:d})}catch(e){u(a)(e)}}),C=e=>t=>{let n=t.addContext,r=Object.entries(e);return t.addContext=e=>{n?.(e);for(let[t,n]of r)t in e||Object.assign(e,{[t]:(...t)=>n(e,...t)})},t},w=(e,n,r,i)=>{if(e.signal.aborted)return Promise.resolve();let a=i.leading??!1,c=i.waitForFn??!1;return u(`poll`,e,e=>new Promise((i,l)=>{let u=0,f=null,p=()=>{f!==null&&(o(f),f=null)},m=e=>{try{f=s(h,typeof r==`function`?r(e):r)}catch(e){p(),l(e)}},h=()=>{f=null,c||m(u+1),g()},g=()=>{let t=u++;d(e,e=>n(e,t)).then(()=>{c&&!e.signal.aborted&&m(u)},e=>{p(),l(e)})};t(e,p),a?(g(),c||m(u)):m(0)})).catch(t=>{if(!e.signal.aborted)throw t})};function T(e,t,n,r={}){if(typeof e!=`object`){let r=t,i=n??{};return(t,n)=>w(n,p(r,t),e,i)}let i=t;return w(e,(e,t)=>i(t),n,r)}function E(e,t){let n=m(t);return Object.keys(t).length===0?Promise.resolve(n):g(`race`,e,t,async e=>{let[t,r]=await Promise.race(e.map(([e,t])=>t.then(t=>[e,t])));return n[t]=r,n},`end`)}const D=(e,t,n)=>typeof e==`function`?e(t,n):e,O=e=>({times:e.times??3,delay:e.delay??0,shouldRetry:e.shouldRetry??(()=>!0)}),k=(e,t,n)=>u(`retry`,e,async e=>{let{times:r,delay:i,shouldRetry:a}=O(n);for(let n=1;;n++)try{return await d(e,e=>t(e,n))}catch(t){if(e.signal.throwIfAborted(),!(n<r)||!a(t,n))throw t;let o=D(i,n,t);o>0&&await c(e,o)}});function A(e,t,n={}){if(typeof e==`function`){let n=e;return(e,r)=>k(r,p(n,e),t??{})}let r=t;return k(e,(e,t)=>r(t),n)}function j(e,n,r={}){return u(`take`,e,i=>new Promise((a,o)=>{let{predicate:s}=r,c=[],l=()=>{for(let e of c)e()},u=e=>{l(),o(e)},d=n;c.push(e.on(d,e=>{(!s||s(e))&&(l(),a(e))})),c.push(t(i,u)),c.push(t({signal:r.signal},u))}))}const M=(t,r,i)=>u(`timeout`,t,async t=>{let a=n(t),c=s(()=>a.ctx.abort(new DOMException(`Timed out after ${r}ms`,`TimeoutError`)),r);try{return await l(Promise.resolve(e(a.ctx,`run`,()=>i(a.ctx))),a.ctx)}finally{o(c),a.unlink()}});function N(e,t,n){if(typeof e==`number`){let n=t;return(t,r)=>M(r,e,p(n,t))}let r=t,i=n;return M(e,r,e=>i({signal:e.signal,abort:e.abort}))}export{_ as all,y as allSettled,x as backoff,S as cancellable,c as delay,C as effectsPlugin,t as onAbort,T as poll,E as race,A as retry,j as take,N as timeout};
@@ -1,4 +1,4 @@
1
- import { F as EventMap, I as Keys, c as BoundForm, j as WithContext, p as Bus, u as Effects, v as Context, y as ContextOf } from "./action-creator-D2CotugT.js";
1
+ import { F as EventMap, I as Keys, c as BoundForm, j as WithContext, p as Bus, r as FreeActionCreator, t as ActionCreator, u as Effects, v as Context, y as ContextOf } from "./action-creator-D2CotugT.js";
2
2
  //#region src/core/context-types.d.ts
3
3
  /**
4
4
  * `unknown` when none of the `fields` is already a context field of the bus,
@@ -124,7 +124,8 @@ type TakeOptions<P> = {
124
124
  signal?: AbortSignal | undefined;
125
125
  };
126
126
  /**
127
- * Waits for the next `event` on the bus and resolves with its payload. It sees
127
+ * Waits for the next `event` on the bus and resolves with its payload. `event` is the name
128
+ * of an event or an action creator, as for `bus.on`. It sees
128
129
  * only events emitted after the call, takes only one, and unsubscribes when it
129
130
  * is done. If `ctx` (or `options.signal`) aborts first, it unsubscribes and
130
131
  * rejects with the abort reason.
@@ -141,6 +142,9 @@ type TakeOptions<P> = {
141
142
  * take(ctx, "saved", { signal, predicate: (id) => id === draftId }),
142
143
  * );
143
144
  *
145
+ * // an action creator works as the name does, and gives its payload type
146
+ * const stopped = await take(ctx, stopRequested);
147
+ *
144
148
  * // a type guard narrows the result: `failed` is `{ ok: false }`
145
149
  * const failed = await take(ctx, "result", {
146
150
  * predicate: (result): result is { ok: false } => !result.ok,
@@ -151,6 +155,14 @@ declare function take<E extends EventMap, K extends Keys<E>, T extends E[K]>(ctx
151
155
  predicate: (payload: E[K]) => payload is T;
152
156
  }): Promise<T>;
153
157
  declare function take<E extends EventMap, K extends Keys<E>>(ctx: Context<E>, event: K, options?: TakeOptions<E[K]>): Promise<E[K]>;
158
+ declare function take<E extends EventMap, K extends Keys<E>, T extends E[K]>(ctx: Context<E>, creator: FreeActionCreator<K>, options: TakeOptions<E[K]> & {
159
+ predicate: (payload: E[K]) => payload is T;
160
+ }): Promise<T>;
161
+ declare function take<E extends EventMap, K extends Keys<E>>(ctx: Context<E>, creator: FreeActionCreator<K>, options?: TakeOptions<E[K]>): Promise<E[K]>;
162
+ declare function take<E extends EventMap, P, T extends P>(ctx: Context<E>, creator: ActionCreator<P>, options: TakeOptions<P> & {
163
+ predicate: (payload: P) => payload is T;
164
+ }): Promise<T>;
165
+ declare function take<E extends EventMap, P>(ctx: Context<E>, creator: ActionCreator<P>, options?: TakeOptions<P>): Promise<P>;
154
166
  //#endregion
155
167
  //#region src/effects/plugin.d.ts
156
168
  /** The effects that `effectsPlugin` can put on `ctx`. */
@@ -177,7 +189,12 @@ type Bound<E extends EventMap> = {
177
189
  <T extends Results>(effects: T): Promise<{ [K in keyof T]: PromiseSettledResult<Awaited<ReturnType<T[K]>>>; }>;
178
190
  <const T extends List>(effects: T): Promise<{ -readonly [K in keyof T]: PromiseSettledResult<Awaited<ReturnType<T[K]>>>; }>;
179
191
  };
180
- take: <K extends Keys<E>>(event: K, options?: TakeOptions<E[K]>) => Promise<E[K]>;
192
+ take: {
193
+ <K extends Keys<E>>(event: K, options?: TakeOptions<E[K]>): Promise<E[K]>;
194
+ /** A creator without a payload type: the payload comes from the event map. */
195
+ <K extends Keys<E>>(creator: FreeActionCreator<K>, options?: TakeOptions<E[K]>): Promise<E[K]>;
196
+ <P>(creator: ActionCreator<P>, options?: TakeOptions<P>): Promise<P>;
197
+ };
181
198
  delay: (ms: number | (() => number)) => Promise<void>;
182
199
  };
183
200
  /** Any function whose first parameter takes `{ signal }` can go on the context, not only the built-in ones. */
@@ -1,4 +1,4 @@
1
- import { B as Keys, N as WithContext, b as Context, d as Effects, h as Bus, l as BoundForm, z as EventMap } from "./action-creator-Bpa8BUS9.js";
1
+ import { B as Keys, N as WithContext, b as Context, d as Effects, h as Bus, l as BoundForm, r as FreeActionCreator, t as ActionCreator, z as EventMap } from "./action-creator-Bpa8BUS9.js";
2
2
  import { n as NoClash } from "./context-types-BKIH5a8s.js";
3
3
  //#region src/utils/delay.d.ts
4
4
  /**
@@ -118,7 +118,8 @@ type TakeOptions<P> = {
118
118
  signal?: AbortSignal | undefined;
119
119
  };
120
120
  /**
121
- * Waits for the next `event` on the bus and resolves with its payload. It sees
121
+ * Waits for the next `event` on the bus and resolves with its payload. `event` is the name
122
+ * of an event or an action creator, as for `bus.on`. It sees
122
123
  * only events emitted after the call, takes only one, and unsubscribes when it
123
124
  * is done. If `ctx` (or `options.signal`) aborts first, it unsubscribes and
124
125
  * rejects with the abort reason.
@@ -135,6 +136,9 @@ type TakeOptions<P> = {
135
136
  * take(ctx, "saved", { signal, predicate: (id) => id === draftId }),
136
137
  * );
137
138
  *
139
+ * // an action creator works as the name does, and gives its payload type
140
+ * const stopped = await take(ctx, stopRequested);
141
+ *
138
142
  * // a type guard narrows the result: `failed` is `{ ok: false }`
139
143
  * const failed = await take(ctx, "result", {
140
144
  * predicate: (result): result is { ok: false } => !result.ok,
@@ -145,6 +149,14 @@ declare function take<E extends EventMap, K extends Keys<E>, T extends E[K]>(ctx
145
149
  predicate: (payload: E[K]) => payload is T;
146
150
  }): Promise<T>;
147
151
  declare function take<E extends EventMap, K extends Keys<E>>(ctx: Context<E>, event: K, options?: TakeOptions<E[K]>): Promise<E[K]>;
152
+ declare function take<E extends EventMap, K extends Keys<E>, T extends E[K]>(ctx: Context<E>, creator: FreeActionCreator<K>, options: TakeOptions<E[K]> & {
153
+ predicate: (payload: E[K]) => payload is T;
154
+ }): Promise<T>;
155
+ declare function take<E extends EventMap, K extends Keys<E>>(ctx: Context<E>, creator: FreeActionCreator<K>, options?: TakeOptions<E[K]>): Promise<E[K]>;
156
+ declare function take<E extends EventMap, P, T extends P>(ctx: Context<E>, creator: ActionCreator<P>, options: TakeOptions<P> & {
157
+ predicate: (payload: P) => payload is T;
158
+ }): Promise<T>;
159
+ declare function take<E extends EventMap, P>(ctx: Context<E>, creator: ActionCreator<P>, options?: TakeOptions<P>): Promise<P>;
148
160
  //#endregion
149
161
  //#region src/effects/plugin.d.ts
150
162
  /** The effects that `effectsPlugin` can put on `ctx`. */
@@ -171,7 +183,12 @@ type Bound<E extends EventMap> = {
171
183
  <T extends Results>(effects: T): Promise<{ [K in keyof T]: PromiseSettledResult<Awaited<ReturnType<T[K]>>>; }>;
172
184
  <const T extends List>(effects: T): Promise<{ -readonly [K in keyof T]: PromiseSettledResult<Awaited<ReturnType<T[K]>>>; }>;
173
185
  };
174
- take: <K extends Keys<E>>(event: K, options?: TakeOptions<E[K]>) => Promise<E[K]>;
186
+ take: {
187
+ <K extends Keys<E>>(event: K, options?: TakeOptions<E[K]>): Promise<E[K]>;
188
+ /** A creator without a payload type: the payload comes from the event map. */
189
+ <K extends Keys<E>>(creator: FreeActionCreator<K>, options?: TakeOptions<E[K]>): Promise<E[K]>;
190
+ <P>(creator: ActionCreator<P>, options?: TakeOptions<P>): Promise<P>;
191
+ };
175
192
  delay: (ms: number | (() => number)) => Promise<void>;
176
193
  };
177
194
  /** Any function whose first parameter takes `{ signal }` can go on the context, not only the built-in ones. */
package/dist/scope.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { P as WithSignal, a as EmitScope, d as Effects, f as Signaled, h as Bus, o as Scope, u as Effect, z as EventMap } from "./action-creator-Bpa8BUS9.js";
2
- import { n as ScopeSlots, r as Scoped } from "./types-CbdJKC2z.js";
2
+ import { n as ScopeSlots, r as Scoped } from "./types-DC-aLJit.js";
3
3
  //#region src/scope/effect.d.ts
4
4
  /**
5
5
  * Marks a function whose first parameter is `{ signal }` as an effect, so that
@@ -0,0 +1,46 @@
1
+ import { T as EventKey, h as Bus, r as FreeActionCreator, t as ActionCreator, z as EventMap } from "./action-creator-Bpa8BUS9.js";
2
+ import { t as StateOf } from "./state-of-C19H6BoV.js";
3
+ import { Readable } from "svelte/store";
4
+ //#region src/svelte/plugin.d.ts
5
+ /** What `sveltePlugin` adds to the bus. */
6
+ type SvelteApi<E extends EventMap> = {
7
+ /**
8
+ * A readable Svelte store: `initial` at first, then the payload of every emit of `event`.
9
+ * The bus listens only while something subscribes (the first subscriber starts it, the last
10
+ * one stops it), and the bus keeps no values, so an event emitted while nothing reads the
11
+ * store is lost. It is state of the components that read it, not a store of the app. A
12
+ * function payload is stored, not called. The method does not read `this`, so
13
+ * `export const { eventStore } = bus` gives a free function.
14
+ */
15
+ eventStore: {
16
+ <K extends EventKey<E>, S>(event: K, initial: StateOf<E[K], S>): Readable<StateOf<E[K], S>>;
17
+ /** A creator without a payload type: the payload comes from the event map. */
18
+ <K extends EventKey<E>, S>(creator: FreeActionCreator<K>, initial: StateOf<E[K], S>): Readable<StateOf<E[K], S>>;
19
+ <P, T extends string>(creator: ActionCreator<P, T>, initial: P): Readable<P>;
20
+ };
21
+ };
22
+ /**
23
+ * Adds `bus.eventStore(event, initial)`: an event of the bus as a Svelte store, so `$found` in
24
+ * a component shows the last payload and Svelte subscribes and unsubscribes for you. The store
25
+ * is not a store of the app: it keeps the last payload only while something reads it, and an
26
+ * event that came before is lost. Keep a value that must outlive the component in a store of
27
+ * your own. Needs `svelte` 5 or newer. Returns the same bus.
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * import { createBus } from "nanoeffects";
32
+ * import { createAction } from "nanoeffects/actions";
33
+ * import { sveltePlugin } from "nanoeffects/svelte";
34
+ *
35
+ * export const bus = createBus().use(sveltePlugin());
36
+ * export const { eventStore } = bus; // a free function
37
+ *
38
+ * const searchLoaded = createAction<string[]>("search/loaded");
39
+ *
40
+ * // in a component: `$found` is string[], set by every searchLoaded
41
+ * const found = eventStore(searchLoaded, []);
42
+ * ```
43
+ */
44
+ export declare const sveltePlugin: () => <E extends EventMap>(bus: Bus<E>) => Bus<E> & SvelteApi<E>;
45
+ //#endregion
46
+ export type { SvelteApi };
package/dist/svelte.js ADDED
@@ -0,0 +1 @@
1
+ import{readable as e}from"svelte/store";const t=()=>t=>{function n(n,r){let i=n;return e(r,e=>t.on(i,e))}return Object.assign(t,{eventStore:n})};export{t as sveltePlugin};
@@ -1,5 +1,5 @@
1
1
  import { d as Effects, o as Scope, s as WithFields, z as EventMap } from "./action-creator-Bpa8BUS9.js";
2
- import { t as BoundOf } from "./plugin-D9UTzGRG.js";
2
+ import { t as BoundOf } from "./plugin-BiGv84Xu.js";
3
3
  //#region src/scope/types.d.ts
4
4
  /**
5
5
  * The slots `scopePlugin` fills for `modulePlugin`. They are not on `Bus`: a bus
package/docs/README.md CHANGED
@@ -19,6 +19,7 @@ Code for every guide step: [`examples/guide.ts`](../examples/guide.ts) (type-che
19
19
  | Already on Redux / Zustand / MobX / Pinia | [Stores](stores.md) |
20
20
  | A React form with async checks | [Build a sign-up form in React](react.md) |
21
21
  | A Vue app | [Use nanoeffects in a Vue app](vue.md) |
22
+ | A Svelte app | [Use nanoeffects in a Svelte app](svelte.md) |
22
23
  | Old responses overwrite new ones | [Cancel stale requests](cancel-stale-requests.md) |
23
24
  | Debounced input that must also cancel the old request | [Debounce and abort](debounce-and-abort.md) |
24
25
  | A second click sends a second request | [Prevent a double submit](prevent-double-submit.md) |
@@ -34,6 +35,7 @@ Code for every guide step: [`examples/guide.ts`](../examples/guide.ts) (type-che
34
35
  - [Actions, commands, jobs and modules](actions.md)
35
36
  - [Sign-up form in React](react.md) — one form: races, double submit, retry
36
37
  - [nanoeffects in a Vue app](vue.md) — `watchEmitter` and `useEventRef`
38
+ - [nanoeffects in a Svelte app](svelte.md) — `eventStore`
37
39
  - [Context fields](context.md) — store or client on every task
38
40
  - [Use the bus from a class](oop.md) — `extendBus`, `@WithBus`, `@On`, and `dispose()` for the subscriptions of an instance
39
41
  - [TypeScript in many files](typescript.md) — keep the types of the bus in commands and modules
package/docs/effects.md CHANGED
@@ -244,18 +244,24 @@ bus.on("watch", (_, ctx) => {
244
244
  - Under `latest`, subscriptions of a superseded run end with that run.
245
245
  - `ctx.off(event)` clears every handler of the event on the bus, not only the task’s.
246
246
 
247
- `take(ctx, event, options?)` waits for the next `event` and resolves with its payload:
247
+ `take(ctx, event, options?)` waits for the next `event` and resolves with its payload. `event` is the name of an event or an action creator, as for `bus.on`:
248
248
 
249
249
  ```js
250
250
  import { createBus } from "nanoeffects";
251
+ import { createAction } from "nanoeffects/actions";
251
252
  import { take, timeout } from "nanoeffects/effects";
252
253
 
253
254
  const bus = createBus();
255
+ const stopRequested = createAction("stop"); // an event with a name; calling it builds the action
254
256
 
255
257
  bus.on("login", async (user, ctx) => {
256
258
  const reason = await take(ctx, "logout"); // resolves on the next logout
257
259
  cleanup(user, reason);
258
260
 
261
+ // an action creator works the same, and its payload type is the type of the result
262
+ const stopped = await take(ctx, stopRequested);
263
+ console.log(stopped);
264
+
259
265
  // wait for a matching event, but not longer than 5 s
260
266
  const id = await timeout(ctx, 5000, ({ signal }) =>
261
267
  take(ctx, "saved", { signal, predicate: (savedId) => savedId === draft.id }),
@@ -264,6 +270,7 @@ bus.on("login", async (user, ctx) => {
264
270
  ```
265
271
 
266
272
  - Sees only events emitted after the call, takes one, and unsubscribes.
273
+ - With an action creator the result has the payload type of the creator. A creator made without a payload type (`createAction("saved")`) takes it from the event map of the bus.
267
274
  - `options.predicate` skips payloads it rejects. In TypeScript, a type guard (`(payload): payload is Admin`) narrows the type of the result.
268
275
  - `options.signal` stops the wait (how a `race` or `timeout` starter cancels it).
269
276
  - On abort of the task or of `options.signal`, unsubscribes and rejects with the abort reason.
@@ -14,7 +14,7 @@ Read this page if you know redux-saga and want to find the same job in nanoeffec
14
14
  | `fork(fn, x)` | `ctx.run(task, x)` without `await` |
15
15
  | `spawn(fn, x)` | `ctx.emit(event, x)` or `bus.emit(event, x)` |
16
16
  | `put(action)` | `ctx.emit(action)` |
17
- | `take(pattern)` | [`take(ctx, event, { predicate })`](effects.md) |
17
+ | `take(pattern)` | [`take(ctx, event, { predicate })`](effects.md), where `event` is a name or an action creator |
18
18
  | `select` | a [context field](context.md), such as `store` |
19
19
  | `all`, `race` | [`all`, `race`](effects.md) |
20
20
  | `retry`, `delay` | [`retry`, `delay`](effects.md) |
@@ -62,6 +62,8 @@ bus.on(
62
62
 
63
63
  Tasks are plain `async` functions. `ctx.signal` replaces `cancel`: pass it to `fetch` or to your client, and the request stops.
64
64
 
65
+ To see the counter, `takeLatest` with `delay`, a cancel and a failing call running, open the [counter example](../examples/counter): it has a page without a store and a page with Redux Toolkit.
66
+
65
67
  ## Start a task without waiting
66
68
 
67
69
  `fork` and `spawn` differ in what happens when the caller is aborted. Pick by that.
package/docs/package.md CHANGED
@@ -16,6 +16,7 @@ Imports are split so you only load what you use. `createBus` stays small; the re
16
16
  | `nanoeffects/redux` | `createEffectsMiddleware` |
17
17
  | `nanoeffects/observable` | `createObserve`, `Subject` |
18
18
  | `nanoeffects/react` | `reactPlugin`: adds the `useEmitter` hook to a bus (needs React 18 or newer) |
19
+ | `nanoeffects/svelte` | `sveltePlugin`: adds `eventStore` to a bus (needs Svelte 5 or newer) |
19
20
  | `nanoeffects/vue` | `vuePlugin`: adds `watchEmitter` and `useEventRef` to a bus (needs Vue 3.3 or newer) |
20
21
  | `nanoeffects/dev` | `devPlugin` (no-op in production) |
21
22
  | `nanoeffects/trace` | `createTracer`, the loggers and `tracePlugin` (names for the trace) |
package/docs/starter.md CHANGED
@@ -48,7 +48,7 @@ Pass `--template` to skip the question. With npm, put `--` before the option.
48
48
  | `react-ts` | The `react` app in TypeScript | You build a React app in TypeScript |
49
49
  | `domains-ts` | Commands, a job and modules, with the logic split into domain folders and React as a thin layer | You build an app with more than one feature and want the logic off the UI |
50
50
  | `vue-ts` | The `react-ts` app in Vue 3, with `watchEmitter` and `useEventRef` from `nanoeffects/vue` | You build a Vue 3 app |
51
- | `svelte-ts` | The `react-ts` app in Svelte 5, with a Svelte store made from an event | You build a Svelte app |
51
+ | `svelte-ts` | The `react-ts` app in Svelte 5, with `eventStore` from `nanoeffects/svelte` | You build a Svelte app |
52
52
 
53
53
  ```bash
54
54
  npm create nanoeffects@latest my-app -- --template react
@@ -74,7 +74,7 @@ npm create nanoeffects@latest my-app -- --template vue-ts
74
74
 
75
75
  ### Start with Svelte
76
76
 
77
- `svelte-ts` is the search app of `react-ts` in Svelte 5. It needs no part of nanoeffects for Svelte: a Svelte store is any object with `subscribe`, so a small helper of the project, `src/event-store.ts`, makes a store from an event with `readable` and `bus.on`. In a component, `$found` reads it, and Svelte subscribes and unsubscribes for you. The query goes to the bus from the `oninput` handler, so nothing is emitted when the component mounts. The store listens only while something reads it, and is [not a store of the app](react.md#show-the-last-value-of-an-event-as-state): a value that several components share belongs in a store of your own.
77
+ `svelte-ts` is the search app of `react-ts` in Svelte 5. Its bus uses `sveltePlugin` from `nanoeffects/svelte`: `eventStore` makes a Svelte store from an event. In a component, `$found` reads it, and Svelte subscribes and unsubscribes for you. The query goes to the bus from the `oninput` handler, so nothing is emitted when the component mounts. The store listens only while something reads it, and is [not a store of the app](svelte.md#it-is-not-a-store-of-the-app): a value that several components share belongs in a store of your own.
78
78
 
79
79
  ```bash
80
80
  npm create nanoeffects@latest my-app -- --template svelte-ts
package/docs/stores.md CHANGED
@@ -25,7 +25,7 @@ Redux’s `dispatch` → reducers updates **state**. It does not give you first-
25
25
 
26
26
  `createEffectsMiddleware(bus)` does the same job: after the reducer runs, the action also hits the nanoeffects bus you pass to it. Keep RTK for state; use policies and effects for async.
27
27
 
28
- Skip this section if you are not already on Redux. The recipe as a file, type-checked with the project: [`examples/redux.ts`](../examples/redux.ts).
28
+ Skip this section if you are not already on Redux. The recipe as a file, type-checked with the project: [`examples/redux.ts`](../examples/redux.ts). To run it, open the [counter example](../examples/counter): `redux.html` is a counter with Redux Toolkit and this middleware.
29
29
 
30
30
  ```js
31
31
  // bus.js
package/docs/svelte.md ADDED
@@ -0,0 +1,81 @@
1
+ # Use nanoeffects in a Svelte app
2
+
3
+ Use this page when your app is in Svelte 5 and a component has to show the result of an event. `sveltePlugin` gives you one function for that, `eventStore`. To see it in a running project, start from the `svelte-ts` template in [Start a project from a template](starter.md#start-with-svelte).
4
+
5
+ You need Svelte 5 or newer and `nanoeffects` installed. If you do not know what the bus is, read the [Guide](guide.md) first.
6
+
7
+ ## Add the plugin to the bus
8
+
9
+ **Problem.** A Svelte component reads a value with `$store`. An event of the bus is not a store, so without help the component writes its own `readable` and its own `bus.on`, and has to remember to stop listening. The same few lines are copied into every component.
10
+
11
+ **When.** A component shows the payload of an event, such as the result of a search.
12
+
13
+ `sveltePlugin()` adds `eventStore` to the bus. Take it out of the bus once, in the file that makes it, and import it where you need it:
14
+
15
+ ```js
16
+ // bus.js
17
+ import { createBus } from "nanoeffects";
18
+ import { sveltePlugin } from "nanoeffects/svelte";
19
+
20
+ // createBus — the event bus, created once outside Svelte
21
+ // sveltePlugin — adds eventStore to the bus
22
+ export const bus = createBus().use(sveltePlugin());
23
+ export const { eventStore } = bus; // a free function: it does not read `this`
24
+ ```
25
+
26
+ ## Show the result of an event
27
+
28
+ <!-- docs-check: continue -->
29
+
30
+ `eventStore(event, initial)` returns a Svelte store. Its value is `initial` at first and the payload of every `event` after that. In a component, `$found` reads it, and Svelte subscribes and unsubscribes for you. A payload that is a function is stored, not called.
31
+
32
+ ```js
33
+ // search.js
34
+ import { createAction } from "nanoeffects/actions";
35
+
36
+ // createAction — an event with a name; calling it builds { type, payload }
37
+ export const searchLoaded = createAction("search/loaded");
38
+ ```
39
+
40
+ <!-- docs-check: skip - a .svelte file -->
41
+ ```svelte
42
+ <script>
43
+ import { eventStore } from "./bus";
44
+ import { searchLoaded } from "./search";
45
+
46
+ // eventStore — like a store of [], but searchLoaded sets the value
47
+ const found = eventStore(searchLoaded, []);
48
+ </script>
49
+
50
+ <ul>
51
+ {#each $found as title (title)}
52
+ <li>{title}</li>
53
+ {/each}
54
+ </ul>
55
+ ```
56
+
57
+ In TypeScript the type of the store comes from the event: with `createAction<string[]>("search/loaded")` it is `Readable<string[]>`, and for an event with no payload type it comes from `initial`.
58
+
59
+ To send a value to the bus, call `bus.emit` from the handler of the event, for example `oninput`. Nothing is emitted when the component mounts, so no plugin function is needed for that direction.
60
+
61
+ ### It is not a store of the app
62
+
63
+ The bus listens only while something reads the store: the first `$found` starts it, and the last one stops it. The bus keeps no values, so an event that came while nothing read the store is lost, and a component that mounts later starts from `initial`. To keep a value for components that come later, keep it in a store of your own and write to it from a handler of the event:
64
+
65
+ ```js
66
+ // found-store.js
67
+ import { writable } from "svelte/store";
68
+ import { bus } from "./bus";
69
+ import { searchLoaded } from "./search";
70
+
71
+ // writable — a Svelte store that you keep for the whole app
72
+ export const foundTitles = writable([]);
73
+
74
+ // bus.on — copy every searchLoaded into the store, whether or not a component is open
75
+ bus.on(searchLoaded, (titles) => foundTitles.set(titles));
76
+ ```
77
+
78
+ ## Where to go next
79
+
80
+ - The same job for React: [Build a sign-up form in React](react.md); for Vue: [Use nanoeffects in a Vue app](vue.md).
81
+ - A policy in a component (a debounced save): in the script of a component make it once with [`withPolicy`](policies.md#use-a-policy-without-a-bus); Svelte runs the script once, so it needs no hook.
package/llms-full.txt CHANGED
@@ -9,7 +9,7 @@ Rules that generated code often gets wrong:
9
9
  - A handler gets the payload and a task context: `(payload, ctx)`. The context has `signal`, `emit`, `on`, `run`. Pass `ctx.signal` to `fetch`.
10
10
  - Effects take `ctx` as the first argument: `retry(ctx, fn, options)`, `timeout(ctx, ms, fn)`, `take(ctx, "event")`.
11
11
  - Policies wrap a handler: `bus.on("search", latest(async (query, ctx) => { ... }))`.
12
- - Each part is imported from its own path: `nanoeffects` (`createBus`), `nanoeffects/policies`, `nanoeffects/effects`, `nanoeffects/actions`, `nanoeffects/redux`, `nanoeffects/observable`, `nanoeffects/react` (`reactPlugin`, adds `bus.useEmitter` and `bus.useEventState`; `usePolicy`; needs React), `nanoeffects/vue` (`vuePlugin`, adds `bus.watchEmitter` and `bus.useEventRef`; needs Vue), `nanoeffects/trace` (`createTracer`, loggers, `tracePlugin`), `nanoeffects/dev`.
12
+ - Each part is imported from its own path: `nanoeffects` (`createBus`), `nanoeffects/policies`, `nanoeffects/effects`, `nanoeffects/actions`, `nanoeffects/redux`, `nanoeffects/observable`, `nanoeffects/react` (`reactPlugin`, adds `bus.useEmitter` and `bus.useEventState`; `usePolicy`; needs React), `nanoeffects/svelte` (`sveltePlugin`, adds `bus.eventStore`; needs Svelte), `nanoeffects/vue` (`vuePlugin`, adds `bus.watchEmitter` and `bus.useEventRef`; needs Vue), `nanoeffects/trace` (`createTracer`, loggers, `tracePlugin`), `nanoeffects/dev`.
13
13
  - `bus.emit(command(payload))` runs the command's handler and returns its result. Plain events return nothing.
14
14
 
15
15
  ---
@@ -553,7 +553,7 @@ Pass `--template` to skip the question. With npm, put `--` before the option.
553
553
  | `react-ts` | The `react` app in TypeScript | You build a React app in TypeScript |
554
554
  | `domains-ts` | Commands, a job and modules, with the logic split into domain folders and React as a thin layer | You build an app with more than one feature and want the logic off the UI |
555
555
  | `vue-ts` | The `react-ts` app in Vue 3, with `watchEmitter` and `useEventRef` from `nanoeffects/vue` | You build a Vue 3 app |
556
- | `svelte-ts` | The `react-ts` app in Svelte 5, with a Svelte store made from an event | You build a Svelte app |
556
+ | `svelte-ts` | The `react-ts` app in Svelte 5, with `eventStore` from `nanoeffects/svelte` | You build a Svelte app |
557
557
 
558
558
  ```bash
559
559
  npm create nanoeffects@latest my-app -- --template react
@@ -579,7 +579,7 @@ npm create nanoeffects@latest my-app -- --template vue-ts
579
579
 
580
580
  ### Start with Svelte
581
581
 
582
- `svelte-ts` is the search app of `react-ts` in Svelte 5. It needs no part of nanoeffects for Svelte: a Svelte store is any object with `subscribe`, so a small helper of the project, `src/event-store.ts`, makes a store from an event with `readable` and `bus.on`. In a component, `$found` reads it, and Svelte subscribes and unsubscribes for you. The query goes to the bus from the `oninput` handler, so nothing is emitted when the component mounts. The store listens only while something reads it, and is [not a store of the app](react.md#show-the-last-value-of-an-event-as-state): a value that several components share belongs in a store of your own.
582
+ `svelte-ts` is the search app of `react-ts` in Svelte 5. Its bus uses `sveltePlugin` from `nanoeffects/svelte`: `eventStore` makes a Svelte store from an event. In a component, `$found` reads it, and Svelte subscribes and unsubscribes for you. The query goes to the bus from the `oninput` handler, so nothing is emitted when the component mounts. The store listens only while something reads it, and is [not a store of the app](svelte.md#it-is-not-a-store-of-the-app): a value that several components share belongs in a store of your own.
583
583
 
584
584
  ```bash
585
585
  npm create nanoeffects@latest my-app -- --template svelte-ts
@@ -692,6 +692,7 @@ Imports are split so you only load what you use. `createBus` stays small; the re
692
692
  | `nanoeffects/redux` | `createEffectsMiddleware` |
693
693
  | `nanoeffects/observable` | `createObserve`, `Subject` |
694
694
  | `nanoeffects/react` | `reactPlugin`: adds the `useEmitter` hook to a bus (needs React 18 or newer) |
695
+ | `nanoeffects/svelte` | `sveltePlugin`: adds `eventStore` to a bus (needs Svelte 5 or newer) |
695
696
  | `nanoeffects/vue` | `vuePlugin`: adds `watchEmitter` and `useEventRef` to a bus (needs Vue 3.3 or newer) |
696
697
  | `nanoeffects/dev` | `devPlugin` (no-op in production) |
697
698
  | `nanoeffects/trace` | `createTracer`, the loggers and `tracePlugin` (names for the trace) |
@@ -1827,18 +1828,24 @@ bus.on("watch", (_, ctx) => {
1827
1828
  - Under `latest`, subscriptions of a superseded run end with that run.
1828
1829
  - `ctx.off(event)` clears every handler of the event on the bus, not only the task’s.
1829
1830
 
1830
- `take(ctx, event, options?)` waits for the next `event` and resolves with its payload:
1831
+ `take(ctx, event, options?)` waits for the next `event` and resolves with its payload. `event` is the name of an event or an action creator, as for `bus.on`:
1831
1832
 
1832
1833
  ```js
1833
1834
  import { createBus } from "nanoeffects";
1835
+ import { createAction } from "nanoeffects/actions";
1834
1836
  import { take, timeout } from "nanoeffects/effects";
1835
1837
 
1836
1838
  const bus = createBus();
1839
+ const stopRequested = createAction("stop"); // an event with a name; calling it builds the action
1837
1840
 
1838
1841
  bus.on("login", async (user, ctx) => {
1839
1842
  const reason = await take(ctx, "logout"); // resolves on the next logout
1840
1843
  cleanup(user, reason);
1841
1844
 
1845
+ // an action creator works the same, and its payload type is the type of the result
1846
+ const stopped = await take(ctx, stopRequested);
1847
+ console.log(stopped);
1848
+
1842
1849
  // wait for a matching event, but not longer than 5 s
1843
1850
  const id = await timeout(ctx, 5000, ({ signal }) =>
1844
1851
  take(ctx, "saved", { signal, predicate: (savedId) => savedId === draft.id }),
@@ -1847,6 +1854,7 @@ bus.on("login", async (user, ctx) => {
1847
1854
  ```
1848
1855
 
1849
1856
  - Sees only events emitted after the call, takes one, and unsubscribes.
1857
+ - With an action creator the result has the payload type of the creator. A creator made without a payload type (`createAction("saved")`) takes it from the event map of the bus.
1850
1858
  - `options.predicate` skips payloads it rejects. In TypeScript, a type guard (`(payload): payload is Admin`) narrows the type of the result.
1851
1859
  - `options.signal` stops the wait (how a `race` or `timeout` starter cancels it).
1852
1860
  - On abort of the task or of `options.signal`, unsubscribes and rejects with the abort reason.
@@ -2287,7 +2295,7 @@ Redux’s `dispatch` → reducers updates **state**. It does not give you first-
2287
2295
 
2288
2296
  `createEffectsMiddleware(bus)` does the same job: after the reducer runs, the action also hits the nanoeffects bus you pass to it. Keep RTK for state; use policies and effects for async.
2289
2297
 
2290
- Skip this section if you are not already on Redux. The recipe as a file, type-checked with the project: [`examples/redux.ts`](../examples/redux.ts).
2298
+ Skip this section if you are not already on Redux. The recipe as a file, type-checked with the project: [`examples/redux.ts`](../examples/redux.ts). To run it, open the [counter example](../examples/counter): `redux.html` is a counter with Redux Toolkit and this middleware.
2291
2299
 
2292
2300
  ```js
2293
2301
  // bus.js
@@ -3695,6 +3703,91 @@ In TypeScript the type of the `ref` comes from the event: with `createAction<str
3695
3703
  - A policy in a component (a debounced save): in `<script setup>` make it once with [`withPolicy`](policies.md#use-a-policy-without-a-bus); Vue runs the setup once, so it needs no hook.
3696
3704
  - Keep values in Pinia: [Connect Redux, Zustand, MobX, or Pinia](stores.md).
3697
3705
 
3706
+ ---
3707
+ Source: docs/svelte.md
3708
+
3709
+ # Use nanoeffects in a Svelte app
3710
+
3711
+ Use this page when your app is in Svelte 5 and a component has to show the result of an event. `sveltePlugin` gives you one function for that, `eventStore`. To see it in a running project, start from the `svelte-ts` template in [Start a project from a template](starter.md#start-with-svelte).
3712
+
3713
+ You need Svelte 5 or newer and `nanoeffects` installed. If you do not know what the bus is, read the [Guide](guide.md) first.
3714
+
3715
+ ## Add the plugin to the bus
3716
+
3717
+ **Problem.** A Svelte component reads a value with `$store`. An event of the bus is not a store, so without help the component writes its own `readable` and its own `bus.on`, and has to remember to stop listening. The same few lines are copied into every component.
3718
+
3719
+ **When.** A component shows the payload of an event, such as the result of a search.
3720
+
3721
+ `sveltePlugin()` adds `eventStore` to the bus. Take it out of the bus once, in the file that makes it, and import it where you need it:
3722
+
3723
+ ```js
3724
+ // bus.js
3725
+ import { createBus } from "nanoeffects";
3726
+ import { sveltePlugin } from "nanoeffects/svelte";
3727
+
3728
+ // createBus — the event bus, created once outside Svelte
3729
+ // sveltePlugin — adds eventStore to the bus
3730
+ export const bus = createBus().use(sveltePlugin());
3731
+ export const { eventStore } = bus; // a free function: it does not read `this`
3732
+ ```
3733
+
3734
+ ## Show the result of an event
3735
+
3736
+ <!-- docs-check: continue -->
3737
+
3738
+ `eventStore(event, initial)` returns a Svelte store. Its value is `initial` at first and the payload of every `event` after that. In a component, `$found` reads it, and Svelte subscribes and unsubscribes for you. A payload that is a function is stored, not called.
3739
+
3740
+ ```js
3741
+ // search.js
3742
+ import { createAction } from "nanoeffects/actions";
3743
+
3744
+ // createAction — an event with a name; calling it builds { type, payload }
3745
+ export const searchLoaded = createAction("search/loaded");
3746
+ ```
3747
+
3748
+ <!-- docs-check: skip - a .svelte file -->
3749
+ ```svelte
3750
+ <script>
3751
+ import { eventStore } from "./bus";
3752
+ import { searchLoaded } from "./search";
3753
+
3754
+ // eventStore — like a store of [], but searchLoaded sets the value
3755
+ const found = eventStore(searchLoaded, []);
3756
+ </script>
3757
+
3758
+ <ul>
3759
+ {#each $found as title (title)}
3760
+ <li>{title}</li>
3761
+ {/each}
3762
+ </ul>
3763
+ ```
3764
+
3765
+ In TypeScript the type of the store comes from the event: with `createAction<string[]>("search/loaded")` it is `Readable<string[]>`, and for an event with no payload type it comes from `initial`.
3766
+
3767
+ To send a value to the bus, call `bus.emit` from the handler of the event, for example `oninput`. Nothing is emitted when the component mounts, so no plugin function is needed for that direction.
3768
+
3769
+ ### It is not a store of the app
3770
+
3771
+ The bus listens only while something reads the store: the first `$found` starts it, and the last one stops it. The bus keeps no values, so an event that came while nothing read the store is lost, and a component that mounts later starts from `initial`. To keep a value for components that come later, keep it in a store of your own and write to it from a handler of the event:
3772
+
3773
+ ```js
3774
+ // found-store.js
3775
+ import { writable } from "svelte/store";
3776
+ import { bus } from "./bus";
3777
+ import { searchLoaded } from "./search";
3778
+
3779
+ // writable — a Svelte store that you keep for the whole app
3780
+ export const foundTitles = writable([]);
3781
+
3782
+ // bus.on — copy every searchLoaded into the store, whether or not a component is open
3783
+ bus.on(searchLoaded, (titles) => foundTitles.set(titles));
3784
+ ```
3785
+
3786
+ ## Where to go next
3787
+
3788
+ - The same job for React: [Build a sign-up form in React](react.md); for Vue: [Use nanoeffects in a Vue app](vue.md).
3789
+ - A policy in a component (a debounced save): in the script of a component make it once with [`withPolicy`](policies.md#use-a-policy-without-a-bus); Svelte runs the script once, so it needs no hook.
3790
+
3698
3791
  ---
3699
3792
  Source: docs/context.md
3700
3793
 
@@ -4633,7 +4726,7 @@ Read this page if you know redux-saga and want to find the same job in nanoeffec
4633
4726
  | `fork(fn, x)` | `ctx.run(task, x)` without `await` |
4634
4727
  | `spawn(fn, x)` | `ctx.emit(event, x)` or `bus.emit(event, x)` |
4635
4728
  | `put(action)` | `ctx.emit(action)` |
4636
- | `take(pattern)` | [`take(ctx, event, { predicate })`](effects.md) |
4729
+ | `take(pattern)` | [`take(ctx, event, { predicate })`](effects.md), where `event` is a name or an action creator |
4637
4730
  | `select` | a [context field](context.md), such as `store` |
4638
4731
  | `all`, `race` | [`all`, `race`](effects.md) |
4639
4732
  | `retry`, `delay` | [`retry`, `delay`](effects.md) |
@@ -4681,6 +4774,8 @@ bus.on(
4681
4774
 
4682
4775
  Tasks are plain `async` functions. `ctx.signal` replaces `cancel`: pass it to `fetch` or to your client, and the request stops.
4683
4776
 
4777
+ To see the counter, `takeLatest` with `delay`, a cancel and a failing call running, open the [counter example](../examples/counter): it has a page without a store and a page with Redux Toolkit.
4778
+
4684
4779
  ## Start a task without waiting
4685
4780
 
4686
4781
  `fork` and `spawn` differ in what happens when the caller is aborted. Pick by that.
package/llms.txt CHANGED
@@ -9,7 +9,7 @@ Rules that generated code often gets wrong:
9
9
  - A handler gets the payload and a task context: `(payload, ctx)`. The context has `signal`, `emit`, `on`, `run`. Pass `ctx.signal` to `fetch`.
10
10
  - Effects take `ctx` as the first argument: `retry(ctx, fn, options)`, `timeout(ctx, ms, fn)`, `take(ctx, "event")`.
11
11
  - Policies wrap a handler: `bus.on("search", latest(async (query, ctx) => { ... }))`.
12
- - Each part is imported from its own path: `nanoeffects` (`createBus`), `nanoeffects/policies`, `nanoeffects/effects`, `nanoeffects/actions`, `nanoeffects/redux`, `nanoeffects/observable`, `nanoeffects/react` (`reactPlugin`, adds `bus.useEmitter` and `bus.useEventState`; `usePolicy`; needs React), `nanoeffects/vue` (`vuePlugin`, adds `bus.watchEmitter` and `bus.useEventRef`; needs Vue), `nanoeffects/trace` (`createTracer`, loggers, `tracePlugin`), `nanoeffects/dev`.
12
+ - Each part is imported from its own path: `nanoeffects` (`createBus`), `nanoeffects/policies`, `nanoeffects/effects`, `nanoeffects/actions`, `nanoeffects/redux`, `nanoeffects/observable`, `nanoeffects/react` (`reactPlugin`, adds `bus.useEmitter` and `bus.useEventState`; `usePolicy`; needs React), `nanoeffects/svelte` (`sveltePlugin`, adds `bus.eventStore`; needs Svelte), `nanoeffects/vue` (`vuePlugin`, adds `bus.watchEmitter` and `bus.useEventRef`; needs Vue), `nanoeffects/trace` (`createTracer`, loggers, `tracePlugin`), `nanoeffects/dev`.
13
13
  - `bus.emit(command(payload))` runs the command's handler and returns its result. Plain events return nothing.
14
14
 
15
15
  ## Start here
@@ -37,6 +37,7 @@ Rules that generated code often gets wrong:
37
37
  - [Build a sign-up form in React](docs/react.md): a form with a username check, a submit that cannot fire twice, and retry; `useEventState` shows an event as state, `usePolicy` keeps a debounced handler between renders
38
38
  - [Build a chat with domains, modules and a small server](docs/chat-example.md): rooms, a history under `latest`, a send under `queue` and `retry`, a search with `allSettled` and `timeout`, new messages polled with `poll`
39
39
  - [Use nanoeffects in a Vue app](docs/vue.md): `vuePlugin` adds `watchEmitter` (a value of a component to the bus) and `useEventRef` (an event as a ref)
40
+ - [Use nanoeffects in a Svelte app](docs/svelte.md): `sveltePlugin` adds `eventStore` (an event as a Svelte store)
40
41
  - [Context fields](docs/context.md): put a store or client on every task
41
42
  - [Scopes](docs/scope.md): fields for one command, action, job, module or `emit`, and a way to replace them in a test
42
43
  - [Use the bus from a class](docs/oop.md): `Emitter`, `extendBus`, `@WithBus`, `@On`, `@Once`, and `dispose()` for the subscriptions of an instance
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nanoeffects",
3
- "version": "0.21.0",
3
+ "version": "0.22.0",
4
4
  "description": "Cancel stale async work and fix race conditions in event handlers: a typed event bus where every handler is a task with an AbortSignal, plus latest, debounce, throttle, queue, retry, timeout and poll. About 1.4 kB gzip.",
5
5
  "keywords": [
6
6
  "event-bus",
@@ -126,6 +126,10 @@
126
126
  "types": "./dist/react.d.ts",
127
127
  "import": "./dist/react.js"
128
128
  },
129
+ "./svelte": {
130
+ "types": "./dist/svelte.d.ts",
131
+ "import": "./dist/svelte.js"
132
+ },
129
133
  "./vue": {
130
134
  "types": "./dist/vue.d.ts",
131
135
  "import": "./dist/vue.js"
@@ -183,6 +187,7 @@
183
187
  "react-dom": "^19.3.1",
184
188
  "redux": "^5.0.1",
185
189
  "size-limit": "^14.2.0",
190
+ "svelte": "^5.57.3",
186
191
  "tsdown": "0.23.1",
187
192
  "typescript": "7.0.2",
188
193
  "typescript-5": "npm:typescript@^5.9.3",
@@ -262,6 +267,14 @@
262
267
  ],
263
268
  "limit": "1.24 kB"
264
269
  },
270
+ {
271
+ "name": "svelte",
272
+ "path": "dist/svelte.js",
273
+ "ignore": [
274
+ "svelte"
275
+ ],
276
+ "limit": "0.3 kB"
277
+ },
265
278
  {
266
279
  "name": "vue",
267
280
  "path": "dist/vue.js",
@@ -283,12 +296,16 @@
283
296
  ],
284
297
  "peerDependencies": {
285
298
  "react": ">=18",
299
+ "svelte": ">=5",
286
300
  "vue": ">=3.3"
287
301
  },
288
302
  "peerDependenciesMeta": {
289
303
  "react": {
290
304
  "optional": true
291
305
  },
306
+ "svelte": {
307
+ "optional": true
308
+ },
292
309
  "vue": {
293
310
  "optional": true
294
311
  }