@vue-modeler/model 2.0.1-beta.1 → 2.1.0-beta.1
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/dist/index.cjs +1 -1
- package/dist/index.d.ts +28 -0
- package/dist/index.js +39 -37
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var m=Object.defineProperty;var A=(r,t,e)=>t in r?m(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e;var n=(r,t,e)=>A(r,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("vue");class w 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 u extends Error{constructor(t,e){super(t,e),this.message=t,this.options=e,this.name=this.constructor.name}}class p extends u{constructor(t,e,o){super(`Trying to update state of ${t} from ${e} to ${o}`),this.name=this.constructor.name}}class g extends u{constructor(t,e){super(`Unexpected AbortError for the action ${t} in state ${e}`),this.name=this.constructor.name}}const y=r=>r instanceof DOMException&&r.name==="AbortError"||typeof r=="object"&&r!==null&&"message"in r&&r.message==="canceled",s=class s{constructor(t,e){n(this,"name");n(this,"_state",s.possibleState.ready);n(this,"_value",null);n(this,"_args",null);this.model=t,this.actionFunction=e;const o=e.name;if(!(o in t&&typeof t[o]=="function"))throw new u(`Model does not contain method ${o}`);if(typeof e[s.actionFlag]!="function")throw new u(`Method ${o} is not action`);this.name=o}toString(){return this.name}get possibleStates(){return Object.values(s.possibleState)}get state(){return this._state}set state(t){this._state=t,this.model.setActionState(this)}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)}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 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 i=this.actionFunction[s.actionFlag].apply(this.model,e);if(!(i instanceof Promise))return this.state=s.possibleState.ready,Promise.resolve();const d=i.then(()=>{this.ready()}).catch(a=>{if(a instanceof u||a instanceof RangeError||a instanceof ReferenceError||a instanceof SyntaxError||a instanceof TypeError||a instanceof URIError||a instanceof EvalError)throw a;const S=y(a);if(S&&!this.is(s.possibleState.pending,s.possibleState.lock))throw new g(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 w(this.name,{cause:a}))});return this._value={promise:d,abortController:o},d}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()}};n(s,"actionFlag",Symbol("__action_original_method__")),n(s,"possibleState",{pending:"pending",error:"error",lock:"lock",ready:"ready",abort:"abort"}),n(s,"abortedByLock",Symbol("lock"));let c=s;const v=Proxy;function E(r){if(!(r instanceof b))throw new Error("ProtoModel instance is required");return new v(l.shallowReactive(r),{get(e,o,h){const i=Reflect.get(e,o,h),d=typeof i=="function";return d&&c.actionFlag in i&&typeof i[c.actionFlag]=="function"?e.action(i):d?i.bind(e):i}})}const f=class f{constructor(){n(this,"_effectScope",l.effectScope(!0));n(this,"_actions",new WeakMap);n(this,"_actionIds",new WeakMap);n(this,"_actionStates",new Map);n(this,"_actionsSize",0);n(this,"_watchStopHandlers",new Set)}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(c.possibleState.pending).value}get hasActionWithError(){return!!this.getActionStatesRef(c.possibleState.error).value}watch(...t){if(t.length===0)throw new Error("watch requires at least one argument");const e=t.length===1?this._effectScope.run(()=>l.watchEffect(t[0])):this._effectScope.run(()=>l.watch(...t));if(!e)throw new Error("watchStopHandler is undefined");return this._watchStopHandlers.add(e),e}computed(t,e){return this._effectScope.run(()=>l.computed(t,e))}updateBit(t,e,o){const h=o?1:0,i=~(1<<e);return t&i|h<<e}createAction(t){const e=l.shallowReactive(new c(this,t));return this._actions.set(t,e),this._actionIds.set(e,++this._actionsSize),this.setActionState(e),e}getActionStatesRef(t){const e=this._actionStates.get(t)||l.ref(0);return this._actionStates.get(t)===void 0&&this._actionStates.set(t,e),e}action(t){if(!(c.actionFlag in t&&typeof t[c.actionFlag]=="function"))throw new u("Action decorator is not applied to the method");return this._actions.get(t)||this.createAction(t)}setActionState(t){const e=this._actionIds.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)}isModelOf(t){return this instanceof t}destructor(){this._watchStopHandlers.forEach(t=>{t()}),this._watchStopHandlers=new Set,this._effectScope.stop()}};n(f,"createModel",E);let b=f;function k(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");const e=t.name.toString(),o={[e]:function(...h){return this.action(o[e]).exec(...h)}};return o[e][c.actionFlag]=r,o[e]}exports.ActionError=w;exports.ActionInternalError=u;exports.ActionStatusConflictError=p;exports.ActionUnexpectedAbortError=g;exports.ProtoModel=b;exports.action=k;
|
package/dist/index.d.ts
CHANGED
|
@@ -110,6 +110,33 @@ export declare class ActionUnexpectedAbortError extends ActionInternalError {
|
|
|
110
110
|
|
|
111
111
|
declare type ActionValue = ActionPendingValue | ActionError | null;
|
|
112
112
|
|
|
113
|
+
/**
|
|
114
|
+
* Wraps ProtoModel instance with proxy to handle get traps for actions
|
|
115
|
+
* and to return Action instance instead of original method.
|
|
116
|
+
*
|
|
117
|
+
* ```ts
|
|
118
|
+
* class TestModel extends ProtoModel {
|
|
119
|
+
* constructor() {
|
|
120
|
+
* super()
|
|
121
|
+
* }
|
|
122
|
+
*
|
|
123
|
+
* @action async someAction(): Promise<void> {
|
|
124
|
+
* return Promise.resolve()
|
|
125
|
+
* }
|
|
126
|
+
* }
|
|
127
|
+
*
|
|
128
|
+
* const model = createModel(new TestModel())
|
|
129
|
+
* const action = model.someAction // will return Action instance instead of original method
|
|
130
|
+
* model.someAction.exec() // will execute action
|
|
131
|
+
* model.someAction.isPending // will return true if action is pending
|
|
132
|
+
* model.someAction.error // will return error if action is errored
|
|
133
|
+
* ```
|
|
134
|
+
* @param protoModel - ProtoModel instance.
|
|
135
|
+
* @returns model instance wrapped with proxy.
|
|
136
|
+
* @see src/proto-model.ts
|
|
137
|
+
*/
|
|
138
|
+
declare function createModel<Target extends ProtoModel>(protoModel: Target): Model<Target>;
|
|
139
|
+
|
|
113
140
|
export declare type Model<T> = {
|
|
114
141
|
[K in keyof T]: T[K] extends ((...args: infer Args) => Promise<void>) ? Action<Args> : K extends ProtectedMethodInModel ? never : T[K];
|
|
115
142
|
};
|
|
@@ -136,6 +163,7 @@ export declare abstract class ProtoModel {
|
|
|
136
163
|
protected _actionStates: Map<"error" | "abort" | "lock" | "pending" | "ready", Ref<number>>;
|
|
137
164
|
protected _actionsSize: number;
|
|
138
165
|
protected _watchStopHandlers: Set<WatchStopHandle>;
|
|
166
|
+
protected static createModel: typeof createModel;
|
|
139
167
|
/**
|
|
140
168
|
* Creates a model instance.
|
|
141
169
|
*
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var n = (r, t, e) =>
|
|
4
|
-
import { shallowReactive as
|
|
5
|
-
class
|
|
1
|
+
var w = Object.defineProperty;
|
|
2
|
+
var m = (r, t, e) => t in r ? w(r, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : r[t] = e;
|
|
3
|
+
var n = (r, t, e) => m(r, typeof t != "symbol" ? t + "" : t, e);
|
|
4
|
+
import { shallowReactive as S, effectScope as g, watchEffect as A, watch as y, computed as v, ref as k } from "vue";
|
|
5
|
+
class E extends Error {
|
|
6
6
|
constructor(t, e) {
|
|
7
7
|
super(e.cause.message), this.actionName = t, this.options = e, this.name = this.constructor.name;
|
|
8
8
|
}
|
|
@@ -21,12 +21,12 @@ class l extends Error {
|
|
|
21
21
|
super(t, e), this.message = t, this.options = e, this.name = this.constructor.name;
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
-
class
|
|
24
|
+
class d extends l {
|
|
25
25
|
constructor(t, e, o) {
|
|
26
26
|
super(`Trying to update state of ${t} from ${e} to ${o}`), this.name = this.constructor.name;
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
-
class
|
|
29
|
+
class M extends l {
|
|
30
30
|
constructor(t, e) {
|
|
31
31
|
super(`Unexpected AbortError for the action ${t} in state ${e}`), this.name = this.constructor.name;
|
|
32
32
|
}
|
|
@@ -96,7 +96,7 @@ const P = (r) => r instanceof DOMException && r.name === "AbortError" || typeof
|
|
|
96
96
|
*/
|
|
97
97
|
exec(...t) {
|
|
98
98
|
if (this.is(s.possibleState.lock, s.possibleState.pending))
|
|
99
|
-
throw new
|
|
99
|
+
throw new d(
|
|
100
100
|
this.name,
|
|
101
101
|
this.state,
|
|
102
102
|
s.possibleState.pending
|
|
@@ -112,18 +112,18 @@ const P = (r) => r instanceof DOMException && r.name === "AbortError" || typeof
|
|
|
112
112
|
}).catch((a) => {
|
|
113
113
|
if (a instanceof l || a instanceof RangeError || a instanceof ReferenceError || a instanceof SyntaxError || a instanceof TypeError || a instanceof URIError || a instanceof EvalError)
|
|
114
114
|
throw a;
|
|
115
|
-
const
|
|
116
|
-
if (
|
|
117
|
-
throw new
|
|
118
|
-
if (
|
|
115
|
+
const f = P(a);
|
|
116
|
+
if (f && !this.is(s.possibleState.pending, s.possibleState.lock))
|
|
117
|
+
throw new M(this.name, this.state);
|
|
118
|
+
if (f && this._value.abortController instanceof AbortController && this._value.abortController.signal.reason === s.abortedByLock) {
|
|
119
119
|
this.state = s.possibleState.lock, this._value = null;
|
|
120
120
|
return;
|
|
121
121
|
}
|
|
122
|
-
if (
|
|
122
|
+
if (f) {
|
|
123
123
|
this.state = s.possibleState.abort;
|
|
124
124
|
return;
|
|
125
125
|
}
|
|
126
|
-
this.setError(new
|
|
126
|
+
this.setError(new E(this.name, { cause: a }));
|
|
127
127
|
});
|
|
128
128
|
return this._value = {
|
|
129
129
|
promise: u,
|
|
@@ -141,7 +141,7 @@ const P = (r) => r instanceof DOMException && r.name === "AbortError" || typeof
|
|
|
141
141
|
}
|
|
142
142
|
unlock() {
|
|
143
143
|
if (!this.isLock)
|
|
144
|
-
throw new
|
|
144
|
+
throw new d(
|
|
145
145
|
this.name,
|
|
146
146
|
this.state,
|
|
147
147
|
s.possibleState.ready
|
|
@@ -150,7 +150,7 @@ const P = (r) => r instanceof DOMException && r.name === "AbortError" || typeof
|
|
|
150
150
|
}
|
|
151
151
|
setError(t) {
|
|
152
152
|
if (!this.isPending)
|
|
153
|
-
throw new
|
|
153
|
+
throw new d(
|
|
154
154
|
this.name,
|
|
155
155
|
this.state,
|
|
156
156
|
s.possibleState.error
|
|
@@ -162,7 +162,7 @@ const P = (r) => r instanceof DOMException && r.name === "AbortError" || typeof
|
|
|
162
162
|
}
|
|
163
163
|
resetError() {
|
|
164
164
|
if (!this.error)
|
|
165
|
-
throw new
|
|
165
|
+
throw new d(
|
|
166
166
|
this.name,
|
|
167
167
|
this.state,
|
|
168
168
|
s.possibleState.ready
|
|
@@ -178,12 +178,12 @@ n(s, "actionFlag", Symbol("__action_original_method__")), n(s, "possibleState",
|
|
|
178
178
|
abort: "abort"
|
|
179
179
|
}), n(s, "abortedByLock", Symbol("lock"));
|
|
180
180
|
let c = s;
|
|
181
|
-
const
|
|
182
|
-
function
|
|
183
|
-
if (!(r instanceof
|
|
181
|
+
const R = Proxy;
|
|
182
|
+
function _(r) {
|
|
183
|
+
if (!(r instanceof b))
|
|
184
184
|
throw new Error("ProtoModel instance is required");
|
|
185
|
-
return new
|
|
186
|
-
|
|
185
|
+
return new R(
|
|
186
|
+
S(r),
|
|
187
187
|
{
|
|
188
188
|
get(e, o, h) {
|
|
189
189
|
const i = Reflect.get(e, o, h), u = typeof i == "function";
|
|
@@ -192,10 +192,10 @@ function M(r) {
|
|
|
192
192
|
}
|
|
193
193
|
);
|
|
194
194
|
}
|
|
195
|
-
class
|
|
195
|
+
const p = class p {
|
|
196
196
|
constructor() {
|
|
197
197
|
// each model has its own effect scope to avoid memory leaks
|
|
198
|
-
n(this, "_effectScope",
|
|
198
|
+
n(this, "_effectScope", g(!0));
|
|
199
199
|
// we use WeakMap to store actions as keys to avoid memory leaks
|
|
200
200
|
n(this, "_actions", /* @__PURE__ */ new WeakMap());
|
|
201
201
|
n(this, "_actionIds", /* @__PURE__ */ new WeakMap());
|
|
@@ -213,10 +213,10 @@ class f {
|
|
|
213
213
|
* @see src/create-model.ts
|
|
214
214
|
*/
|
|
215
215
|
static model(...t) {
|
|
216
|
-
if (this.prototype ===
|
|
216
|
+
if (this.prototype === p.prototype)
|
|
217
217
|
throw new Error("ProtoModel is abstract class and can not be instantiated");
|
|
218
218
|
const e = new this(...t);
|
|
219
|
-
return
|
|
219
|
+
return p.createModel(e);
|
|
220
220
|
}
|
|
221
221
|
get hasPendingActions() {
|
|
222
222
|
return !!this.getActionStatesRef(c.possibleState.pending).value;
|
|
@@ -283,13 +283,13 @@ class f {
|
|
|
283
283
|
watch(...t) {
|
|
284
284
|
if (t.length === 0)
|
|
285
285
|
throw new Error("watch requires at least one argument");
|
|
286
|
-
const e = t.length === 1 ? this._effectScope.run(() =>
|
|
286
|
+
const e = t.length === 1 ? this._effectScope.run(() => A(t[0])) : this._effectScope.run(() => y(...t));
|
|
287
287
|
if (!e)
|
|
288
288
|
throw new Error("watchStopHandler is undefined");
|
|
289
289
|
return this._watchStopHandlers.add(e), e;
|
|
290
290
|
}
|
|
291
291
|
computed(t, e) {
|
|
292
|
-
return this._effectScope.run(() =>
|
|
292
|
+
return this._effectScope.run(() => v(t, e));
|
|
293
293
|
}
|
|
294
294
|
// @see https://github.com/trekhleb/javascript-algorithms/blob/master/src/algorithms/math/bits/updateBit.js
|
|
295
295
|
updateBit(t, e, o) {
|
|
@@ -297,11 +297,11 @@ class f {
|
|
|
297
297
|
return t & i | h << e;
|
|
298
298
|
}
|
|
299
299
|
createAction(t) {
|
|
300
|
-
const e =
|
|
300
|
+
const e = S(new c(this, t));
|
|
301
301
|
return this._actions.set(t, e), this._actionIds.set(e, ++this._actionsSize), this.setActionState(e), e;
|
|
302
302
|
}
|
|
303
303
|
getActionStatesRef(t) {
|
|
304
|
-
const e = this._actionStates.get(t) ||
|
|
304
|
+
const e = this._actionStates.get(t) || k(0);
|
|
305
305
|
return this._actionStates.get(t) === void 0 && this._actionStates.set(t, e), e;
|
|
306
306
|
}
|
|
307
307
|
/**
|
|
@@ -374,8 +374,10 @@ class f {
|
|
|
374
374
|
t();
|
|
375
375
|
}), this._watchStopHandlers = /* @__PURE__ */ new Set(), this._effectScope.stop();
|
|
376
376
|
}
|
|
377
|
-
}
|
|
378
|
-
|
|
377
|
+
};
|
|
378
|
+
n(p, "createModel", _);
|
|
379
|
+
let b = p;
|
|
380
|
+
function L(r, t) {
|
|
379
381
|
if (t.static)
|
|
380
382
|
throw new Error("Action decorator is not supported for static methods");
|
|
381
383
|
if (t.private)
|
|
@@ -391,10 +393,10 @@ function I(r, t) {
|
|
|
391
393
|
return o[e][c.actionFlag] = r, o[e];
|
|
392
394
|
}
|
|
393
395
|
export {
|
|
394
|
-
|
|
396
|
+
E as ActionError,
|
|
395
397
|
l as ActionInternalError,
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
398
|
+
d as ActionStatusConflictError,
|
|
399
|
+
M as ActionUnexpectedAbortError,
|
|
400
|
+
b as ProtoModel,
|
|
401
|
+
L as action
|
|
400
402
|
};
|