Comparing version 0.5.9 to 0.5.10
import { FC } from 'react'; | ||
import { transaction, untrack } from 'reactive-box'; | ||
export { value, selector, prop, cache, signal, on, sync, cycle, loop, effect, isolate, shared, initial, observe, useValue, useLocal, useShared, useScoped, Scope, free, mock, unmock, transaction, untrack, Ensurable, }; | ||
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, }; | ||
declare type Ensurable<T> = T | void; | ||
@@ -45,2 +45,10 @@ declare type Callable<T> = { | ||
declare function loop(body: () => Promise<any>): () => void; | ||
declare type Pool<K> = K & { | ||
count: number; | ||
threads: StopSignal[]; | ||
pending: boolean; | ||
}; | ||
declare type StopSignal = Signal<void, boolean>; | ||
declare function stoppable(): StopSignal; | ||
declare function pool<K extends () => Promise<any>>(body: K): Pool<K>; | ||
declare function isolate(): () => () => void; | ||
@@ -47,0 +55,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.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.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; | ||
const reactive_box_1 = require("reactive-box"); | ||
@@ -52,2 +52,4 @@ Object.defineProperty(exports, "transaction", { enumerable: true, get: function () { return reactive_box_1.transaction; } }); | ||
let scope_context; | ||
let pool_context; | ||
const def_prop = Object.defineProperty; | ||
function value(init) { | ||
@@ -64,3 +66,3 @@ const [get, set] = reactive_box_1.box(init); | ||
set.update = (fn) => set(fn(get())); | ||
Object.defineProperty(set, key, { get, set }); | ||
def_prop(set, key, { get, set }); | ||
return set; | ||
@@ -73,3 +75,3 @@ } | ||
h.get = get; | ||
Object.defineProperty(h, key, { get }); | ||
def_prop(h, key, { get }); | ||
return h; | ||
@@ -83,25 +85,31 @@ } | ||
const ready = resolve; | ||
const finish = reactive_box_1.untrack(); | ||
if (transform) | ||
data = transform(data); | ||
promisify(); | ||
resolve = def_promisify(fn); | ||
set([data]); | ||
ready(data); | ||
finish(); | ||
}; | ||
const get_val = () => get()[0]; | ||
fn[0] = get_val; | ||
fn[Symbol.iterator] = function* () { | ||
yield get_val; | ||
}; | ||
fn.get = get_val; | ||
Object.defineProperty(fn, key, { get: get_val }); | ||
promisify(); | ||
function promisify() { | ||
const promise = new Promise(r => (resolve = r)); | ||
['then', 'catch', 'finally'].forEach(prop => { | ||
fn[prop] = promise[prop].bind(promise); | ||
}); | ||
} | ||
def_get(fn, () => get()[0]); | ||
resolve = def_promisify(fn); | ||
return fn; | ||
} | ||
exports.signal = signal; | ||
function def_get(ctx, get) { | ||
ctx[0] = get; | ||
ctx[Symbol.iterator] = function* () { | ||
yield get; | ||
}; | ||
ctx.get = get; | ||
def_prop(ctx, key, { get }); | ||
} | ||
function def_promisify(ctx) { | ||
let resolve; | ||
const promise = new Promise(r => (resolve = r)); | ||
['then', 'catch', 'finally'].forEach(prop => { | ||
ctx[prop] = promise[prop].bind(promise); | ||
}); | ||
return resolve; | ||
} | ||
function on(target, listener) { | ||
@@ -171,2 +179,53 @@ const sync_mode = is_sync; | ||
exports.loop = loop; | ||
function stoppable() { | ||
if (!pool_context) | ||
throw new Error('Parent "pool" didn\'t find'); | ||
return pool_context; | ||
} | ||
exports.stoppable = stoppable; | ||
function pool(body) { | ||
const [get_threads, set_threads] = reactive_box_1.box([]); | ||
const get_count = () => get_threads().length; | ||
const [get_pending] = reactive_box_1.sel(() => get_count() > 0); | ||
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); | ||
set_threads(get_threads().concat(stop)); | ||
const stack = pool_context; | ||
pool_context = stop; | ||
let ret; | ||
try { | ||
ret = body.apply(this, arguments); | ||
} | ||
finally { | ||
pool_context = stack; | ||
if (ret && ret.finally) { | ||
ret.finally(stop); | ||
} | ||
else { | ||
stop(); | ||
} | ||
} | ||
; | ||
return ret; | ||
} | ||
def_prop(run, 'count', { get: get_count }); | ||
def_prop(run, 'threads', { get: get_threads }); | ||
def_prop(run, 'pending', { get: get_pending }); | ||
return run; | ||
} | ||
exports.pool = pool; | ||
function isolate() { | ||
@@ -326,5 +385,5 @@ const stack = context_unsubs; | ||
exports.free = free; | ||
function boxProperty(o, p, init) { | ||
const [get, set] = reactive_box_1.box(init); | ||
Object.defineProperty(o, p, { get, set }); | ||
function box_property(o, p, init) { | ||
const b = reactive_box_1.box(init); | ||
def_prop(o, p, { get: b[0], set: b[1] }); | ||
} | ||
@@ -335,7 +394,7 @@ function prop(_proto, key, descriptor) { | ||
get() { | ||
boxProperty(this, key, initializer && initializer()); | ||
box_property(this, key, initializer && initializer()); | ||
return this[key]; | ||
}, | ||
set(value) { | ||
boxProperty(this, key, initializer && initializer()); | ||
box_property(this, key, initializer && initializer()); | ||
this[key] = value; | ||
@@ -350,3 +409,3 @@ }, | ||
const [get] = reactive_box_1.sel(descriptor.get); | ||
Object.defineProperty(this, key, { get }); | ||
def_prop(this, key, { get }); | ||
return this[key]; | ||
@@ -353,0 +412,0 @@ }, |
{ | ||
"name": "realar", | ||
"version": "0.5.9", | ||
"version": "0.5.10", | ||
"description": "React state manager", | ||
@@ -88,3 +88,3 @@ "repository": { | ||
}, | ||
"gitHead": "e7c2402a990cf43b5ee236eb430092cef22c664a" | ||
"gitHead": "b5822dba95a0ed01b1b0957bca25a082ae31d9d6" | ||
} |
@@ -430,3 +430,3 @@ # Realar | ||
_Documentation not ready yet for `effect`, `loop`, `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` functions. It's coming soon._ | ||
@@ -433,0 +433,0 @@ ### Demos |
123
src/index.ts
@@ -14,2 +14,4 @@ import React, { Context, FC } from 'react'; | ||
loop, | ||
pool, | ||
stoppable, | ||
effect, | ||
@@ -71,3 +73,6 @@ isolate, | ||
let scope_context: any; | ||
let pool_context: any; | ||
const def_prop = Object.defineProperty; | ||
type Ensurable<T> = T | void; | ||
@@ -124,3 +129,3 @@ | ||
Object.defineProperty(set, key, { get, set }); | ||
def_prop(set, key, { get, set }); | ||
return set; | ||
@@ -133,3 +138,3 @@ } | ||
h.get = get; | ||
Object.defineProperty(h, key, { get }); | ||
def_prop(h, key, { get }); | ||
return h; | ||
@@ -147,27 +152,32 @@ } | ||
const ready = resolve; | ||
const finish = untrack(); | ||
if (transform) data = transform(data); | ||
promisify(); | ||
resolve = def_promisify(fn); | ||
set([data]); | ||
ready(data); | ||
finish(); | ||
}; | ||
const get_val = () => get()[0]; | ||
fn[0] = get_val; | ||
fn[Symbol.iterator] = function* () { | ||
yield get_val; | ||
}; | ||
fn.get = get_val; | ||
def_get(fn, () => get()[0]); | ||
resolve = def_promisify(fn); | ||
Object.defineProperty(fn, key, { get: get_val }); | ||
return fn as any; | ||
} | ||
promisify(); | ||
function def_get(ctx: any, get: () => any) { | ||
ctx[0] = get; | ||
ctx[Symbol.iterator] = function* () { | ||
yield get; | ||
}; | ||
ctx.get = get; | ||
def_prop(ctx, key, { get }); | ||
} | ||
function promisify() { | ||
const promise = new Promise(r => (resolve = r)); | ||
['then', 'catch', 'finally'].forEach(prop => { | ||
(fn as any)[prop] = (promise as any)[prop].bind(promise); | ||
}); | ||
} | ||
return fn as any; | ||
function def_promisify(ctx: any) { | ||
let resolve; | ||
const promise = new Promise(r => (resolve = r)); | ||
['then', 'catch', 'finally'].forEach(prop => { | ||
ctx[prop] = (promise as any)[prop].bind(promise); | ||
}); | ||
return resolve; | ||
} | ||
@@ -241,2 +251,65 @@ | ||
type Pool<K> = K & { | ||
count: number; | ||
threads: StopSignal[]; | ||
pending: boolean; | ||
} | ||
type StopSignal = Signal<void, boolean>; | ||
function stoppable(): StopSignal { | ||
if (!pool_context) throw new Error('Parent "pool" didn\'t find'); | ||
return pool_context; | ||
} | ||
function pool<K extends () => Promise<any>>(body: K): Pool<K> { | ||
const [get_threads, set_threads] = box([]); | ||
const get_count = () => get_threads().length; | ||
const [get_pending] = sel(() => get_count() > 0); | ||
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(); | ||
}; | ||
resolve = def_promisify(stop); | ||
def_get(stop, get_inactive); | ||
set_threads(get_threads().concat(stop)); | ||
const stack = pool_context; | ||
pool_context = stop; | ||
let ret; | ||
try { | ||
ret = body.apply(this, arguments); | ||
} finally { | ||
pool_context = stack; | ||
if (ret && ret.finally) { | ||
ret.finally(stop); | ||
} else { | ||
stop(); | ||
} | ||
}; | ||
return ret; | ||
} | ||
def_prop(run, 'count', { get: get_count }); | ||
def_prop(run, 'threads', { get: get_threads }); | ||
def_prop(run, 'pending', { get: get_pending }); | ||
return run as any; | ||
} | ||
function isolate() { | ||
@@ -409,5 +482,5 @@ const stack = context_unsubs; | ||
function boxProperty(o: any, p: string | number | symbol, init?: any): any { | ||
const [get, set] = box(init); | ||
Object.defineProperty(o, p, { get, set }); | ||
function box_property(o: any, p: string | number | symbol, init?: any): any { | ||
const b = box(init); | ||
def_prop(o, p, { get: b[0], set: b[1] }); | ||
} | ||
@@ -419,7 +492,7 @@ | ||
get() { | ||
boxProperty(this, key, initializer && initializer()); | ||
box_property(this, key, initializer && initializer()); | ||
return this[key]; | ||
}, | ||
set(value: any) { | ||
boxProperty(this, key, initializer && initializer()); | ||
box_property(this, key, initializer && initializer()); | ||
this[key] = value; | ||
@@ -434,3 +507,3 @@ }, | ||
const [get] = sel(descriptor.get); | ||
Object.defineProperty(this, key, { get }); | ||
def_prop(this, key, { get }); | ||
return this[key]; | ||
@@ -437,0 +510,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
56805
906