@vue-modeler/model 2.2.4 → 2.2.5-beta.2

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
@@ -1,5 +1,7 @@
1
1
  # vue-modeler/model
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/@vue-modeler/model.svg)](https://www.npmjs.com/package/@vue-modeler/model) [![codecov](https://codecov.io/gh/vue-modeler/model/branch/main/graph/badge.svg?token=BFQI22MBZ1)](https://codecov.io/gh/vue-modeler/model)
4
+
3
5
  ## What is @vue-modeler/model
4
6
 
5
7
  A state management library based on models for [Vue.js](https://vuejs.org/). The extremely simple API serves single purpose — creating models. It preserves types, supports OOP, DRY, and SOLID principles.
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var L=Object.defineProperty;var B=(r,t,e)=>t in r?L(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e;var i=(r,t,e)=>B(r,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("vue");class I extends Error{constructor(t,e){super(e.cause.message),this.actionName=t,this.options=e,this.name=this.constructor.name}get cause(){return this.options.cause}throwCause(){throw this.cause}toString(){return this.options.cause.message}}class d extends Error{constructor(t,e){super(t,e),this.message=t,this.options=e,this.name=this.constructor.name}}class b extends d{constructor(t,e,o){super(`Trying to update state of ${t} from ${e} to ${o}`),this.name=this.constructor.name}}class $ extends d{constructor(t,e){super(`Unexpected AbortError for the action ${t} in state ${e}`),this.name=this.constructor.name}}const T=r=>r instanceof DOMException&&r.name==="AbortError"||typeof r=="object"&&r!==null&&"message"in r&&r.message==="canceled",s=class s{constructor(t,e,o,c,h){i(this,"name");i(this,"_state",s.possibleState.ready);i(this,"_value",null);i(this,"_args",null);this._model=t,this.actionFunction=e,this.ownerGetter=o,this.setStateCb=c,this._validateArgs=h;const n=e.name;if(!(n in this._model&&typeof this._model[n]=="function"))throw new d(`Model does not contain method ${n}`);if(typeof e[s.actionFlag]!="function")throw new d(`Method ${n} is not action`);this.name=n}static create(t,e,o,c,h){return u.shallowReactive(new s(t,e,o,c,h))}toString(){return this.name}get owner(){return this.ownerGetter()}get possibleStates(){return Object.values(s.possibleState)}get state(){return this._state}set state(t){const e=this._state;this._state=t,this.setStateCb(this,e,t)}get abortController(){return this.isPending?this._value.abortController:null}get args(){return this._args||[]}get promise(){return this.isPending?this._value.promise:null}get error(){return this.isError?this._value:null}get abortReason(){return this.isAbort?this._value.abortController.signal.reason:null}get isPending(){return this.state===s.possibleState.pending}get isError(){return this.state===s.possibleState.error}get isReady(){return this.state===s.possibleState.ready}get isLock(){return this.state===s.possibleState.lock}get isAbort(){return this.state===s.possibleState.abort}is(...t){return!!t.find(e=>this.state===e)}validate(...t){return this._validateArgs(this,...t)}exec(...t){if(this.is(s.possibleState.lock,s.possibleState.pending))throw new b(this.name,this.state,s.possibleState.pending);const e=[...t];let o=t.length&&t[t.length-1];o instanceof AbortController||(o=new AbortController,e.push(o)),this.state=s.possibleState.pending,this._args=t;const h=this.actionFunction[s.actionFlag].apply(this._model,e);if(!(h instanceof Promise))return this.state=s.possibleState.ready,Promise.resolve();const n=h.then(()=>{this.ready()}).catch(a=>{if(a instanceof d||a instanceof RangeError||a instanceof ReferenceError||a instanceof SyntaxError||a instanceof TypeError||a instanceof URIError||a instanceof EvalError)throw a;const w=T(a);if(w&&!this.is(s.possibleState.pending,s.possibleState.lock))throw new $(this.name,this.state);if(w&&this._value.abortController instanceof AbortController&&this._value.abortController.signal.reason===s.abortedByLock){this.state=s.possibleState.lock,this._value=null;return}if(w){this.state=s.possibleState.abort;return}this.setError(new I(this.name,{cause:a}))});return this._value={promise:n,abortController:o},n}abort(t){return this.isPending?(this._value.abortController.abort(t),this._value.promise):Promise.resolve()}lock(){return this.isPending?this.abort(s.abortedByLock):(this.state=s.possibleState.lock,this._value=null,Promise.resolve())}unlock(){if(!this.isLock)throw new b(this.name,this.state,s.possibleState.ready);return this.ready()}setError(t){if(!this.isPending)throw new b(this.name,this.state,s.possibleState.error);return this.state=s.possibleState.error,this._value=t,this}ready(){return this.state=s.possibleState.ready,this}resetError(){if(!this.error)throw new b(this.name,this.state,s.possibleState.ready);return this.ready()}};i(s,"actionFlag",Symbol("__action_original_method__")),i(s,"possibleState",{pending:"pending",error:"error",lock:"lock",ready:"ready",abort:"abort"}),i(s,"abortedByLock",Symbol("lock"));let l=s;const p=Symbol("scope"),S=Symbol("model"),A=Symbol("actions"),y=Symbol("actionIds"),g=Symbol("actionStates"),E=Symbol("actionsSize"),f=Symbol("watchStopHandlers"),D=Proxy;var k,M,P,C,R,x,F;F=p,x=S,R=A,C=y,P=g,M=E,k=f;const m=class m{constructor(){i(this,F,u.effectScope(!0));i(this,x,null);i(this,R,new WeakMap);i(this,C,new WeakMap);i(this,P,new Map);i(this,M,0);i(this,k,new Set)}static createModel(t){if(!(t instanceof m))throw new Error("ProtoModel instance is required");const e=new D(u.shallowReactive(t),{get(o,c,h){const n=Reflect.get(o,c,h),a=typeof n=="function";return a&&l.actionFlag in n&&typeof n[l.actionFlag]=="function"?o.action(n):a?n.bind(o):n}});return t[S]=e,e}static model(...t){if(this.prototype===m.prototype)throw new Error("ProtoModel is abstract class and can not be instantiated");const e=new this(...t);return m.createModel(e)}get hasPendingActions(){return!!this.getActionStatesRef(l.possibleState.pending).value}get hasActionWithError(){return!!this.getActionStatesRef(l.possibleState.error).value}watch(...t){if(t.length===0)throw new Error("watch requires at least one argument");const e=t.length===1?this[p].run(()=>u.watchEffect(t[0])):this[p].run(()=>u.watch(...t));if(!e)throw new Error("watchStopHandler is undefined");return this[f].add(e),()=>{e(),this[f].delete(e)}}computed(t,e){return this[p].run(()=>u.computed(t,e))}updateBit(t,e,o){const c=o?1:0,h=~(1<<e);return t&h|c<<e}createAction(t){const e=()=>{if(!this[S])throw new Error("Model not set");return this[S]},o=l.create(this,t,e,this.setActionState.bind(this),this.validateArgs.bind(this));return this[A].set(t,o),this[y].set(o,++this[E]),this.setActionState(o),o}getActionStatesRef(t){const e=this[g].get(t)||u.ref(0);return this[g].get(t)===void 0&&this[g].set(t,e),e}action(t){if(!(l.actionFlag in t&&typeof t[l.actionFlag]=="function"))throw new d("Action decorator is not applied to the method");return this[A].get(t)||this.createAction(t)}setActionState(t){const e=this[y].get(t);if(!e)throw new Error("Action not found");for(const o of t.possibleStates)o!==t.state&&(this.getActionStatesRef(o).value=this.updateBit(this.getActionStatesRef(o).value,e,!1));this.getActionStatesRef(t.state).value=this.updateBit(this.getActionStatesRef(t.state).value,e,!0)}validateArgs(t,...e){const o=`validateArgs is not implemented for action ${t.name} in the model`;return[new Error(o)]}isModelOf(t){return this instanceof t}destructor(){this[f].forEach(t=>{t()}),this[f]=new Set,this[p].stop()}};let v=m;function O(r,t){if(t.static)throw new Error("Action decorator is not supported for static methods");if(t.private)throw new Error("Action decorator is not supported for private methods");let e;try{e=t.name.toString()}catch(c){const n=`Invalid context. Can\`t get name of the method: ${c instanceof Error?c.message:"unknown error"}`;throw new Error(n)}const o={[e]:function(...c){return this.action(o[e]).exec(...c)}};return o[e][l.actionFlag]=r,o[e]}exports.Action=l;exports.ActionError=I;exports.ActionInternalError=d;exports.ActionStatusConflictError=b;exports.ActionUnexpectedAbortError=$;exports.ProtoModel=v;exports.action=O;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("vue");class v extends Error{constructor(t,e){super(e.cause.message),this.actionName=t,this.options=e,this.name=this.constructor.name}get cause(){return this.options.cause}throwCause(){throw this.cause}toString(){return this.options.cause.message}}class l extends Error{constructor(t,e){super(t,e),this.message=t,this.options=e,this.name=this.constructor.name}}class p extends l{constructor(t,e,r){super(`Trying to update state of ${t} from ${e} to ${r}`),this.name=this.constructor.name}}class A extends l{constructor(t,e){super(`Unexpected AbortError for the action ${t} in state ${e}`),this.name=this.constructor.name}}const k=a=>a instanceof DOMException&&a.name==="AbortError"||typeof a=="object"&&a!==null&&"message"in a&&a.message==="canceled";class s{constructor(t,e,r,i,c){this._model=t,this.actionFunction=e,this.ownerGetter=r,this.setStateCb=i,this._validateArgs=c;const o=e.name;if(!(o in this._model&&typeof this._model[o]=="function"))throw new l(`Model does not contain method ${o}`);if(typeof e[s.actionFlag]!="function")throw new l(`Method ${o} is not action`);this.name=o}static actionFlag=Symbol("__action_original_method__");static possibleState={pending:"pending",error:"error",lock:"lock",ready:"ready",abort:"abort"};static abortedByLock=Symbol("lock");name;_state=s.possibleState.ready;_value=null;_args=null;static create(t,e,r,i,c){return h.shallowReactive(new s(t,e,r,i,c))}toString(){return this.name}get owner(){return this.ownerGetter()}get possibleStates(){return Object.values(s.possibleState)}get state(){return this._state}set state(t){const e=this._state;this._state=t,this.setStateCb(this,e,t)}get abortController(){return this.isPending?this._value.abortController:null}get args(){return this._args??[]}get promise(){return this.isPending?this._value.promise:null}get error(){return this.isError?this._value:null}get abortReason(){return this.isAbort?this._value.abortController.signal.reason:null}get isPending(){return this.state===s.possibleState.pending}get isError(){return this.state===s.possibleState.error}get isReady(){return this.state===s.possibleState.ready}get isLock(){return this.state===s.possibleState.lock}get isAbort(){return this.state===s.possibleState.abort}is(...t){return t.includes(this.state)}validate(...t){return this._validateArgs(this,...t)}exec(...t){if(this.is(s.possibleState.lock,s.possibleState.pending))throw new p(this.name,this.state,s.possibleState.pending);const e=[...t];let r=t.length&&t.at(-1);r instanceof AbortController||(r=new AbortController,e.push(r)),this.state=s.possibleState.pending,this._args=t;const c=this.actionFunction[s.actionFlag].apply(this._model,e);if(!(c instanceof Promise))return this.state=s.possibleState.ready,Promise.resolve();const o=c.then(()=>{this.ready()}).catch(n=>{if(n instanceof l||n instanceof RangeError||n instanceof ReferenceError||n instanceof SyntaxError||n instanceof TypeError||n instanceof URIError||n instanceof EvalError)throw n;const S=k(n);if(S&&!this.is(s.possibleState.pending,s.possibleState.lock))throw new A(this.name,this.state);if(S&&this._value.abortController instanceof AbortController&&this._value.abortController.signal.reason===s.abortedByLock){this.state=s.possibleState.lock,this._value=null;return}if(S){this.state=s.possibleState.abort;return}this.setError(new v(this.name,{cause:n}))});return this._value={promise:o,abortController:r},o}abort(t){return this.isPending?(this._value.abortController.abort(t),this._value.promise):Promise.resolve()}lock(){return this.isPending?this.abort(s.abortedByLock):(this.state=s.possibleState.lock,this._value=null,Promise.resolve())}unlock(){if(!this.isLock)throw new p(this.name,this.state,s.possibleState.ready);return this.ready()}setError(t){if(!this.isPending)throw new p(this.name,this.state,s.possibleState.error);return this.state=s.possibleState.error,this._value=t,this}ready(){return this.state=s.possibleState.ready,this}resetError(){if(!this.error)throw new p(this.name,this.state,s.possibleState.ready);return this.ready()}}const u=Symbol("scope"),b=Symbol("model"),g=Symbol("actions"),w=Symbol("actionIds"),m=Symbol("actionStates"),y=Symbol("actionsSize"),d=Symbol("watchStopHandlers"),M=Proxy;class f{[u]=h.effectScope(!0);[b]=null;[g]=new WeakMap;[w]=new WeakMap;[m]=new Map;[y]=0;[d]=new Set;static createModel(t){if(!(t instanceof f))throw new TypeError("ProtoModel instance is required");const e=new M(h.shallowReactive(t),{get(r,i,c){const o=Reflect.get(r,i,c),n=typeof o=="function";return n&&s.actionFlag in o&&typeof o[s.actionFlag]=="function"?r.action(o):n?o.bind(r):o}});return t[b]=e,e}static model(...t){if(this.prototype===f.prototype)throw new Error("ProtoModel is abstract class and can not be instantiated");const e=new this(...t);return f.createModel(e)}get hasPendingActions(){return!!this.getActionStatesRef(s.possibleState.pending).value}get hasActionWithError(){return!!this.getActionStatesRef(s.possibleState.error).value}watch(...t){if(t.length===0)throw new Error("watch requires at least one argument");const e=t.length===1?this[u].run(()=>h.watchEffect(t[0])):this[u].run(()=>h.watch(...t));if(!e)throw new Error("watchStopHandler is undefined");return this[d].add(e),()=>{e(),this[d].delete(e)}}computed(t,e){return this[u].run(()=>h.computed(t,e))}updateBit(t,e,r){const i=r?1:0,c=~(1<<e);return t&c|i<<e}createAction(t){const e=()=>{if(!this[b])throw new Error("Model not set");return this[b]},r=s.create(this,t,e,this.setActionState.bind(this),this.validateArgs.bind(this));return this[g].set(t,r),this[w].set(r,++this[y]),this.setActionState(r),r}getActionStatesRef(t){const e=this[m].get(t)||h.ref(0);return this[m].get(t)===void 0&&this[m].set(t,e),e}action(t){if(!(s.actionFlag in t&&typeof t[s.actionFlag]=="function"))throw new l("Action decorator is not applied to the method");return this[g].get(t)||this.createAction(t)}setActionState(t){const e=this[w].get(t);if(!e)throw new Error("Action not found");for(const r of t.possibleStates)r!==t.state&&(this.getActionStatesRef(r).value=this.updateBit(this.getActionStatesRef(r).value,e,!1));this.getActionStatesRef(t.state).value=this.updateBit(this.getActionStatesRef(t.state).value,e,!0)}validateArgs(t,...e){const r=`validateArgs is not implemented for action ${t.name} in the model`;return[new Error(r)]}isModelOf(t){return this instanceof t}destructor(){this[d].forEach(t=>{t()}),this[d]=new Set,this[u].stop()}}function P(a,t){if(t.static)throw new Error("Action decorator is not supported for static methods");if(t.private)throw new Error("Action decorator is not supported for private methods");let e;try{e=t.name.toString()}catch(i){const o=`Invalid context. Can\`t get name of the method: ${i instanceof Error?i.message:"unknown error"}`;throw new Error(o)}const r={[e]:function(...i){return this.action(r[e]).exec(...i)}};return r[e][s.actionFlag]=a,r[e]}exports.Action=s;exports.ActionError=v;exports.ActionInternalError=l;exports.ActionStatusConflictError=p;exports.ActionUnexpectedAbortError=A;exports.ProtoModel=f;exports.action=P;
package/dist/index.d.ts CHANGED
@@ -26,7 +26,7 @@ export declare class Action<T extends object, Args extends any[] = unknown[]> im
26
26
  readonly ready: "ready";
27
27
  readonly abort: "abort";
28
28
  };
29
- static abortedByLock: symbol;
29
+ static readonly abortedByLock: unique symbol;
30
30
  readonly name: string;
31
31
  protected _state: ActionStateName;
32
32
  protected _value: ActionValue;
package/dist/index.js CHANGED
@@ -1,8 +1,5 @@
1
- var $ = Object.defineProperty;
2
- var K = (r, t, e) => t in r ? $(r, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : r[t] = e;
3
- var i = (r, t, e) => K(r, typeof t != "symbol" ? t + "" : t, e);
4
- import { shallowReactive as F, effectScope as L, watchEffect as B, watch as D, computed as T, ref as H } from "vue";
5
- class O extends Error {
1
+ import { shallowReactive as y, effectScope as A, watchEffect as E, watch as k, computed as M, ref as C } from "vue";
2
+ class P extends Error {
6
3
  constructor(t, e) {
7
4
  super(e.cause.message), this.actionName = t, this.options = e, this.name = this.constructor.name;
8
5
  }
@@ -16,42 +13,52 @@ class O extends Error {
16
13
  return this.options.cause.message;
17
14
  }
18
15
  }
19
- class u extends Error {
16
+ class h extends Error {
20
17
  constructor(t, e) {
21
18
  super(t, e), this.message = t, this.options = e, this.name = this.constructor.name;
22
19
  }
23
20
  }
24
- class b extends u {
25
- constructor(t, e, o) {
26
- super(`Trying to update state of ${t} from ${e} to ${o}`), this.name = this.constructor.name;
21
+ class d extends h {
22
+ constructor(t, e, r) {
23
+ super(`Trying to update state of ${t} from ${e} to ${r}`), this.name = this.constructor.name;
27
24
  }
28
25
  }
29
- class j extends u {
26
+ class R extends h {
30
27
  constructor(t, e) {
31
28
  super(`Unexpected AbortError for the action ${t} in state ${e}`), this.name = this.constructor.name;
32
29
  }
33
30
  }
34
- const z = (r) => r instanceof DOMException && r.name === "AbortError" || typeof r == "object" && r !== null && "message" in r && r.message === "canceled", s = class s {
35
- constructor(t, e, o, c, h) {
36
- i(this, "name");
37
- i(this, "_state", s.possibleState.ready);
38
- i(this, "_value", null);
39
- i(this, "_args", null);
40
- this._model = t, this.actionFunction = e, this.ownerGetter = o, this.setStateCb = c, this._validateArgs = h;
41
- const n = e.name;
42
- if (!(n in this._model && typeof this._model[n] == "function"))
43
- throw new u(`Model does not contain method ${n}`);
31
+ const x = (a) => a instanceof DOMException && a.name === "AbortError" || typeof a == "object" && a !== null && "message" in a && a.message === "canceled";
32
+ class s {
33
+ constructor(t, e, r, i, c) {
34
+ this._model = t, this.actionFunction = e, this.ownerGetter = r, this.setStateCb = i, this._validateArgs = c;
35
+ const o = e.name;
36
+ if (!(o in this._model && typeof this._model[o] == "function"))
37
+ throw new h(`Model does not contain method ${o}`);
44
38
  if (typeof e[s.actionFlag] != "function")
45
- throw new u(`Method ${n} is not action`);
46
- this.name = n;
47
- }
48
- static create(t, e, o, c, h) {
49
- return F(new s(
39
+ throw new h(`Method ${o} is not action`);
40
+ this.name = o;
41
+ }
42
+ static actionFlag = /* @__PURE__ */ Symbol("__action_original_method__");
43
+ static possibleState = {
44
+ pending: "pending",
45
+ error: "error",
46
+ lock: "lock",
47
+ ready: "ready",
48
+ abort: "abort"
49
+ };
50
+ static abortedByLock = /* @__PURE__ */ Symbol("lock");
51
+ name;
52
+ _state = s.possibleState.ready;
53
+ _value = null;
54
+ _args = null;
55
+ static create(t, e, r, i, c) {
56
+ return y(new s(
50
57
  t,
51
58
  e,
52
- o,
53
- c,
54
- h
59
+ r,
60
+ i,
61
+ c
55
62
  ));
56
63
  }
57
64
  toString() {
@@ -73,9 +80,8 @@ const z = (r) => r instanceof DOMException && r.name === "AbortError" || typeof
73
80
  get abortController() {
74
81
  return this.isPending ? this._value.abortController : null;
75
82
  }
76
- // TODO: add tests
77
83
  get args() {
78
- return this._args || [];
84
+ return this._args ?? [];
79
85
  }
80
86
  get promise() {
81
87
  return this.isPending ? this._value.promise : null;
@@ -102,7 +108,7 @@ const z = (r) => r instanceof DOMException && r.name === "AbortError" || typeof
102
108
  return this.state === s.possibleState.abort;
103
109
  }
104
110
  is(...t) {
105
- return !!t.find((e) => this.state === e);
111
+ return t.includes(this.state);
106
112
  }
107
113
  validate(...t) {
108
114
  return this._validateArgs(this, ...t);
@@ -112,39 +118,39 @@ const z = (r) => r instanceof DOMException && r.name === "AbortError" || typeof
112
118
  */
113
119
  exec(...t) {
114
120
  if (this.is(s.possibleState.lock, s.possibleState.pending))
115
- throw new b(
121
+ throw new d(
116
122
  this.name,
117
123
  this.state,
118
124
  s.possibleState.pending
119
125
  );
120
126
  const e = [...t];
121
- let o = t.length && t[t.length - 1];
122
- o instanceof AbortController || (o = new AbortController(), e.push(o)), this.state = s.possibleState.pending, this._args = t;
123
- const h = this.actionFunction[s.actionFlag].apply(this._model, e);
124
- if (!(h instanceof Promise))
127
+ let r = t.length && t.at(-1);
128
+ r instanceof AbortController || (r = new AbortController(), e.push(r)), this.state = s.possibleState.pending, this._args = t;
129
+ const c = this.actionFunction[s.actionFlag].apply(this._model, e);
130
+ if (!(c instanceof Promise))
125
131
  return this.state = s.possibleState.ready, Promise.resolve();
126
- const n = h.then(() => {
132
+ const o = c.then(() => {
127
133
  this.ready();
128
- }).catch((a) => {
129
- if (a instanceof u || a instanceof RangeError || a instanceof ReferenceError || a instanceof SyntaxError || a instanceof TypeError || a instanceof URIError || a instanceof EvalError)
130
- throw a;
131
- const S = z(a);
132
- if (S && !this.is(s.possibleState.pending, s.possibleState.lock))
133
- throw new j(this.name, this.state);
134
- if (S && this._value.abortController instanceof AbortController && this._value.abortController.signal.reason === s.abortedByLock) {
134
+ }).catch((n) => {
135
+ if (n instanceof h || n instanceof RangeError || n instanceof ReferenceError || n instanceof SyntaxError || n instanceof TypeError || n instanceof URIError || n instanceof EvalError)
136
+ throw n;
137
+ const m = x(n);
138
+ if (m && !this.is(s.possibleState.pending, s.possibleState.lock))
139
+ throw new R(this.name, this.state);
140
+ if (m && this._value.abortController instanceof AbortController && this._value.abortController.signal.reason === s.abortedByLock) {
135
141
  this.state = s.possibleState.lock, this._value = null;
136
142
  return;
137
143
  }
138
- if (S) {
144
+ if (m) {
139
145
  this.state = s.possibleState.abort;
140
146
  return;
141
147
  }
142
- this.setError(new O(this.name, { cause: a }));
148
+ this.setError(new P(this.name, { cause: n }));
143
149
  });
144
150
  return this._value = {
145
- promise: n,
146
- abortController: o
147
- }, n;
151
+ promise: o,
152
+ abortController: r
153
+ }, o;
148
154
  }
149
155
  // Returns same promise as exec method
150
156
  // but in reject state
@@ -157,7 +163,7 @@ const z = (r) => r instanceof DOMException && r.name === "AbortError" || typeof
157
163
  }
158
164
  unlock() {
159
165
  if (!this.isLock)
160
- throw new b(
166
+ throw new d(
161
167
  this.name,
162
168
  this.state,
163
169
  s.possibleState.ready
@@ -166,7 +172,7 @@ const z = (r) => r instanceof DOMException && r.name === "AbortError" || typeof
166
172
  }
167
173
  setError(t) {
168
174
  if (!this.isPending)
169
- throw new b(
175
+ throw new d(
170
176
  this.name,
171
177
  this.state,
172
178
  s.possibleState.error
@@ -178,39 +184,27 @@ const z = (r) => r instanceof DOMException && r.name === "AbortError" || typeof
178
184
  }
179
185
  resetError() {
180
186
  if (!this.error)
181
- throw new b(
187
+ throw new d(
182
188
  this.name,
183
189
  this.state,
184
190
  s.possibleState.ready
185
191
  );
186
192
  return this.ready();
187
193
  }
188
- };
189
- i(s, "actionFlag", Symbol("__action_original_method__")), i(s, "possibleState", {
190
- pending: "pending",
191
- error: "error",
192
- lock: "lock",
193
- ready: "ready",
194
- abort: "abort"
195
- }), i(s, "abortedByLock", Symbol("lock"));
196
- let l = s;
197
- const d = Symbol("scope"), m = Symbol("model"), w = Symbol("actions"), y = Symbol("actionIds"), g = Symbol("actionStates"), A = Symbol("actionsSize"), p = Symbol("watchStopHandlers"), G = Proxy;
198
- var E, k, M, P, C, R, x;
199
- x = d, R = m, C = w, P = y, M = g, k = A, E = p;
200
- const f = class f {
201
- constructor() {
202
- // each model has its own effect scope to avoid memory leaks
203
- i(this, x, L(!0));
204
- i(this, R, null);
205
- // we use WeakMap to store actions as keys to avoid memory leaks
206
- i(this, C, /* @__PURE__ */ new WeakMap());
207
- i(this, P, /* @__PURE__ */ new WeakMap());
208
- i(this, M, /* @__PURE__ */ new Map());
209
- // WeakMap doesn't have a size property, so we need to store the size of the map
210
- i(this, k, 0);
211
- // watchers are stored in a set to avoid memory leaks
212
- i(this, E, /* @__PURE__ */ new Set());
213
- }
194
+ }
195
+ const l = /* @__PURE__ */ Symbol("scope"), p = /* @__PURE__ */ Symbol("model"), g = /* @__PURE__ */ Symbol("actions"), S = /* @__PURE__ */ Symbol("actionIds"), f = /* @__PURE__ */ Symbol("actionStates"), w = /* @__PURE__ */ Symbol("actionsSize"), u = /* @__PURE__ */ Symbol("watchStopHandlers"), F = Proxy;
196
+ class b {
197
+ // each model has its own effect scope to avoid memory leaks
198
+ [l] = A(!0);
199
+ [p] = null;
200
+ // we use WeakMap to store actions as keys to avoid memory leaks
201
+ [g] = /* @__PURE__ */ new WeakMap();
202
+ [S] = /* @__PURE__ */ new WeakMap();
203
+ [f] = /* @__PURE__ */ new Map();
204
+ // WeakMap doesn't have a size property, so we need to store the size of the map
205
+ [w] = 0;
206
+ // watchers are stored in a set to avoid memory leaks
207
+ [u] = /* @__PURE__ */ new Set();
214
208
  /**
215
209
  * Wraps ProtoModel instance with proxy to handle get traps for actions
216
210
  * and to return Action instance instead of original method.
@@ -236,18 +230,18 @@ const f = class f {
236
230
  * @returns model instance wrapped with proxy.
237
231
  */
238
232
  static createModel(t) {
239
- if (!(t instanceof f))
240
- throw new Error("ProtoModel instance is required");
241
- const e = new G(
242
- F(t),
233
+ if (!(t instanceof b))
234
+ throw new TypeError("ProtoModel instance is required");
235
+ const e = new F(
236
+ y(t),
243
237
  {
244
- get(o, c, h) {
245
- const n = Reflect.get(o, c, h), a = typeof n == "function";
246
- return a && l.actionFlag in n && typeof n[l.actionFlag] == "function" ? o.action(n) : a ? n.bind(o) : n;
238
+ get(r, i, c) {
239
+ const o = Reflect.get(r, i, c), n = typeof o == "function";
240
+ return n && s.actionFlag in o && typeof o[s.actionFlag] == "function" ? r.action(o) : n ? o.bind(r) : o;
247
241
  }
248
242
  }
249
243
  );
250
- return t[m] = e, e;
244
+ return t[p] = e, e;
251
245
  }
252
246
  /**
253
247
  * Creates a model instance.
@@ -256,16 +250,16 @@ const f = class f {
256
250
  * @returns model instance.
257
251
  */
258
252
  static model(...t) {
259
- if (this.prototype === f.prototype)
253
+ if (this.prototype === b.prototype)
260
254
  throw new Error("ProtoModel is abstract class and can not be instantiated");
261
255
  const e = new this(...t);
262
- return f.createModel(e);
256
+ return b.createModel(e);
263
257
  }
264
258
  get hasPendingActions() {
265
- return !!this.getActionStatesRef(l.possibleState.pending).value;
259
+ return !!this.getActionStatesRef(s.possibleState.pending).value;
266
260
  }
267
261
  get hasActionWithError() {
268
- return !!this.getActionStatesRef(l.possibleState.error).value;
262
+ return !!this.getActionStatesRef(s.possibleState.error).value;
269
263
  }
270
264
  /**
271
265
  * Registers watcher in the model effect scope.
@@ -326,38 +320,38 @@ const f = class f {
326
320
  watch(...t) {
327
321
  if (t.length === 0)
328
322
  throw new Error("watch requires at least one argument");
329
- const e = t.length === 1 ? this[d].run(() => B(t[0])) : this[d].run(() => D(...t));
323
+ const e = t.length === 1 ? this[l].run(() => E(t[0])) : this[l].run(() => k(...t));
330
324
  if (!e)
331
325
  throw new Error("watchStopHandler is undefined");
332
- return this[p].add(e), () => {
333
- e(), this[p].delete(e);
326
+ return this[u].add(e), () => {
327
+ e(), this[u].delete(e);
334
328
  };
335
329
  }
336
330
  computed(t, e) {
337
- return this[d].run(() => T(t, e));
331
+ return this[l].run(() => M(t, e));
338
332
  }
339
333
  // @see https://github.com/trekhleb/javascript-algorithms/blob/master/src/algorithms/math/bits/updateBit.js
340
- updateBit(t, e, o) {
341
- const c = o ? 1 : 0, h = ~(1 << e);
342
- return t & h | c << e;
334
+ updateBit(t, e, r) {
335
+ const i = r ? 1 : 0, c = ~(1 << e);
336
+ return t & c | i << e;
343
337
  }
344
338
  createAction(t) {
345
339
  const e = () => {
346
- if (!this[m])
340
+ if (!this[p])
347
341
  throw new Error("Model not set");
348
- return this[m];
349
- }, o = l.create(
342
+ return this[p];
343
+ }, r = s.create(
350
344
  this,
351
345
  t,
352
346
  e,
353
347
  this.setActionState.bind(this),
354
348
  this.validateArgs.bind(this)
355
349
  );
356
- return this[w].set(t, o), this[y].set(o, ++this[A]), this.setActionState(o), o;
350
+ return this[g].set(t, r), this[S].set(r, ++this[w]), this.setActionState(r), r;
357
351
  }
358
352
  getActionStatesRef(t) {
359
- const e = this[g].get(t) || H(0);
360
- return this[g].get(t) === void 0 && this[g].set(t, e), e;
353
+ const e = this[f].get(t) || C(0);
354
+ return this[f].get(t) === void 0 && this[f].set(t, e), e;
361
355
  }
362
356
  /**
363
357
  * Gets Action instance by wrapped original method or create Action instance.
@@ -403,9 +397,9 @@ const f = class f {
403
397
  * @returns action
404
398
  */
405
399
  action(t) {
406
- if (!(l.actionFlag in t && typeof t[l.actionFlag] == "function"))
407
- throw new u("Action decorator is not applied to the method");
408
- return this[w].get(t) || this.createAction(t);
400
+ if (!(s.actionFlag in t && typeof t[s.actionFlag] == "function"))
401
+ throw new h("Action decorator is not applied to the method");
402
+ return this[g].get(t) || this.createAction(t);
409
403
  }
410
404
  /**
411
405
  * It is public method in context ProtoModel,
@@ -414,29 +408,28 @@ const f = class f {
414
408
  * @see type Model<T>
415
409
  */
416
410
  setActionState(t) {
417
- const e = this[y].get(t);
411
+ const e = this[S].get(t);
418
412
  if (!e)
419
413
  throw new Error("Action not found");
420
- for (const o of t.possibleStates)
421
- o !== t.state && (this.getActionStatesRef(o).value = this.updateBit(this.getActionStatesRef(o).value, e, !1));
414
+ for (const r of t.possibleStates)
415
+ r !== t.state && (this.getActionStatesRef(r).value = this.updateBit(this.getActionStatesRef(r).value, e, !1));
422
416
  this.getActionStatesRef(t.state).value = this.updateBit(this.getActionStatesRef(t.state).value, e, !0);
423
417
  }
424
418
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
425
419
  validateArgs(t, ...e) {
426
- const o = `validateArgs is not implemented for action ${t.name} in the model`;
427
- return [new Error(o)];
420
+ const r = `validateArgs is not implemented for action ${t.name} in the model`;
421
+ return [new Error(r)];
428
422
  }
429
423
  isModelOf(t) {
430
424
  return this instanceof t;
431
425
  }
432
426
  destructor() {
433
- this[p].forEach((t) => {
427
+ this[u].forEach((t) => {
434
428
  t();
435
- }), this[p] = /* @__PURE__ */ new Set(), this[d].stop();
429
+ }), this[u] = /* @__PURE__ */ new Set(), this[l].stop();
436
430
  }
437
- };
438
- let v = f;
439
- function N(r, t) {
431
+ }
432
+ function K(a, t) {
440
433
  if (t.static)
441
434
  throw new Error("Action decorator is not supported for static methods");
442
435
  if (t.private)
@@ -444,26 +437,26 @@ function N(r, t) {
444
437
  let e;
445
438
  try {
446
439
  e = t.name.toString();
447
- } catch (c) {
448
- const n = `Invalid context. Can\`t get name of the method: ${c instanceof Error ? c.message : "unknown error"}`;
449
- throw new Error(n);
440
+ } catch (i) {
441
+ const o = `Invalid context. Can\`t get name of the method: ${i instanceof Error ? i.message : "unknown error"}`;
442
+ throw new Error(o);
450
443
  }
451
- const o = {
444
+ const r = {
452
445
  // Action constructor checks that model has method with the same name.
453
446
  // We can`t define anonymous function and change name because Function.name is readonly property.
454
447
  // So we need to create stub object to save original method name
455
- [e]: function(...c) {
456
- return this.action(o[e]).exec(...c);
448
+ [e]: function(...i) {
449
+ return this.action(r[e]).exec(...i);
457
450
  }
458
451
  };
459
- return o[e][l.actionFlag] = r, o[e];
452
+ return r[e][s.actionFlag] = a, r[e];
460
453
  }
461
454
  export {
462
- l as Action,
463
- O as ActionError,
464
- u as ActionInternalError,
465
- b as ActionStatusConflictError,
466
- j as ActionUnexpectedAbortError,
467
- v as ProtoModel,
468
- N as action
455
+ s as Action,
456
+ P as ActionError,
457
+ h as ActionInternalError,
458
+ d as ActionStatusConflictError,
459
+ R as ActionUnexpectedAbortError,
460
+ b as ProtoModel,
461
+ K as action
469
462
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@vue-modeler/model",
4
- "version": "2.2.4",
4
+ "version": "2.2.5-beta.2",
5
5
  "description": "A state management library based on models for Vue.js",
6
6
  "author": "abratko",
7
7
  "license": "MIT",
@@ -21,30 +21,31 @@
21
21
  "access": "public"
22
22
  },
23
23
  "devDependencies": {
24
- "@eslint/js": "^9.23.0",
24
+ "@eslint/js": "^9.39.2",
25
25
  "@semantic-release/changelog": "^6.0.3",
26
26
  "@semantic-release/git": "^10.0.1",
27
- "@types/eslint__js": "^8.42.3",
28
- "@types/node": "^22.14.0",
29
- "@vitest/coverage-v8": "2.1.3",
30
- "@vue/test-utils": "^1.3.6",
27
+ "@types/node": "^25.0.3",
28
+ "@vitest/coverage-v8": "4.0.16",
29
+ "@vue/test-utils": "^2.4.6",
31
30
  "conventional-changelog-conventionalcommits": "^9.1.0",
32
- "eslint": "^9.23.0",
33
- "eslint-scope": "^8.3.0",
34
- "eslint-visitor-keys": "^4.2.0",
35
- "jsdom": "^25.0.1",
36
- "semantic-release": "^24.2.3",
37
- "typescript": "^5.8.2",
38
- "typescript-eslint": "^8.29.0",
39
- "vite": "^5.4.16",
40
- "vite-plugin-dts": "^4.5.3",
41
- "vitest": "^2.1.9"
31
+ "eslint": "^9.39.2",
32
+ "eslint-scope": "^9.0.0",
33
+ "eslint-visitor-keys": "^5.0.0",
34
+ "jsdom": "^27.4.0",
35
+ "semantic-release": "^25.0.2",
36
+ "typescript": "^5.9.3",
37
+ "typescript-eslint": "^8.51.0",
38
+ "vite": "^7.3.0",
39
+ "vite-plugin-dts": "^4.5.4",
40
+ "vitest": "^4.0.16",
41
+ "vue": ">=2.7 <4.0.0"
42
42
  },
43
43
  "peerDependencies": {
44
44
  "vue": ">=2.7 <4.0.0"
45
45
  },
46
46
  "scripts": {
47
47
  "build": "tsc && vite build",
48
+ "lint": "eslint .",
48
49
  "test": "tsc --noEmit && vitest",
49
50
  "coverage": "vitest run --coverage",
50
51
  "semantic-release": "semantic-release"