@vue-modeler/model 2.2.0-beta.1 → 2.2.0-beta.3

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 CHANGED
@@ -1 +1 @@
1
- "use strict";var $=Object.defineProperty;var B=(r,t,e)=>t in r?$(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e;var n=(r,t,e)=>B(r,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("vue");class K 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 b extends u{constructor(t,e,o){super(`Trying to update state of ${t} from ${e} to ${o}`),this.name=this.constructor.name}}class L extends u{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){n(this,"name");n(this,"_state",s.possibleState.ready);n(this,"_value",null);n(this,"_args",null);this._model=t,this.actionFunction=e,this.modelGetter=o;const i=e.name;if(!(i in this._model&&typeof this._model[i]=="function"))throw new u(`Model does not contain method ${i}`);if(typeof e[s.actionFlag]!="function")throw new u(`Method ${i} is not action`);this.name=i}static create(t,e,o){return h.shallowReactive(new s(t,e,o))}toString(){return this.name}get owner(){return this.modelGetter()}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 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 a=this.actionFunction[s.actionFlag].apply(this._model,e);if(!(a instanceof Promise))return this.state=s.possibleState.ready,Promise.resolve();const d=a.then(()=>{this.ready()}).catch(c=>{if(c instanceof u||c instanceof RangeError||c instanceof ReferenceError||c instanceof SyntaxError||c instanceof TypeError||c instanceof URIError||c instanceof EvalError)throw c;const y=T(c);if(y&&!this.is(s.possibleState.pending,s.possibleState.lock))throw new L(this.name,this.state);if(y&&this._value.abortController instanceof AbortController&&this._value.abortController.signal.reason===s.abortedByLock){this.state=s.possibleState.lock,this._value=null;return}if(y){this.state=s.possibleState.abort;return}this.setError(new K(this.name,{cause:c}))});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 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()}};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 l=s;const D=Proxy;function I(r){if(!(r instanceof g))throw new Error("ProtoModel instance is required");return new D(h.shallowReactive(r),{get(e,o,i){const a=Reflect.get(e,o,i),d=typeof a=="function";return d&&l.actionFlag in a&&typeof a[l.actionFlag]=="function"?e.action(a):d?a.bind(e):a}})}const p=Symbol("scope"),S=Symbol("model"),A=Symbol("actions"),v=Symbol("actionIds"),w=Symbol("actionStates"),E=Symbol("actionsSize"),f=Symbol("watchStopHandlers");var k,M,P,R,C,x,F;F=p,x=S,C=A,R=v,P=w,M=E,k=f;const m=class m{constructor(){n(this,F,h.effectScope(!0));n(this,x,null);n(this,C,new WeakMap);n(this,R,new WeakMap);n(this,P,new Map);n(this,M,0);n(this,k,new Set)}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),o=m.createModel(e);return e[S]=o,o}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(()=>h.watchEffect(t[0])):this[p].run(()=>h.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(()=>h.computed(t,e))}updateBit(t,e,o){const i=o?1:0,a=~(1<<e);return t&a|i<<e}createAction(t){const e=()=>{if(!this[S])throw new Error("Model not set");return this[S]},o=l.create(this,t,e);return this[A].set(t,o),this[v].set(o,++this[E]),this.setActionState(o),o}getActionStatesRef(t){const e=this[w].get(t)||h.ref(0);return this[w].get(t)===void 0&&this[w].set(t,e),e}action(t){if(!(l.actionFlag in t&&typeof t[l.actionFlag]=="function"))throw new u("Action decorator is not applied to the method");return this[A].get(t)||this.createAction(t)}setActionState(t){const e=this[v].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[f].forEach(t=>{t()}),this[f]=new Set,this[p].stop()}};n(m,"createModel",I);let g=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");const e=t.name.toString(),o={[e]:function(...i){return this.action(o[e]).exec(...i)}};return o[e][l.actionFlag]=r,o[e]}exports.ActionError=K;exports.ActionInternalError=u;exports.ActionStatusConflictError=b;exports.ActionUnexpectedAbortError=L;exports.ProtoModel=g;exports.action=O;
1
+ "use strict";var L=Object.defineProperty;var $=(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)=>$(r,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=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 u extends Error{constructor(t,e){super(t,e),this.message=t,this.options=e,this.name=this.constructor.name}}class b extends u{constructor(t,e,o){super(`Trying to update state of ${t} from ${e} to ${o}`),this.name=this.constructor.name}}class K extends u{constructor(t,e){super(`Unexpected AbortError for the action ${t} in state ${e}`),this.name=this.constructor.name}}const B=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,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=h;const n=e.name;if(!(n in this._model&&typeof this._model[n]=="function"))throw new u(`Model does not contain method ${n}`);if(typeof e[s.actionFlag]!="function")throw new u(`Method ${n} is not action`);this.name=n}static create(t,e,o,h){return l.shallowReactive(new s(t,e,o,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.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)}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 n=this.actionFunction[s.actionFlag].apply(this._model,e);if(!(n instanceof Promise))return this.state=s.possibleState.ready,Promise.resolve();const d=n.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 y=B(a);if(y&&!this.is(s.possibleState.pending,s.possibleState.lock))throw new K(this.name,this.state);if(y&&this._value.abortController instanceof AbortController&&this._value.abortController.signal.reason===s.abortedByLock){this.state=s.possibleState.lock,this._value=null;return}if(y){this.state=s.possibleState.abort;return}this.setError(new I(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 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 c=s;const T=Proxy;function D(r){if(!(r instanceof g))throw new Error("ProtoModel instance is required");return new T(l.shallowReactive(r),{get(e,o,h){const n=Reflect.get(e,o,h),d=typeof n=="function";return d&&c.actionFlag in n&&typeof n[c.actionFlag]=="function"?e.action(n):d?n.bind(e):n}})}const p=Symbol("scope"),m=Symbol("model"),A=Symbol("actions"),v=Symbol("actionIds"),w=Symbol("actionStates"),E=Symbol("actionsSize"),f=Symbol("watchStopHandlers");var k,M,P,C,R,x,F;F=p,x=m,R=A,C=v,P=w,M=E,k=f;const S=class S{constructor(){i(this,F,l.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 model(...t){if(this.prototype===S.prototype)throw new Error("ProtoModel is abstract class and can not be instantiated");const e=new this(...t),o=S.createModel(e);return e[m]=o,o}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[p].run(()=>l.watchEffect(t[0])):this[p].run(()=>l.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(()=>l.computed(t,e))}updateBit(t,e,o){const h=o?1:0,n=~(1<<e);return t&n|h<<e}createAction(t){const e=()=>{if(!this[m])throw new Error("Model not set");return this[m]},o=c.create(this,t,e,this.setActionState.bind(this));return this[A].set(t,o),this[v].set(o,++this[E]),this.setActionState(o),o}getActionStatesRef(t){const e=this[w].get(t)||l.ref(0);return this[w].get(t)===void 0&&this[w].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[A].get(t)||this.createAction(t)}setActionState(t){const e=this[v].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[f].forEach(t=>{t()}),this[f]=new Set,this[p].stop()}};i(S,"createModel",D);let g=S;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");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.Action=c;exports.ActionError=I;exports.ActionInternalError=u;exports.ActionStatusConflictError=b;exports.ActionUnexpectedAbortError=K;exports.ProtoModel=g;exports.action=O;
package/dist/index.d.ts CHANGED
@@ -6,42 +6,17 @@ import { Ref } from 'vue';
6
6
  import { ShallowReactive } from 'vue';
7
7
  import { WatchStopHandle } from 'vue';
8
8
 
9
- export declare type Action<T extends ProtoModel, Args extends any[] = unknown[]> = Omit<ActionInner<T, Args>, 'call'>;
10
-
11
- export declare function action<T extends ProtoModel, Args extends unknown[]>(originalMethod: (this: T, ...args: Args) => Promise<void>, context: ClassMethodDecoratorContext<T, (this: T, ...args: Args) => Promise<void>>): OriginalMethodWrapper<Args>;
12
-
13
- /**
14
- * IMPORTANT: this class looks like error,
15
- * but it is an exception in the correct terminology "errors vs exceptions".
16
- *
17
- * In other words, this is a class of errors that must be handled
18
- * and displayed to the user as messages in UI layer.
19
- */
20
- export declare class ActionError extends Error {
21
- protected actionName: string;
22
- protected options: {
23
- cause: Error;
24
- };
25
- constructor(actionName: string, options: {
26
- cause: Error;
27
- });
28
- get cause(): Error;
29
- throwCause(): void;
30
- toString(): string;
31
- }
32
-
33
- declare const actionIdsKey: unique symbol;
34
-
35
9
  /**
36
10
  * We should to use here `<T extends ProtoModel>` because
37
11
  * we need some methods from `ProtoModel` class which are protected in context of `Model<T>`.
38
12
  * For example, `setActionState` method.
39
13
  * @see `ProtoModel.setActionState`
40
14
  */
41
- declare class ActionInner<T extends ProtoModel, Args extends any[] = unknown[]> {
15
+ export declare class Action<T extends object, Args extends any[] = unknown[], Owner extends object = Model<T>> implements ActionLike<Owner, Args> {
42
16
  protected _model: T;
43
17
  protected actionFunction: OriginalMethodWrapper<Args>;
44
- protected modelGetter: () => Model<T>;
18
+ protected ownerGetter: () => Owner;
19
+ protected setStateCb?: ((action: SrActionLike<Owner, Args>, oldState: ActionStateName, newState: ActionStateName) => void) | undefined;
45
20
  static readonly actionFlag: unique symbol;
46
21
  static readonly possibleState: {
47
22
  readonly pending: "pending";
@@ -55,11 +30,10 @@ declare class ActionInner<T extends ProtoModel, Args extends any[] = unknown[]>
55
30
  protected _state: ActionStateName;
56
31
  protected _value: ActionValue;
57
32
  protected _args: Args | null;
58
- constructor(_model: T, // TODO: thing about this arg, it may be potential problem
59
- actionFunction: OriginalMethodWrapper<Args>, modelGetter: () => Model<T>);
60
- static create<T extends ProtoModel, Args extends unknown[] = unknown[]>(model: T, actionFunction: OriginalMethodWrapper<Args>, modelGetter: () => Model<T>): ActionInner<T, Args>;
33
+ constructor(_model: T, actionFunction: OriginalMethodWrapper<Args>, ownerGetter: () => Owner, setStateCb?: ((action: SrActionLike<Owner, Args>, oldState: ActionStateName, newState: ActionStateName) => void) | undefined);
34
+ static create<T extends ProtoModel, Args extends unknown[] = unknown[], Owner extends object = Model<T>>(model: T, actionFunction: OriginalMethodWrapper<Args>, ownerGetter: () => Owner, setStateCb?: (action: SrActionLike<Owner, Args>, oldState: ActionStateName, newState: ActionStateName) => void): SrActionLike<Owner, Args>;
61
35
  toString(): string;
62
- get owner(): Model<T>;
36
+ get owner(): Owner;
63
37
  get possibleStates(): ActionStateName[];
64
38
  get state(): ActionStateName;
65
39
  protected set state(newState: ActionStateName);
@@ -86,6 +60,30 @@ declare class ActionInner<T extends ProtoModel, Args extends any[] = unknown[]>
86
60
  resetError(): this;
87
61
  }
88
62
 
63
+ export declare function action<T extends ProtoModel, Args extends unknown[]>(originalMethod: (this: T, ...args: Args) => Promise<void>, context: ClassMethodDecoratorContext<T, (this: T, ...args: Args) => Promise<void>>): OriginalMethodWrapper<Args>;
64
+
65
+ /**
66
+ * IMPORTANT: this class looks like error,
67
+ * but it is an exception in the correct terminology "errors vs exceptions".
68
+ *
69
+ * In other words, this is a class of errors that must be handled
70
+ * and displayed to the user as messages in UI layer.
71
+ */
72
+ export declare class ActionError extends Error {
73
+ protected actionName: string;
74
+ protected options: {
75
+ cause: Error;
76
+ };
77
+ constructor(actionName: string, options: {
78
+ cause: Error;
79
+ });
80
+ get cause(): Error;
81
+ throwCause(): void;
82
+ toString(): string;
83
+ }
84
+
85
+ declare const actionIdsKey: unique symbol;
86
+
89
87
  /**
90
88
  * IMPORTANT: this class is an error in the correct terminology "errors vs exceptions".
91
89
  *
@@ -104,6 +102,34 @@ export declare class ActionInternalError extends Error {
104
102
  } | undefined);
105
103
  }
106
104
 
105
+ /**
106
+ * Public API interface for Action instances.
107
+ * Describes only the public contract without implementation details.
108
+ */
109
+ export declare interface ActionLike<Owner extends object, Args extends any[] = unknown[]> {
110
+ readonly name: string;
111
+ readonly owner: Owner;
112
+ readonly possibleStates: ActionStateName[];
113
+ readonly state: ActionStateName;
114
+ readonly abortController: null | AbortController;
115
+ readonly args: Args | never[];
116
+ readonly promise: null | Promise<void>;
117
+ readonly error: null | ActionError;
118
+ readonly abortReason: unknown;
119
+ readonly isPending: boolean;
120
+ readonly isError: boolean;
121
+ readonly isReady: boolean;
122
+ readonly isLock: boolean;
123
+ readonly isAbort: boolean;
124
+ is(...args: ActionStateName[]): boolean;
125
+ exec(...args: Args): Promise<void>;
126
+ abort(reason?: unknown): Promise<void>;
127
+ lock(): Promise<void>;
128
+ unlock(): this;
129
+ resetError(): this;
130
+ toString(): string;
131
+ }
132
+
107
133
  declare interface ActionPendingValue {
108
134
  promise: Promise<void>;
109
135
  abortController: AbortController;
@@ -113,7 +139,7 @@ declare const actionsKey: unique symbol;
113
139
 
114
140
  declare const actionsSizeKey: unique symbol;
115
141
 
116
- export declare type ActionStateName = keyof typeof ActionInner.possibleState;
142
+ export declare type ActionStateName = keyof typeof Action.possibleState;
117
143
 
118
144
  declare const actionStatesKey: unique symbol;
119
145
 
@@ -154,15 +180,15 @@ declare type ActionValue = ActionPendingValue | ActionError | null;
154
180
  */
155
181
  declare function createModel<Target extends ProtoModel>(protoModel: Target): Model<Target>;
156
182
 
157
- export declare type Model<T extends ProtoModel> = {
158
- [K in keyof T]: T[K] extends ((...args: infer Args) => Promise<void>) ? Action<T, Args> : K extends ProtectedMethodInModel ? never : T[K];
159
- };
183
+ export declare type Model<T extends object = object> = ShallowReactive<{
184
+ [K in keyof T]: T[K] extends ((...args: infer Args) => Promise<void>) ? SrActionLike<T, Args> : K extends ProtectedMethodInModel ? never : T[K];
185
+ }>;
160
186
 
161
187
  export declare type ModelAdapterProxyConstructor = new <Target extends ProtoModel>(target: Target, handler: ProxyHandler<Target>) => Model<Target>;
162
188
 
163
189
  export declare type ModelConstructor<T extends new (...args: unknown[]) => unknown> = T extends new (...args: unknown[]) => infer R ? R extends ProtoModel ? T : never : never;
164
190
 
165
- declare type ModelConstructor_2 = new (...args: any[]) => ProtoModel;
191
+ declare type ModelConstructor_2<T extends ProtoModel> = new (...args: any[]) => T;
166
192
 
167
193
  declare const modelKey: unique symbol;
168
194
 
@@ -170,7 +196,7 @@ export declare type OriginalMethod = (...args: any[]) => Promise<void>;
170
196
 
171
197
  export declare interface OriginalMethodWrapper<Args extends any[] = unknown[]> {
172
198
  (...args: Args): Promise<void>;
173
- [ActionInner.actionFlag]: OriginalMethod;
199
+ [Action.actionFlag]: OriginalMethod;
174
200
  }
175
201
 
176
202
  export declare type ProtectedMethodInModel = 'action' | 'setActionState';
@@ -178,9 +204,9 @@ export declare type ProtectedMethodInModel = 'action' | 'setActionState';
178
204
  export declare abstract class ProtoModel {
179
205
  protected [scopeKey]: EffectScope;
180
206
  protected [modelKey]: Model<this> | null;
181
- protected [actionsKey]: WeakMap<OriginalMethodWrapper<unknown[]>, ShallowReactive<Action<this>>>;
182
- protected [actionIdsKey]: WeakMap<ShallowReactive<Action<this>>, number>;
183
- protected [actionStatesKey]: Map<"error" | "abort" | "lock" | "pending" | "ready", Ref<number>>;
207
+ protected [actionsKey]: WeakMap<OriginalMethodWrapper<unknown[]>, SrActionLike<Model<this>>>;
208
+ protected [actionIdsKey]: WeakMap<SrActionLike<Model<this>>, number>;
209
+ protected [actionStatesKey]: Map<"pending" | "error" | "lock" | "ready" | "abort", Ref<number>>;
184
210
  protected [actionsSizeKey]: number;
185
211
  protected [watchStopHandlersKey]: Set<WatchStopHandle>;
186
212
  protected static createModel: typeof createModel;
@@ -253,7 +279,7 @@ export declare abstract class ProtoModel {
253
279
  protected watch(...args: unknown[]): WatchStopHandle;
254
280
  protected computed<T>(getter: ComputedGetter<T>, debugOptions?: DebuggerOptions): ComputedRef<T>;
255
281
  protected updateBit(number: number, bitPosition: number, bitValue: boolean): number;
256
- protected createAction(actionFunction: OriginalMethodWrapper): ShallowReactive<Action<this>>;
282
+ protected createAction(actionFunction: OriginalMethodWrapper): SrActionLike<Model<this>>;
257
283
  protected getActionStatesRef(stateName: ActionStateName): Ref<number>;
258
284
  /**
259
285
  * Gets Action instance by wrapped original method or create Action instance.
@@ -298,20 +324,26 @@ export declare abstract class ProtoModel {
298
324
  * @param originalMethod - defined as OriginalMethod or OriginalMethodWrapper.
299
325
  * @returns action
300
326
  */
301
- protected action(originalMethod: OriginalMethod | OriginalMethodWrapper): ShallowReactive<Action<this>>;
327
+ protected action(originalMethod: OriginalMethod | OriginalMethodWrapper): SrActionLike<Model<this>>;
302
328
  /**
303
329
  * It is public method in context ProtoModel,
304
330
  * but in Model<ProtoModel> context it is protected method
305
331
  *
306
332
  * @see type Model<T>
307
333
  */
308
- setActionState(action: Action<this>): void;
309
- isModelOf(typeModel: ModelConstructor_2): boolean;
334
+ setActionState(action: SrActionLike<Model<this>>): void;
335
+ isModelOf<T extends ProtoModel>(typeModel: ModelConstructor_2<T>): boolean;
310
336
  destructor(): void;
311
337
  }
312
338
 
313
339
  declare const scopeKey: unique symbol;
314
340
 
341
+ /**
342
+ * Reactive ActionLike type - ActionLike wrapped in ShallowReactive.
343
+ * This is the type used throughout the codebase for action instances.
344
+ */
345
+ export declare type SrActionLike<Owner extends object, Args extends any[] = unknown[]> = ShallowReactive<ActionLike<Owner, Args>>;
346
+
315
347
  declare const watchStopHandlersKey: unique symbol;
316
348
 
317
349
  export { }
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
- var K = Object.defineProperty;
2
- var L = (r, t, e) => t in r ? K(r, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : r[t] = e;
3
- var n = (r, t, e) => L(r, typeof t != "symbol" ? t + "" : t, e);
4
- import { shallowReactive as F, effectScope as $, watchEffect as B, watch as D, computed as T, ref as H } from "vue";
5
- class I extends Error {
1
+ var I = Object.defineProperty;
2
+ var K = (r, t, e) => t in r ? I(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 $, watch as B, computed as D, ref as T } from "vue";
5
+ class H 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
  }
@@ -16,43 +16,43 @@ class I extends Error {
16
16
  return this.options.cause.message;
17
17
  }
18
18
  }
19
- class l extends Error {
19
+ class u extends Error {
20
20
  constructor(t, e) {
21
21
  super(t, e), this.message = t, this.options = e, this.name = this.constructor.name;
22
22
  }
23
23
  }
24
- class b extends l {
24
+ class b extends u {
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 O extends l {
29
+ class O extends u {
30
30
  constructor(t, e) {
31
31
  super(`Unexpected AbortError for the action ${t} in state ${e}`), this.name = this.constructor.name;
32
32
  }
33
33
  }
34
34
  const j = (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) {
36
- n(this, "name");
37
- n(this, "_state", s.possibleState.ready);
38
- n(this, "_value", null);
39
- n(this, "_args", null);
40
- this._model = t, this.actionFunction = e, this.modelGetter = o;
41
- const i = e.name;
42
- if (!(i in this._model && typeof this._model[i] == "function"))
43
- throw new l(`Model does not contain method ${i}`);
35
+ constructor(t, e, o, c) {
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;
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}`);
44
44
  if (typeof e[s.actionFlag] != "function")
45
- throw new l(`Method ${i} is not action`);
46
- this.name = i;
45
+ throw new u(`Method ${n} is not action`);
46
+ this.name = n;
47
47
  }
48
- static create(t, e, o) {
49
- return F(new s(t, e, o));
48
+ static create(t, e, o, c) {
49
+ return F(new s(t, e, o, c));
50
50
  }
51
51
  toString() {
52
52
  return this.name;
53
53
  }
54
54
  get owner() {
55
- return this.modelGetter();
55
+ return this.ownerGetter();
56
56
  }
57
57
  get possibleStates() {
58
58
  return Object.values(s.possibleState);
@@ -61,7 +61,8 @@ const j = (r) => r instanceof DOMException && r.name === "AbortError" || typeof
61
61
  return this._state;
62
62
  }
63
63
  set state(t) {
64
- this._state = t, this._model.setActionState(this);
64
+ const e = this._state;
65
+ this._state = t, this.setStateCb && this.setStateCb(this, e, t);
65
66
  }
66
67
  get abortController() {
67
68
  return this.isPending ? this._value.abortController : null;
@@ -110,15 +111,15 @@ const j = (r) => r instanceof DOMException && r.name === "AbortError" || typeof
110
111
  const e = [...t];
111
112
  let o = t.length && t[t.length - 1];
112
113
  o instanceof AbortController || (o = new AbortController(), e.push(o)), this.state = s.possibleState.pending, this._args = t;
113
- const a = this.actionFunction[s.actionFlag].apply(this._model, e);
114
- if (!(a instanceof Promise))
114
+ const n = this.actionFunction[s.actionFlag].apply(this._model, e);
115
+ if (!(n instanceof Promise))
115
116
  return this.state = s.possibleState.ready, Promise.resolve();
116
- const u = a.then(() => {
117
+ const l = n.then(() => {
117
118
  this.ready();
118
- }).catch((c) => {
119
- if (c instanceof l || c instanceof RangeError || c instanceof ReferenceError || c instanceof SyntaxError || c instanceof TypeError || c instanceof URIError || c instanceof EvalError)
120
- throw c;
121
- const w = j(c);
119
+ }).catch((a) => {
120
+ if (a instanceof u || a instanceof RangeError || a instanceof ReferenceError || a instanceof SyntaxError || a instanceof TypeError || a instanceof URIError || a instanceof EvalError)
121
+ throw a;
122
+ const w = j(a);
122
123
  if (w && !this.is(s.possibleState.pending, s.possibleState.lock))
123
124
  throw new O(this.name, this.state);
124
125
  if (w && this._value.abortController instanceof AbortController && this._value.abortController.signal.reason === s.abortedByLock) {
@@ -129,12 +130,12 @@ const j = (r) => r instanceof DOMException && r.name === "AbortError" || typeof
129
130
  this.state = s.possibleState.abort;
130
131
  return;
131
132
  }
132
- this.setError(new I(this.name, { cause: c }));
133
+ this.setError(new H(this.name, { cause: a }));
133
134
  });
134
135
  return this._value = {
135
- promise: u,
136
+ promise: l,
136
137
  abortController: o
137
- }, u;
138
+ }, l;
138
139
  }
139
140
  // Returns same promise as exec method
140
141
  // but in reject state
@@ -176,13 +177,13 @@ const j = (r) => r instanceof DOMException && r.name === "AbortError" || typeof
176
177
  return this.ready();
177
178
  }
178
179
  };
179
- n(s, "actionFlag", Symbol("__action_original_method__")), n(s, "possibleState", {
180
+ i(s, "actionFlag", Symbol("__action_original_method__")), i(s, "possibleState", {
180
181
  pending: "pending",
181
182
  error: "error",
182
183
  lock: "lock",
183
184
  ready: "ready",
184
185
  abort: "abort"
185
- }), n(s, "abortedByLock", Symbol("lock"));
186
+ }), i(s, "abortedByLock", Symbol("lock"));
186
187
  let h = s;
187
188
  const z = Proxy;
188
189
  function G(r) {
@@ -191,29 +192,29 @@ function G(r) {
191
192
  return new z(
192
193
  F(r),
193
194
  {
194
- get(e, o, i) {
195
- const a = Reflect.get(e, o, i), u = typeof a == "function";
196
- return u && h.actionFlag in a && typeof a[h.actionFlag] == "function" ? e.action(a) : u ? a.bind(e) : a;
195
+ get(e, o, c) {
196
+ const n = Reflect.get(e, o, c), l = typeof n == "function";
197
+ return l && h.actionFlag in n && typeof n[h.actionFlag] == "function" ? e.action(n) : l ? n.bind(e) : n;
197
198
  }
198
199
  }
199
200
  );
200
201
  }
201
202
  const d = Symbol("scope"), m = Symbol("model"), g = Symbol("actions"), y = Symbol("actionIds"), S = Symbol("actionStates"), v = Symbol("actionsSize"), p = Symbol("watchStopHandlers");
202
- var k, E, M, P, R, C, x;
203
- x = d, C = m, R = g, P = y, M = S, E = v, k = p;
203
+ var k, E, M, C, P, R, x;
204
+ x = d, R = m, P = g, C = y, M = S, E = v, k = p;
204
205
  const f = class f {
205
206
  constructor() {
206
207
  // each model has its own effect scope to avoid memory leaks
207
- n(this, x, $(!0));
208
- n(this, C, null);
208
+ i(this, x, L(!0));
209
+ i(this, R, null);
209
210
  // we use WeakMap to store actions as keys to avoid memory leaks
210
- n(this, R, /* @__PURE__ */ new WeakMap());
211
- n(this, P, /* @__PURE__ */ new WeakMap());
212
- n(this, M, /* @__PURE__ */ new Map());
211
+ i(this, P, /* @__PURE__ */ new WeakMap());
212
+ i(this, C, /* @__PURE__ */ new WeakMap());
213
+ i(this, M, /* @__PURE__ */ new Map());
213
214
  // WeakMap doesn't have a size property, so we need to store the size of the map
214
- n(this, E, 0);
215
+ i(this, E, 0);
215
216
  // watchers are stored in a set to avoid memory leaks
216
- n(this, k, /* @__PURE__ */ new Set());
217
+ i(this, k, /* @__PURE__ */ new Set());
217
218
  }
218
219
  /**
219
220
  * Creates a model instance.
@@ -293,7 +294,7 @@ const f = class f {
293
294
  watch(...t) {
294
295
  if (t.length === 0)
295
296
  throw new Error("watch requires at least one argument");
296
- const e = t.length === 1 ? this[d].run(() => B(t[0])) : this[d].run(() => D(...t));
297
+ const e = t.length === 1 ? this[d].run(() => $(t[0])) : this[d].run(() => B(...t));
297
298
  if (!e)
298
299
  throw new Error("watchStopHandler is undefined");
299
300
  return this[p].add(e), () => {
@@ -301,23 +302,28 @@ const f = class f {
301
302
  };
302
303
  }
303
304
  computed(t, e) {
304
- return this[d].run(() => T(t, e));
305
+ return this[d].run(() => D(t, e));
305
306
  }
306
307
  // @see https://github.com/trekhleb/javascript-algorithms/blob/master/src/algorithms/math/bits/updateBit.js
307
308
  updateBit(t, e, o) {
308
- const i = o ? 1 : 0, a = ~(1 << e);
309
- return t & a | i << e;
309
+ const c = o ? 1 : 0, n = ~(1 << e);
310
+ return t & n | c << e;
310
311
  }
311
312
  createAction(t) {
312
313
  const e = () => {
313
314
  if (!this[m])
314
315
  throw new Error("Model not set");
315
316
  return this[m];
316
- }, o = h.create(this, t, e);
317
+ }, o = h.create(
318
+ this,
319
+ t,
320
+ e,
321
+ this.setActionState.bind(this)
322
+ );
317
323
  return this[g].set(t, o), this[y].set(o, ++this[v]), this.setActionState(o), o;
318
324
  }
319
325
  getActionStatesRef(t) {
320
- const e = this[S].get(t) || H(0);
326
+ const e = this[S].get(t) || T(0);
321
327
  return this[S].get(t) === void 0 && this[S].set(t, e), e;
322
328
  }
323
329
  /**
@@ -365,7 +371,7 @@ const f = class f {
365
371
  */
366
372
  action(t) {
367
373
  if (!(h.actionFlag in t && typeof t[h.actionFlag] == "function"))
368
- throw new l("Action decorator is not applied to the method");
374
+ throw new u("Action decorator is not applied to the method");
369
375
  return this[g].get(t) || this.createAction(t);
370
376
  }
371
377
  /**
@@ -391,7 +397,7 @@ const f = class f {
391
397
  }), this[p] = /* @__PURE__ */ new Set(), this[d].stop();
392
398
  }
393
399
  };
394
- n(f, "createModel", G);
400
+ i(f, "createModel", G);
395
401
  let A = f;
396
402
  function V(r, t) {
397
403
  if (t.static)
@@ -402,15 +408,16 @@ function V(r, t) {
402
408
  // Action constructor checks that model has method with the same name.
403
409
  // We can`t define anonymous function and change name because Function.name is readonly property.
404
410
  // So we need to create stub object to save original method name
405
- [e]: function(...i) {
406
- return this.action(o[e]).exec(...i);
411
+ [e]: function(...c) {
412
+ return this.action(o[e]).exec(...c);
407
413
  }
408
414
  };
409
415
  return o[e][h.actionFlag] = r, o[e];
410
416
  }
411
417
  export {
412
- I as ActionError,
413
- l as ActionInternalError,
418
+ h as Action,
419
+ H as ActionError,
420
+ u as ActionInternalError,
414
421
  b as ActionStatusConflictError,
415
422
  O as ActionUnexpectedAbortError,
416
423
  A as ProtoModel,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@vue-modeler/model",
4
- "version": "2.2.0-beta.1",
4
+ "version": "2.2.0-beta.3",
5
5
  "description": "A state management library based on models for Vue.js",
6
6
  "author": "abratko",
7
7
  "license": "MIT",