@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 +2 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +123 -130
- package/package.json +17 -16
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# vue-modeler/model
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@vue-modeler/model) [](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";
|
|
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
|
-
|
|
2
|
-
|
|
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
|
|
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
|
|
25
|
-
constructor(t, e,
|
|
26
|
-
super(`Trying to update state of ${t} from ${e} to ${
|
|
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
|
|
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
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
|
46
|
-
this.name =
|
|
47
|
-
}
|
|
48
|
-
static
|
|
49
|
-
|
|
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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
|
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
|
|
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
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
if (!(
|
|
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
|
|
132
|
+
const o = c.then(() => {
|
|
127
133
|
this.ready();
|
|
128
|
-
}).catch((
|
|
129
|
-
if (
|
|
130
|
-
throw
|
|
131
|
-
const
|
|
132
|
-
if (
|
|
133
|
-
throw new
|
|
134
|
-
if (
|
|
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 (
|
|
144
|
+
if (m) {
|
|
139
145
|
this.state = s.possibleState.abort;
|
|
140
146
|
return;
|
|
141
147
|
}
|
|
142
|
-
this.setError(new
|
|
148
|
+
this.setError(new P(this.name, { cause: n }));
|
|
143
149
|
});
|
|
144
150
|
return this._value = {
|
|
145
|
-
promise:
|
|
146
|
-
abortController:
|
|
147
|
-
},
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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
|
|
240
|
-
throw new
|
|
241
|
-
const e = new
|
|
242
|
-
|
|
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(
|
|
245
|
-
const
|
|
246
|
-
return
|
|
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[
|
|
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 ===
|
|
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
|
|
256
|
+
return b.createModel(e);
|
|
263
257
|
}
|
|
264
258
|
get hasPendingActions() {
|
|
265
|
-
return !!this.getActionStatesRef(
|
|
259
|
+
return !!this.getActionStatesRef(s.possibleState.pending).value;
|
|
266
260
|
}
|
|
267
261
|
get hasActionWithError() {
|
|
268
|
-
return !!this.getActionStatesRef(
|
|
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[
|
|
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[
|
|
333
|
-
e(), this[
|
|
326
|
+
return this[u].add(e), () => {
|
|
327
|
+
e(), this[u].delete(e);
|
|
334
328
|
};
|
|
335
329
|
}
|
|
336
330
|
computed(t, e) {
|
|
337
|
-
return this[
|
|
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,
|
|
341
|
-
const
|
|
342
|
-
return t &
|
|
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[
|
|
340
|
+
if (!this[p])
|
|
347
341
|
throw new Error("Model not set");
|
|
348
|
-
return this[
|
|
349
|
-
},
|
|
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[
|
|
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[
|
|
360
|
-
return this[
|
|
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 (!(
|
|
407
|
-
throw new
|
|
408
|
-
return this[
|
|
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[
|
|
411
|
+
const e = this[S].get(t);
|
|
418
412
|
if (!e)
|
|
419
413
|
throw new Error("Action not found");
|
|
420
|
-
for (const
|
|
421
|
-
|
|
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
|
|
427
|
-
return [new Error(
|
|
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[
|
|
427
|
+
this[u].forEach((t) => {
|
|
434
428
|
t();
|
|
435
|
-
}), this[
|
|
429
|
+
}), this[u] = /* @__PURE__ */ new Set(), this[l].stop();
|
|
436
430
|
}
|
|
437
|
-
}
|
|
438
|
-
|
|
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 (
|
|
448
|
-
const
|
|
449
|
-
throw new Error(
|
|
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
|
|
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(...
|
|
456
|
-
return this.action(
|
|
448
|
+
[e]: function(...i) {
|
|
449
|
+
return this.action(r[e]).exec(...i);
|
|
457
450
|
}
|
|
458
451
|
};
|
|
459
|
-
return
|
|
452
|
+
return r[e][s.actionFlag] = a, r[e];
|
|
460
453
|
}
|
|
461
454
|
export {
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
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
|
+
"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.
|
|
24
|
+
"@eslint/js": "^9.39.2",
|
|
25
25
|
"@semantic-release/changelog": "^6.0.3",
|
|
26
26
|
"@semantic-release/git": "^10.0.1",
|
|
27
|
-
"@types/
|
|
28
|
-
"@
|
|
29
|
-
"@
|
|
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.
|
|
33
|
-
"eslint-scope": "^
|
|
34
|
-
"eslint-visitor-keys": "^
|
|
35
|
-
"jsdom": "^
|
|
36
|
-
"semantic-release": "^
|
|
37
|
-
"typescript": "^5.
|
|
38
|
-
"typescript-eslint": "^8.
|
|
39
|
-
"vite": "^
|
|
40
|
-
"vite-plugin-dts": "^4.5.
|
|
41
|
-
"vitest": "^
|
|
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"
|