Comparing version 0.5.10 to 0.5.11
import { FC } from 'react'; | ||
import { transaction, untrack } from 'reactive-box'; | ||
export { value, selector, prop, cache, signal, on, sync, cycle, loop, pool, stoppable, effect, isolate, shared, initial, observe, useValue, useLocal, useShared, useScoped, Scope, free, mock, unmock, transaction, untrack, Ensurable, }; | ||
export { value, selector, prop, cache, signal, ready, on, once, effect, sync, cycle, loop, pool, stoppable, wrap, isolate, shared, initial, observe, useValue, useLocal, useShared, useScoped, Scope, free, mock, unmock, transaction, untrack, Ensurable, }; | ||
declare type Ensurable<T> = T | void; | ||
@@ -12,19 +12,20 @@ declare type Callable<T> = { | ||
0: () => T; | ||
1: () => void; | ||
readonly val: T; | ||
get(): T; | ||
} & [() => T, () => void]; | ||
declare type Value<T> = Callable<T> & { | ||
0: () => T; | ||
free(): void; | ||
} & [() => T]; | ||
declare type Value<T, K = T> = Callable<T> & { | ||
0: () => K; | ||
1: (value: T) => void; | ||
val: T; | ||
update: (fn: (state: T) => T) => void; | ||
get(): T; | ||
val: T & K; | ||
update: (fn: (state: K) => T) => void; | ||
get(): K; | ||
set(value: T): void; | ||
} & [() => T, (value: T) => void]; | ||
} & [() => K, (value: T) => void]; | ||
declare type Signal<T, K = T> = Callable<T> & Pick<Promise<T>, 'then' | 'catch' | 'finally'> & { | ||
0: () => K; | ||
1: (value: T) => void; | ||
readonly val: K; | ||
get(): K; | ||
} & [() => K]; | ||
} & [() => K, (value: T) => void]; | ||
declare type Reactionable<T> = { | ||
@@ -38,9 +39,13 @@ 0: () => T; | ||
declare function signal<T = void>(init: T): Signal<T>; | ||
declare function signal<T = void, R = T>(init: R, transform: (data: T) => R): Signal<T, R>; | ||
declare function on<T>(target: Reactionable<Ensurable<T>>, listener: (value: T, prev?: T) => void): () => void; | ||
declare function on<T>(target: Reactionable<T>, listener: (value: T, prev?: T) => void): () => void; | ||
declare function sync<T>(target: Reactionable<T>, listener: (value: T, prev?: T) => void): () => void; | ||
declare function effect(fn: () => void): void; | ||
declare function effect(fn: () => () => any): () => any; | ||
declare function cycle(body: () => void): () => void; | ||
declare function ready<T = void>(): Signal<T, Ensurable<T>>; | ||
declare function ready<T = void>(init: T): Signal<T>; | ||
declare function wrap<T, K, P>(target: Signal<T, K>, set: () => T, get: (data: K) => P): Signal<void, P>; | ||
declare function wrap<T, K, P, M = T>(target: Signal<T, K>, set: (data: M) => T, get: (data: K) => P): Signal<M, P>; | ||
declare function wrap<T, K>(target: Signal<T, K>, set: () => T): Signal<void, K>; | ||
declare function wrap<T, K, M = T>(target: Signal<T, K>, set: (data: M) => T): Signal<M, K>; | ||
declare function wrap<T, K, P>(target: Value<T, K>, set: () => T, get: (data: K) => P): Value<void, P>; | ||
declare function wrap<T, K, P, M = T>(target: Value<T, K>, set: (data: M) => T, get: (data: K) => P): Value<M, P>; | ||
declare function wrap<T, K>(target: Value<T, K>, set: () => T): Signal<void, K>; | ||
declare function wrap<T, K, M = T>(target: Value<T, K>, set: (data: M) => T): Signal<M, K>; | ||
declare function wrap<M, T>(target: Selector<T>, get: (data: T) => M): Selector<M>; | ||
declare function loop(body: () => Promise<any>): () => void; | ||
@@ -55,2 +60,10 @@ declare type Pool<K> = K & { | ||
declare function pool<K extends () => Promise<any>>(body: K): Pool<K>; | ||
declare function on<T>(target: Reactionable<Ensurable<T>>, listener: (value: T, prev?: T) => void): () => void; | ||
declare function on<T>(target: Reactionable<T>, listener: (value: T, prev?: T) => void): () => void; | ||
declare function once<T>(target: Reactionable<Ensurable<T>>, listener: (value: T, prev?: T) => void): () => void; | ||
declare function once<T>(target: Reactionable<T>, listener: (value: T, prev?: T) => void): () => void; | ||
declare function sync<T>(target: Reactionable<T>, listener: (value: T, prev?: T) => void): () => void; | ||
declare function effect(fn: () => void): void; | ||
declare function effect(fn: () => () => any): () => any; | ||
declare function cycle(body: () => void): () => void; | ||
declare function isolate(): () => () => void; | ||
@@ -57,0 +70,0 @@ declare function initial(data: any): void; |
@@ -12,3 +12,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.untrack = exports.transaction = exports.unmock = exports.mock = exports.free = exports.Scope = exports.useScoped = exports.useShared = exports.useLocal = exports.useValue = exports.observe = exports.initial = exports.shared = exports.isolate = exports.effect = exports.stoppable = exports.pool = exports.loop = exports.cycle = exports.sync = exports.on = exports.signal = exports.cache = exports.prop = exports.selector = exports.value = void 0; | ||
exports.untrack = exports.transaction = exports.unmock = exports.mock = exports.free = exports.Scope = exports.useScoped = exports.useShared = exports.useLocal = exports.useValue = exports.observe = exports.initial = exports.shared = exports.isolate = exports.wrap = exports.stoppable = exports.pool = exports.loop = exports.cycle = exports.sync = exports.effect = exports.once = exports.on = exports.ready = exports.signal = exports.cache = exports.prop = exports.selector = exports.value = void 0; | ||
const reactive_box_1 = require("reactive-box"); | ||
@@ -52,16 +52,7 @@ Object.defineProperty(exports, "transaction", { enumerable: true, get: function () { return reactive_box_1.transaction; } }); | ||
let scope_context; | ||
let pool_context; | ||
let stoppable_context; | ||
const def_prop = Object.defineProperty; | ||
function value(init) { | ||
const [get, set] = reactive_box_1.box(init); | ||
set[Symbol.iterator] = function* () { | ||
yield get; | ||
yield set; | ||
}; | ||
set[0] = get; | ||
set[1] = set; | ||
set.get = get; | ||
set.set = set; | ||
set.update = (fn) => set(fn(get())); | ||
def_prop(set, key, { get, set }); | ||
def_format(set, get, set); | ||
return set; | ||
@@ -71,10 +62,9 @@ } | ||
function selector(body) { | ||
const h = reactive_box_1.sel(body); | ||
const get = h[0]; | ||
h.get = get; | ||
def_prop(h, key, { get }); | ||
const [get, free] = reactive_box_1.sel(body); | ||
const h = def_format([], get); | ||
h.free = free; | ||
return h; | ||
} | ||
exports.selector = selector; | ||
function signal(init, transform) { | ||
function signal(init) { | ||
let resolve; | ||
@@ -84,11 +74,7 @@ const [get, set] = reactive_box_1.box([init]); | ||
const ready = resolve; | ||
const finish = reactive_box_1.untrack(); | ||
if (transform) | ||
data = transform(data); | ||
resolve = def_promisify(fn); | ||
set([data]); | ||
ready(data); | ||
finish(); | ||
}; | ||
def_get(fn, () => get()[0]); | ||
def_format(fn, () => get()[0], fn, 1); | ||
resolve = def_promisify(fn); | ||
@@ -98,9 +84,35 @@ return fn; | ||
exports.signal = signal; | ||
function def_get(ctx, get) { | ||
function ready(init) { | ||
let resolve; | ||
const [get, set] = reactive_box_1.box([init]); | ||
const fn = function (data) { | ||
set([data]); | ||
resolve(data); | ||
}; | ||
def_format(fn, () => get()[0], fn, 1); | ||
resolve = def_promisify(fn); | ||
return fn; | ||
} | ||
exports.ready = ready; | ||
function def_format(ctx, get, set, no_set_update) { | ||
if (!Array.isArray(ctx)) { | ||
ctx[Symbol.iterator] = function* () { | ||
yield get; | ||
if (set) | ||
yield set; | ||
}; | ||
} | ||
ctx[0] = get; | ||
ctx[Symbol.iterator] = function* () { | ||
yield get; | ||
}; | ||
ctx.get = get; | ||
def_prop(ctx, key, { get }); | ||
const val_prop = { get }; | ||
if (set) { | ||
ctx[1] = set; | ||
if (!no_set_update) { | ||
ctx.set = set; | ||
ctx.update = (fn) => set(fn(get())); | ||
val_prop.set = set; | ||
} | ||
} | ||
def_prop(ctx, key, val_prop); | ||
return ctx; | ||
} | ||
@@ -115,50 +127,67 @@ function def_promisify(ctx) { | ||
} | ||
function on(target, listener) { | ||
const sync_mode = is_sync; | ||
let free; | ||
is_sync = 0; | ||
function stop_signal() { | ||
return wrap(ready(false), () => true); | ||
} | ||
function wrap(target, set, get) { | ||
let source_get, source_set; | ||
if (target[0]) { | ||
target = target[0]; // box or selector or custom reactive | ||
source_get = target[0]; | ||
if (target[1]) | ||
source_set = target[1]; | ||
} | ||
if (!get && set && !source_set) { | ||
get = set; | ||
set = 0; | ||
} | ||
if ((set && !source_set) || (get && !source_get)) { | ||
throw new Error('Incorrect wrapping target'); | ||
} | ||
let dest; | ||
let dest_set; | ||
if (set) { | ||
dest = dest_set = function (data) { | ||
const finish = reactive_box_1.untrack(); | ||
const stack = stoppable_context; | ||
stoppable_context = stop_signal(); | ||
try { | ||
data = set(data); | ||
if (!stoppable_context[0]()) | ||
source_set(data); | ||
} | ||
finally { | ||
stoppable_context = stack; | ||
finish(); | ||
} | ||
}; | ||
} | ||
else if (source_set) { | ||
dest = function (data) { | ||
source_set(data); | ||
}; | ||
} | ||
else { | ||
[target, free] = reactive_box_1.sel(target); | ||
dest = []; | ||
} | ||
let value; | ||
const [run, stop] = reactive_box_1.expr(target, () => { | ||
const prev = value; | ||
listener((value = run()), prev); | ||
}); | ||
value = run(); | ||
const unsub = () => { | ||
if (free) | ||
free(); | ||
stop(); | ||
}; | ||
if (context_unsubs) | ||
context_unsubs.push(unsub); | ||
if (sync_mode) | ||
listener(value); | ||
return unsub; | ||
if (target.then) { | ||
const methods = ['catch', 'finally']; | ||
if (get) { | ||
def_prop(dest, 'then', { | ||
get() { | ||
const promise = target.then(get); | ||
return promise.then.bind(promise); | ||
}, | ||
}); | ||
} | ||
else { | ||
methods.push('then'); | ||
} | ||
methods.forEach(prop => { | ||
def_prop(dest, prop, { | ||
get: () => target[prop], | ||
}); | ||
}); | ||
} | ||
return def_format(dest, get ? () => get(source_get()) : source_get, dest_set || source_set, !target.update); | ||
} | ||
exports.on = on; | ||
function sync(target, listener) { | ||
is_sync = 1; | ||
return on(target, listener); | ||
} | ||
exports.sync = sync; | ||
function effect(fn) { | ||
const unsub = fn(); | ||
if (unsub && context_unsubs) | ||
context_unsubs.push(unsub); | ||
return unsub; | ||
} | ||
exports.effect = effect; | ||
function cycle(body) { | ||
const [run, stop] = reactive_box_1.expr(body); | ||
run(); | ||
if (context_unsubs) | ||
context_unsubs.push(stop); | ||
return stop; | ||
} | ||
exports.cycle = cycle; | ||
exports.wrap = wrap; | ||
function loop(body) { | ||
@@ -181,5 +210,5 @@ let running = 1; | ||
function stoppable() { | ||
if (!pool_context) | ||
throw new Error('Parent "pool" didn\'t find'); | ||
return pool_context; | ||
if (!stoppable_context) | ||
throw new Error('Parent "pool" or "wrap" didn\'t find'); | ||
return stoppable_context; | ||
} | ||
@@ -192,20 +221,9 @@ exports.stoppable = stoppable; | ||
function run() { | ||
let resolve; | ||
const [get_inactive, set_inactive] = reactive_box_1.box(false); | ||
const stop = () => { | ||
const finish = reactive_box_1.untrack(); | ||
if (!get_inactive()) { | ||
const commit = reactive_box_1.transaction(); | ||
set_inactive(true); | ||
set_threads(get_threads().filter((ctx) => ctx !== stop)); | ||
commit(); | ||
resolve(true); | ||
} | ||
finish(); | ||
}; | ||
resolve = def_promisify(stop); | ||
def_get(stop, get_inactive); | ||
const stop = stop_signal(); | ||
const isolate_finish = isolate(); | ||
once(stop, () => set_threads(get_threads().filter(ctx => ctx !== stop))); | ||
isolate_finish(); | ||
set_threads(get_threads().concat(stop)); | ||
const stack = pool_context; | ||
pool_context = stop; | ||
const stack = stoppable_context; | ||
stoppable_context = stop; | ||
let ret; | ||
@@ -216,3 +234,3 @@ try { | ||
finally { | ||
pool_context = stack; | ||
stoppable_context = stack; | ||
if (ret && ret.finally) { | ||
@@ -225,3 +243,2 @@ ret.finally(stop); | ||
} | ||
; | ||
return ret; | ||
@@ -235,2 +252,62 @@ } | ||
exports.pool = pool; | ||
function on(target, listener) { | ||
const sync_mode = is_sync; | ||
let free; | ||
is_sync = 0; | ||
if (target[0]) { | ||
target = target[0]; // box or selector or custom reactive | ||
} | ||
else { | ||
[target, free] = reactive_box_1.sel(target); | ||
} | ||
let value; | ||
const [run, stop] = reactive_box_1.expr(target, () => { | ||
const prev = value; | ||
listener((value = run()), prev); | ||
}); | ||
value = run(); | ||
const unsub = () => { | ||
if (free) | ||
free(); | ||
stop(); | ||
}; | ||
if (context_unsubs) | ||
context_unsubs.push(unsub); | ||
if (sync_mode) | ||
listener(value); | ||
return unsub; | ||
} | ||
exports.on = on; | ||
function once(target, listener) { | ||
const unsub = on(target, (value, prev) => { | ||
try { | ||
listener(value, prev); | ||
} | ||
finally { | ||
unsub(); | ||
} | ||
}); | ||
return unsub; | ||
} | ||
exports.once = once; | ||
function sync(target, listener) { | ||
is_sync = 1; | ||
return on(target, listener); | ||
} | ||
exports.sync = sync; | ||
function effect(fn) { | ||
const unsub = fn(); | ||
if (unsub && context_unsubs) | ||
context_unsubs.push(unsub); | ||
return unsub; | ||
} | ||
exports.effect = effect; | ||
function cycle(body) { | ||
const [run, stop] = reactive_box_1.expr(body); | ||
run(); | ||
if (context_unsubs) | ||
context_unsubs.push(stop); | ||
return stop; | ||
} | ||
exports.cycle = cycle; | ||
function isolate() { | ||
@@ -237,0 +314,0 @@ const stack = context_unsubs; |
{ | ||
"name": "realar", | ||
"version": "0.5.10", | ||
"version": "0.5.11", | ||
"description": "React state manager", | ||
@@ -88,3 +88,3 @@ "repository": { | ||
}, | ||
"gitHead": "b5822dba95a0ed01b1b0957bca25a082ae31d9d6" | ||
"gitHead": "c6d8c311f3fbe5a70fff4711cc5df471d624b53b" | ||
} |
@@ -38,3 +38,3 @@ # Realar | ||
- __Lightweight and Fast__. Really light ~2kB. And only those components are updated in which it is really necessary to make changes. | ||
- __Lightweight and Fast__. Really light ~3kB. And only those components are updated in which it is really necessary to make changes. | ||
@@ -431,3 +431,3 @@ - __React component context level scopes__. Declaration one scope and use as many reactive values as you want without the need to define a new React context for each changeable value. | ||
_Documentation not ready yet for `effect`, `loop`, `pool`, `stoppable`, `initial`, `mock`, `unmock`, `free`, `transaction`, `untrack`, `isolate` functions. It's coming soon._ | ||
_Documentation not ready yet for `effect`, `loop`, `pool`, `stoppable`, `initial`, `mock`, `unmock`, `free`, `transaction`, `untrack`, `isolate`, `wrap`, `ready` functions. It's coming soon._ | ||
@@ -434,0 +434,0 @@ ### Demos |
325
src/index.ts
@@ -10,3 +10,6 @@ import React, { Context, FC } from 'react'; | ||
signal, | ||
ready, | ||
on, | ||
once, | ||
effect, | ||
sync, | ||
@@ -17,3 +20,3 @@ cycle, | ||
stoppable, | ||
effect, | ||
wrap, | ||
isolate, | ||
@@ -74,3 +77,3 @@ shared, | ||
let scope_context: any; | ||
let pool_context: any; | ||
let stoppable_context: any; | ||
@@ -91,15 +94,15 @@ const def_prop = Object.defineProperty; | ||
0: () => T; | ||
1: () => void; | ||
readonly val: T; | ||
get(): T; | ||
} & [() => T, () => void]; | ||
free(): void; | ||
} & [() => T]; | ||
type Value<T> = Callable<T> & { | ||
0: () => T; | ||
type Value<T, K = T> = Callable<T> & { | ||
0: () => K; | ||
1: (value: T) => void; | ||
val: T; | ||
update: (fn: (state: T) => T) => void; | ||
get(): T; | ||
val: T & K; | ||
update: (fn: (state: K) => T) => void; | ||
get(): K; | ||
set(value: T): void; | ||
} & [() => T, (value: T) => void]; | ||
} & [() => K, (value: T) => void]; | ||
@@ -109,5 +112,6 @@ type Signal<T, K = T> = Callable<T> & | ||
0: () => K; | ||
1: (value: T) => void; | ||
readonly val: K; | ||
get(): K; | ||
} & [() => K]; | ||
} & [() => K, (value: T) => void]; | ||
@@ -120,15 +124,3 @@ type Reactionable<T> = { 0: () => T } | [() => T] | (() => T); | ||
const [get, set] = box(init) as any; | ||
set[Symbol.iterator] = function* () { | ||
yield get; | ||
yield set; | ||
}; | ||
set[0] = get; | ||
set[1] = set; | ||
set.get = get; | ||
set.set = set; | ||
set.update = (fn: any) => set(fn(get())); | ||
def_prop(set, key, { get, set }); | ||
def_format(set, get, set); | ||
return set; | ||
@@ -138,6 +130,5 @@ } | ||
function selector<T>(body: () => T): Selector<T> { | ||
const h = sel(body) as any; | ||
const get = h[0]; | ||
h.get = get; | ||
def_prop(h, key, { get }); | ||
const [get, free] = sel(body); | ||
const h = def_format([], get); | ||
h.free = free; | ||
return h; | ||
@@ -148,4 +139,3 @@ } | ||
function signal<T = void>(init: T): Signal<T>; | ||
function signal<T = void, R = T>(init: R, transform: (data: T) => R): Signal<T, R>; | ||
function signal(init?: any, transform?: any) { | ||
function signal(init?: any) { | ||
let resolve: any; | ||
@@ -156,11 +146,8 @@ const [get, set] = box([init]); | ||
const ready = resolve; | ||
const finish = untrack(); | ||
if (transform) data = transform(data); | ||
resolve = def_promisify(fn); | ||
set([data]); | ||
ready(data); | ||
finish(); | ||
}; | ||
def_get(fn, () => get()[0]); | ||
def_format(fn, () => get()[0], fn, 1); | ||
resolve = def_promisify(fn); | ||
@@ -171,9 +158,40 @@ | ||
function def_get(ctx: any, get: () => any) { | ||
function ready<T = void>(): Signal<T, Ensurable<T>>; | ||
function ready<T = void>(init: T): Signal<T>; | ||
function ready(init?: any) { | ||
let resolve: any; | ||
const [get, set] = box([init]); | ||
const fn = function (data: any) { | ||
set([data]); | ||
resolve(data); | ||
}; | ||
def_format(fn, () => get()[0], fn, 1); | ||
resolve = def_promisify(fn); | ||
return fn as any; | ||
} | ||
function def_format(ctx: any, get: any, set?: any, no_set_update?: any) { | ||
if (!Array.isArray(ctx)) { | ||
ctx[Symbol.iterator] = function* () { | ||
yield get; | ||
if (set) yield set; | ||
}; | ||
} | ||
ctx[0] = get; | ||
ctx[Symbol.iterator] = function* () { | ||
yield get; | ||
}; | ||
ctx.get = get; | ||
def_prop(ctx, key, { get }); | ||
const val_prop = { get } as any; | ||
if (set) { | ||
ctx[1] = set; | ||
if (!no_set_update) { | ||
ctx.set = set; | ||
ctx.update = (fn: any) => set(fn(get())); | ||
val_prop.set = set; | ||
} | ||
} | ||
def_prop(ctx, key, val_prop); | ||
return ctx; | ||
} | ||
@@ -190,53 +208,91 @@ | ||
function on<T>( | ||
target: Reactionable<Ensurable<T>>, | ||
listener: (value: T, prev?: T) => void | ||
): () => void; | ||
function on<T>(target: Reactionable<T>, listener: (value: T, prev?: T) => void): () => void; | ||
function on(target: any, listener: (value: any, prev?: any) => void): () => void { | ||
const sync_mode = is_sync; | ||
let free: (() => void) | undefined; | ||
function stop_signal() { | ||
return wrap(ready(false), () => true); | ||
} | ||
is_sync = 0; | ||
function wrap<T, K, P>(target: Signal<T, K>, set: () => T, get: (data: K) => P): Signal<void, P>; | ||
function wrap<T, K, P, M = T>( | ||
target: Signal<T, K>, | ||
set: (data: M) => T, | ||
get: (data: K) => P | ||
): Signal<M, P>; | ||
function wrap<T, K>(target: Signal<T, K>, set: () => T): Signal<void, K>; | ||
function wrap<T, K, M = T>(target: Signal<T, K>, set: (data: M) => T): Signal<M, K>; | ||
function wrap<T, K, P>(target: Value<T, K>, set: () => T, get: (data: K) => P): Value<void, P>; | ||
function wrap<T, K, P, M = T>( | ||
target: Value<T, K>, | ||
set: (data: M) => T, | ||
get: (data: K) => P | ||
): Value<M, P>; | ||
function wrap<T, K>(target: Value<T, K>, set: () => T): Signal<void, K>; | ||
function wrap<T, K, M = T>(target: Value<T, K>, set: (data: M) => T): Signal<M, K>; | ||
function wrap<M, T>(target: Selector<T>, get: (data: T) => M): Selector<M>; | ||
function wrap(target: any, set?: any, get?: any) { | ||
let source_get: any, source_set: any; | ||
if (target[0]) { | ||
target = target[0]; // box or selector or custom reactive | ||
} else { | ||
[target, free] = sel(target); | ||
source_get = target[0]; | ||
if (target[1]) source_set = target[1]; | ||
} | ||
if (!get && set && !source_set) { | ||
get = set; | ||
set = 0; | ||
} | ||
if ((set && !source_set) || (get && !source_get)) { | ||
throw new Error('Incorrect wrapping target'); | ||
} | ||
let value: any; | ||
let dest: any; | ||
let dest_set: any; | ||
const [run, stop] = expr(target, () => { | ||
const prev = value; | ||
listener((value = run()), prev); | ||
}); | ||
value = run(); | ||
const unsub = () => { | ||
if (free) free(); | ||
stop(); | ||
}; | ||
if (context_unsubs) context_unsubs.push(unsub); | ||
if (sync_mode) listener(value); | ||
return unsub; | ||
} | ||
if (set) { | ||
dest = dest_set = function (data?: any) { | ||
const finish = untrack(); | ||
const stack = stoppable_context; | ||
stoppable_context = stop_signal(); | ||
function sync<T>(target: Reactionable<T>, listener: (value: T, prev?: T) => void): () => void { | ||
is_sync = 1; | ||
return on(target, listener); | ||
} | ||
try { | ||
data = set(data); | ||
if (!stoppable_context[0]()) source_set(data); | ||
} finally { | ||
stoppable_context = stack; | ||
finish(); | ||
} | ||
}; | ||
} else if (source_set) { | ||
dest = function (data?: any) { | ||
source_set(data); | ||
}; | ||
} else { | ||
dest = []; | ||
} | ||
function effect(fn: () => void): void; | ||
function effect(fn: () => () => any): () => any; | ||
function effect(fn: any) { | ||
const unsub = fn(); | ||
if (unsub && context_unsubs) context_unsubs.push(unsub); | ||
return unsub; | ||
} | ||
if (target.then) { | ||
const methods = ['catch', 'finally']; | ||
if (get) { | ||
def_prop(dest, 'then', { | ||
get() { | ||
const promise = target.then(get); | ||
return promise.then.bind(promise); | ||
}, | ||
}); | ||
} else { | ||
methods.push('then'); | ||
} | ||
methods.forEach(prop => { | ||
def_prop(dest, prop, { | ||
get: () => target[prop], | ||
}); | ||
}); | ||
} | ||
function cycle(body: () => void) { | ||
const [run, stop] = expr(body); | ||
run(); | ||
if (context_unsubs) context_unsubs.push(stop); | ||
return stop; | ||
return def_format( | ||
dest, | ||
get ? () => get(source_get()) : source_get, | ||
dest_set || source_set, | ||
!target.update | ||
); | ||
} | ||
@@ -248,3 +304,3 @@ | ||
while (running) await body(); | ||
} | ||
}; | ||
const unsub = () => { | ||
@@ -262,3 +318,3 @@ if (running) running = 0; | ||
pending: boolean; | ||
} | ||
}; | ||
@@ -268,4 +324,4 @@ type StopSignal = Signal<void, boolean>; | ||
function stoppable(): StopSignal { | ||
if (!pool_context) throw new Error('Parent "pool" didn\'t find'); | ||
return pool_context; | ||
if (!stoppable_context) throw new Error('Parent "pool" or "wrap" didn\'t find'); | ||
return stoppable_context; | ||
} | ||
@@ -279,23 +335,11 @@ | ||
function run() { | ||
let resolve: (inactive: boolean) => void; | ||
const [get_inactive, set_inactive] = box(false); | ||
const stop = () => { | ||
const finish = untrack(); | ||
if (!get_inactive()) { | ||
const commit = transaction(); | ||
set_inactive(true); | ||
set_threads(get_threads().filter((ctx) => ctx !== stop)); | ||
commit(); | ||
resolve(true); | ||
} | ||
finish(); | ||
}; | ||
const stop = stop_signal(); | ||
const isolate_finish = isolate(); | ||
once(stop, () => set_threads(get_threads().filter(ctx => ctx !== stop))); | ||
isolate_finish(); | ||
resolve = def_promisify(stop); | ||
def_get(stop, get_inactive); | ||
set_threads(get_threads().concat(stop)); | ||
const stack = pool_context; | ||
pool_context = stop; | ||
const stack = stoppable_context; | ||
stoppable_context = stop; | ||
@@ -306,3 +350,3 @@ let ret; | ||
} finally { | ||
pool_context = stack; | ||
stoppable_context = stack; | ||
@@ -314,3 +358,3 @@ if (ret && ret.finally) { | ||
} | ||
}; | ||
} | ||
return ret; | ||
@@ -326,2 +370,71 @@ } | ||
function on<T>( | ||
target: Reactionable<Ensurable<T>>, | ||
listener: (value: T, prev?: T) => void | ||
): () => void; | ||
function on<T>(target: Reactionable<T>, listener: (value: T, prev?: T) => void): () => void; | ||
function on(target: any, listener: (value: any, prev?: any) => void): () => void { | ||
const sync_mode = is_sync; | ||
let free: (() => void) | undefined; | ||
is_sync = 0; | ||
if (target[0]) { | ||
target = target[0]; // box or selector or custom reactive | ||
} else { | ||
[target, free] = sel(target); | ||
} | ||
let value: any; | ||
const [run, stop] = expr(target, () => { | ||
const prev = value; | ||
listener((value = run()), prev); | ||
}); | ||
value = run(); | ||
const unsub = () => { | ||
if (free) free(); | ||
stop(); | ||
}; | ||
if (context_unsubs) context_unsubs.push(unsub); | ||
if (sync_mode) listener(value); | ||
return unsub; | ||
} | ||
function once<T>( | ||
target: Reactionable<Ensurable<T>>, | ||
listener: (value: T, prev?: T) => void | ||
): () => void; | ||
function once<T>(target: Reactionable<T>, listener: (value: T, prev?: T) => void): () => void; | ||
function once(target: any, listener: (value: any, prev?: any) => void): () => void { | ||
const unsub = on(target, (value, prev) => { | ||
try { | ||
listener(value, prev); | ||
} finally { | ||
unsub(); | ||
} | ||
}); | ||
return unsub; | ||
} | ||
function sync<T>(target: Reactionable<T>, listener: (value: T, prev?: T) => void): () => void { | ||
is_sync = 1; | ||
return on(target, listener); | ||
} | ||
function effect(fn: () => void): void; | ||
function effect(fn: () => () => any): () => any; | ||
function effect(fn: any) { | ||
const unsub = fn(); | ||
if (unsub && context_unsubs) context_unsubs.push(unsub); | ||
return unsub; | ||
} | ||
function cycle(body: () => void) { | ||
const [run, stop] = expr(body); | ||
run(); | ||
if (context_unsubs) context_unsubs.push(stop); | ||
return stop; | ||
} | ||
function isolate() { | ||
@@ -335,3 +448,3 @@ const stack = context_unsubs; | ||
if (unsubs) call_array(unsubs); | ||
} | ||
}; | ||
}; | ||
@@ -338,0 +451,0 @@ } |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
64956
1096