Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

proxy-state-tree

Package Overview
Dependencies
Maintainers
2
Versions
865
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

proxy-state-tree - npm Package Compare versions

Comparing version 6.3.0 to 6.3.1-1709665053033

dist/proxy-state-tree.min.js.map

3

dist/proxy-state-tree.min.js

@@ -1,1 +0,2 @@

!function(t){var e={};function r(i){if(e[i])return e[i].exports;var s=e[i]={i:i,l:!1,exports:{}};return t[i].call(s.exports,s,s.exports,r),s.l=!0,s.exports}r.m=t,r.c=e,r.d=function(t,e,i){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(r.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var s in t)r.d(i,s,function(e){return t[e]}.bind(null,s));return i},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=0)}([function(t,e,r){r.r(e);const i=(()=>{let t;try{t="production"}catch(e){t="development"}return t})(),s=Symbol("IS_PROXY"),n=Symbol("PATH"),a=Symbol("VALUE"),o=Symbol("PROXY_TREE"),c=new Set(["push","shift","pop","unshift","splice","reverse","sort","copyWithin"]),h=t=>t&&t[s]?t[a]:t,u=t=>"object"==typeof t&&null!==t&&!Array.isArray(t)&&"Object"!==t.constructor.name&&Object.isExtensible(t),l=t=>void 0!==t&&(!u(t)||u(t)&&!(t instanceof Date)&&!(t instanceof Map)&&!(t instanceof Set));class p{constructor(t){this.tree=t,this.CACHED_PROXY=Symbol("CACHED_PROXY"),this.delimiter=t.master.options.delimiter,this.ssr=Boolean(t.master.options.ssr)}concat(t,e){return t?t+this.delimiter+e:e}ensureMutationTrackingIsEnabled(t){if("production"!==i&&this.tree.master.options.devmode&&!this.tree.canMutate())throw new Error(`proxy-state-tree - You are mutating the path "${t}", but it is not allowed. The following could have happened:\n \n - The mutation is explicitly being blocket\n - You are passing state to a 3rd party tool trying to manipulate the state\n - You are running asynchronous code and forgot to "await" its execution\n `)}isDefaultProxifier(){return this.tree.proxifier===this.tree.master.proxifier}ensureValueDosntExistInStateTreeElsewhere(t){if("production"!==i){if(t&&!0===t[s])throw new Error(`proxy-state-tree - You are trying to insert a value that already exists in the state tree on path "${t[n]}"`);return t}}trackPath(t){if(this.tree.canTrack())if(this.isDefaultProxifier()){const e=this.tree.master.currentTree;if(!e)return;e.addTrackingPath(t)}else this.tree.addTrackingPath(t)}getTrackingTree(){return this.tree.master.currentTree&&this.isDefaultProxifier()?this.tree.master.currentTree:this.tree.canTrack()&&this.tree.canTrack()?this.tree:null}getMutationTree(){return this.tree.master.mutationTree||this.tree}isProxyCached(t,e){return t[this.CACHED_PROXY]&&String(t[this.CACHED_PROXY][n])===String(e)}createArrayProxy(t,e){if(!this.ssr&&this.isProxyCached(t,e))return t[this.CACHED_PROXY];const r=this,o=new Proxy(t,{get(o,u){if(u===s)return!0;if(u===n)return e;if(u===a)return t;if("indexOf"===u)return(e,r)=>t.indexOf(h(e),h(r));if("length"===u||"function"==typeof o[u]&&!c.has(String(u))||"symbol"==typeof u)return o[u];const p=r.getTrackingTree(),f=r.concat(e,u),d=p||r.tree;p&&p.proxifier.trackPath(f),d.trackPathListeners.forEach(t=>t(f));const m=String(u);return c.has(m)?(...t)=>{const s=r.getMutationTree();let n;return n="production"===i?o[u](...t):o[u](...t.map(t=>r.ensureValueDosntExistInStateTreeElsewhere(t))),s.addMutation({method:m,path:e,delimiter:r.delimiter,args:t,hasChangedValue:!0}),n}:l(o[u])?r.proxify(o[u],f):o[u]},set(t,i,s){const n=r.concat(e,i),a=r.getMutationTree(),o=Reflect.set(t,i,s);return a.addMutation({method:"set",path:n,args:[s],delimiter:r.delimiter,hasChangedValue:!0}),o}});return this.ssr||Object.defineProperty(t,this.CACHED_PROXY,{value:o,configurable:!0}),o}createObjectProxy(t,e){if(!this.ssr&&this.isProxyCached(t,e))return t[this.CACHED_PROXY];const r=this,i=new Proxy(t,{get(c,h){if(h===s)return!0;if(h===n)return e;if(h===a)return t;if(h===o)return r.tree;if("symbol"==typeof h||h in Object.prototype)return c[h];const p=Object.getOwnPropertyDescriptor(c,h)||Object.getPrototypeOf(c)&&Object.getOwnPropertyDescriptor(Object.getPrototypeOf(c),h);if(p&&"get"in p){const t=p.get.call(i);return r.tree.master.options.devmode&&r.tree.master.options.onGetter&&r.tree.master.options.onGetter(r.concat(e,h),t),t}const f=r.getTrackingTree(),d=c[h],m=r.concat(e,h),g=f||r.tree;return"function"==typeof d?r.tree.master.options.onGetFunction?r.tree.master.options.onGetFunction(f||r.tree,m,c,h):u(c)?d:d.call(c,r.tree,m):(g.trackPathListeners.forEach(t=>t(m)),f&&f.proxifier.trackPath(m),l(d)?r.proxify(d,m):d)},set(t,i,s){const n=r.concat(e,i);let a;i in t||(a=e);const o=r.getMutationTree(),c=t[i];"function"==typeof s&&r.tree.master.options.onSetFunction&&(s=r.tree.master.options.onSetFunction(r.getTrackingTree()||r.tree,n,t,i,s));const h=c!==s,u=Reflect.set(t,i,s);return o.addMutation({method:"set",path:n,args:[s],delimiter:r.delimiter,hasChangedValue:h},a),u},deleteProperty(t,i){const s=r.concat(e,i);let n;i in t&&(n=e);const a=r.getMutationTree();return delete t[i],a.addMutation({method:"unset",path:s,args:[],delimiter:r.delimiter,hasChangedValue:!0},n),!0}});return this.ssr||Object.defineProperty(t,this.CACHED_PROXY,{value:i,configurable:!0}),i}proxify(t,e){if(t){if(t[s]&&(String(t[n])!==String(e)||t[a][this.CACHED_PROXY]!==t))return this.proxify(t[a],e);if(t[s])return t;if(Array.isArray(t))return this.createArrayProxy(t,e);if((t=>"[object Object]"===String(t)&&"Object"===t.constructor.name)(t)||u(t))return this.createObjectProxy(t,e)}return t}}class f{constructor(t,e){this.mutationCallbacks=[],this.mutations=[],this.objectChanges=new Set,this.isTracking=!1,this.isBlocking=!1,this.trackPathListeners=[],this.isTracking=!0,this.master=t,this.proxifier=e||new p(this),this.state=this.proxifier.proxify(t.sourceState,"")}trackPaths(){const t=new Set,e=e=>{t.add(e)};return this.trackPathListeners.push(e),()=>(this.trackPathListeners.splice(this.trackPathListeners.indexOf(e),1),t)}getMutations(){const t=this.mutations.slice();return this.mutations.length=0,t}getObjectChanges(){const t=new Set([...this.objectChanges]);return this.objectChanges.clear(),t}addMutation(t,e){const r=this.master.currentFlushId;this.mutations.push(t),e&&this.objectChanges.add(e);for(const i of this.master.mutationCallbacks)i(t,new Set(e?[t.path,e]:[t.path]),r);for(const i of this.mutationCallbacks)i(t,new Set(e?[t.path,e]:[t.path]),r)}flush(t=!1){return this.master.flush(this,t)}onMutation(t){this.mutationCallbacks.push(t)}canMutate(){return this.isTracking&&!this.isBlocking}canTrack(){return!1}blockMutations(){this.isBlocking=!0}enableMutations(){this.isBlocking=!1}dispose(){return this.isTracking=!1,this.mutationCallbacks.length=0,this.proxifier=this.master.proxifier,this}}class d{constructor(t){this.pathDependencies=new Set,this.shouldTrack=!1,this.trackPathListeners=[],this.master=t,this.proxifier=t.proxifier,this.state=t.state}trackPaths(){const t=new Set,e=e=>{t.add(e)};return this.trackPathListeners.push(e),()=>(this.trackPathListeners.splice(this.trackPathListeners.indexOf(e),1),t)}canMutate(){return!1}canTrack(){return!0}addTrackingPath(t){this.shouldTrack&&(this.pathDependencies.add(t),this.callback&&this.master.addPathDependency(t,this.callback))}track(t){return this.master.changeTrackStateTree(this),this.shouldTrack=!0,this.clearTracking(),t&&(this.callback=(...e)=>{this.callback&&t(...e)}),this}clearTracking(){if(this.callback)for(const t of this.pathDependencies)this.master.removePathDependency(t,this.callback);this.pathDependencies.clear()}stopTracking(){this.shouldTrack=!1}trackScope(t,e){const r=this.master.previousTree,i=this.master.currentTree;this.master.currentTree=this,this.track(e);const s=t(this);return this.master.currentTree=i,this.master.previousTree=r,this.stopTracking(),s}dispose(){return this.callback?(this.clearTracking(),this.callback=null,this.proxifier=this.master.proxifier,this.master.currentTree===this&&(this.master.currentTree=null),this):(this.pathDependencies.clear(),this)}}r.d(e,"ProxyStateTree",(function(){return m})),r.d(e,"IS_PROXY",(function(){return s})),r.d(e,"PROXY_TREE",(function(){return o})),r.d(e,"VALUE",(function(){return a})),r.d(e,"PATH",(function(){return n})),r.d(e,"TrackStateTree",(function(){return d})),r.d(e,"MutationTree",(function(){return f}));class m{constructor(t,e={}){this.cache={mutationTree:[],trackStateTree:[]},this.flushCallbacks=[],this.mutationCallbacks=[],this.currentFlushId=0,this.pathDependencies={},void 0===e.devmode&&(e.devmode=!0),e.delimiter||(e.delimiter="."),this.master=this,this.sourceState=t,this.options=e,this.createTrackStateProxifier()}createTrackStateProxifier(){const t=new d(this);this.proxifier=t.proxifier=new p(t),this.state=t.state=this.proxifier.proxify(this.sourceState,"")}getMutationTree(){if(!this.options.devmode)return this.mutationTree=this.mutationTree||new f(this,this.proxifier);return this.cache.mutationTree.pop()||new f(this)}getTrackStateTree(){return this.cache.trackStateTree.pop()||new d(this)}getTrackStateTreeWithProxifier(){const t=this.getTrackStateTree();return this.options.ssr?t.state=this.sourceState:(t.proxifier=new p(t),t.state=t.proxifier.proxify(this.sourceState,"")),t}changeTrackStateTree(t){this.previousTree=this.currentTree,this.currentTree=t}disposeTree(t){t instanceof f?this.cache.mutationTree.push(t.dispose()):t instanceof d&&this.cache.trackStateTree.push(t.dispose())}onMutation(t){return this.mutationCallbacks.push(t),()=>{this.mutationCallbacks.splice(this.mutationCallbacks.indexOf(t),1)}}forceFlush(){const t=[],e=[];for(const r in this.pathDependencies){this.pathDependencies[r].forEach(r=>{r(t,e,this.currentFlushId++,!1)})}}flush(t,e=!1){let r;if(r=Array.isArray(t)?t.reduce((t,e)=>({mutations:t.mutations.concat(e.getMutations()),objectChanges:new Set([...t.objectChanges,...e.getObjectChanges()])}),{mutations:[],objectChanges:new Set}):{mutations:t.getMutations(),objectChanges:t.getObjectChanges()},!r.mutations.length&&!r.objectChanges.size)return{mutations:[],flushId:null};const i=new Set,s=new Set,n=this.currentFlushId++;for(const t of r.objectChanges)this.pathDependencies[t]&&i.add(t);for(const t of r.mutations)t.hasChangedValue&&i.add(t.path);const a=Array.from(i).sort();for(const t of a)if(this.pathDependencies[t])for(const e of this.pathDependencies[t])s.add(e);for(const t of s)t(r.mutations,a,n,e);const o=this.flushCallbacks.slice();for(const t of o)this.flushCallbacks.includes(t)&&t(r.mutations,a,n,e);return i.clear(),s.clear(),{mutations:r.mutations,flushId:n}}onFlush(t){return this.flushCallbacks.push(t),()=>this.flushCallbacks.splice(this.flushCallbacks.indexOf(t),1)}rescope(t,e){return t&&t[s]?e.proxifier.proxify(t[a],t[n]):t}addPathDependency(t,e){this.pathDependencies[t]||(this.pathDependencies[t]=new Set),this.pathDependencies[t].add(e)}removePathDependency(t,e){this.pathDependencies[t].delete(e),this.pathDependencies[t].size||delete this.pathDependencies[t]}toJSON(){return this.sourceState}}}]);
(()=>{let e;try{e="production"}catch{e="development"}})(),Symbol("IS_PROXY"),Symbol("PATH"),Symbol("VALUE"),Symbol("PROXY_TREE"),new Set(["push","shift","pop","unshift","splice","reverse","sort","copyWithin"]);
//# sourceMappingURL=proxy-state-tree.min.js.map

@@ -8,3 +8,2 @@ import { MutationTree } from './MutationTree';

export declare class ProxyStateTree<T extends object> implements IProxyStateTree<T> {
private cache;
flushCallbacks: IFlushCallback[];

@@ -29,3 +28,5 @@ mutationCallbacks: IMutationCallback[];

getTrackStateTreeWithProxifier(): ITrackStateTree<T>;
changeTrackStateTree(tree: ITrackStateTree<T>): void;
setTrackStateTree(tree: ITrackStateTree<T>): void;
unsetTrackStateTree(tree: ITrackStateTree<T>): void;
clearTrackStateTree(): void;
disposeTree(tree: IMutationTree<T> | ITrackStateTree<T>): void;

@@ -32,0 +33,0 @@ onMutation(callback: IMutationCallback): () => void;

@@ -8,6 +8,2 @@ import { MutationTree } from './MutationTree';

constructor(state, options = {}) {
this.cache = {
mutationTree: [],
trackStateTree: [],
};
this.flushCallbacks = [];

@@ -39,2 +35,4 @@ this.mutationCallbacks = [];

getMutationTree() {
// We never want to do tracking when we want to do mutations
this.clearTrackStateTree();
if (!this.options.devmode) {

@@ -44,7 +42,6 @@ return (this.mutationTree =

}
const tree = this.cache.mutationTree.pop() || new MutationTree(this);
return tree;
return new MutationTree(this);
}
getTrackStateTree() {
return this.cache.trackStateTree.pop() || new TrackStateTree(this);
return new TrackStateTree(this);
}

@@ -62,13 +59,21 @@ getTrackStateTreeWithProxifier() {

}
changeTrackStateTree(tree) {
setTrackStateTree(tree) {
this.previousTree = this.currentTree;
this.currentTree = tree;
}
unsetTrackStateTree(tree) {
// We only allow unsetting it when it is currently the active tree
if (this.currentTree === tree) {
this.currentTree = null;
}
}
clearTrackStateTree() {
this.previousTree = null;
this.currentTree = null;
}
disposeTree(tree) {
if (tree instanceof MutationTree) {
this.cache.mutationTree.push(tree.dispose());
;
tree.dispose();
}
else if (tree instanceof TrackStateTree) {
this.cache.trackStateTree.push(tree.dispose());
}
}

@@ -75,0 +80,0 @@ onMutation(callback) {

import { IMutation, IMutationCallback, IMutationTree, IProxifier, IProxyStateTree } from './types';
export declare class MutationTree<T extends object> implements IMutationTree<T> {
private mutationCallbacks;
master: IProxyStateTree<T>;
root: IProxyStateTree<T>;
state: T;

@@ -12,3 +12,3 @@ proxifier: IProxifier<T>;

trackPathListeners: Array<(path: string) => void>;
constructor(master: IProxyStateTree<T>, proxifier?: IProxifier<T>);
constructor(root: IProxyStateTree<T>, proxifier?: IProxifier<T>);
trackPaths(): () => Set<string>;

@@ -15,0 +15,0 @@ getMutations(): IMutation[];

import { Proxifier } from './Proxyfier';
export class MutationTree {
constructor(master, proxifier) {
constructor(root, proxifier) {
this.mutationCallbacks = [];

@@ -11,5 +11,5 @@ this.mutations = [];

this.isTracking = true;
this.master = master;
this.root = root;
this.proxifier = proxifier || new Proxifier(this);
this.state = this.proxifier.proxify(master.sourceState, '');
this.state = this.proxifier.proxify(root.sourceState, '');
}

@@ -38,3 +38,3 @@ trackPaths() {

addMutation(mutation, objectChangePath) {
const currentFlushId = this.master.currentFlushId;
const currentFlushId = this.root.currentFlushId;
this.mutations.push(mutation);

@@ -44,3 +44,3 @@ if (objectChangePath) {

}
for (const cb of this.master.mutationCallbacks) {
for (const cb of this.root.mutationCallbacks) {
cb(mutation, new Set(objectChangePath ? [mutation.path, objectChangePath] : [mutation.path]), currentFlushId);

@@ -53,3 +53,3 @@ }

flush(isAsync = false) {
return this.master.flush(this, isAsync);
return this.root.flush(this, isAsync);
}

@@ -74,3 +74,3 @@ onMutation(callback) {

this.mutationCallbacks.length = 0;
this.proxifier = this.master.proxifier;
this.proxifier = this.root.proxifier;
return this;

@@ -77,0 +77,0 @@ }

@@ -6,3 +6,3 @@ const ENVIRONMENT = (() => {

}
catch (_a) {
catch {
env = 'development';

@@ -47,4 +47,4 @@ }

this.CACHED_PROXY = Symbol('CACHED_PROXY');
this.delimiter = tree.master.options.delimiter;
this.ssr = Boolean(tree.master.options.ssr);
this.delimiter = tree.root.options.delimiter;
this.ssr = Boolean(tree.root.options.ssr);
}

@@ -57,6 +57,6 @@ concat(path, prop) {

return;
if (this.tree.master.options.devmode && !this.tree.canMutate()) {
if (this.tree.root.options.devmode && !this.tree.canMutate()) {
throw new Error(`proxy-state-tree - You are mutating the path "${path}", but it is not allowed. The following could have happened:
- The mutation is explicitly being blocket
- The mutation is explicitly being blocked
- You are passing state to a 3rd party tool trying to manipulate the state

@@ -68,3 +68,3 @@ - You are running asynchronous code and forgot to "await" its execution

isDefaultProxifier() {
return this.tree.proxifier === this.tree.master.proxifier;
return this.tree.proxifier === this.tree.root.proxifier;
}

@@ -84,3 +84,3 @@ ensureValueDosntExistInStateTreeElsewhere(value) {

if (this.isDefaultProxifier()) {
const trackStateTree = this.tree.master.currentTree;
const trackStateTree = this.tree.root.currentTree;
if (!trackStateTree) {

@@ -101,4 +101,4 @@ return;

getTrackingTree() {
if (this.tree.master.currentTree && this.isDefaultProxifier()) {
return this.tree.master.currentTree;
if (this.tree.root.currentTree && this.isDefaultProxifier()) {
return this.tree.root.currentTree;
}

@@ -114,3 +114,3 @@ if (!this.tree.canTrack()) {

getMutationTree() {
return this.tree.master.mutationTree || this.tree;
return this.tree.root.mutationTree || this.tree;
}

@@ -163,5 +163,5 @@ isProxyCached(value, path) {

method,
path: path,
path,
delimiter: proxifier.delimiter,
args: args,
args,
hasChangedValue: true,

@@ -223,5 +223,5 @@ });

const value = descriptor.get.call(proxy);
if (proxifier.tree.master.options.devmode &&
proxifier.tree.master.options.onGetter) {
proxifier.tree.master.options.onGetter(proxifier.concat(path, prop), value);
if (proxifier.tree.root.options.devmode &&
proxifier.tree.root.options.onGetter) {
proxifier.tree.root.options.onGetter(proxifier.concat(path, prop), value);
}

@@ -235,4 +235,4 @@ return value;

if (typeof targetValue === 'function') {
if (proxifier.tree.master.options.onGetFunction) {
return proxifier.tree.master.options.onGetFunction(trackingTree || proxifier.tree, nestedPath, target, prop);
if (proxifier.tree.root.options.onGetFunction) {
return proxifier.tree.root.options.onGetFunction(trackingTree || proxifier.tree, nestedPath, target, prop);
}

@@ -263,4 +263,4 @@ return isClass(target)

if (typeof value === 'function' &&
proxifier.tree.master.options.onSetFunction) {
value = proxifier.tree.master.options.onSetFunction(proxifier.getTrackingTree() || proxifier.tree, nestedPath, target, prop, value);
proxifier.tree.root.options.onSetFunction) {
value = proxifier.tree.root.options.onSetFunction(proxifier.getTrackingTree() || proxifier.tree, nestedPath, target, prop, value);
}

@@ -267,0 +267,0 @@ const hasChangedValue = existingValue !== value;

import { IProxifier, IProxyStateTree, ITrackCallback, ITrackScopedCallback, ITrackStateTree } from './types';
export declare class TrackStateTree<T extends object> implements ITrackStateTree<T> {
private disposeOnReset;
master: IProxyStateTree<T>;
root: IProxyStateTree<T>;
pathDependencies: Set<string>;
callback: ITrackCallback;
shouldTrack: boolean;
state: T;
proxifier: IProxifier<T>;
trackPathListeners: Array<(path: string) => void>;
constructor(master: IProxyStateTree<T>);
constructor(root: IProxyStateTree<T>);
trackPaths(): () => Set<string>;
track(): this;
canMutate(): boolean;
canTrack(): boolean;
addTrackingPath(path: string): void;
track(cb?: ITrackCallback): this;
clearTracking(): void;
stopTracking(): void;
trackScope(scope: ITrackScopedCallback<T>, cb?: ITrackCallback): any;
dispose(): this;
subscribe(cb: ITrackCallback): () => void;
trackScope(scope: ITrackScopedCallback<T>): this;
}
export class TrackStateTree {
constructor(master) {
constructor(root) {
this.pathDependencies = new Set();
this.shouldTrack = false;
this.trackPathListeners = [];
this.master = master;
this.proxifier = master.proxifier;
this.state = master.state;
this.root = root;
this.proxifier = root.proxifier;
this.state = root.state;
}

@@ -21,2 +20,6 @@ trackPaths() {

}
track() {
this.root.setTrackStateTree(this);
return this;
}
canMutate() {

@@ -29,58 +32,23 @@ return false;

addTrackingPath(path) {
if (!this.shouldTrack) {
return;
}
this.pathDependencies.add(path);
if (this.callback) {
this.master.addPathDependency(path, this.callback);
}
}
track(cb) {
this.master.changeTrackStateTree(this);
this.shouldTrack = true;
this.clearTracking();
if (cb) {
this.callback = (...args) => {
if (!this.callback) {
return;
}
// eslint-disable-next-line
cb(...args);
};
subscribe(cb) {
this.root.unsetTrackStateTree(this);
for (const path of this.pathDependencies) {
this.root.addPathDependency(path, cb);
}
return this;
}
clearTracking() {
if (this.callback) {
return () => {
for (const path of this.pathDependencies) {
this.master.removePathDependency(path, this.callback);
this.root.removePathDependency(path, cb);
}
}
this.pathDependencies.clear();
};
}
stopTracking() {
this.shouldTrack = false;
}
trackScope(scope, cb) {
const previousPreviousTree = this.master.previousTree;
const previousCurrentTree = this.master.currentTree;
this.master.currentTree = this;
this.track(cb);
const result = scope(this);
this.master.currentTree = previousCurrentTree;
this.master.previousTree = previousPreviousTree;
this.stopTracking();
return result;
}
dispose() {
if (!this.callback) {
this.pathDependencies.clear();
return this;
}
this.clearTracking();
this.callback = null;
this.proxifier = this.master.proxifier;
if (this.master.currentTree === this) {
this.master.currentTree = null;
}
trackScope(scope) {
const previousPreviousTree = this.root.previousTree;
const previousCurrentTree = this.root.currentTree;
this.root.currentTree = this;
this.track();
scope(this);
this.root.currentTree = previousCurrentTree;
this.root.previousTree = previousPreviousTree;
return this;

@@ -87,0 +55,0 @@ }

@@ -29,3 +29,3 @@ export interface IProxifier<T extends object> {

objectChanges: Set<string>;
master: IProxyStateTree<T>;
root: IProxyStateTree<T>;
proxifier: IProxifier<T>;

@@ -44,16 +44,11 @@ mutations: IMutation[];

addTrackingPath(path: string): void;
track(cb?: ITrackCallback): ITrackStateTree<T>;
stopTracking(): void;
trackScope(scope: ITrackScopedCallback<T>, callback?: ITrackCallback): any;
trackPaths(): () => Set<string>;
subscribe(cb: ITrackCallback): () => void;
track(): ITrackStateTree<T>;
trackScope(scope: ITrackScopedCallback<T>): any;
canTrack(): boolean;
canMutate(): boolean;
dispose(): ITrackStateTree<T>;
clearTracking(): void;
master: IProxyStateTree<T>;
shouldTrack: boolean;
root: IProxyStateTree<T>;
proxifier: IProxifier<T>;
state: T;
pathDependencies: Set<string>;
callback: ITrackCallback;
trackPathListeners: Array<(path: string) => void>;

@@ -72,3 +67,3 @@ }

}
export declare type TTree = IMutationTree<any> | ITrackStateTree<any>;
export type TTree = IMutationTree<any> | ITrackStateTree<any>;
export interface IRemoveProxyCallback {

@@ -82,3 +77,5 @@ (path: string): void;

getMutationTree(): IMutationTree<T>;
changeTrackStateTree(tree: ITrackStateTree<T>): void;
setTrackStateTree(tree: ITrackStateTree<T> | null): void;
unsetTrackStateTree(tree: ITrackStateTree<T> | null): void;
clearTrackStateTree(): void;
disposeTree(proxy: TTree): void;

@@ -85,0 +82,0 @@ onMutation(cb: IMutationCallback): void;

@@ -8,3 +8,2 @@ import { MutationTree } from './MutationTree';

export declare class ProxyStateTree<T extends object> implements IProxyStateTree<T> {
private cache;
flushCallbacks: IFlushCallback[];

@@ -29,3 +28,5 @@ mutationCallbacks: IMutationCallback[];

getTrackStateTreeWithProxifier(): ITrackStateTree<T>;
changeTrackStateTree(tree: ITrackStateTree<T>): void;
setTrackStateTree(tree: ITrackStateTree<T>): void;
unsetTrackStateTree(tree: ITrackStateTree<T>): void;
clearTrackStateTree(): void;
disposeTree(tree: IMutationTree<T> | ITrackStateTree<T>): void;

@@ -32,0 +33,0 @@ onMutation(callback: IMutationCallback): () => void;

@@ -17,6 +17,2 @@ "use strict";

constructor(state, options = {}) {
this.cache = {
mutationTree: [],
trackStateTree: [],
};
this.flushCallbacks = [];

@@ -48,2 +44,4 @@ this.mutationCallbacks = [];

getMutationTree() {
// We never want to do tracking when we want to do mutations
this.clearTrackStateTree();
if (!this.options.devmode) {

@@ -53,7 +51,6 @@ return (this.mutationTree =

}
const tree = this.cache.mutationTree.pop() || new MutationTree_1.MutationTree(this);
return tree;
return new MutationTree_1.MutationTree(this);
}
getTrackStateTree() {
return this.cache.trackStateTree.pop() || new TrackStateTree_1.TrackStateTree(this);
return new TrackStateTree_1.TrackStateTree(this);
}

@@ -71,13 +68,21 @@ getTrackStateTreeWithProxifier() {

}
changeTrackStateTree(tree) {
setTrackStateTree(tree) {
this.previousTree = this.currentTree;
this.currentTree = tree;
}
unsetTrackStateTree(tree) {
// We only allow unsetting it when it is currently the active tree
if (this.currentTree === tree) {
this.currentTree = null;
}
}
clearTrackStateTree() {
this.previousTree = null;
this.currentTree = null;
}
disposeTree(tree) {
if (tree instanceof MutationTree_1.MutationTree) {
this.cache.mutationTree.push(tree.dispose());
;
tree.dispose();
}
else if (tree instanceof TrackStateTree_1.TrackStateTree) {
this.cache.trackStateTree.push(tree.dispose());
}
}

@@ -84,0 +89,0 @@ onMutation(callback) {

import { IMutation, IMutationCallback, IMutationTree, IProxifier, IProxyStateTree } from './types';
export declare class MutationTree<T extends object> implements IMutationTree<T> {
private mutationCallbacks;
master: IProxyStateTree<T>;
root: IProxyStateTree<T>;
state: T;

@@ -12,3 +12,3 @@ proxifier: IProxifier<T>;

trackPathListeners: Array<(path: string) => void>;
constructor(master: IProxyStateTree<T>, proxifier?: IProxifier<T>);
constructor(root: IProxyStateTree<T>, proxifier?: IProxifier<T>);
trackPaths(): () => Set<string>;

@@ -15,0 +15,0 @@ getMutations(): IMutation[];

@@ -6,3 +6,3 @@ "use strict";

class MutationTree {
constructor(master, proxifier) {
constructor(root, proxifier) {
this.mutationCallbacks = [];

@@ -15,5 +15,5 @@ this.mutations = [];

this.isTracking = true;
this.master = master;
this.root = root;
this.proxifier = proxifier || new Proxyfier_1.Proxifier(this);
this.state = this.proxifier.proxify(master.sourceState, '');
this.state = this.proxifier.proxify(root.sourceState, '');
}

@@ -42,3 +42,3 @@ trackPaths() {

addMutation(mutation, objectChangePath) {
const currentFlushId = this.master.currentFlushId;
const currentFlushId = this.root.currentFlushId;
this.mutations.push(mutation);

@@ -48,3 +48,3 @@ if (objectChangePath) {

}
for (const cb of this.master.mutationCallbacks) {
for (const cb of this.root.mutationCallbacks) {
cb(mutation, new Set(objectChangePath ? [mutation.path, objectChangePath] : [mutation.path]), currentFlushId);

@@ -57,3 +57,3 @@ }

flush(isAsync = false) {
return this.master.flush(this, isAsync);
return this.root.flush(this, isAsync);
}

@@ -78,3 +78,3 @@ onMutation(callback) {

this.mutationCallbacks.length = 0;
this.proxifier = this.master.proxifier;
this.proxifier = this.root.proxifier;
return this;

@@ -81,0 +81,0 @@ }

@@ -49,4 +49,4 @@ "use strict";

this.CACHED_PROXY = Symbol('CACHED_PROXY');
this.delimiter = tree.master.options.delimiter;
this.ssr = Boolean(tree.master.options.ssr);
this.delimiter = tree.root.options.delimiter;
this.ssr = Boolean(tree.root.options.ssr);
}

@@ -59,6 +59,6 @@ concat(path, prop) {

return;
if (this.tree.master.options.devmode && !this.tree.canMutate()) {
if (this.tree.root.options.devmode && !this.tree.canMutate()) {
throw new Error(`proxy-state-tree - You are mutating the path "${path}", but it is not allowed. The following could have happened:
- The mutation is explicitly being blocket
- The mutation is explicitly being blocked
- You are passing state to a 3rd party tool trying to manipulate the state

@@ -70,3 +70,3 @@ - You are running asynchronous code and forgot to "await" its execution

isDefaultProxifier() {
return this.tree.proxifier === this.tree.master.proxifier;
return this.tree.proxifier === this.tree.root.proxifier;
}

@@ -86,3 +86,3 @@ ensureValueDosntExistInStateTreeElsewhere(value) {

if (this.isDefaultProxifier()) {
const trackStateTree = this.tree.master.currentTree;
const trackStateTree = this.tree.root.currentTree;
if (!trackStateTree) {

@@ -103,4 +103,4 @@ return;

getTrackingTree() {
if (this.tree.master.currentTree && this.isDefaultProxifier()) {
return this.tree.master.currentTree;
if (this.tree.root.currentTree && this.isDefaultProxifier()) {
return this.tree.root.currentTree;
}

@@ -116,3 +116,3 @@ if (!this.tree.canTrack()) {

getMutationTree() {
return this.tree.master.mutationTree || this.tree;
return this.tree.root.mutationTree || this.tree;
}

@@ -165,5 +165,5 @@ isProxyCached(value, path) {

method,
path: path,
path,
delimiter: proxifier.delimiter,
args: args,
args,
hasChangedValue: true,

@@ -225,5 +225,5 @@ });

const value = descriptor.get.call(proxy);
if (proxifier.tree.master.options.devmode &&
proxifier.tree.master.options.onGetter) {
proxifier.tree.master.options.onGetter(proxifier.concat(path, prop), value);
if (proxifier.tree.root.options.devmode &&
proxifier.tree.root.options.onGetter) {
proxifier.tree.root.options.onGetter(proxifier.concat(path, prop), value);
}

@@ -237,4 +237,4 @@ return value;

if (typeof targetValue === 'function') {
if (proxifier.tree.master.options.onGetFunction) {
return proxifier.tree.master.options.onGetFunction(trackingTree || proxifier.tree, nestedPath, target, prop);
if (proxifier.tree.root.options.onGetFunction) {
return proxifier.tree.root.options.onGetFunction(trackingTree || proxifier.tree, nestedPath, target, prop);
}

@@ -265,4 +265,4 @@ return isClass(target)

if (typeof value === 'function' &&
proxifier.tree.master.options.onSetFunction) {
value = proxifier.tree.master.options.onSetFunction(proxifier.getTrackingTree() || proxifier.tree, nestedPath, target, prop, value);
proxifier.tree.root.options.onSetFunction) {
value = proxifier.tree.root.options.onSetFunction(proxifier.getTrackingTree() || proxifier.tree, nestedPath, target, prop, value);
}

@@ -269,0 +269,0 @@ const hasChangedValue = existingValue !== value;

import { IProxifier, IProxyStateTree, ITrackCallback, ITrackScopedCallback, ITrackStateTree } from './types';
export declare class TrackStateTree<T extends object> implements ITrackStateTree<T> {
private disposeOnReset;
master: IProxyStateTree<T>;
root: IProxyStateTree<T>;
pathDependencies: Set<string>;
callback: ITrackCallback;
shouldTrack: boolean;
state: T;
proxifier: IProxifier<T>;
trackPathListeners: Array<(path: string) => void>;
constructor(master: IProxyStateTree<T>);
constructor(root: IProxyStateTree<T>);
trackPaths(): () => Set<string>;
track(): this;
canMutate(): boolean;
canTrack(): boolean;
addTrackingPath(path: string): void;
track(cb?: ITrackCallback): this;
clearTracking(): void;
stopTracking(): void;
trackScope(scope: ITrackScopedCallback<T>, cb?: ITrackCallback): any;
dispose(): this;
subscribe(cb: ITrackCallback): () => void;
trackScope(scope: ITrackScopedCallback<T>): this;
}

@@ -5,9 +5,8 @@ "use strict";

class TrackStateTree {
constructor(master) {
constructor(root) {
this.pathDependencies = new Set();
this.shouldTrack = false;
this.trackPathListeners = [];
this.master = master;
this.proxifier = master.proxifier;
this.state = master.state;
this.root = root;
this.proxifier = root.proxifier;
this.state = root.state;
}

@@ -25,2 +24,6 @@ trackPaths() {

}
track() {
this.root.setTrackStateTree(this);
return this;
}
canMutate() {

@@ -33,58 +36,23 @@ return false;

addTrackingPath(path) {
if (!this.shouldTrack) {
return;
}
this.pathDependencies.add(path);
if (this.callback) {
this.master.addPathDependency(path, this.callback);
}
}
track(cb) {
this.master.changeTrackStateTree(this);
this.shouldTrack = true;
this.clearTracking();
if (cb) {
this.callback = (...args) => {
if (!this.callback) {
return;
}
// eslint-disable-next-line
cb(...args);
};
subscribe(cb) {
this.root.unsetTrackStateTree(this);
for (const path of this.pathDependencies) {
this.root.addPathDependency(path, cb);
}
return this;
}
clearTracking() {
if (this.callback) {
return () => {
for (const path of this.pathDependencies) {
this.master.removePathDependency(path, this.callback);
this.root.removePathDependency(path, cb);
}
}
this.pathDependencies.clear();
};
}
stopTracking() {
this.shouldTrack = false;
}
trackScope(scope, cb) {
const previousPreviousTree = this.master.previousTree;
const previousCurrentTree = this.master.currentTree;
this.master.currentTree = this;
this.track(cb);
const result = scope(this);
this.master.currentTree = previousCurrentTree;
this.master.previousTree = previousPreviousTree;
this.stopTracking();
return result;
}
dispose() {
if (!this.callback) {
this.pathDependencies.clear();
return this;
}
this.clearTracking();
this.callback = null;
this.proxifier = this.master.proxifier;
if (this.master.currentTree === this) {
this.master.currentTree = null;
}
trackScope(scope) {
const previousPreviousTree = this.root.previousTree;
const previousCurrentTree = this.root.currentTree;
this.root.currentTree = this;
this.track();
scope(this);
this.root.currentTree = previousCurrentTree;
this.root.previousTree = previousPreviousTree;
return this;

@@ -91,0 +59,0 @@ }

@@ -29,3 +29,3 @@ export interface IProxifier<T extends object> {

objectChanges: Set<string>;
master: IProxyStateTree<T>;
root: IProxyStateTree<T>;
proxifier: IProxifier<T>;

@@ -44,16 +44,11 @@ mutations: IMutation[];

addTrackingPath(path: string): void;
track(cb?: ITrackCallback): ITrackStateTree<T>;
stopTracking(): void;
trackScope(scope: ITrackScopedCallback<T>, callback?: ITrackCallback): any;
trackPaths(): () => Set<string>;
subscribe(cb: ITrackCallback): () => void;
track(): ITrackStateTree<T>;
trackScope(scope: ITrackScopedCallback<T>): any;
canTrack(): boolean;
canMutate(): boolean;
dispose(): ITrackStateTree<T>;
clearTracking(): void;
master: IProxyStateTree<T>;
shouldTrack: boolean;
root: IProxyStateTree<T>;
proxifier: IProxifier<T>;
state: T;
pathDependencies: Set<string>;
callback: ITrackCallback;
trackPathListeners: Array<(path: string) => void>;

@@ -72,3 +67,3 @@ }

}
export declare type TTree = IMutationTree<any> | ITrackStateTree<any>;
export type TTree = IMutationTree<any> | ITrackStateTree<any>;
export interface IRemoveProxyCallback {

@@ -82,3 +77,5 @@ (path: string): void;

getMutationTree(): IMutationTree<T>;
changeTrackStateTree(tree: ITrackStateTree<T>): void;
setTrackStateTree(tree: ITrackStateTree<T> | null): void;
unsetTrackStateTree(tree: ITrackStateTree<T> | null): void;
clearTrackStateTree(): void;
disposeTree(proxy: TTree): void;

@@ -85,0 +82,0 @@ onMutation(cb: IMutationCallback): void;

{
"name": "proxy-state-tree",
"version": "6.3.0",
"version": "6.3.1-1709665053033",
"description": "An implementation of the Mobx/Vue state tracking approach, for library authors",

@@ -11,3 +11,3 @@ "main": "lib/index.js",

"build:lib": "tsc --outDir lib --module commonjs",
"build:es": "tsc --outDir es --module es2015",
"build:es": "tsc --outDir es --module ES2020 --target ES2020",
"build:dist": "webpack --config webpack.config.js",

@@ -18,3 +18,3 @@ "clean": "rimraf es lib coverage",

"test:watch": "jest --watch --updateSnapshot --coverage false",
"test:size": "bundlesize",
"test:size": "size-limit",
"prebuild": "npm run clean",

@@ -42,12 +42,13 @@ "postbuild": "rimraf {lib,es}/**/__tests__",

"devDependencies": {
"bundlesize": "^0.17.2",
"terser-webpack-plugin": "^1.3.0",
"webpack": "^4.35.0"
"@size-limit/file": "^8.2.6",
"size-limit": "^8.2.6",
"terser-webpack-plugin": "^5.3.9",
"webpack": "^5.88.2"
},
"bundlesize": [
"size-limit": [
{
"path": "./dist/proxy-state-tree.min.js",
"maxSize": "4 kB"
"limit": "300 B"
}
]
}
# proxy-state-tree
An implementation of the Mobx/Vue state tracking approach with a state tree, for library authors
An implementation of the Mobx/Vue state tracking approach with a state tree, for library authors.
`npm install proxy-state-tree`
## Why
The **proxy-state-tree** project is created to stimulate innovation in state management. The introduction of [Flux](https://facebook.github.io/flux/) was followed by a big wave of libraries trying to improve on the idea. All these iterations helped moving the community forward and [Redux](https://redux.js.org/) was born a year later. It was frustrating to have all these variations of the same idea, but at the same time it made the core idea better. One factor I believe made this possible is that Flux state management is based on **immutability**. It is a difficult concept to understand, but when you understand it, it is easy to implement the concept of **change**. You literally just check if a value you depend on has changed. That said, immutability tends to put a lof effort on the hands of the consumer. You have to think really hard about how you structure state and expose state to components to avoid performance issues and prevent boilerplate.

@@ -122,5 +124,5 @@

This forked tree is allowed to perform actual mutations.
This forked tree is allowed to perform actual mutations.
### onMutation
### mutationTree.onMutation

@@ -137,3 +139,3 @@ ```js

## diposeTree
## disposeTree

@@ -209,3 +211,2 @@ ```js

## rescope

@@ -234,4 +235,4 @@

Every fork of a **MutationTree** has its own *proxifier*. The reason for this is that in development each mutation tree fork should live on its own for tracking purposes.
Every fork of a **MutationTree** has its own *proxifier*. The reason for this is that in development each mutation tree fork should live on its own for tracking purposes.
When running in production there is only one *proxifier* shared among all trees, and there is only one mutationtree instance as tracking is no longer needed.

@@ -11,9 +11,10 @@ const path = require('path')

},
devtool: 'source-map',
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
test: /\.js(\?.*)?$/i,
parallel: true,
sourceMap: true,
terserOptions: {
sourceMap: true,
module: true,

@@ -20,0 +21,0 @@ },

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc