@vielzeug/ripple 26.10.6 → 26.10.9

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/README.md CHANGED
@@ -15,7 +15,9 @@ yarn add @vielzeug/ripple
15
15
  ```ts
16
16
  import { createRipple } from '@vielzeug/ripple';
17
17
 
18
- const ripple = createRipple();
18
+ const ripple = createRipple({
19
+ onError: (error, context) => console.error(context.kind, error),
20
+ });
19
21
 
20
22
  const count = ripple.signal(0);
21
23
  const doubled = ripple.computed(() => count.value * 2);
@@ -30,6 +32,10 @@ stop.dispose();
30
32
  ripple.dispose();
31
33
  ```
32
34
 
35
+ `onError` handles runtime callback failures; async resource failures are state values. Effects
36
+ flush synchronously, so use `batch()` to coalesce writes. Package errors use `RippleError`,
37
+ `RippleCycleError`, and `RippleDisposedError`.
38
+
33
39
  ## Documentation
34
40
 
35
41
  - [Overview](https://vielzeug.dev/ripple/)
package/dist/_async.cjs CHANGED
@@ -1,2 +1,2 @@
1
- const e=require("./errors.cjs"),t=require("./runtime.cjs");var createResource=n=>(r,i,a)=>{let o=n.signal({status:`pending`},{name:a?.name}),s=n.signal(0),c,l=!1,u,run=()=>{s.value,c?.abort();let e;try{e=r()}catch(e){o.value=l?{error:e,previous:u,status:`error`}:{error:e,status:`error`};return}let t=new AbortController;c=t,o.value=l?{previous:u,status:`pending`}:{status:`pending`};let n;try{n=Promise.resolve(i(e,{signal:t.signal}))}catch(e){n=Promise.reject(e)}n.then(e=>{!d.disposed&&!t.signal.aborted&&(l=!0,u=e,o.value={status:`success`,value:e})},e=>{!d.disposed&&!t.signal.aborted&&(o.value=l?{error:e,previous:u,status:`error`}:{error:e,status:`error`})})},d=n.effect(()=>(run(),()=>c?.abort()),{name:a?.name}),assertActive=()=>{if(d.disposed)throw new e.RippleDisposedResourceError(`Cannot use a disposed resource.`)},f={get disposalSignal(){return d.disposalSignal},dispose:()=>d.dispose(),get disposed(){return d.disposed},get name(){return o.name},peek:()=>o.peek(),reload:()=>{assertActive(),s.value=s.peek()+1},subscribe:e=>(assertActive(),o.subscribe(e)),[Symbol.dispose](){this.dispose()},get value(){return o.value}};return Object.defineProperty(f,t.REACTIVE,{value:!0}),f};exports.createResource=createResource;
1
+ const e=require("./errors.cjs"),t=require("./runtime.cjs");var createResource=n=>(r,i,a)=>{let o=n.signal({status:`pending`},{name:a?.name}),s=n.signal(0),c,l=!1,u,run=()=>{s.value,c?.abort();let e;try{e=r()}catch(e){o.value=l?{error:e,previous:u,status:`error`}:{error:e,status:`error`};return}let t=new AbortController;c=t,o.value=l?{previous:u,status:`pending`}:{status:`pending`};let n;try{n=Promise.resolve(i(e,{signal:t.signal}))}catch(e){n=Promise.reject(e)}n.then(e=>{!d.disposed&&!t.signal.aborted&&(l=!0,u=e,o.value={status:`success`,value:e})},e=>{!d.disposed&&!t.signal.aborted&&(o.value=l?{error:e,previous:u,status:`error`}:{error:e,status:`error`})})},d=n.effect(()=>(run(),()=>c?.abort()),{name:a?.name}),assertActive=()=>{if(d.disposed)throw new e.RippleDisposedError(`Cannot use a disposed resource.`)},f={get disposalSignal(){return d.disposalSignal},dispose:()=>d.dispose(),get disposed(){return d.disposed},get name(){return o.name},peek:()=>o.peek(),reload:()=>{assertActive(),s.value=s.peek()+1},subscribe:e=>(assertActive(),o.subscribe(e)),[Symbol.dispose](){this.dispose()},get value(){return o.value}};return Object.defineProperty(f,t.REACTIVE,{value:!0}),f};exports.createResource=createResource;
2
2
  //# sourceMappingURL=_async.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"_async.cjs","names":[],"sources":["../src/_async.ts"],"sourcesContent":["import { RippleDisposedResourceError } from './errors';\nimport { REACTIVE } from './runtime';\nimport type { Disposable, EffectHandle, Readable, Signal } from './types';\n\nexport type AsyncState<T> =\n | { readonly previous?: T; readonly status: 'pending' }\n | { readonly status: 'success'; readonly value: T }\n | { readonly error: unknown; readonly previous?: T; readonly status: 'error' };\n\nexport interface Resource<T> extends Readable<AsyncState<T>>, Disposable {\n reload(): void;\n}\n\nexport type ResourceOptions = {\n name?: string;\n};\n\ntype AsyncRuntime = {\n effect(callback: () => undefined | (() => void), options?: { name?: string }): EffectHandle;\n signal<T>(initial: T, options?: { name?: string }): Signal<T>;\n};\n\n/** Resource only depends on primitive runtime methods; graph binding stays private. */\nexport const createResource =\n (runtime: AsyncRuntime) =>\n <Source, Value>(\n source: () => Source,\n loader: (source: Source, context: { readonly signal: AbortSignal }) => Promise<Value>,\n options?: ResourceOptions,\n ): Resource<Value> => {\n const state = runtime.signal<AsyncState<Value>>({ status: 'pending' }, { name: options?.name });\n const reloadEpoch = runtime.signal(0);\n let active: AbortController | undefined;\n let hasPrevious = false;\n let previousValue: Value | undefined;\n\n const run = (): void => {\n void reloadEpoch.value;\n active?.abort();\n\n let input: Source;\n\n try {\n input = source();\n } catch (error) {\n state.value = hasPrevious\n ? { error, previous: previousValue as Value, status: 'error' }\n : { error, status: 'error' };\n\n return;\n }\n\n const next = new AbortController();\n\n active = next;\n state.value = hasPrevious ? { previous: previousValue as Value, status: 'pending' } : { status: 'pending' };\n\n let request: Promise<Value>;\n\n try {\n request = Promise.resolve(loader(input, { signal: next.signal }));\n } catch (error) {\n request = Promise.reject(error);\n }\n\n void request.then(\n (value) => {\n if (!stop.disposed && !next.signal.aborted) {\n hasPrevious = true;\n previousValue = value;\n state.value = { status: 'success', value };\n }\n },\n (error: unknown) => {\n if (!stop.disposed && !next.signal.aborted) {\n state.value = hasPrevious\n ? { error, previous: previousValue as Value, status: 'error' }\n : { error, status: 'error' };\n }\n },\n );\n };\n\n const stop = runtime.effect(\n () => {\n run();\n\n return () => active?.abort();\n },\n { name: options?.name },\n );\n\n const assertActive = (): void => {\n if (stop.disposed) throw new RippleDisposedResourceError('Cannot use a disposed resource.');\n };\n const resource: Resource<Value> = {\n get disposalSignal() {\n return stop.disposalSignal;\n },\n dispose: () => stop.dispose(),\n get disposed() {\n return stop.disposed;\n },\n get name() {\n return state.name;\n },\n peek: () => state.peek(),\n reload: () => {\n assertActive();\n reloadEpoch.value = reloadEpoch.peek() + 1;\n },\n subscribe: (listener) => {\n assertActive();\n return state.subscribe(listener);\n },\n [Symbol.dispose]() {\n this.dispose();\n },\n get value() {\n return state.value;\n },\n };\n\n Object.defineProperty(resource, REACTIVE, { value: true });\n\n return resource;\n };\n"],"mappings":"2DAuBA,IAAa,eACV,IAEC,EACA,EACA,IACoB,CACpB,IAAM,EAAQ,EAAQ,OAA0B,CAAE,OAAQ,SAAU,EAAG,CAAE,KAAM,GAAS,IAAK,CAAC,EACxF,EAAc,EAAQ,OAAO,CAAC,EAChC,EACA,EAAc,GACd,EAEE,QAAkB,CACtB,EAAiB,MACjB,GAAQ,MAAM,EAEd,IAAI,EAEJ,GAAI,CACF,EAAQ,EAAO,CACjB,OAAS,EAAO,CACd,EAAM,MAAQ,EACV,CAAE,QAAO,SAAU,EAAwB,OAAQ,OAAQ,EAC3D,CAAE,QAAO,OAAQ,OAAQ,EAE7B,MACF,CAEA,IAAM,EAAO,IAAI,gBAEjB,EAAS,EACT,EAAM,MAAQ,EAAc,CAAE,SAAU,EAAwB,OAAQ,SAAU,EAAI,CAAE,OAAQ,SAAU,EAE1G,IAAI,EAEJ,GAAI,CACF,EAAU,QAAQ,QAAQ,EAAO,EAAO,CAAE,OAAQ,EAAK,MAAO,CAAC,CAAC,CAClE,OAAS,EAAO,CACd,EAAU,QAAQ,OAAO,CAAK,CAChC,CAEA,EAAa,KACV,GAAU,CACL,CAAC,EAAK,UAAY,CAAC,EAAK,OAAO,UACjC,EAAc,GACd,EAAgB,EAChB,EAAM,MAAQ,CAAE,OAAQ,UAAW,OAAM,EAE7C,EACC,GAAmB,CACd,CAAC,EAAK,UAAY,CAAC,EAAK,OAAO,UACjC,EAAM,MAAQ,EACV,CAAE,QAAO,SAAU,EAAwB,OAAQ,OAAQ,EAC3D,CAAE,QAAO,OAAQ,OAAQ,EAEjC,CACF,CACF,EAEM,EAAO,EAAQ,YAEjB,IAAI,MAES,GAAQ,MAAM,GAE7B,CAAE,KAAM,GAAS,IAAK,CACxB,EAEM,iBAA2B,CAC/B,GAAI,EAAK,SAAU,MAAM,IAAI,EAAA,4BAA4B,iCAAiC,CAC5F,EACM,EAA4B,CAChC,IAAI,gBAAiB,CACnB,OAAO,EAAK,cACd,EACA,YAAe,EAAK,QAAQ,EAC5B,IAAI,UAAW,CACb,OAAO,EAAK,QACd,EACA,IAAI,MAAO,CACT,OAAO,EAAM,IACf,EACA,SAAY,EAAM,KAAK,EACvB,WAAc,CACZ,aAAa,EACb,EAAY,MAAQ,EAAY,KAAK,EAAI,CAC3C,EACA,UAAY,IACV,aAAa,EACN,EAAM,UAAU,CAAQ,GAEjC,CAAC,OAAO,UAAW,CACjB,KAAK,QAAQ,CACf,EACA,IAAI,OAAQ,CACV,OAAO,EAAM,KACf,CACF,EAIA,OAFA,OAAO,eAAe,EAAU,EAAA,SAAU,CAAE,MAAO,EAAK,CAAC,EAElD,CACT"}
1
+ {"version":3,"file":"_async.cjs","names":[],"sources":["../src/_async.ts"],"sourcesContent":["import { RippleDisposedError } from './errors';\nimport { REACTIVE } from './runtime';\nimport type { Disposable, EffectHandle, Readable, Signal } from './types';\n\nexport type AsyncState<T> =\n | { readonly previous?: T; readonly status: 'pending' }\n | { readonly status: 'success'; readonly value: T }\n | { readonly error: unknown; readonly previous?: T; readonly status: 'error' };\n\nexport interface Resource<T> extends Readable<AsyncState<T>>, Disposable {\n reload(): void;\n}\n\nexport type ResourceOptions = {\n name?: string;\n};\n\ntype AsyncRuntime = {\n effect(callback: () => undefined | (() => void), options?: { name?: string }): EffectHandle;\n signal<T>(initial: T, options?: { name?: string }): Signal<T>;\n};\n\n/** Resource only depends on primitive runtime methods; graph binding stays private. */\nexport const createResource =\n (runtime: AsyncRuntime) =>\n <Source, Value>(\n source: () => Source,\n loader: (source: Source, context: { readonly signal: AbortSignal }) => Promise<Value>,\n options?: ResourceOptions,\n ): Resource<Value> => {\n const state = runtime.signal<AsyncState<Value>>({ status: 'pending' }, { name: options?.name });\n const reloadEpoch = runtime.signal(0);\n let active: AbortController | undefined;\n let hasPrevious = false;\n let previousValue: Value | undefined;\n\n const run = (): void => {\n void reloadEpoch.value;\n active?.abort();\n\n let input: Source;\n\n try {\n input = source();\n } catch (error) {\n state.value = hasPrevious\n ? { error, previous: previousValue as Value, status: 'error' }\n : { error, status: 'error' };\n\n return;\n }\n\n const next = new AbortController();\n\n active = next;\n state.value = hasPrevious ? { previous: previousValue as Value, status: 'pending' } : { status: 'pending' };\n\n let request: Promise<Value>;\n\n try {\n request = Promise.resolve(loader(input, { signal: next.signal }));\n } catch (error) {\n request = Promise.reject(error);\n }\n\n void request.then(\n (value) => {\n if (!stop.disposed && !next.signal.aborted) {\n hasPrevious = true;\n previousValue = value;\n state.value = { status: 'success', value };\n }\n },\n (error: unknown) => {\n if (!stop.disposed && !next.signal.aborted) {\n state.value = hasPrevious\n ? { error, previous: previousValue as Value, status: 'error' }\n : { error, status: 'error' };\n }\n },\n );\n };\n\n const stop = runtime.effect(\n () => {\n run();\n\n return () => active?.abort();\n },\n { name: options?.name },\n );\n\n const assertActive = (): void => {\n if (stop.disposed) throw new RippleDisposedError('Cannot use a disposed resource.');\n };\n const resource: Resource<Value> = {\n get disposalSignal() {\n return stop.disposalSignal;\n },\n dispose: () => stop.dispose(),\n get disposed() {\n return stop.disposed;\n },\n get name() {\n return state.name;\n },\n peek: () => state.peek(),\n reload: () => {\n assertActive();\n reloadEpoch.value = reloadEpoch.peek() + 1;\n },\n subscribe: (listener) => {\n assertActive();\n return state.subscribe(listener);\n },\n [Symbol.dispose]() {\n this.dispose();\n },\n get value() {\n return state.value;\n },\n };\n\n Object.defineProperty(resource, REACTIVE, { value: true });\n\n return resource;\n };\n"],"mappings":"2DAuBA,IAAa,eACV,IAEC,EACA,EACA,IACoB,CACpB,IAAM,EAAQ,EAAQ,OAA0B,CAAE,OAAQ,SAAU,EAAG,CAAE,KAAM,GAAS,IAAK,CAAC,EACxF,EAAc,EAAQ,OAAO,CAAC,EAChC,EACA,EAAc,GACd,EAEE,QAAkB,CACtB,EAAiB,MACjB,GAAQ,MAAM,EAEd,IAAI,EAEJ,GAAI,CACF,EAAQ,EAAO,CACjB,OAAS,EAAO,CACd,EAAM,MAAQ,EACV,CAAE,QAAO,SAAU,EAAwB,OAAQ,OAAQ,EAC3D,CAAE,QAAO,OAAQ,OAAQ,EAE7B,MACF,CAEA,IAAM,EAAO,IAAI,gBAEjB,EAAS,EACT,EAAM,MAAQ,EAAc,CAAE,SAAU,EAAwB,OAAQ,SAAU,EAAI,CAAE,OAAQ,SAAU,EAE1G,IAAI,EAEJ,GAAI,CACF,EAAU,QAAQ,QAAQ,EAAO,EAAO,CAAE,OAAQ,EAAK,MAAO,CAAC,CAAC,CAClE,OAAS,EAAO,CACd,EAAU,QAAQ,OAAO,CAAK,CAChC,CAEA,EAAa,KACV,GAAU,CACL,CAAC,EAAK,UAAY,CAAC,EAAK,OAAO,UACjC,EAAc,GACd,EAAgB,EAChB,EAAM,MAAQ,CAAE,OAAQ,UAAW,OAAM,EAE7C,EACC,GAAmB,CACd,CAAC,EAAK,UAAY,CAAC,EAAK,OAAO,UACjC,EAAM,MAAQ,EACV,CAAE,QAAO,SAAU,EAAwB,OAAQ,OAAQ,EAC3D,CAAE,QAAO,OAAQ,OAAQ,EAEjC,CACF,CACF,EAEM,EAAO,EAAQ,YAEjB,IAAI,MAES,GAAQ,MAAM,GAE7B,CAAE,KAAM,GAAS,IAAK,CACxB,EAEM,iBAA2B,CAC/B,GAAI,EAAK,SAAU,MAAM,IAAI,EAAA,oBAAoB,iCAAiC,CACpF,EACM,EAA4B,CAChC,IAAI,gBAAiB,CACnB,OAAO,EAAK,cACd,EACA,YAAe,EAAK,QAAQ,EAC5B,IAAI,UAAW,CACb,OAAO,EAAK,QACd,EACA,IAAI,MAAO,CACT,OAAO,EAAM,IACf,EACA,SAAY,EAAM,KAAK,EACvB,WAAc,CACZ,aAAa,EACb,EAAY,MAAQ,EAAY,KAAK,EAAI,CAC3C,EACA,UAAY,IACV,aAAa,EACN,EAAM,UAAU,CAAQ,GAEjC,CAAC,OAAO,UAAW,CACjB,KAAK,QAAQ,CACf,EACA,IAAI,OAAQ,CACV,OAAO,EAAM,KACf,CACF,EAIA,OAFA,OAAO,eAAe,EAAU,EAAA,SAAU,CAAE,MAAO,EAAK,CAAC,EAElD,CACT"}
package/dist/_async.js CHANGED
@@ -1,2 +1,2 @@
1
- import{RippleDisposedResourceError as e}from"./errors.js";import{REACTIVE as t}from"./runtime.js";var createResource=n=>(r,i,a)=>{let o=n.signal({status:`pending`},{name:a?.name}),s=n.signal(0),c,l=!1,u,run=()=>{s.value,c?.abort();let e;try{e=r()}catch(e){o.value=l?{error:e,previous:u,status:`error`}:{error:e,status:`error`};return}let t=new AbortController;c=t,o.value=l?{previous:u,status:`pending`}:{status:`pending`};let n;try{n=Promise.resolve(i(e,{signal:t.signal}))}catch(e){n=Promise.reject(e)}n.then(e=>{!d.disposed&&!t.signal.aborted&&(l=!0,u=e,o.value={status:`success`,value:e})},e=>{!d.disposed&&!t.signal.aborted&&(o.value=l?{error:e,previous:u,status:`error`}:{error:e,status:`error`})})},d=n.effect(()=>(run(),()=>c?.abort()),{name:a?.name}),assertActive=()=>{if(d.disposed)throw new e(`Cannot use a disposed resource.`)},f={get disposalSignal(){return d.disposalSignal},dispose:()=>d.dispose(),get disposed(){return d.disposed},get name(){return o.name},peek:()=>o.peek(),reload:()=>{assertActive(),s.value=s.peek()+1},subscribe:e=>(assertActive(),o.subscribe(e)),[Symbol.dispose](){this.dispose()},get value(){return o.value}};return Object.defineProperty(f,t,{value:!0}),f};export{createResource};
1
+ import{RippleDisposedError as e}from"./errors.js";import{REACTIVE as t}from"./runtime.js";var createResource=n=>(r,i,a)=>{let o=n.signal({status:`pending`},{name:a?.name}),s=n.signal(0),c,l=!1,u,run=()=>{s.value,c?.abort();let e;try{e=r()}catch(e){o.value=l?{error:e,previous:u,status:`error`}:{error:e,status:`error`};return}let t=new AbortController;c=t,o.value=l?{previous:u,status:`pending`}:{status:`pending`};let n;try{n=Promise.resolve(i(e,{signal:t.signal}))}catch(e){n=Promise.reject(e)}n.then(e=>{!d.disposed&&!t.signal.aborted&&(l=!0,u=e,o.value={status:`success`,value:e})},e=>{!d.disposed&&!t.signal.aborted&&(o.value=l?{error:e,previous:u,status:`error`}:{error:e,status:`error`})})},d=n.effect(()=>(run(),()=>c?.abort()),{name:a?.name}),assertActive=()=>{if(d.disposed)throw new e(`Cannot use a disposed resource.`)},f={get disposalSignal(){return d.disposalSignal},dispose:()=>d.dispose(),get disposed(){return d.disposed},get name(){return o.name},peek:()=>o.peek(),reload:()=>{assertActive(),s.value=s.peek()+1},subscribe:e=>(assertActive(),o.subscribe(e)),[Symbol.dispose](){this.dispose()},get value(){return o.value}};return Object.defineProperty(f,t,{value:!0}),f};export{createResource};
2
2
  //# sourceMappingURL=_async.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"_async.js","names":[],"sources":["../src/_async.ts"],"sourcesContent":["import { RippleDisposedResourceError } from './errors';\nimport { REACTIVE } from './runtime';\nimport type { Disposable, EffectHandle, Readable, Signal } from './types';\n\nexport type AsyncState<T> =\n | { readonly previous?: T; readonly status: 'pending' }\n | { readonly status: 'success'; readonly value: T }\n | { readonly error: unknown; readonly previous?: T; readonly status: 'error' };\n\nexport interface Resource<T> extends Readable<AsyncState<T>>, Disposable {\n reload(): void;\n}\n\nexport type ResourceOptions = {\n name?: string;\n};\n\ntype AsyncRuntime = {\n effect(callback: () => undefined | (() => void), options?: { name?: string }): EffectHandle;\n signal<T>(initial: T, options?: { name?: string }): Signal<T>;\n};\n\n/** Resource only depends on primitive runtime methods; graph binding stays private. */\nexport const createResource =\n (runtime: AsyncRuntime) =>\n <Source, Value>(\n source: () => Source,\n loader: (source: Source, context: { readonly signal: AbortSignal }) => Promise<Value>,\n options?: ResourceOptions,\n ): Resource<Value> => {\n const state = runtime.signal<AsyncState<Value>>({ status: 'pending' }, { name: options?.name });\n const reloadEpoch = runtime.signal(0);\n let active: AbortController | undefined;\n let hasPrevious = false;\n let previousValue: Value | undefined;\n\n const run = (): void => {\n void reloadEpoch.value;\n active?.abort();\n\n let input: Source;\n\n try {\n input = source();\n } catch (error) {\n state.value = hasPrevious\n ? { error, previous: previousValue as Value, status: 'error' }\n : { error, status: 'error' };\n\n return;\n }\n\n const next = new AbortController();\n\n active = next;\n state.value = hasPrevious ? { previous: previousValue as Value, status: 'pending' } : { status: 'pending' };\n\n let request: Promise<Value>;\n\n try {\n request = Promise.resolve(loader(input, { signal: next.signal }));\n } catch (error) {\n request = Promise.reject(error);\n }\n\n void request.then(\n (value) => {\n if (!stop.disposed && !next.signal.aborted) {\n hasPrevious = true;\n previousValue = value;\n state.value = { status: 'success', value };\n }\n },\n (error: unknown) => {\n if (!stop.disposed && !next.signal.aborted) {\n state.value = hasPrevious\n ? { error, previous: previousValue as Value, status: 'error' }\n : { error, status: 'error' };\n }\n },\n );\n };\n\n const stop = runtime.effect(\n () => {\n run();\n\n return () => active?.abort();\n },\n { name: options?.name },\n );\n\n const assertActive = (): void => {\n if (stop.disposed) throw new RippleDisposedResourceError('Cannot use a disposed resource.');\n };\n const resource: Resource<Value> = {\n get disposalSignal() {\n return stop.disposalSignal;\n },\n dispose: () => stop.dispose(),\n get disposed() {\n return stop.disposed;\n },\n get name() {\n return state.name;\n },\n peek: () => state.peek(),\n reload: () => {\n assertActive();\n reloadEpoch.value = reloadEpoch.peek() + 1;\n },\n subscribe: (listener) => {\n assertActive();\n return state.subscribe(listener);\n },\n [Symbol.dispose]() {\n this.dispose();\n },\n get value() {\n return state.value;\n },\n };\n\n Object.defineProperty(resource, REACTIVE, { value: true });\n\n return resource;\n };\n"],"mappings":"kGAuBA,IAAa,eACV,IAEC,EACA,EACA,IACoB,CACpB,IAAM,EAAQ,EAAQ,OAA0B,CAAE,OAAQ,SAAU,EAAG,CAAE,KAAM,GAAS,IAAK,CAAC,EACxF,EAAc,EAAQ,OAAO,CAAC,EAChC,EACA,EAAc,GACd,EAEE,QAAkB,CACtB,EAAiB,MACjB,GAAQ,MAAM,EAEd,IAAI,EAEJ,GAAI,CACF,EAAQ,EAAO,CACjB,OAAS,EAAO,CACd,EAAM,MAAQ,EACV,CAAE,QAAO,SAAU,EAAwB,OAAQ,OAAQ,EAC3D,CAAE,QAAO,OAAQ,OAAQ,EAE7B,MACF,CAEA,IAAM,EAAO,IAAI,gBAEjB,EAAS,EACT,EAAM,MAAQ,EAAc,CAAE,SAAU,EAAwB,OAAQ,SAAU,EAAI,CAAE,OAAQ,SAAU,EAE1G,IAAI,EAEJ,GAAI,CACF,EAAU,QAAQ,QAAQ,EAAO,EAAO,CAAE,OAAQ,EAAK,MAAO,CAAC,CAAC,CAClE,OAAS,EAAO,CACd,EAAU,QAAQ,OAAO,CAAK,CAChC,CAEA,EAAa,KACV,GAAU,CACL,CAAC,EAAK,UAAY,CAAC,EAAK,OAAO,UACjC,EAAc,GACd,EAAgB,EAChB,EAAM,MAAQ,CAAE,OAAQ,UAAW,OAAM,EAE7C,EACC,GAAmB,CACd,CAAC,EAAK,UAAY,CAAC,EAAK,OAAO,UACjC,EAAM,MAAQ,EACV,CAAE,QAAO,SAAU,EAAwB,OAAQ,OAAQ,EAC3D,CAAE,QAAO,OAAQ,OAAQ,EAEjC,CACF,CACF,EAEM,EAAO,EAAQ,YAEjB,IAAI,MAES,GAAQ,MAAM,GAE7B,CAAE,KAAM,GAAS,IAAK,CACxB,EAEM,iBAA2B,CAC/B,GAAI,EAAK,SAAU,MAAM,IAAI,EAA4B,iCAAiC,CAC5F,EACM,EAA4B,CAChC,IAAI,gBAAiB,CACnB,OAAO,EAAK,cACd,EACA,YAAe,EAAK,QAAQ,EAC5B,IAAI,UAAW,CACb,OAAO,EAAK,QACd,EACA,IAAI,MAAO,CACT,OAAO,EAAM,IACf,EACA,SAAY,EAAM,KAAK,EACvB,WAAc,CACZ,aAAa,EACb,EAAY,MAAQ,EAAY,KAAK,EAAI,CAC3C,EACA,UAAY,IACV,aAAa,EACN,EAAM,UAAU,CAAQ,GAEjC,CAAC,OAAO,UAAW,CACjB,KAAK,QAAQ,CACf,EACA,IAAI,OAAQ,CACV,OAAO,EAAM,KACf,CACF,EAIA,OAFA,OAAO,eAAe,EAAU,EAAU,CAAE,MAAO,EAAK,CAAC,EAElD,CACT"}
1
+ {"version":3,"file":"_async.js","names":[],"sources":["../src/_async.ts"],"sourcesContent":["import { RippleDisposedError } from './errors';\nimport { REACTIVE } from './runtime';\nimport type { Disposable, EffectHandle, Readable, Signal } from './types';\n\nexport type AsyncState<T> =\n | { readonly previous?: T; readonly status: 'pending' }\n | { readonly status: 'success'; readonly value: T }\n | { readonly error: unknown; readonly previous?: T; readonly status: 'error' };\n\nexport interface Resource<T> extends Readable<AsyncState<T>>, Disposable {\n reload(): void;\n}\n\nexport type ResourceOptions = {\n name?: string;\n};\n\ntype AsyncRuntime = {\n effect(callback: () => undefined | (() => void), options?: { name?: string }): EffectHandle;\n signal<T>(initial: T, options?: { name?: string }): Signal<T>;\n};\n\n/** Resource only depends on primitive runtime methods; graph binding stays private. */\nexport const createResource =\n (runtime: AsyncRuntime) =>\n <Source, Value>(\n source: () => Source,\n loader: (source: Source, context: { readonly signal: AbortSignal }) => Promise<Value>,\n options?: ResourceOptions,\n ): Resource<Value> => {\n const state = runtime.signal<AsyncState<Value>>({ status: 'pending' }, { name: options?.name });\n const reloadEpoch = runtime.signal(0);\n let active: AbortController | undefined;\n let hasPrevious = false;\n let previousValue: Value | undefined;\n\n const run = (): void => {\n void reloadEpoch.value;\n active?.abort();\n\n let input: Source;\n\n try {\n input = source();\n } catch (error) {\n state.value = hasPrevious\n ? { error, previous: previousValue as Value, status: 'error' }\n : { error, status: 'error' };\n\n return;\n }\n\n const next = new AbortController();\n\n active = next;\n state.value = hasPrevious ? { previous: previousValue as Value, status: 'pending' } : { status: 'pending' };\n\n let request: Promise<Value>;\n\n try {\n request = Promise.resolve(loader(input, { signal: next.signal }));\n } catch (error) {\n request = Promise.reject(error);\n }\n\n void request.then(\n (value) => {\n if (!stop.disposed && !next.signal.aborted) {\n hasPrevious = true;\n previousValue = value;\n state.value = { status: 'success', value };\n }\n },\n (error: unknown) => {\n if (!stop.disposed && !next.signal.aborted) {\n state.value = hasPrevious\n ? { error, previous: previousValue as Value, status: 'error' }\n : { error, status: 'error' };\n }\n },\n );\n };\n\n const stop = runtime.effect(\n () => {\n run();\n\n return () => active?.abort();\n },\n { name: options?.name },\n );\n\n const assertActive = (): void => {\n if (stop.disposed) throw new RippleDisposedError('Cannot use a disposed resource.');\n };\n const resource: Resource<Value> = {\n get disposalSignal() {\n return stop.disposalSignal;\n },\n dispose: () => stop.dispose(),\n get disposed() {\n return stop.disposed;\n },\n get name() {\n return state.name;\n },\n peek: () => state.peek(),\n reload: () => {\n assertActive();\n reloadEpoch.value = reloadEpoch.peek() + 1;\n },\n subscribe: (listener) => {\n assertActive();\n return state.subscribe(listener);\n },\n [Symbol.dispose]() {\n this.dispose();\n },\n get value() {\n return state.value;\n },\n };\n\n Object.defineProperty(resource, REACTIVE, { value: true });\n\n return resource;\n };\n"],"mappings":"0FAuBA,IAAa,eACV,IAEC,EACA,EACA,IACoB,CACpB,IAAM,EAAQ,EAAQ,OAA0B,CAAE,OAAQ,SAAU,EAAG,CAAE,KAAM,GAAS,IAAK,CAAC,EACxF,EAAc,EAAQ,OAAO,CAAC,EAChC,EACA,EAAc,GACd,EAEE,QAAkB,CACtB,EAAiB,MACjB,GAAQ,MAAM,EAEd,IAAI,EAEJ,GAAI,CACF,EAAQ,EAAO,CACjB,OAAS,EAAO,CACd,EAAM,MAAQ,EACV,CAAE,QAAO,SAAU,EAAwB,OAAQ,OAAQ,EAC3D,CAAE,QAAO,OAAQ,OAAQ,EAE7B,MACF,CAEA,IAAM,EAAO,IAAI,gBAEjB,EAAS,EACT,EAAM,MAAQ,EAAc,CAAE,SAAU,EAAwB,OAAQ,SAAU,EAAI,CAAE,OAAQ,SAAU,EAE1G,IAAI,EAEJ,GAAI,CACF,EAAU,QAAQ,QAAQ,EAAO,EAAO,CAAE,OAAQ,EAAK,MAAO,CAAC,CAAC,CAClE,OAAS,EAAO,CACd,EAAU,QAAQ,OAAO,CAAK,CAChC,CAEA,EAAa,KACV,GAAU,CACL,CAAC,EAAK,UAAY,CAAC,EAAK,OAAO,UACjC,EAAc,GACd,EAAgB,EAChB,EAAM,MAAQ,CAAE,OAAQ,UAAW,OAAM,EAE7C,EACC,GAAmB,CACd,CAAC,EAAK,UAAY,CAAC,EAAK,OAAO,UACjC,EAAM,MAAQ,EACV,CAAE,QAAO,SAAU,EAAwB,OAAQ,OAAQ,EAC3D,CAAE,QAAO,OAAQ,OAAQ,EAEjC,CACF,CACF,EAEM,EAAO,EAAQ,YAEjB,IAAI,MAES,GAAQ,MAAM,GAE7B,CAAE,KAAM,GAAS,IAAK,CACxB,EAEM,iBAA2B,CAC/B,GAAI,EAAK,SAAU,MAAM,IAAI,EAAoB,iCAAiC,CACpF,EACM,EAA4B,CAChC,IAAI,gBAAiB,CACnB,OAAO,EAAK,cACd,EACA,YAAe,EAAK,QAAQ,EAC5B,IAAI,UAAW,CACb,OAAO,EAAK,QACd,EACA,IAAI,MAAO,CACT,OAAO,EAAM,IACf,EACA,SAAY,EAAM,KAAK,EACvB,WAAc,CACZ,aAAa,EACb,EAAY,MAAQ,EAAY,KAAK,EAAI,CAC3C,EACA,UAAY,IACV,aAAa,EACN,EAAM,UAAU,CAAQ,GAEjC,CAAC,OAAO,UAAW,CACjB,KAAK,QAAQ,CACf,EACA,IAAI,OAAQ,CACV,OAAO,EAAM,KACf,CACF,EAIA,OAFA,OAAO,eAAe,EAAU,EAAU,CAAE,MAAO,EAAK,CAAC,EAElD,CACT"}
package/dist/_default.cjs CHANGED
@@ -1,2 +1,2 @@
1
- const e=require("./runtime.cjs"),t=require("./_async.cjs"),n=require("./_subscribable.cjs"),r=require("./_watch.cjs");var createRipple=i=>{let a=new e.ReactiveRuntime(i),o=n.createFromSubscribable(a),s=t.createResource(a);return{batch:a.batch,computed:a.computed,createScope:a.createScope,get disposalSignal(){return a.disposalSignal},dispose:()=>a.dispose(),get disposed(){return a.disposed},effect:a.effect,fromSubscribable:o,resource:s,signal:a.signal,tap:a.tap,untrack:a.untrack,watch:r.createWatch(a),[Symbol.dispose]:()=>a.dispose()}},i=createRipple();exports.createRipple=createRipple,exports.defaultRipple=i;
1
+ const e=require("./runtime.cjs"),t=require("./_async.cjs"),n=require("./_subscribable.cjs"),r=require("./_watch.cjs");var createRipple=i=>{let a=new e.ReactiveRuntime(i),o=n.createFromSubscribable(a),s=t.createResource(a);return{batch:a.batch,computed:a.computed,createScope:a.createScope,get disposalSignal(){return a.disposalSignal},dispose:()=>a.dispose(),get disposed(){return a.disposed},effect:a.effect,fromSubscribable:o,resource:s,signal:a.signal,untrack:a.untrack,watch:r.createWatch(a),[Symbol.dispose]:()=>a.dispose()}},i=createRipple();exports.createRipple=createRipple,exports.defaultRipple=i;
2
2
  //# sourceMappingURL=_default.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"_default.cjs","names":[],"sources":["../src/_default.ts"],"sourcesContent":["import { createResource, type Resource, type ResourceOptions } from './_async';\nimport { type BridgedReadable, createFromSubscribable, type FromSubscribableOptions } from './_subscribable';\nimport { createWatch, type WatchOptions } from './_watch';\nimport { ReactiveRuntime } from './runtime';\nimport type {\n Cleanup,\n ComputedOptions,\n Disposable,\n EffectHandle,\n EffectOptions,\n Readable,\n RippleEvent,\n RippleOptions,\n Scope,\n Signal,\n SignalOptions,\n Subscribable,\n Unsubscribe,\n} from './types';\n\nexport interface Ripple extends Disposable {\n batch<T>(fn: () => T): T;\n computed<T>(derive: () => T, options?: ComputedOptions<T>): Readable<T>;\n createScope(name?: string): Scope;\n effect(callback: () => Cleanup | undefined, options?: EffectOptions): EffectHandle;\n fromSubscribable<T>(source: Subscribable<T>, options?: FromSubscribableOptions): BridgedReadable<T>;\n resource<Source, Value>(\n source: () => Source,\n loader: (source: Source, context: { readonly signal: AbortSignal }) => Promise<Value>,\n options?: ResourceOptions,\n ): Resource<Value>;\n signal<T>(initial: T, options?: SignalOptions<T>): Signal<T>;\n tap(handler: (event: RippleEvent) => void, options?: { signal?: AbortSignal }): Unsubscribe;\n untrack<T>(fn: () => T): T;\n watch<T>(\n source: Readable<T> | (() => T),\n callback: (value: T, previous: T | undefined) => void,\n options?: WatchOptions<T>,\n ): EffectHandle;\n}\n\n/**\n * Creates one complete reactive graph with its own ownership boundary. All\n * factories on the returned object share its runtime. Use this for tests, SSR\n * requests, embedded applications, or independently disposable features.\n * `dispose()` is terminal: create a new graph for a new lifetime.\n */\nexport const createRipple = (options?: RippleOptions): Ripple => {\n const runtime = new ReactiveRuntime(options);\n const fromSubscribable = createFromSubscribable(runtime);\n const resource = createResource(runtime);\n\n return {\n batch: runtime.batch,\n computed: runtime.computed,\n createScope: runtime.createScope,\n get disposalSignal() {\n return runtime.disposalSignal;\n },\n dispose: () => runtime.dispose(),\n get disposed() {\n return runtime.disposed;\n },\n effect: runtime.effect,\n fromSubscribable,\n resource,\n signal: runtime.signal,\n tap: runtime.tap,\n untrack: runtime.untrack,\n watch: createWatch(runtime),\n [Symbol.dispose]: () => runtime.dispose(),\n };\n};\n\n/**\n * The shared default reactive graph: process-lifetime. Root helpers\n * (`signal`, `computed`, `effect`, `batch`, `createScope`, `untrack`, `watch`, `resource`, `fromSubscribable`)\n * are re-exported from the package root as bound methods on this single graph\n * instance. Use these only when the application has one graph for its entire\n * lifetime; they are never disposed. For isolated, disposable graphs (tests,\n * SSR, embedded features) use `createRipple()` instead.\n */\nexport const defaultRipple = createRipple();\n"],"mappings":"sHA+CA,IAAa,aAAgB,GAAoC,CAC/D,IAAM,EAAU,IAAI,EAAA,gBAAgB,CAAO,EACrC,EAAmB,EAAA,uBAAuB,CAAO,EACjD,EAAW,EAAA,eAAe,CAAO,EAEvC,MAAO,CACL,MAAO,EAAQ,MACf,SAAU,EAAQ,SAClB,YAAa,EAAQ,YACrB,IAAI,gBAAiB,CACnB,OAAO,EAAQ,cACjB,EACA,YAAe,EAAQ,QAAQ,EAC/B,IAAI,UAAW,CACb,OAAO,EAAQ,QACjB,EACA,OAAQ,EAAQ,OAChB,mBACA,WACA,OAAQ,EAAQ,OAChB,IAAK,EAAQ,IACb,QAAS,EAAQ,QACjB,MAAO,EAAA,YAAY,CAAO,GACzB,OAAO,aAAgB,EAAQ,QAAQ,CAC1C,CACF,EAUa,EAAgB,aAAa"}
1
+ {"version":3,"file":"_default.cjs","names":[],"sources":["../src/_default.ts"],"sourcesContent":["import { createResource, type Resource, type ResourceOptions } from './_async';\nimport { type BridgedReadable, createFromSubscribable, type FromSubscribableOptions } from './_subscribable';\nimport { createWatch, type WatchOptions } from './_watch';\nimport { ReactiveRuntime } from './runtime';\nimport type {\n Cleanup,\n ComputedOptions,\n Disposable,\n EffectHandle,\n EffectOptions,\n Readable,\n RippleOptions,\n Scope,\n Signal,\n SignalOptions,\n Subscribable,\n} from './types';\n\nexport interface Ripple extends Disposable {\n batch<T>(fn: () => T): T;\n computed<T>(derive: () => T, options?: ComputedOptions<T>): Readable<T>;\n createScope(name?: string): Scope;\n effect(callback: () => Cleanup | undefined, options?: EffectOptions): EffectHandle;\n fromSubscribable<T>(source: Subscribable<T>, options?: FromSubscribableOptions): BridgedReadable<T>;\n resource<Source, Value>(\n source: () => Source,\n loader: (source: Source, context: { readonly signal: AbortSignal }) => Promise<Value>,\n options?: ResourceOptions,\n ): Resource<Value>;\n signal<T>(initial: T, options?: SignalOptions<T>): Signal<T>;\n untrack<T>(fn: () => T): T;\n watch<T>(\n source: Readable<T> | (() => T),\n callback: (value: T, previous: T | undefined) => void,\n options?: WatchOptions<T>,\n ): EffectHandle;\n}\n\n/**\n * Creates one complete reactive graph with its own ownership boundary. All\n * factories on the returned object share its runtime. Use this for tests, SSR\n * requests, embedded applications, or independently disposable features.\n * `dispose()` is terminal: create a new graph for a new lifetime.\n */\nexport const createRipple = (options?: RippleOptions): Ripple => {\n const runtime = new ReactiveRuntime(options);\n const fromSubscribable = createFromSubscribable(runtime);\n const resource = createResource(runtime);\n\n return {\n batch: runtime.batch,\n computed: runtime.computed,\n createScope: runtime.createScope,\n get disposalSignal() {\n return runtime.disposalSignal;\n },\n dispose: () => runtime.dispose(),\n get disposed() {\n return runtime.disposed;\n },\n effect: runtime.effect,\n fromSubscribable,\n resource,\n signal: runtime.signal,\n untrack: runtime.untrack,\n watch: createWatch(runtime),\n [Symbol.dispose]: () => runtime.dispose(),\n };\n};\n\n/**\n * The shared default reactive graph: process-lifetime. Root helpers\n * (`signal`, `computed`, `effect`, `batch`, `createScope`, `untrack`, `watch`, `resource`, `fromSubscribable`)\n * are re-exported from the package root as bound methods on this single graph\n * instance. Use these only when the application has one graph for its entire\n * lifetime; they are never disposed. For isolated, disposable graphs (tests,\n * SSR, embedded features) use `createRipple()` instead.\n */\nexport const defaultRipple = createRipple();\n"],"mappings":"sHA4CA,IAAa,aAAgB,GAAoC,CAC/D,IAAM,EAAU,IAAI,EAAA,gBAAgB,CAAO,EACrC,EAAmB,EAAA,uBAAuB,CAAO,EACjD,EAAW,EAAA,eAAe,CAAO,EAEvC,MAAO,CACL,MAAO,EAAQ,MACf,SAAU,EAAQ,SAClB,YAAa,EAAQ,YACrB,IAAI,gBAAiB,CACnB,OAAO,EAAQ,cACjB,EACA,YAAe,EAAQ,QAAQ,EAC/B,IAAI,UAAW,CACb,OAAO,EAAQ,QACjB,EACA,OAAQ,EAAQ,OAChB,mBACA,WACA,OAAQ,EAAQ,OAChB,QAAS,EAAQ,QACjB,MAAO,EAAA,YAAY,CAAO,GACzB,OAAO,aAAgB,EAAQ,QAAQ,CAC1C,CACF,EAUa,EAAgB,aAAa"}
@@ -1,7 +1,7 @@
1
1
  import { type Resource, type ResourceOptions } from './_async';
2
2
  import { type BridgedReadable, type FromSubscribableOptions } from './_subscribable';
3
3
  import { type WatchOptions } from './_watch';
4
- import type { Cleanup, ComputedOptions, Disposable, EffectHandle, EffectOptions, Readable, RippleEvent, RippleOptions, Scope, Signal, SignalOptions, Subscribable, Unsubscribe } from './types';
4
+ import type { Cleanup, ComputedOptions, Disposable, EffectHandle, EffectOptions, Readable, RippleOptions, Scope, Signal, SignalOptions, Subscribable } from './types';
5
5
  export interface Ripple extends Disposable {
6
6
  batch<T>(fn: () => T): T;
7
7
  computed<T>(derive: () => T, options?: ComputedOptions<T>): Readable<T>;
@@ -12,9 +12,6 @@ export interface Ripple extends Disposable {
12
12
  readonly signal: AbortSignal;
13
13
  }) => Promise<Value>, options?: ResourceOptions): Resource<Value>;
14
14
  signal<T>(initial: T, options?: SignalOptions<T>): Signal<T>;
15
- tap(handler: (event: RippleEvent) => void, options?: {
16
- signal?: AbortSignal;
17
- }): Unsubscribe;
18
15
  untrack<T>(fn: () => T): T;
19
16
  watch<T>(source: Readable<T> | (() => T), callback: (value: T, previous: T | undefined) => void, options?: WatchOptions<T>): EffectHandle;
20
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"_default.d.ts","sourceRoot":"","sources":["../src/_default.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,UAAU,CAAC;AAC/E,OAAO,EAAE,KAAK,eAAe,EAA0B,KAAK,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC7G,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AAE1D,OAAO,KAAK,EACV,OAAO,EACP,eAAe,EACf,UAAU,EACV,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,WAAW,EACX,aAAa,EACb,KAAK,EACL,MAAM,EACN,aAAa,EACb,YAAY,EACZ,WAAW,EACZ,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,MAAO,SAAQ,UAAU;IACxC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IACzB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACxE,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAClC,MAAM,CAAC,QAAQ,EAAE,MAAM,OAAO,GAAG,SAAS,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,YAAY,CAAC;IACnF,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,uBAAuB,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;IACpG,QAAQ,CAAC,MAAM,EAAE,KAAK,EACpB,MAAM,EAAE,MAAM,MAAM,EACpB,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;KAAE,KAAK,OAAO,CAAC,KAAK,CAAC,EACrF,OAAO,CAAC,EAAE,eAAe,GACxB,QAAQ,CAAC,KAAK,CAAC,CAAC;IACnB,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IAC7D,GAAG,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,WAAW,CAAC;IAC5F,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3B,KAAK,CAAC,CAAC,EACL,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAC/B,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,SAAS,KAAK,IAAI,EACrD,OAAO,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,GACxB,YAAY,CAAC;CACjB;AAED;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GAAI,UAAU,aAAa,KAAG,MAyBtD,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,QAAiB,CAAC"}
1
+ {"version":3,"file":"_default.d.ts","sourceRoot":"","sources":["../src/_default.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,UAAU,CAAC;AAC/E,OAAO,EAAE,KAAK,eAAe,EAA0B,KAAK,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC7G,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AAE1D,OAAO,KAAK,EACV,OAAO,EACP,eAAe,EACf,UAAU,EACV,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,aAAa,EACb,KAAK,EACL,MAAM,EACN,aAAa,EACb,YAAY,EACb,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,MAAO,SAAQ,UAAU;IACxC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IACzB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACxE,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAClC,MAAM,CAAC,QAAQ,EAAE,MAAM,OAAO,GAAG,SAAS,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,YAAY,CAAC;IACnF,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,uBAAuB,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;IACpG,QAAQ,CAAC,MAAM,EAAE,KAAK,EACpB,MAAM,EAAE,MAAM,MAAM,EACpB,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;KAAE,KAAK,OAAO,CAAC,KAAK,CAAC,EACrF,OAAO,CAAC,EAAE,eAAe,GACxB,QAAQ,CAAC,KAAK,CAAC,CAAC;IACnB,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IAC7D,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3B,KAAK,CAAC,CAAC,EACL,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAC/B,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,SAAS,KAAK,IAAI,EACrD,OAAO,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,GACxB,YAAY,CAAC;CACjB;AAED;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GAAI,UAAU,aAAa,KAAG,MAwBtD,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,QAAiB,CAAC"}
package/dist/_default.js CHANGED
@@ -1,2 +1,2 @@
1
- import{ReactiveRuntime as e}from"./runtime.js";import{createResource as t}from"./_async.js";import{createFromSubscribable as n}from"./_subscribable.js";import{createWatch as r}from"./_watch.js";var createRipple=i=>{let a=new e(i),o=n(a),s=t(a);return{batch:a.batch,computed:a.computed,createScope:a.createScope,get disposalSignal(){return a.disposalSignal},dispose:()=>a.dispose(),get disposed(){return a.disposed},effect:a.effect,fromSubscribable:o,resource:s,signal:a.signal,tap:a.tap,untrack:a.untrack,watch:r(a),[Symbol.dispose]:()=>a.dispose()}},i=createRipple();export{createRipple,i as defaultRipple};
1
+ import{ReactiveRuntime as e}from"./runtime.js";import{createResource as t}from"./_async.js";import{createFromSubscribable as n}from"./_subscribable.js";import{createWatch as r}from"./_watch.js";var createRipple=i=>{let a=new e(i),o=n(a),s=t(a);return{batch:a.batch,computed:a.computed,createScope:a.createScope,get disposalSignal(){return a.disposalSignal},dispose:()=>a.dispose(),get disposed(){return a.disposed},effect:a.effect,fromSubscribable:o,resource:s,signal:a.signal,untrack:a.untrack,watch:r(a),[Symbol.dispose]:()=>a.dispose()}},i=createRipple();export{createRipple,i as defaultRipple};
2
2
  //# sourceMappingURL=_default.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"_default.js","names":[],"sources":["../src/_default.ts"],"sourcesContent":["import { createResource, type Resource, type ResourceOptions } from './_async';\nimport { type BridgedReadable, createFromSubscribable, type FromSubscribableOptions } from './_subscribable';\nimport { createWatch, type WatchOptions } from './_watch';\nimport { ReactiveRuntime } from './runtime';\nimport type {\n Cleanup,\n ComputedOptions,\n Disposable,\n EffectHandle,\n EffectOptions,\n Readable,\n RippleEvent,\n RippleOptions,\n Scope,\n Signal,\n SignalOptions,\n Subscribable,\n Unsubscribe,\n} from './types';\n\nexport interface Ripple extends Disposable {\n batch<T>(fn: () => T): T;\n computed<T>(derive: () => T, options?: ComputedOptions<T>): Readable<T>;\n createScope(name?: string): Scope;\n effect(callback: () => Cleanup | undefined, options?: EffectOptions): EffectHandle;\n fromSubscribable<T>(source: Subscribable<T>, options?: FromSubscribableOptions): BridgedReadable<T>;\n resource<Source, Value>(\n source: () => Source,\n loader: (source: Source, context: { readonly signal: AbortSignal }) => Promise<Value>,\n options?: ResourceOptions,\n ): Resource<Value>;\n signal<T>(initial: T, options?: SignalOptions<T>): Signal<T>;\n tap(handler: (event: RippleEvent) => void, options?: { signal?: AbortSignal }): Unsubscribe;\n untrack<T>(fn: () => T): T;\n watch<T>(\n source: Readable<T> | (() => T),\n callback: (value: T, previous: T | undefined) => void,\n options?: WatchOptions<T>,\n ): EffectHandle;\n}\n\n/**\n * Creates one complete reactive graph with its own ownership boundary. All\n * factories on the returned object share its runtime. Use this for tests, SSR\n * requests, embedded applications, or independently disposable features.\n * `dispose()` is terminal: create a new graph for a new lifetime.\n */\nexport const createRipple = (options?: RippleOptions): Ripple => {\n const runtime = new ReactiveRuntime(options);\n const fromSubscribable = createFromSubscribable(runtime);\n const resource = createResource(runtime);\n\n return {\n batch: runtime.batch,\n computed: runtime.computed,\n createScope: runtime.createScope,\n get disposalSignal() {\n return runtime.disposalSignal;\n },\n dispose: () => runtime.dispose(),\n get disposed() {\n return runtime.disposed;\n },\n effect: runtime.effect,\n fromSubscribable,\n resource,\n signal: runtime.signal,\n tap: runtime.tap,\n untrack: runtime.untrack,\n watch: createWatch(runtime),\n [Symbol.dispose]: () => runtime.dispose(),\n };\n};\n\n/**\n * The shared default reactive graph: process-lifetime. Root helpers\n * (`signal`, `computed`, `effect`, `batch`, `createScope`, `untrack`, `watch`, `resource`, `fromSubscribable`)\n * are re-exported from the package root as bound methods on this single graph\n * instance. Use these only when the application has one graph for its entire\n * lifetime; they are never disposed. For isolated, disposable graphs (tests,\n * SSR, embedded features) use `createRipple()` instead.\n */\nexport const defaultRipple = createRipple();\n"],"mappings":"kMA+CA,IAAa,aAAgB,GAAoC,CAC/D,IAAM,EAAU,IAAI,EAAgB,CAAO,EACrC,EAAmB,EAAuB,CAAO,EACjD,EAAW,EAAe,CAAO,EAEvC,MAAO,CACL,MAAO,EAAQ,MACf,SAAU,EAAQ,SAClB,YAAa,EAAQ,YACrB,IAAI,gBAAiB,CACnB,OAAO,EAAQ,cACjB,EACA,YAAe,EAAQ,QAAQ,EAC/B,IAAI,UAAW,CACb,OAAO,EAAQ,QACjB,EACA,OAAQ,EAAQ,OAChB,mBACA,WACA,OAAQ,EAAQ,OAChB,IAAK,EAAQ,IACb,QAAS,EAAQ,QACjB,MAAO,EAAY,CAAO,GACzB,OAAO,aAAgB,EAAQ,QAAQ,CAC1C,CACF,EAUa,EAAgB,aAAa"}
1
+ {"version":3,"file":"_default.js","names":[],"sources":["../src/_default.ts"],"sourcesContent":["import { createResource, type Resource, type ResourceOptions } from './_async';\nimport { type BridgedReadable, createFromSubscribable, type FromSubscribableOptions } from './_subscribable';\nimport { createWatch, type WatchOptions } from './_watch';\nimport { ReactiveRuntime } from './runtime';\nimport type {\n Cleanup,\n ComputedOptions,\n Disposable,\n EffectHandle,\n EffectOptions,\n Readable,\n RippleOptions,\n Scope,\n Signal,\n SignalOptions,\n Subscribable,\n} from './types';\n\nexport interface Ripple extends Disposable {\n batch<T>(fn: () => T): T;\n computed<T>(derive: () => T, options?: ComputedOptions<T>): Readable<T>;\n createScope(name?: string): Scope;\n effect(callback: () => Cleanup | undefined, options?: EffectOptions): EffectHandle;\n fromSubscribable<T>(source: Subscribable<T>, options?: FromSubscribableOptions): BridgedReadable<T>;\n resource<Source, Value>(\n source: () => Source,\n loader: (source: Source, context: { readonly signal: AbortSignal }) => Promise<Value>,\n options?: ResourceOptions,\n ): Resource<Value>;\n signal<T>(initial: T, options?: SignalOptions<T>): Signal<T>;\n untrack<T>(fn: () => T): T;\n watch<T>(\n source: Readable<T> | (() => T),\n callback: (value: T, previous: T | undefined) => void,\n options?: WatchOptions<T>,\n ): EffectHandle;\n}\n\n/**\n * Creates one complete reactive graph with its own ownership boundary. All\n * factories on the returned object share its runtime. Use this for tests, SSR\n * requests, embedded applications, or independently disposable features.\n * `dispose()` is terminal: create a new graph for a new lifetime.\n */\nexport const createRipple = (options?: RippleOptions): Ripple => {\n const runtime = new ReactiveRuntime(options);\n const fromSubscribable = createFromSubscribable(runtime);\n const resource = createResource(runtime);\n\n return {\n batch: runtime.batch,\n computed: runtime.computed,\n createScope: runtime.createScope,\n get disposalSignal() {\n return runtime.disposalSignal;\n },\n dispose: () => runtime.dispose(),\n get disposed() {\n return runtime.disposed;\n },\n effect: runtime.effect,\n fromSubscribable,\n resource,\n signal: runtime.signal,\n untrack: runtime.untrack,\n watch: createWatch(runtime),\n [Symbol.dispose]: () => runtime.dispose(),\n };\n};\n\n/**\n * The shared default reactive graph: process-lifetime. Root helpers\n * (`signal`, `computed`, `effect`, `batch`, `createScope`, `untrack`, `watch`, `resource`, `fromSubscribable`)\n * are re-exported from the package root as bound methods on this single graph\n * instance. Use these only when the application has one graph for its entire\n * lifetime; they are never disposed. For isolated, disposable graphs (tests,\n * SSR, embedded features) use `createRipple()` instead.\n */\nexport const defaultRipple = createRipple();\n"],"mappings":"kMA4CA,IAAa,aAAgB,GAAoC,CAC/D,IAAM,EAAU,IAAI,EAAgB,CAAO,EACrC,EAAmB,EAAuB,CAAO,EACjD,EAAW,EAAe,CAAO,EAEvC,MAAO,CACL,MAAO,EAAQ,MACf,SAAU,EAAQ,SAClB,YAAa,EAAQ,YACrB,IAAI,gBAAiB,CACnB,OAAO,EAAQ,cACjB,EACA,YAAe,EAAQ,QAAQ,EAC/B,IAAI,UAAW,CACb,OAAO,EAAQ,QACjB,EACA,OAAQ,EAAQ,OAChB,mBACA,WACA,OAAQ,EAAQ,OAChB,QAAS,EAAQ,QACjB,MAAO,EAAY,CAAO,GACzB,OAAO,aAAgB,EAAQ,QAAQ,CAC1C,CACF,EAUa,EAAgB,aAAa"}
@@ -1 +1 @@
1
- {"version":3,"file":"_watch.cjs","names":[],"sources":["../src/_watch.ts"],"sourcesContent":["import type { EffectHandle, Equality, Readable } from './types';\n\nexport type WatchOptions<T> = {\n equals?: Equality<T>;\n immediate?: boolean;\n name?: string;\n};\n\ntype WatchRuntime = {\n effect(callback: () => undefined | (() => void), options?: { name?: string }): EffectHandle;\n untrack<T>(fn: () => T): T;\n};\n\nexport const createWatch =\n (runtime: WatchRuntime) =>\n <T>(\n source: Readable<T> | (() => T),\n callback: (value: T, previous: T | undefined) => void,\n options?: WatchOptions<T>,\n ): EffectHandle => {\n const read = typeof source === 'function' ? source : () => source.value;\n const equals = options?.equals ?? Object.is;\n let initial = true;\n let previous: T | undefined;\n\n return runtime.effect(\n () => {\n const value = read();\n\n if (initial) {\n initial = false;\n previous = value;\n\n if (options?.immediate) runtime.untrack(() => callback(value, undefined));\n\n return;\n }\n\n if (equals(previous as T, value)) return;\n\n const oldValue = previous;\n\n previous = value;\n runtime.untrack(() => callback(value, oldValue));\n },\n { name: options?.name },\n );\n };\n"],"mappings":"AAaA,IAAa,YACV,IAEC,EACA,EACA,IACiB,CACjB,IAAM,EAAO,OAAO,GAAW,WAAa,MAAe,EAAO,MAC5D,EAAS,GAAS,QAAU,OAAO,GACrC,EAAU,GACV,EAEJ,OAAO,EAAQ,WACP,CACJ,IAAM,EAAQ,EAAK,EAEnB,GAAI,EAAS,CACX,EAAU,GACV,EAAW,EAEP,GAAS,WAAW,EAAQ,YAAc,EAAS,EAAO,IAAA,EAAS,CAAC,EAExE,MACF,CAEA,GAAI,EAAO,EAAe,CAAK,EAAG,OAElC,IAAM,EAAW,EAEjB,EAAW,EACX,EAAQ,YAAc,EAAS,EAAO,CAAQ,CAAC,CACjD,EACA,CAAE,KAAM,GAAS,IAAK,CACxB,CACF"}
1
+ {"version":3,"file":"_watch.cjs","names":[],"sources":["../src/_watch.ts"],"sourcesContent":["import type { EffectHandle, Equality, Readable } from './types';\n\nexport type WatchOptions<T> = {\n equals?: Equality<T>;\n /** Run the callback once at setup, before returning the handle. */\n immediate?: boolean;\n name?: string;\n};\n\ntype WatchRuntime = {\n effect(callback: () => undefined | (() => void), options?: { name?: string }): EffectHandle;\n untrack<T>(fn: () => T): T;\n};\n\nexport const createWatch =\n (runtime: WatchRuntime) =>\n <T>(\n source: Readable<T> | (() => T),\n callback: (value: T, previous: T | undefined) => void,\n options?: WatchOptions<T>,\n ): EffectHandle => {\n const read = typeof source === 'function' ? source : () => source.value;\n const equals = options?.equals ?? Object.is;\n let initial = true;\n let previous: T | undefined;\n\n return runtime.effect(\n () => {\n const value = read();\n\n if (initial) {\n initial = false;\n previous = value;\n\n if (options?.immediate) runtime.untrack(() => callback(value, undefined));\n\n return;\n }\n\n if (equals(previous as T, value)) return;\n\n const oldValue = previous;\n\n previous = value;\n runtime.untrack(() => callback(value, oldValue));\n },\n { name: options?.name },\n );\n };\n"],"mappings":"AAcA,IAAa,YACV,IAEC,EACA,EACA,IACiB,CACjB,IAAM,EAAO,OAAO,GAAW,WAAa,MAAe,EAAO,MAC5D,EAAS,GAAS,QAAU,OAAO,GACrC,EAAU,GACV,EAEJ,OAAO,EAAQ,WACP,CACJ,IAAM,EAAQ,EAAK,EAEnB,GAAI,EAAS,CACX,EAAU,GACV,EAAW,EAEP,GAAS,WAAW,EAAQ,YAAc,EAAS,EAAO,IAAA,EAAS,CAAC,EAExE,MACF,CAEA,GAAI,EAAO,EAAe,CAAK,EAAG,OAElC,IAAM,EAAW,EAEjB,EAAW,EACX,EAAQ,YAAc,EAAS,EAAO,CAAQ,CAAC,CACjD,EACA,CAAE,KAAM,GAAS,IAAK,CACxB,CACF"}
package/dist/_watch.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { EffectHandle, Equality, Readable } from './types';
2
2
  export type WatchOptions<T> = {
3
3
  equals?: Equality<T>;
4
+ /** Run the callback once at setup, before returning the handle. */
4
5
  immediate?: boolean;
5
6
  name?: string;
6
7
  };
@@ -1 +1 @@
1
- {"version":3,"file":"_watch.d.ts","sourceRoot":"","sources":["../src/_watch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEhE,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI;IAC5B,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,KAAK,YAAY,GAAG;IAClB,MAAM,CAAC,QAAQ,EAAE,MAAM,SAAS,GAAG,CAAC,MAAM,IAAI,CAAC,EAAE,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,YAAY,CAAC;IAC5F,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;CAC5B,CAAC;AAEF,eAAO,MAAM,WAAW,GACrB,SAAS,YAAY,MACrB,CAAC,EACA,QAAQ,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAC/B,UAAU,CAAC,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,SAAS,KAAK,IAAI,EACrD,UAAU,YAAY,CAAC,CAAC,CAAC,KACxB,YA4BF,CAAC"}
1
+ {"version":3,"file":"_watch.d.ts","sourceRoot":"","sources":["../src/_watch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEhE,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI;IAC5B,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IACrB,mEAAmE;IACnE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,KAAK,YAAY,GAAG;IAClB,MAAM,CAAC,QAAQ,EAAE,MAAM,SAAS,GAAG,CAAC,MAAM,IAAI,CAAC,EAAE,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,YAAY,CAAC;IAC5F,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;CAC5B,CAAC;AAEF,eAAO,MAAM,WAAW,GACrB,SAAS,YAAY,MACrB,CAAC,EACA,QAAQ,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAC/B,UAAU,CAAC,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,SAAS,KAAK,IAAI,EACrD,UAAU,YAAY,CAAC,CAAC,CAAC,KACxB,YA4BF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"_watch.js","names":[],"sources":["../src/_watch.ts"],"sourcesContent":["import type { EffectHandle, Equality, Readable } from './types';\n\nexport type WatchOptions<T> = {\n equals?: Equality<T>;\n immediate?: boolean;\n name?: string;\n};\n\ntype WatchRuntime = {\n effect(callback: () => undefined | (() => void), options?: { name?: string }): EffectHandle;\n untrack<T>(fn: () => T): T;\n};\n\nexport const createWatch =\n (runtime: WatchRuntime) =>\n <T>(\n source: Readable<T> | (() => T),\n callback: (value: T, previous: T | undefined) => void,\n options?: WatchOptions<T>,\n ): EffectHandle => {\n const read = typeof source === 'function' ? source : () => source.value;\n const equals = options?.equals ?? Object.is;\n let initial = true;\n let previous: T | undefined;\n\n return runtime.effect(\n () => {\n const value = read();\n\n if (initial) {\n initial = false;\n previous = value;\n\n if (options?.immediate) runtime.untrack(() => callback(value, undefined));\n\n return;\n }\n\n if (equals(previous as T, value)) return;\n\n const oldValue = previous;\n\n previous = value;\n runtime.untrack(() => callback(value, oldValue));\n },\n { name: options?.name },\n );\n };\n"],"mappings":"AAaA,IAAa,YACV,IAEC,EACA,EACA,IACiB,CACjB,IAAM,EAAO,OAAO,GAAW,WAAa,MAAe,EAAO,MAC5D,EAAS,GAAS,QAAU,OAAO,GACrC,EAAU,GACV,EAEJ,OAAO,EAAQ,WACP,CACJ,IAAM,EAAQ,EAAK,EAEnB,GAAI,EAAS,CACX,EAAU,GACV,EAAW,EAEP,GAAS,WAAW,EAAQ,YAAc,EAAS,EAAO,IAAA,EAAS,CAAC,EAExE,MACF,CAEA,GAAI,EAAO,EAAe,CAAK,EAAG,OAElC,IAAM,EAAW,EAEjB,EAAW,EACX,EAAQ,YAAc,EAAS,EAAO,CAAQ,CAAC,CACjD,EACA,CAAE,KAAM,GAAS,IAAK,CACxB,CACF"}
1
+ {"version":3,"file":"_watch.js","names":[],"sources":["../src/_watch.ts"],"sourcesContent":["import type { EffectHandle, Equality, Readable } from './types';\n\nexport type WatchOptions<T> = {\n equals?: Equality<T>;\n /** Run the callback once at setup, before returning the handle. */\n immediate?: boolean;\n name?: string;\n};\n\ntype WatchRuntime = {\n effect(callback: () => undefined | (() => void), options?: { name?: string }): EffectHandle;\n untrack<T>(fn: () => T): T;\n};\n\nexport const createWatch =\n (runtime: WatchRuntime) =>\n <T>(\n source: Readable<T> | (() => T),\n callback: (value: T, previous: T | undefined) => void,\n options?: WatchOptions<T>,\n ): EffectHandle => {\n const read = typeof source === 'function' ? source : () => source.value;\n const equals = options?.equals ?? Object.is;\n let initial = true;\n let previous: T | undefined;\n\n return runtime.effect(\n () => {\n const value = read();\n\n if (initial) {\n initial = false;\n previous = value;\n\n if (options?.immediate) runtime.untrack(() => callback(value, undefined));\n\n return;\n }\n\n if (equals(previous as T, value)) return;\n\n const oldValue = previous;\n\n previous = value;\n runtime.untrack(() => callback(value, oldValue));\n },\n { name: options?.name },\n );\n };\n"],"mappings":"AAcA,IAAa,YACV,IAEC,EACA,EACA,IACiB,CACjB,IAAM,EAAO,OAAO,GAAW,WAAa,MAAe,EAAO,MAC5D,EAAS,GAAS,QAAU,OAAO,GACrC,EAAU,GACV,EAEJ,OAAO,EAAQ,WACP,CACJ,IAAM,EAAQ,EAAK,EAEnB,GAAI,EAAS,CACX,EAAU,GACV,EAAW,EAEP,GAAS,WAAW,EAAQ,YAAc,EAAS,EAAO,IAAA,EAAS,CAAC,EAExE,MACF,CAEA,GAAI,EAAO,EAAe,CAAK,EAAG,OAElC,IAAM,EAAW,EAEjB,EAAW,EACX,EAAQ,YAAc,EAAS,EAAO,CAAQ,CAAC,CACjD,EACA,CAAE,KAAM,GAAS,IAAK,CACxB,CACF"}
package/dist/errors.cjs CHANGED
@@ -1,2 +1,2 @@
1
- var RippleError=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},RippleComputedCycleError=class extends RippleError{},RippleDisposedResourceError=class extends RippleError{},RippleDisposedRuntimeError=class extends RippleError{},RippleDisposedScopeError=class extends RippleError{},RippleInfiniteLoopError=class extends RippleError{};exports.RippleComputedCycleError=RippleComputedCycleError,exports.RippleDisposedResourceError=RippleDisposedResourceError,exports.RippleDisposedRuntimeError=RippleDisposedRuntimeError,exports.RippleDisposedScopeError=RippleDisposedScopeError,exports.RippleError=RippleError,exports.RippleInfiniteLoopError=RippleInfiniteLoopError;
1
+ var RippleError=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},RippleCycleError=class extends RippleError{},RippleDisposedError=class extends RippleError{};exports.RippleCycleError=RippleCycleError,exports.RippleDisposedError=RippleDisposedError,exports.RippleError=RippleError;
2
2
  //# sourceMappingURL=errors.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["export class RippleError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class RippleComputedCycleError extends RippleError {}\nexport class RippleDisposedResourceError extends RippleError {}\nexport class RippleDisposedRuntimeError extends RippleError {}\nexport class RippleDisposedScopeError extends RippleError {}\nexport class RippleInfiniteLoopError extends RippleError {}\n"],"mappings":"AAAA,IAAa,YAAb,cAAiC,KAAM,CACrC,YAAY,EAAiB,EAAwB,CACnD,MAAM,EAAS,CAAO,EACtB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CACF,EAEa,yBAAb,cAA8C,WAAY,CAAC,EAC9C,4BAAb,cAAiD,WAAY,CAAC,EACjD,2BAAb,cAAgD,WAAY,CAAC,EAChD,yBAAb,cAA8C,WAAY,CAAC,EAC9C,wBAAb,cAA6C,WAAY,CAAC"}
1
+ {"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["export class RippleError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** User code that never settles: a computed cycle or a runaway flush loop. */\nexport class RippleCycleError extends RippleError {}\n\n/** Any operation against a disposed runtime, scope, resource, or bridge. */\nexport class RippleDisposedError extends RippleError {}\n"],"mappings":"AAAA,IAAa,YAAb,cAAiC,KAAM,CACrC,YAAY,EAAiB,EAAwB,CACnD,MAAM,EAAS,CAAO,EACtB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CACF,EAGa,iBAAb,cAAsC,WAAY,CAAC,EAGtC,oBAAb,cAAyC,WAAY,CAAC"}
package/dist/errors.d.ts CHANGED
@@ -1,14 +1,10 @@
1
1
  export declare class RippleError extends Error {
2
2
  constructor(message: string, options?: ErrorOptions);
3
3
  }
4
- export declare class RippleComputedCycleError extends RippleError {
4
+ /** User code that never settles: a computed cycle or a runaway flush loop. */
5
+ export declare class RippleCycleError extends RippleError {
5
6
  }
6
- export declare class RippleDisposedResourceError extends RippleError {
7
- }
8
- export declare class RippleDisposedRuntimeError extends RippleError {
9
- }
10
- export declare class RippleDisposedScopeError extends RippleError {
11
- }
12
- export declare class RippleInfiniteLoopError extends RippleError {
7
+ /** Any operation against a disposed runtime, scope, resource, or bridge. */
8
+ export declare class RippleDisposedError extends RippleError {
13
9
  }
14
10
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,WAAY,SAAQ,KAAK;gBACxB,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAKpD;AAED,qBAAa,wBAAyB,SAAQ,WAAW;CAAG;AAC5D,qBAAa,2BAA4B,SAAQ,WAAW;CAAG;AAC/D,qBAAa,0BAA2B,SAAQ,WAAW;CAAG;AAC9D,qBAAa,wBAAyB,SAAQ,WAAW;CAAG;AAC5D,qBAAa,uBAAwB,SAAQ,WAAW;CAAG"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,WAAY,SAAQ,KAAK;gBACxB,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAKpD;AAED,8EAA8E;AAC9E,qBAAa,gBAAiB,SAAQ,WAAW;CAAG;AAEpD,4EAA4E;AAC5E,qBAAa,mBAAoB,SAAQ,WAAW;CAAG"}
package/dist/errors.js CHANGED
@@ -1,2 +1,2 @@
1
- var RippleError=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},RippleComputedCycleError=class extends RippleError{},RippleDisposedResourceError=class extends RippleError{},RippleDisposedRuntimeError=class extends RippleError{},RippleDisposedScopeError=class extends RippleError{},RippleInfiniteLoopError=class extends RippleError{};export{RippleComputedCycleError,RippleDisposedResourceError,RippleDisposedRuntimeError,RippleDisposedScopeError,RippleError,RippleInfiniteLoopError};
1
+ var RippleError=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},RippleCycleError=class extends RippleError{},RippleDisposedError=class extends RippleError{};export{RippleCycleError,RippleDisposedError,RippleError};
2
2
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["export class RippleError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class RippleComputedCycleError extends RippleError {}\nexport class RippleDisposedResourceError extends RippleError {}\nexport class RippleDisposedRuntimeError extends RippleError {}\nexport class RippleDisposedScopeError extends RippleError {}\nexport class RippleInfiniteLoopError extends RippleError {}\n"],"mappings":"AAAA,IAAa,YAAb,cAAiC,KAAM,CACrC,YAAY,EAAiB,EAAwB,CACnD,MAAM,EAAS,CAAO,EACtB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CACF,EAEa,yBAAb,cAA8C,WAAY,CAAC,EAC9C,4BAAb,cAAiD,WAAY,CAAC,EACjD,2BAAb,cAAgD,WAAY,CAAC,EAChD,yBAAb,cAA8C,WAAY,CAAC,EAC9C,wBAAb,cAA6C,WAAY,CAAC"}
1
+ {"version":3,"file":"errors.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["export class RippleError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** User code that never settles: a computed cycle or a runaway flush loop. */\nexport class RippleCycleError extends RippleError {}\n\n/** Any operation against a disposed runtime, scope, resource, or bridge. */\nexport class RippleDisposedError extends RippleError {}\n"],"mappings":"AAAA,IAAa,YAAb,cAAiC,KAAM,CACrC,YAAY,EAAiB,EAAwB,CACnD,MAAM,EAAS,CAAO,EACtB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CACF,EAGa,iBAAb,cAAsC,WAAY,CAAC,EAGtC,oBAAb,cAAyC,WAAY,CAAC"}
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./errors.cjs"),t=require("./runtime.cjs"),n=require("./_default.cjs");var r=n.defaultRipple.signal,i=n.defaultRipple.computed,a=n.defaultRipple.effect,o=n.defaultRipple.batch,s=n.defaultRipple.createScope,c=n.defaultRipple.untrack,l=n.defaultRipple.watch,u=n.defaultRipple.resource,d=n.defaultRipple.fromSubscribable;exports.RippleComputedCycleError=e.RippleComputedCycleError,exports.RippleDisposedResourceError=e.RippleDisposedResourceError,exports.RippleDisposedRuntimeError=e.RippleDisposedRuntimeError,exports.RippleDisposedScopeError=e.RippleDisposedScopeError,exports.RippleError=e.RippleError,exports.RippleInfiniteLoopError=e.RippleInfiniteLoopError,exports.batch=o,exports.computed=i,exports.createRipple=n.createRipple,exports.createScope=s,exports.effect=a,exports.fromSubscribable=d,exports.isReactive=t.isReactive,exports.resource=u,exports.signal=r,exports.untrack=c,exports.watch=l;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./errors.cjs"),t=require("./runtime.cjs"),n=require("./_default.cjs");var r=n.defaultRipple.signal,i=n.defaultRipple.computed,a=n.defaultRipple.effect,o=n.defaultRipple.batch,s=n.defaultRipple.createScope,c=n.defaultRipple.untrack,l=n.defaultRipple.watch,u=n.defaultRipple.resource,d=n.defaultRipple.fromSubscribable;exports.RippleCycleError=e.RippleCycleError,exports.RippleDisposedError=e.RippleDisposedError,exports.RippleError=e.RippleError,exports.batch=o,exports.computed=i,exports.createRipple=n.createRipple,exports.createScope=s,exports.effect=a,exports.fromSubscribable=d,exports.isReactive=t.isReactive,exports.resource=u,exports.signal=r,exports.untrack=c,exports.watch=l;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["export type { AsyncState, Resource, ResourceOptions } from './_async';\nexport { createRipple, type Ripple } from './_default';\nexport type { BridgedReadable, FromSubscribableOptions } from './_subscribable';\nexport type { WatchOptions } from './_watch';\nexport {\n RippleComputedCycleError,\n RippleDisposedResourceError,\n RippleDisposedRuntimeError,\n RippleDisposedScopeError,\n RippleError,\n RippleInfiniteLoopError,\n} from './errors';\nexport { isReactive } from './runtime';\nexport type {\n Cleanup,\n ComputedOptions,\n Disposable,\n EffectHandle,\n EffectOptions,\n Equality,\n Readable,\n RippleErrorContext,\n RippleErrorPolicy,\n RippleEvent,\n RippleOptions,\n Scope,\n Signal,\n SignalOptions,\n Subscribable,\n Unsubscribe,\n} from './types';\n\nimport { defaultRipple } from './_default';\n\nexport const signal = defaultRipple.signal;\nexport const computed = defaultRipple.computed;\nexport const effect = defaultRipple.effect;\nexport const batch = defaultRipple.batch;\nexport const createScope = defaultRipple.createScope;\nexport const untrack = defaultRipple.untrack;\nexport const watch = defaultRipple.watch;\nexport const resource = defaultRipple.resource;\nexport const fromSubscribable = defaultRipple.fromSubscribable;\n"],"mappings":"0JAkCA,IAAa,EAAS,EAAA,cAAc,OACvB,EAAW,EAAA,cAAc,SACzB,EAAS,EAAA,cAAc,OACvB,EAAQ,EAAA,cAAc,MACtB,EAAc,EAAA,cAAc,YAC5B,EAAU,EAAA,cAAc,QACxB,EAAQ,EAAA,cAAc,MACtB,EAAW,EAAA,cAAc,SACzB,EAAmB,EAAA,cAAc"}
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["export type { AsyncState, Resource, ResourceOptions } from './_async';\nexport { createRipple, type Ripple } from './_default';\nexport type { BridgedReadable, FromSubscribableOptions } from './_subscribable';\nexport type { WatchOptions } from './_watch';\nexport { RippleCycleError, RippleDisposedError, RippleError } from './errors';\nexport { isReactive } from './runtime';\nexport type {\n Cleanup,\n ComputedOptions,\n Disposable,\n EffectHandle,\n EffectOptions,\n Equality,\n Readable,\n RippleErrorContext,\n RippleOptions,\n Scope,\n Signal,\n SignalOptions,\n Subscribable,\n Unsubscribe,\n} from './types';\n\nimport { defaultRipple } from './_default';\n\nexport const signal = defaultRipple.signal;\nexport const computed = defaultRipple.computed;\nexport const effect = defaultRipple.effect;\nexport const batch = defaultRipple.batch;\nexport const createScope = defaultRipple.createScope;\nexport const untrack = defaultRipple.untrack;\nexport const watch = defaultRipple.watch;\nexport const resource = defaultRipple.resource;\nexport const fromSubscribable = defaultRipple.fromSubscribable;\n"],"mappings":"0JAyBA,IAAa,EAAS,EAAA,cAAc,OACvB,EAAW,EAAA,cAAc,SACzB,EAAS,EAAA,cAAc,OACvB,EAAQ,EAAA,cAAc,MACtB,EAAc,EAAA,cAAc,YAC5B,EAAU,EAAA,cAAc,QACxB,EAAQ,EAAA,cAAc,MACtB,EAAW,EAAA,cAAc,SACzB,EAAmB,EAAA,cAAc"}
package/dist/index.d.ts CHANGED
@@ -2,9 +2,9 @@ export type { AsyncState, Resource, ResourceOptions } from './_async';
2
2
  export { createRipple, type Ripple } from './_default';
3
3
  export type { BridgedReadable, FromSubscribableOptions } from './_subscribable';
4
4
  export type { WatchOptions } from './_watch';
5
- export { RippleComputedCycleError, RippleDisposedResourceError, RippleDisposedRuntimeError, RippleDisposedScopeError, RippleError, RippleInfiniteLoopError, } from './errors';
5
+ export { RippleCycleError, RippleDisposedError, RippleError } from './errors';
6
6
  export { isReactive } from './runtime';
7
- export type { Cleanup, ComputedOptions, Disposable, EffectHandle, EffectOptions, Equality, Readable, RippleErrorContext, RippleErrorPolicy, RippleEvent, RippleOptions, Scope, Signal, SignalOptions, Subscribable, Unsubscribe, } from './types';
7
+ export type { Cleanup, ComputedOptions, Disposable, EffectHandle, EffectOptions, Equality, Readable, RippleErrorContext, RippleOptions, Scope, Signal, SignalOptions, Subscribable, Unsubscribe, } from './types';
8
8
  export declare const signal: <T>(initial: T, options?: import("./types").SignalOptions<T>) => import("./types").Signal<T>;
9
9
  export declare const computed: <T>(derive: () => T, options?: import("./types").ComputedOptions<T>) => import("./types").Readable<T>;
10
10
  export declare const effect: (callback: () => import("./types").Cleanup | undefined, options?: import("./types").EffectOptions) => import("./types").EffectHandle;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,KAAK,MAAM,EAAE,MAAM,YAAY,CAAC;AACvD,YAAY,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAChF,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EACL,wBAAwB,EACxB,2BAA2B,EAC3B,0BAA0B,EAC1B,wBAAwB,EACxB,WAAW,EACX,uBAAuB,GACxB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,YAAY,EACV,OAAO,EACP,eAAe,EACf,UAAU,EACV,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,kBAAkB,EAClB,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,KAAK,EACL,MAAM,EACN,aAAa,EACb,YAAY,EACZ,WAAW,GACZ,MAAM,SAAS,CAAC;AAIjB,eAAO,MAAM,MAAM,8FAAuB,CAAC;AAC3C,eAAO,MAAM,QAAQ,uGAAyB,CAAC;AAC/C,eAAO,MAAM,MAAM,sIAAuB,CAAC;AAC3C,eAAO,MAAM,KAAK,uBAAsB,CAAC;AACzC,eAAO,MAAM,WAAW,4CAA4B,CAAC;AACrD,eAAO,MAAM,OAAO,uBAAwB,CAAC;AAC7C,eAAO,MAAM,KAAK,+LAAsB,CAAC;AACzC,eAAO,MAAM,QAAQ;;yGAAyB,CAAC;AAC/C,eAAO,MAAM,gBAAgB,6JAAiC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,KAAK,MAAM,EAAE,MAAM,YAAY,CAAC;AACvD,YAAY,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAChF,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC9E,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,YAAY,EACV,OAAO,EACP,eAAe,EACf,UAAU,EACV,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,kBAAkB,EAClB,aAAa,EACb,KAAK,EACL,MAAM,EACN,aAAa,EACb,YAAY,EACZ,WAAW,GACZ,MAAM,SAAS,CAAC;AAIjB,eAAO,MAAM,MAAM,8FAAuB,CAAC;AAC3C,eAAO,MAAM,QAAQ,uGAAyB,CAAC;AAC/C,eAAO,MAAM,MAAM,sIAAuB,CAAC;AAC3C,eAAO,MAAM,KAAK,uBAAsB,CAAC;AACzC,eAAO,MAAM,WAAW,4CAA4B,CAAC;AACrD,eAAO,MAAM,OAAO,uBAAwB,CAAC;AAC7C,eAAO,MAAM,KAAK,+LAAsB,CAAC;AACzC,eAAO,MAAM,QAAQ;;yGAAyB,CAAC;AAC/C,eAAO,MAAM,gBAAgB,6JAAiC,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import{RippleComputedCycleError as e,RippleDisposedResourceError as t,RippleDisposedRuntimeError as n,RippleDisposedScopeError as r,RippleError as i,RippleInfiniteLoopError as a}from"./errors.js";import{isReactive as o}from"./runtime.js";import{createRipple as s,defaultRipple as c}from"./_default.js";var l=c.signal,u=c.computed,d=c.effect,f=c.batch,p=c.createScope,m=c.untrack,h=c.watch,g=c.resource,_=c.fromSubscribable;export{e as RippleComputedCycleError,t as RippleDisposedResourceError,n as RippleDisposedRuntimeError,r as RippleDisposedScopeError,i as RippleError,a as RippleInfiniteLoopError,f as batch,u as computed,s as createRipple,p as createScope,d as effect,_ as fromSubscribable,o as isReactive,g as resource,l as signal,m as untrack,h as watch};
1
+ import{RippleCycleError as e,RippleDisposedError as t,RippleError as n}from"./errors.js";import{isReactive as r}from"./runtime.js";import{createRipple as i,defaultRipple as a}from"./_default.js";var o=a.signal,s=a.computed,c=a.effect,l=a.batch,u=a.createScope,d=a.untrack,f=a.watch,p=a.resource,m=a.fromSubscribable;export{e as RippleCycleError,t as RippleDisposedError,n as RippleError,l as batch,s as computed,i as createRipple,u as createScope,c as effect,m as fromSubscribable,r as isReactive,p as resource,o as signal,d as untrack,f as watch};
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["export type { AsyncState, Resource, ResourceOptions } from './_async';\nexport { createRipple, type Ripple } from './_default';\nexport type { BridgedReadable, FromSubscribableOptions } from './_subscribable';\nexport type { WatchOptions } from './_watch';\nexport {\n RippleComputedCycleError,\n RippleDisposedResourceError,\n RippleDisposedRuntimeError,\n RippleDisposedScopeError,\n RippleError,\n RippleInfiniteLoopError,\n} from './errors';\nexport { isReactive } from './runtime';\nexport type {\n Cleanup,\n ComputedOptions,\n Disposable,\n EffectHandle,\n EffectOptions,\n Equality,\n Readable,\n RippleErrorContext,\n RippleErrorPolicy,\n RippleEvent,\n RippleOptions,\n Scope,\n Signal,\n SignalOptions,\n Subscribable,\n Unsubscribe,\n} from './types';\n\nimport { defaultRipple } from './_default';\n\nexport const signal = defaultRipple.signal;\nexport const computed = defaultRipple.computed;\nexport const effect = defaultRipple.effect;\nexport const batch = defaultRipple.batch;\nexport const createScope = defaultRipple.createScope;\nexport const untrack = defaultRipple.untrack;\nexport const watch = defaultRipple.watch;\nexport const resource = defaultRipple.resource;\nexport const fromSubscribable = defaultRipple.fromSubscribable;\n"],"mappings":"8SAkCA,IAAa,EAAS,EAAc,OACvB,EAAW,EAAc,SACzB,EAAS,EAAc,OACvB,EAAQ,EAAc,MACtB,EAAc,EAAc,YAC5B,EAAU,EAAc,QACxB,EAAQ,EAAc,MACtB,EAAW,EAAc,SACzB,EAAmB,EAAc"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["export type { AsyncState, Resource, ResourceOptions } from './_async';\nexport { createRipple, type Ripple } from './_default';\nexport type { BridgedReadable, FromSubscribableOptions } from './_subscribable';\nexport type { WatchOptions } from './_watch';\nexport { RippleCycleError, RippleDisposedError, RippleError } from './errors';\nexport { isReactive } from './runtime';\nexport type {\n Cleanup,\n ComputedOptions,\n Disposable,\n EffectHandle,\n EffectOptions,\n Equality,\n Readable,\n RippleErrorContext,\n RippleOptions,\n Scope,\n Signal,\n SignalOptions,\n Subscribable,\n Unsubscribe,\n} from './types';\n\nimport { defaultRipple } from './_default';\n\nexport const signal = defaultRipple.signal;\nexport const computed = defaultRipple.computed;\nexport const effect = defaultRipple.effect;\nexport const batch = defaultRipple.batch;\nexport const createScope = defaultRipple.createScope;\nexport const untrack = defaultRipple.untrack;\nexport const watch = defaultRipple.watch;\nexport const resource = defaultRipple.resource;\nexport const fromSubscribable = defaultRipple.fromSubscribable;\n"],"mappings":"mMAyBA,IAAa,EAAS,EAAc,OACvB,EAAW,EAAc,SACzB,EAAS,EAAc,OACvB,EAAQ,EAAc,MACtB,EAAc,EAAc,YAC5B,EAAU,EAAc,QACxB,EAAQ,EAAc,MACtB,EAAW,EAAc,SACzB,EAAmB,EAAc"}
package/dist/ripple.cjs CHANGED
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var RippleError=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},RippleComputedCycleError=class extends RippleError{},RippleDisposedResourceError=class extends RippleError{},RippleDisposedRuntimeError=class extends RippleError{},RippleDisposedScopeError=class extends RippleError{},RippleInfiniteLoopError=class extends RippleError{},e=Symbol.for(`@vielzeug/ripple/reactive`),t=100,n=Symbol(`ripple.unset`),ReactiveNode=class{[e]=!0;dependents=new Set;name;runtime;constructor(e,t){this.runtime=e,this.name=t}subscribe(e){this.runtime.assertActive(),this.peek();let t={listener:e,onDependencyChanged:()=>this.runtime.enqueueListener(t)};return this.dependents.add(t),()=>this.dependents.delete(t)}notify(){for(let e of[...this.dependents])e.onDependencyChanged()}},SignalNode=class extends ReactiveNode{current;equals;constructor(e,t,n){super(e,n?.name),this.current=t,this.equals=n?.equals??Object.is}get value(){return this.runtime.track(this),this.current}set value(e){if(this.runtime.assertActive(),this.equals(this.current,e))return;let t=this.current;this.current=e,this.runtime.emit({name:this.name,next:e,previous:t,type:`write`}),this.runtime.propagate(()=>this.notify())}peek(){return this.current}update(e){this.value=e(this.current)}},ComputedNode=class extends ReactiveNode{dependencies=new Set;computing=!1;disposed=!1;dirty=!0;current=n;derive;equals;owner;constructor(e,t,n){super(e,n?.name),this.derive=t,this.equals=n?.equals??Object.is}get value(){return this.runtime.track(this),this.refresh(),this.current}peek(){return this.refresh(),this.current}onDependencyChanged(){if(!this.disposed&&(this.dirty||=!0,this.dependents.size>0))try{this.refresh()&&this.notify()}catch(e){this.runtime.report(e,{kind:`computed`,name:this.name})}}setOwner(e){this.owner=e}dispose(){this.disposed||(this.disposed=!0,this.owner?.release(this),this.owner=void 0,this.runtime.clearDependencies(this),this.dependents.clear())}refresh(){if(!this.dirty||this.disposed)return!1;if(this.computing)throw new RippleComputedCycleError(`computed cycle detected${this.name===void 0?``:` "${this.name}"`}`);this.computing=!0,this.runtime.emit({name:this.name,type:`compute`});try{let e=this.runtime.collect(this,this.derive),t=this.current===n||!this.equals(this.current,e);return this.current=e,this.dirty=!1,t}finally{this.computing=!1}}},ScopeNode=class{disposalController=new AbortController;owned=new Set;name;isDisposed=!1;owner;runtime;constructor(e,t){this.runtime=e,this.name=t}get disposed(){return this.isDisposed}get disposalSignal(){return this.disposalController.signal}own(e){e.setOwner(this),this.owned.add(e)}release(e){this.owned.delete(e)}setOwner(e){this.owner=e}run(e){if(this.isDisposed)throw new RippleDisposedScopeError(`Cannot run a disposed scope.`);return this.runtime.withScope(this,e)}dispose(){if(!this.isDisposed){this.isDisposed=!0,this.owner?.release(this),this.owner=void 0;for(let e of[...this.owned].reverse())e.dispose();this.owned.clear(),this.disposalController.abort(),this.runtime.emit({name:this.name,node:`scope`,type:`dispose`})}}[Symbol.dispose](){this.dispose()}},EffectNode=class{dependencies=new Set;disposalController=new AbortController;cleanup;isDisposed=!1;ownershipScope;runScope;callback;options;runtime;constructor(e,t,n){this.runtime=e,this.callback=t,this.options=n}get disposed(){return this.isDisposed}get disposalSignal(){return this.disposalController.signal}setOwner(e){this.ownershipScope=e}onDependencyChanged(){this.isDisposed||this.runtime.enqueue(this)}run(){if(this.isDisposed)return;this.runScope?.dispose(),this.runScope=void 0,this.runCleanup(),this.runtime.emit({name:this.options?.name,type:`effect`});let e=new ScopeNode(this.runtime);try{let t=this.runtime.withEffectScope(e,()=>this.runtime.collectEffect(this,this.callback));this.runScope=e,this.cleanup=typeof t==`function`?t:void 0,this.isDisposed&&(this.runScope.dispose(),this.runScope=void 0,this.runCleanup())}catch(t){e.dispose(),this.runtime.report(t,{kind:`effect`,name:this.options?.name})}}dispose(){this.isDisposed||(this.isDisposed=!0,this.ownershipScope?.release(this),this.ownershipScope=void 0,this.runScope?.dispose(),this.runScope=void 0,this.runtime.clearDependencies(this),this.runCleanup(),this.disposalController.abort(),this.runtime.emit({name:this.options?.name,node:`effect`,type:`dispose`}))}[Symbol.dispose](){this.dispose()}runCleanup(){let e=this.cleanup;if(this.cleanup=void 0,e!==void 0)try{e()}catch(e){this.runtime.report(e,{kind:`cleanup`,name:this.options?.name})}}},ReactiveRuntime=class{activeEffectScope;activeObserver;activeScope;isDisposed=!1;flushDepth=0;flushing=!1;pending=new Set;listeners=new Set;rootScope;tappers=new Set;errorPolicy;constructor(e){this.errorPolicy=e?.errorPolicy??`throw`,this.rootScope=new ScopeNode(this,`runtime`),this.activeScope=this.rootScope}get disposed(){return this.isDisposed}get disposalSignal(){return this.rootScope.disposalSignal}signal=(e,t)=>(this.assertActive(),new SignalNode(this,e,t));computed=(e,t)=>{this.assertActive();let n=new ComputedNode(this,e,t);return(this.activeEffectScope??this.activeScope).own(n),n};effect=(e,t)=>{this.assertActive();let n=new EffectNode(this,e,t);return(this.activeEffectScope??this.activeScope).own(n),n.run(),n};createScope=e=>{this.assertActive();let t=new ScopeNode(this,e);return this.activeScope.own(t),t};batch=e=>(this.assertActive(),this.propagate(e));untrack=e=>(this.assertActive(),this.withObserver(void 0,e));tap=(e,t)=>{if(this.isDisposed)return()=>{};let n=t?.signal;if(n?.aborted)return this.tappers.delete(e),()=>{};if(this.tappers.add(e),n){let onAbort=()=>this.tappers.delete(e);return n.addEventListener(`abort`,onAbort,{once:!0}),()=>{this.tappers.delete(e),n.removeEventListener(`abort`,onAbort)}}return()=>this.tappers.delete(e)};dispose(){this.isDisposed||(this.isDisposed=!0,this.rootScope.dispose(),this.emit({node:`graph`,type:`dispose`}),this.tappers.clear())}assertActive(){if(this.isDisposed)throw new RippleDisposedRuntimeError(`Cannot use a disposed Ripple runtime.`)}track(e){let t=this.activeObserver;t?.collecting!==void 0&&t.collecting.add(e)}clearDependencies(e){for(let t of e.dependencies)t.dependents.delete(e);e.dependencies.clear()}collect(e,t){return this.collectWith(e,t,e.dependencies.size===0)}collectEffect(e,t){return this.collectWith(e,t,!0)}withEffectScope(e,t){let n=this.activeEffectScope;this.activeEffectScope=e;try{return t()}finally{this.activeEffectScope=n}}withObserver(e,t){let n=this.activeObserver;this.activeObserver=e;try{return t()}finally{this.activeObserver=n}}withScope(e,t){let n=this.activeEffectScope,r=this.activeScope;this.activeEffectScope=void 0,this.activeScope=e;try{return t()}finally{this.activeEffectScope=n,this.activeScope=r}}enqueue(e){this.pending.add(e),this.flushDepth===0&&this.flush()}enqueueListener(e){this.listeners.add(e),this.flushDepth===0&&this.flush()}propagate(e){this.flushDepth++;try{return e()}finally{this.flushDepth--,this.flushDepth===0&&this.flush()}}emit(e){if(this.tappers.size!==0)for(let t of this.tappers)try{t(e)}catch{}}report(e,t){this.emit({context:t,error:e,type:`error`}),this.errorPolicy===`throw`&&queueMicrotask(()=>{throw e})}collectWith(e,t,n){let r=this.activeObserver,i=new Set;e.collecting=i,this.activeObserver=e;try{let n=t();return this.commitDependencies(e,i),n}catch(t){throw n&&this.commitDependencies(e,i),t}finally{e.collecting=void 0,this.activeObserver=r}}commitDependencies(e,t){for(let n of e.dependencies)t.has(n)||n.dependents.delete(e);for(let n of t)e.dependencies.has(n)||n.dependents.add(e);e.dependencies.clear();for(let n of t)e.dependencies.add(n)}flush(){if(this.flushing)return;this.flushing=!0;let e=0;try{for(;this.pending.size>0||this.listeners.size>0;){if(++e>t)throw new RippleInfiniteLoopError(`infinite reactive flush (>${t} iterations)`);let n=[...this.pending],r=[...this.listeners];this.pending.clear(),this.listeners.clear();for(let e of n)e.run();for(let e of r)try{e.listener()}catch(e){this.report(e,{kind:`listener`})}}}finally{this.flushing=!1}}},isReactive=t=>{if(typeof t!=`object`||!t||t[e]!==!0)return!1;let n=t;return`value`in n&&typeof n.peek==`function`&&typeof n.subscribe==`function`},createResource=t=>(n,r,i)=>{let a=t.signal({status:`pending`},{name:i?.name}),o=t.signal(0),s,c=!1,l,run=()=>{o.value,s?.abort();let e;try{e=n()}catch(e){a.value=c?{error:e,previous:l,status:`error`}:{error:e,status:`error`};return}let t=new AbortController;s=t,a.value=c?{previous:l,status:`pending`}:{status:`pending`};let i;try{i=Promise.resolve(r(e,{signal:t.signal}))}catch(e){i=Promise.reject(e)}i.then(e=>{!u.disposed&&!t.signal.aborted&&(c=!0,l=e,a.value={status:`success`,value:e})},e=>{!u.disposed&&!t.signal.aborted&&(a.value=c?{error:e,previous:l,status:`error`}:{error:e,status:`error`})})},u=t.effect(()=>(run(),()=>s?.abort()),{name:i?.name}),assertActive=()=>{if(u.disposed)throw new RippleDisposedResourceError(`Cannot use a disposed resource.`)},d={get disposalSignal(){return u.disposalSignal},dispose:()=>u.dispose(),get disposed(){return u.disposed},get name(){return a.name},peek:()=>a.peek(),reload:()=>{assertActive(),o.value=o.peek()+1},subscribe:e=>(assertActive(),a.subscribe(e)),[Symbol.dispose](){this.dispose()},get value(){return a.value}};return Object.defineProperty(d,e,{value:!0}),d},createFromSubscribable=t=>(n,r)=>{let i=t.signal(n.getSnapshot(),{name:r?.name}),a=t.effect(()=>{let sync=()=>{i.value=n.getSnapshot()},e;try{e=n.subscribe(sync),sync()}catch(t){throw e?.(),t}return e},{name:r?.name}),abort=()=>a.dispose();r?.signal?.addEventListener(`abort`,abort,{once:!0}),r?.signal?.aborted&&a.dispose();let assertActive=()=>{if(a.disposed)throw new RippleError(`Cannot subscribe to a disposed bridge.`)},dispose=()=>{r?.signal?.removeEventListener(`abort`,abort),a.dispose()},o={get disposalSignal(){return a.disposalSignal},dispose,get disposed(){return a.disposed},get name(){return i.name},peek:()=>i.peek(),subscribe(e){return assertActive(),i.subscribe(e)},[Symbol.dispose]:dispose,get value(){return i.value}};return Object.defineProperty(o,e,{value:!0}),o},createWatch=e=>(t,n,r)=>{let i=typeof t==`function`?t:()=>t.value,a=r?.equals??Object.is,o=!0,s;return e.effect(()=>{let t=i();if(o){o=!1,s=t,r?.immediate&&e.untrack(()=>n(t,void 0));return}if(a(s,t))return;let c=s;s=t,e.untrack(()=>n(t,c))},{name:r?.name})},createRipple=e=>{let t=new ReactiveRuntime(e),n=createFromSubscribable(t),r=createResource(t);return{batch:t.batch,computed:t.computed,createScope:t.createScope,get disposalSignal(){return t.disposalSignal},dispose:()=>t.dispose(),get disposed(){return t.disposed},effect:t.effect,fromSubscribable:n,resource:r,signal:t.signal,tap:t.tap,untrack:t.untrack,watch:createWatch(t),[Symbol.dispose]:()=>t.dispose()}},r=createRipple(),i=r.signal,a=r.computed,o=r.effect,s=r.batch,c=r.createScope,l=r.untrack,u=r.watch,d=r.resource,f=r.fromSubscribable;exports.RippleComputedCycleError=RippleComputedCycleError,exports.RippleDisposedResourceError=RippleDisposedResourceError,exports.RippleDisposedRuntimeError=RippleDisposedRuntimeError,exports.RippleDisposedScopeError=RippleDisposedScopeError,exports.RippleError=RippleError,exports.RippleInfiniteLoopError=RippleInfiniteLoopError,exports.batch=s,exports.computed=a,exports.createRipple=createRipple,exports.createScope=c,exports.effect=o,exports.fromSubscribable=f,exports.isReactive=isReactive,exports.resource=d,exports.signal=i,exports.untrack=l,exports.watch=u;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var RippleError=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},RippleCycleError=class extends RippleError{},RippleDisposedError=class extends RippleError{},e=Symbol.for(`@vielzeug/ripple/reactive`),t=100,n=Symbol(`ripple.unset`),ReactiveNode=class{[e]=!0;dependents=new Set;name;runtime;constructor(e,t){this.runtime=e,this.name=t}subscribe(e){this.runtime.assertActive(),this.peek();let t={listener:e,onDependencyChanged:()=>this.runtime.enqueueListener(t)};return this.dependents.add(t),()=>this.dependents.delete(t)}notify(){for(let e of[...this.dependents])e.onDependencyChanged()}},SignalNode=class extends ReactiveNode{current;equals;constructor(e,t,n){super(e,n?.name),this.current=t,this.equals=n?.equals??Object.is}get value(){return this.runtime.track(this),this.current}set value(e){this.runtime.assertActive(),!this.equals(this.current,e)&&(this.current=e,this.runtime.propagate(()=>this.notify()))}peek(){return this.current}update(e){this.value=e(this.current)}},ComputedNode=class extends ReactiveNode{dependencies=new Set;computing=!1;disposed=!1;dirty=!0;current=n;derive;equals;owner;constructor(e,t,n){super(e,n?.name),this.derive=t,this.equals=n?.equals??Object.is}get value(){return this.runtime.track(this),this.refresh(),this.evaluated()}peek(){return this.refresh(),this.evaluated()}evaluated(){if(this.current===n)throw new RippleDisposedError(`computed${this.name===void 0?``:` "${this.name}"`} was disposed before it was ever evaluated`);return this.current}onDependencyChanged(){if(!this.disposed&&(this.dirty||=!0,this.dependents.size>0))try{this.refresh()&&this.notify()}catch(e){this.runtime.report(e,{kind:`computed`,name:this.name})}}setOwner(e){this.owner=e}dispose(){this.disposed||(this.disposed=!0,this.owner?.release(this),this.owner=void 0,this.runtime.clearDependencies(this),this.dependents.clear())}refresh(){if(!this.dirty||this.disposed)return!1;if(this.computing)throw new RippleCycleError(`computed cycle detected${this.name===void 0?``:` "${this.name}"`}`);this.computing=!0;try{let e=this.runtime.collect(this,this.derive),t=this.current===n||!this.equals(this.current,e);return this.current=e,this.dirty=!1,t}finally{this.computing=!1}}},ScopeNode=class{disposalController=new AbortController;owned=new Set;name;isDisposed=!1;owner;runtime;constructor(e,t){this.runtime=e,this.name=t}get disposed(){return this.isDisposed}get disposalSignal(){return this.disposalController.signal}own(e){e.setOwner(this),this.owned.add(e)}release(e){this.owned.delete(e)}setOwner(e){this.owner=e}run(e){if(this.isDisposed)throw new RippleDisposedError(`Cannot run a disposed scope.`);return this.runtime.withScope(this,e)}dispose(){if(!this.isDisposed){this.isDisposed=!0,this.owner?.release(this),this.owner=void 0;for(let e of[...this.owned].reverse())e.dispose();this.owned.clear(),this.disposalController.abort()}}[Symbol.dispose](){this.dispose()}},EffectNode=class{dependencies=new Set;disposalController=new AbortController;cleanup;isDisposed=!1;ownershipScope;runScope;callback;options;runtime;constructor(e,t,n){this.runtime=e,this.callback=t,this.options=n}get disposed(){return this.isDisposed}get disposalSignal(){return this.disposalController.signal}setOwner(e){this.ownershipScope=e}onDependencyChanged(){this.isDisposed||this.runtime.enqueue(this)}run(){if(this.isDisposed)return;this.runScope?.dispose(),this.runScope=void 0,this.runCleanup();let e=new ScopeNode(this.runtime);try{let t=this.runtime.withEffectScope(e,()=>this.runtime.collectEffect(this,this.callback));this.runScope=e,this.cleanup=typeof t==`function`?t:void 0,this.isDisposed&&(this.runScope.dispose(),this.runScope=void 0,this.runCleanup())}catch(t){e.dispose(),this.runtime.report(t,{kind:`effect`,name:this.options?.name})}}dispose(){this.isDisposed||(this.isDisposed=!0,this.ownershipScope?.release(this),this.ownershipScope=void 0,this.runScope?.dispose(),this.runScope=void 0,this.runtime.clearDependencies(this),this.runCleanup(),this.disposalController.abort())}[Symbol.dispose](){this.dispose()}runCleanup(){let e=this.cleanup;if(this.cleanup=void 0,e!==void 0)try{e()}catch(e){this.runtime.report(e,{kind:`cleanup`,name:this.options?.name})}}},ReactiveRuntime=class{activeEffectScope;activeObserver;activeScope;isDisposed=!1;flushDepth=0;flushing=!1;pending=new Set;listeners=new Set;rootScope;onError;constructor(e){this.onError=e?.onError??(e=>{queueMicrotask(()=>{throw e})}),this.rootScope=new ScopeNode(this,`runtime`),this.activeScope=this.rootScope}get disposed(){return this.isDisposed}get disposalSignal(){return this.rootScope.disposalSignal}signal=(e,t)=>(this.assertActive(),new SignalNode(this,e,t));computed=(e,t)=>{this.assertActive();let n=new ComputedNode(this,e,t);return(this.activeEffectScope??this.activeScope).own(n),n};effect=(e,t)=>{this.assertActive();let n=new EffectNode(this,e,t);return(this.activeEffectScope??this.activeScope).own(n),n.run(),n};createScope=e=>{this.assertActive();let t=new ScopeNode(this,e);return this.activeScope.own(t),t};batch=e=>(this.assertActive(),this.propagate(e));untrack=e=>(this.assertActive(),this.withObserver(void 0,e));dispose(){this.isDisposed||(this.isDisposed=!0,this.rootScope.dispose())}assertActive(){if(this.isDisposed)throw new RippleDisposedError(`Cannot use a disposed Ripple runtime.`)}track(e){let t=this.activeObserver;t?.collecting!==void 0&&t.collecting.add(e)}clearDependencies(e){for(let t of e.dependencies)t.dependents.delete(e);e.dependencies.clear()}collect(e,t){return this.collectWith(e,t,e.dependencies.size===0)}collectEffect(e,t){return this.collectWith(e,t,!0)}withEffectScope(e,t){let n=this.activeEffectScope;this.activeEffectScope=e;try{return t()}finally{this.activeEffectScope=n}}withObserver(e,t){let n=this.activeObserver;this.activeObserver=e;try{return t()}finally{this.activeObserver=n}}withScope(e,t){let n=this.activeEffectScope,r=this.activeScope;this.activeEffectScope=void 0,this.activeScope=e;try{return t()}finally{this.activeEffectScope=n,this.activeScope=r}}enqueue(e){this.pending.add(e),this.flushDepth===0&&this.flush()}enqueueListener(e){this.listeners.add(e),this.flushDepth===0&&this.flush()}propagate(e){this.flushDepth++;try{return e()}finally{this.flushDepth--,this.flushDepth===0&&this.flush()}}report(e,t){try{this.onError(e,t)}catch{}}collectWith(e,t,n){let r=this.activeObserver,i=new Set;e.collecting=i,this.activeObserver=e;try{let n=t();return this.commitDependencies(e,i),n}catch(t){throw n&&this.commitDependencies(e,i),t}finally{e.collecting=void 0,this.activeObserver=r}}commitDependencies(e,t){for(let n of e.dependencies)t.has(n)||n.dependents.delete(e);for(let n of t)e.dependencies.has(n)||n.dependents.add(e);e.dependencies.clear();for(let n of t)e.dependencies.add(n)}flush(){if(this.flushing)return;this.flushing=!0;let e=0;try{for(;this.pending.size>0||this.listeners.size>0;){if(++e>t){this.report(new RippleCycleError(`infinite reactive flush (>${t} iterations)`),{kind:`flush`}),this.pending.clear(),this.listeners.clear();break}let n=[...this.pending],r=[...this.listeners];this.pending.clear(),this.listeners.clear();for(let e of n)e.run();for(let e of r)try{e.listener()}catch(e){this.report(e,{kind:`listener`})}}}finally{this.flushing=!1}}},isReactive=t=>{if(typeof t!=`object`||!t||t[e]!==!0)return!1;let n=t;return`value`in n&&typeof n.peek==`function`&&typeof n.subscribe==`function`},createResource=t=>(n,r,i)=>{let a=t.signal({status:`pending`},{name:i?.name}),o=t.signal(0),s,c=!1,l,run=()=>{o.value,s?.abort();let e;try{e=n()}catch(e){a.value=c?{error:e,previous:l,status:`error`}:{error:e,status:`error`};return}let t=new AbortController;s=t,a.value=c?{previous:l,status:`pending`}:{status:`pending`};let i;try{i=Promise.resolve(r(e,{signal:t.signal}))}catch(e){i=Promise.reject(e)}i.then(e=>{!u.disposed&&!t.signal.aborted&&(c=!0,l=e,a.value={status:`success`,value:e})},e=>{!u.disposed&&!t.signal.aborted&&(a.value=c?{error:e,previous:l,status:`error`}:{error:e,status:`error`})})},u=t.effect(()=>(run(),()=>s?.abort()),{name:i?.name}),assertActive=()=>{if(u.disposed)throw new RippleDisposedError(`Cannot use a disposed resource.`)},d={get disposalSignal(){return u.disposalSignal},dispose:()=>u.dispose(),get disposed(){return u.disposed},get name(){return a.name},peek:()=>a.peek(),reload:()=>{assertActive(),o.value=o.peek()+1},subscribe:e=>(assertActive(),a.subscribe(e)),[Symbol.dispose](){this.dispose()},get value(){return a.value}};return Object.defineProperty(d,e,{value:!0}),d},createFromSubscribable=t=>(n,r)=>{let i=t.signal(n.getSnapshot(),{name:r?.name}),a=t.effect(()=>{let sync=()=>{i.value=n.getSnapshot()},e;try{e=n.subscribe(sync),sync()}catch(t){throw e?.(),t}return e},{name:r?.name}),abort=()=>a.dispose();r?.signal?.addEventListener(`abort`,abort,{once:!0}),r?.signal?.aborted&&a.dispose();let assertActive=()=>{if(a.disposed)throw new RippleError(`Cannot subscribe to a disposed bridge.`)},dispose=()=>{r?.signal?.removeEventListener(`abort`,abort),a.dispose()},o={get disposalSignal(){return a.disposalSignal},dispose,get disposed(){return a.disposed},get name(){return i.name},peek:()=>i.peek(),subscribe(e){return assertActive(),i.subscribe(e)},[Symbol.dispose]:dispose,get value(){return i.value}};return Object.defineProperty(o,e,{value:!0}),o},createWatch=e=>(t,n,r)=>{let i=typeof t==`function`?t:()=>t.value,a=r?.equals??Object.is,o=!0,s;return e.effect(()=>{let t=i();if(o){o=!1,s=t,r?.immediate&&e.untrack(()=>n(t,void 0));return}if(a(s,t))return;let c=s;s=t,e.untrack(()=>n(t,c))},{name:r?.name})},createRipple=e=>{let t=new ReactiveRuntime(e),n=createFromSubscribable(t),r=createResource(t);return{batch:t.batch,computed:t.computed,createScope:t.createScope,get disposalSignal(){return t.disposalSignal},dispose:()=>t.dispose(),get disposed(){return t.disposed},effect:t.effect,fromSubscribable:n,resource:r,signal:t.signal,untrack:t.untrack,watch:createWatch(t),[Symbol.dispose]:()=>t.dispose()}},r=createRipple(),i=r.signal,a=r.computed,o=r.effect,s=r.batch,c=r.createScope,l=r.untrack,u=r.watch,d=r.resource,f=r.fromSubscribable;exports.RippleCycleError=RippleCycleError,exports.RippleDisposedError=RippleDisposedError,exports.RippleError=RippleError,exports.batch=s,exports.computed=a,exports.createRipple=createRipple,exports.createScope=c,exports.effect=o,exports.fromSubscribable=f,exports.isReactive=isReactive,exports.resource=d,exports.signal=i,exports.untrack=l,exports.watch=u;
2
2
  //# sourceMappingURL=ripple.cjs.map