architex-js 1.0.0 → 1.2.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "architex-js",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "main": "src/index.js",
5
5
  "exports": {
6
6
  ".": "./src/index.js",
@@ -39,4 +39,4 @@
39
39
  "devDependencies": {
40
40
  "vitest": "^3.0.6"
41
41
  }
42
- }
42
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Custom error for abstract methods that are not implemented in a subclass.
3
+ */
4
+ class AbstractMethodNotImplementedException extends Error {
5
+ constructor(msg = "method must be implemented") {
6
+ super(msg);
7
+ this.name = "AbstractMethodNotImplementedException";
8
+ }
9
+ }
10
+
11
+ /**
12
+ * Custom error for attempting to instantiate an abstract class.
13
+ */
14
+ class InstantiatedAbstractClassException extends Error {
15
+ constructor(msg = "Class is of abstract type and can't be instantiated") {
16
+ super(msg);
17
+ this.name = "InstantiatedAbstractClassException";
18
+ }
19
+ }
20
+
21
+ export {
22
+ AbstractMethodNotImplementedException,
23
+ InstantiatedAbstractClassException
24
+ };
@@ -0,0 +1,65 @@
1
+ /**
2
+ * This class is responsible for building the final prototype from a group of mixins
3
+ */
4
+ class MixinBuilder {
5
+ /**
6
+ * Builds the final object or prototype that will inherit into the concrete class
7
+ * @param {...any} mixins classes that will inherit in the final class
8
+ * @returns returns the final class that will inherit in the final context
9
+ */
10
+ static with(...mixins) {
11
+ return mixins.reduce((BaseClass, mixin) => {
12
+ if (
13
+ typeof mixin === "function" &&
14
+ /^class\s/.test(Function.prototype.toString.call(mixin))
15
+ ) {
16
+ // create an intermediate class that extends the BaseClass and applies the mixin
17
+ const MixedClass = class extends BaseClass {
18
+ constructor(...args) {
19
+ super(...args);
20
+ const mixinInstance = new mixin(...args);
21
+
22
+ // copies properties and instance methods of the mixin
23
+ Object.getOwnPropertyNames(mixinInstance).forEach(
24
+ (name) => {
25
+ if (!this.hasOwnProperty(name)) {
26
+ this[name] = mixinInstance[name];
27
+ }
28
+ }
29
+ );
30
+ }
31
+ };
32
+
33
+ // add static members from mixin class to the resulting class
34
+ Object.getOwnPropertyNames(mixin).forEach((name) => {
35
+ if (
36
+ name !== "prototype" &&
37
+ name !== "length" &&
38
+ name !== "name"
39
+ ) {
40
+ MixedClass[name] = mixin[name];
41
+ }
42
+ });
43
+
44
+ // add the mixin prototype to the MixedClass prototype chain
45
+ Object.setPrototypeOf(
46
+ MixedClass.prototype,
47
+ new Proxy(mixin.prototype, {
48
+ get(target, prop, receiver) {
49
+ return (
50
+ Reflect.get(target, prop, receiver) ||
51
+ Reflect.get(BaseClass.prototype, prop, receiver)
52
+ );
53
+ },
54
+ })
55
+ );
56
+
57
+ return MixedClass;
58
+ }
59
+
60
+ return mixin(BaseClass);
61
+ }, class { });
62
+ }
63
+ }
64
+
65
+ export { MixinBuilder };
@@ -0,0 +1 @@
1
+ export * from "./MixinBuilder.js";