Reactive membrane written in Typescript.
Features:
- No thirdparty dependecies
- Easy to use
- ES Modules and CommonJS format
- Support
reactive
,readonly
,ref
- Nice test
The implementation of this module is inspired by Observable Membrane and vue-next.
If you feel confused for "Membrane", you can check these articles:
The following example illustrates how to create a Reactive Membrane
and reactive proxy:
import { ReactiveMembrane } from "reactivity-ts";
const raw = {
a: 1,
b: {
c: 2
}
}
const membrane = new ReactiveMembrane()
const wet = membrane.reactive(raw);
import { ReactiveMembrane } from "reactivity-ts";
const raw = {
a: 1,
b: {
c: 2
}
}
const membrane = new ReactiveMembrane({
accessObserver(target, key) {
console.log("access!");
},
mutationObserver(target, key) {
console.log("mutation!");
}
})
const wet = membrane.reactive(raw);
wet.a; // access!
wet.a = 3; // mutation
You can use distortions to avoid leaking non-observable objects and distorting values observed through the membrane:
import { ReactiveMembrane } from "reactivity-ts";
const raw = { a: 1 };
const membrane = new ReactiveMembrane({
distortion(value) {
if (typeof value === "number") {
return value * 10
}
return value;
}
})
const wet = membrane.reactive(raw);
wet.a; // 10
import { ReactiveMembrane } from "reactivity-ts";
const raw = {
a: 1,
b: {
c: 2
}
}
const membrane = new ReactiveMembrane({
accessObserver(target, key) {
console.log("access!");
}
})
const wet = membrane.readonly(raw);
wet.a; // access!
wet.a = 3; // throw error in development mode, and does nothing in production mode.
Internally, we wrap raw
as an object which has getter and setter function.
import { ReactiveMembrane } from "reactivity-ts";
const membrane = new ReactiveMembrane({
accessObserver(target, key) {
console.log("access!");
},
mutationObserver(target, key) {
console.log("mutation!");
}
})
const wet = membrane.ref(1);
wet; // access!
wet.value = 2; // mutation!
Only create reactive proxy for root level properties.
import { ReactiveMembrane } from "reactivity-ts";
const raw = {
a: 1,
b: {
c: 2
}
}
const membrane = new ReactiveMembrane({
mutationObserver(target, key) {
console.log("mutation!");
}
})
const wet = membrane.shallowReactive(raw);
wet.a = 3; // mutation!
wet.b.c = 3;
NOTE: If you want to change the value of raw.b.c
, you will access raw.b
first. So the accessObserver
will always be trigger.
Only create readonly proxy for root level properties.
import { ReactiveMembrane } from "reactivity-ts";
const raw = {
a: 1,
b: {
c: 2
}
}
const membrane = new ReactiveMembrane();
const wet = membrane.shallowReadonly(raw);
wet.a = 3; // throw error in development mode, and does nothing in production mode.
wet.b.c = 3;
NOTE: If you want to change the value of raw.b.c
, you will access raw.b
first. So the accessObserver
will always be trigger.