ivue 1.0.2 → 1.0.4

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.
Files changed (114) hide show
  1. package/.idea/codeStyles/Project.xml +65 -0
  2. package/.idea/codeStyles/codeStyleConfig.xml +5 -0
  3. package/.idea/inspectionProfiles/Project_Default.xml +6 -0
  4. package/.idea/ivue.iml +8 -0
  5. package/.idea/modules.xml +8 -0
  6. package/.idea/php.xml +19 -0
  7. package/.idea/vcs.xml +6 -0
  8. package/README.md +23 -7
  9. package/coverage/clover.xml +159 -159
  10. package/coverage/coverage-final.json +1 -1
  11. package/coverage/index.html +17 -17
  12. package/coverage/index.ts.html +86 -107
  13. package/dist/index.es.js +74 -90
  14. package/dist/index.umd.js +1 -1
  15. package/dist/src/index.d.ts +1 -196
  16. package/dist/src/ivue.d.ts +218 -0
  17. package/docs/docs/.vitepress/config.ts +110 -22
  18. package/docs/docs/.vitepress/dist/404.html +4 -4
  19. package/docs/docs/.vitepress/dist/api/ivue.html +8 -8
  20. package/docs/docs/.vitepress/dist/api/propsWithDefaults.html +8 -8
  21. package/docs/docs/.vitepress/dist/assets/{api_ivue.md.BCZ4q_0D.js → api_ivue.md.MRwb9Lcb.js} +1 -1
  22. package/docs/docs/.vitepress/dist/assets/{api_ivue.md.BCZ4q_0D.lean.js → api_ivue.md.MRwb9Lcb.lean.js} +1 -1
  23. package/docs/docs/.vitepress/dist/assets/{api_propsWithDefaults.md.Cr5FwI9o.lean.js → api_propsWithDefaults.md.CeE4IC-K.js} +1 -1
  24. package/docs/docs/.vitepress/dist/assets/{api_propsWithDefaults.md.Cr5FwI9o.js → api_propsWithDefaults.md.CeE4IC-K.lean.js} +1 -1
  25. package/docs/docs/.vitepress/dist/assets/{app.DRiljpSE.js → app.ConZRsN0.js} +1 -1
  26. package/docs/docs/.vitepress/dist/assets/chunks/@localSearchIndexroot.CGLWArGd.js +1 -0
  27. package/docs/docs/.vitepress/dist/assets/chunks/Button.vue_vue_type_script_setup_true_lang.P7niV-n8.js +1 -0
  28. package/docs/docs/.vitepress/dist/assets/chunks/VPLocalSearchBox.C7VDyivS.js +7 -0
  29. package/docs/docs/.vitepress/dist/assets/chunks/framework.CNtPHGsN.js +1 -0
  30. package/docs/docs/.vitepress/dist/assets/chunks/index.es.DnWLDAUc.js +1 -0
  31. package/docs/docs/.vitepress/dist/assets/chunks/theme.B7n-r1TY.js +2 -0
  32. package/docs/docs/.vitepress/dist/assets/index.md.wPLoTLBY.js +1 -0
  33. package/docs/docs/.vitepress/dist/assets/index.md.wPLoTLBY.lean.js +1 -0
  34. package/docs/docs/.vitepress/dist/assets/pages_advanced-usage.md.BZgX-VP7.js +1 -0
  35. package/docs/docs/.vitepress/dist/assets/pages_advanced-usage.md.BZgX-VP7.lean.js +1 -0
  36. package/docs/docs/.vitepress/dist/assets/pages_api.md.C_PvCZns.js +7 -0
  37. package/docs/docs/.vitepress/dist/assets/pages_api.md.C_PvCZns.lean.js +7 -0
  38. package/docs/docs/.vitepress/dist/assets/pages_browse-code.md.CPluoaap.js +1 -0
  39. package/docs/docs/.vitepress/dist/assets/pages_browse-code.md.CPluoaap.lean.js +1 -0
  40. package/docs/docs/.vitepress/dist/assets/pages_getting-started.md.knQcOZyP.js +8 -0
  41. package/docs/docs/.vitepress/dist/assets/pages_getting-started.md.knQcOZyP.lean.js +1 -0
  42. package/docs/docs/.vitepress/dist/assets/pages_guidelines.md.DddPdPom.js +101 -0
  43. package/docs/docs/.vitepress/dist/assets/pages_guidelines.md.DddPdPom.lean.js +101 -0
  44. package/docs/docs/.vitepress/dist/assets/pages_how-it-works.md.OJGcGEXF.js +4 -0
  45. package/docs/docs/.vitepress/dist/assets/pages_how-it-works.md.OJGcGEXF.lean.js +4 -0
  46. package/docs/docs/.vitepress/dist/assets/pages_how-its-made.md.Vv9Z9TEi.js +1 -0
  47. package/docs/docs/.vitepress/dist/assets/pages_how-its-made.md.Vv9Z9TEi.lean.js +1 -0
  48. package/docs/docs/.vitepress/dist/assets/pages_introduction.md.DrDm-R8F.js +1 -0
  49. package/docs/docs/.vitepress/dist/assets/pages_introduction.md.DrDm-R8F.lean.js +1 -0
  50. package/docs/docs/.vitepress/dist/assets/pages_usage.md.zSOVjtFF.js +430 -0
  51. package/docs/docs/.vitepress/dist/assets/pages_usage.md.zSOVjtFF.lean.js +430 -0
  52. package/docs/docs/.vitepress/dist/assets/style.Fgx7OB_D.css +1 -0
  53. package/docs/docs/.vitepress/dist/hashmap.json +1 -1
  54. package/docs/docs/.vitepress/dist/index.html +9 -8
  55. package/docs/docs/.vitepress/dist/pages/advanced-usage.html +24 -0
  56. package/docs/docs/.vitepress/dist/pages/api.html +30 -0
  57. package/docs/docs/.vitepress/dist/pages/browse-code.html +24 -0
  58. package/docs/docs/.vitepress/dist/pages/getting-started.html +11 -11
  59. package/docs/docs/.vitepress/dist/pages/guidelines.html +125 -0
  60. package/docs/docs/.vitepress/dist/pages/how-it-works.html +11 -8
  61. package/docs/docs/.vitepress/dist/pages/how-its-made.html +24 -0
  62. package/docs/docs/.vitepress/dist/pages/introduction.html +9 -8
  63. package/docs/docs/.vitepress/dist/pages/usage.html +428 -14
  64. package/docs/docs/.vitepress/theme/index.js +5 -0
  65. package/docs/docs/.vitepress/theme/main.css +29 -0
  66. package/docs/docs/components/Button.vue +1 -1
  67. package/docs/docs/components/guidelines/CounterExternalRefsDetailed.vue +41 -0
  68. package/docs/docs/components/usage/CounterBasic.vue +17 -0
  69. package/docs/docs/components/usage/CounterComposables.vue +19 -0
  70. package/docs/docs/components/usage/CounterComposablesDestructuring.vue +46 -0
  71. package/docs/docs/components/usage/CounterComputeds.vue +25 -0
  72. package/docs/docs/components/usage/CounterComputedsDisabled.vue +32 -0
  73. package/docs/docs/components/usage/CounterDefineExpose.vue +12 -0
  74. package/docs/docs/components/usage/CounterDefineExposeAdvanced.vue +25 -0
  75. package/docs/docs/components/usage/CounterDefineExposeClass.ts +11 -0
  76. package/docs/docs/components/usage/CounterExternalRefs.vue +25 -0
  77. package/docs/docs/components/usage/CounterInsideComposables.vue +27 -0
  78. package/docs/docs/components/usage/CounterInternalRefs.vue +26 -0
  79. package/docs/docs/components/usage/CounterLifecycleHooks.vue +22 -0
  80. package/docs/docs/components/usage/CounterWatch.vue +25 -0
  81. package/docs/docs/components/usage/CounterWithProps.vue +29 -0
  82. package/docs/docs/components/usage/CounterWithPropsAndEmits.vue +36 -0
  83. package/docs/docs/components/usage/functions/useMouse.ts +22 -0
  84. package/docs/docs/index.md +10 -9
  85. package/docs/docs/pages/advanced-usage.md +11 -0
  86. package/docs/docs/pages/api.md +106 -0
  87. package/docs/docs/pages/browse-code.md +18 -0
  88. package/docs/docs/pages/getting-started.md +23 -5
  89. package/docs/docs/pages/guidelines.md +128 -0
  90. package/docs/docs/pages/how-it-works.md +71 -0
  91. package/docs/docs/pages/how-its-made.md +32 -0
  92. package/docs/docs/pages/introduction.md +37 -20
  93. package/docs/docs/pages/usage.md +347 -10
  94. package/docs/package.json +4 -3
  95. package/package.json +4 -2
  96. package/src/__tests__/ivue.vitest.spec.ts +228 -132
  97. package/src/index.ts +1 -463
  98. package/src/ivue.ts +495 -0
  99. package/vite.config.ts +4 -0
  100. package/docs/.env +0 -1
  101. package/docs/docs/.vitepress/dist/assets/chunks/framework.CEhE-9HF.js +0 -1
  102. package/docs/docs/.vitepress/dist/assets/chunks/theme.CldUEgAJ.js +0 -1
  103. package/docs/docs/.vitepress/dist/assets/index.md.B1vDz5mb.js +0 -1
  104. package/docs/docs/.vitepress/dist/assets/index.md.B1vDz5mb.lean.js +0 -1
  105. package/docs/docs/.vitepress/dist/assets/pages_getting-started.md.C7qtPEWU.js +0 -8
  106. package/docs/docs/.vitepress/dist/assets/pages_getting-started.md.C7qtPEWU.lean.js +0 -1
  107. package/docs/docs/.vitepress/dist/assets/pages_how-it-works.md.DKizt6Ny.js +0 -1
  108. package/docs/docs/.vitepress/dist/assets/pages_how-it-works.md.DKizt6Ny.lean.js +0 -1
  109. package/docs/docs/.vitepress/dist/assets/pages_introduction.md.Dkqu-XCz.js +0 -1
  110. package/docs/docs/.vitepress/dist/assets/pages_introduction.md.Dkqu-XCz.lean.js +0 -1
  111. package/docs/docs/.vitepress/dist/assets/pages_usage.md.qo7ICfLC.js +0 -17
  112. package/docs/docs/.vitepress/dist/assets/pages_usage.md.qo7ICfLC.lean.js +0 -17
  113. package/docs/docs/.vitepress/dist/assets/style.BSZVsGuP.css +0 -1
  114. package/docs/docs/components/examples/Counter.vue +0 -17
@@ -1,14 +1,21 @@
1
- import { describe, expect, it } from "vitest";
2
- import { isReactive, ref } from "vue";
3
-
4
- import { ivue, getAllClassDescriptors, getAllClassProperties } from "../index";
1
+ import { describe, expect, it } from 'vitest';
2
+ import { PropType, isReactive, ref } from 'vue';
3
+
4
+ import {
5
+ ExtractPropDefaultTypes,
6
+ getAllClassDescriptors,
7
+ getAllClassProperties,
8
+ isClass,
9
+ ivue,
10
+ propsWithDefaults,
11
+ } from '../index';
5
12
 
6
13
  class Basic {
7
- id = ref("id") as unknown as string;
14
+ id = ref('id') as unknown as string;
8
15
  }
9
16
 
10
17
  class Bit {
11
- _testProperty = ref("test-value") as unknown as string;
18
+ _testProperty = ref('test-value') as unknown as string;
12
19
  /** Setter without a getter. */
13
20
  set testProperty(value: string) {
14
21
  this._testProperty = value;
@@ -16,32 +23,32 @@ class Bit {
16
23
  }
17
24
 
18
25
  class Item extends Bit {
19
- _width = ref(5) as unknown as string | number;
20
- unit = ref("px") as unknown as string;
26
+ _width = ref(5) as unknown as number;
27
+ unit = ref('px') as unknown as string;
21
28
  get width(): string {
22
- return String(this._width) + this.unit;
29
+ return this._width + this.unit;
23
30
  }
24
- set width(value: string | number) {
31
+ set width(value: number) {
25
32
  this._width = value;
26
33
  }
27
- _height = ref(5) as unknown as string | number;
34
+ _height = ref(5) as unknown as number;
28
35
  get height(): string {
29
- return String(this._height) + this.unit;
36
+ return this._height + this.unit;
30
37
  }
31
- set height(value: string | number) {
38
+ set height(value: number) {
32
39
  this._height = value;
33
40
  }
34
41
  }
35
42
 
36
43
  class ProductItem extends Item {
37
- _productType = ref("generic") as unknown as string;
44
+ _productType = ref('generic') as unknown as string;
38
45
  get productType() {
39
46
  return this._productType;
40
47
  }
41
48
  set productType(value) {
42
49
  this._productType = value;
43
50
  }
44
- _productFit = ref("perfect-fit") as unknown as string;
51
+ _productFit = ref('perfect-fit') as unknown as string;
45
52
  get productFit() {
46
53
  return this._productFit;
47
54
  }
@@ -49,17 +56,17 @@ class ProductItem extends Item {
49
56
  set productId(value: number) {
50
57
  this._productId = 0;
51
58
  }
52
- _productFeel = ref("sleek") as unknown as string;
59
+ _productFeel = ref('sleek') as unknown as string;
53
60
  public get productFeel() {
54
61
  return this._productFeel;
55
62
  }
56
63
  }
57
64
 
58
65
  class StoreItem extends ProductItem {
59
- _productType = ref("store") as unknown as string;
66
+ _productType = ref('store') as unknown as string;
60
67
  get productType() {
61
- const prefix = super.productFeel ?? "";
62
- return (prefix ? prefix + ":" : "") + this._productType;
68
+ const prefix = super.productFeel ?? '';
69
+ return (prefix ? prefix + ':' : '') + this._productType;
63
70
  }
64
71
  set productFeel(value: string) {
65
72
  this._productFeel = value;
@@ -67,14 +74,14 @@ class StoreItem extends ProductItem {
67
74
  }
68
75
 
69
76
  class RetailStoreItem extends StoreItem {
70
- _productType = ref("retail") as unknown as string;
77
+ _productType = ref('retail') as unknown as string;
71
78
  /** Do not overwrite productType getter here, on purpose. */
72
79
  productHistory = ref([]);
73
80
  get testProperty() {
74
81
  return this._testProperty;
75
82
  }
76
83
  calculateSize() {
77
- return (this._height as number) + (this._width as number);
84
+ return this._height + this._width;
78
85
  }
79
86
  }
80
87
 
@@ -116,93 +123,93 @@ class Entity {
116
123
  }
117
124
  }
118
125
 
119
- describe("ivue", () => {
120
- describe("base architecture functions", () => {
121
- it("getAllClassDescriptors correctly resolves all parent descriptors", () => {
126
+ describe('ivue', () => {
127
+ describe('base architecture functions', () => {
128
+ it('getAllClassDescriptors correctly resolves all parent descriptors', () => {
122
129
  const descriptors = getAllClassDescriptors(Item);
123
130
 
124
- expect(descriptors.has("width")).toBe(true);
125
- expect(typeof descriptors.get("width")?.get).toBe("function");
126
- expect(typeof descriptors.get("width")?.set).toBe("function");
131
+ expect(descriptors.has('width')).toBe(true);
132
+ expect(typeof descriptors.get('width')?.get).toBe('function');
133
+ expect(typeof descriptors.get('width')?.set).toBe('function');
127
134
 
128
- expect(descriptors.has("height")).toBe(true);
129
- expect(typeof descriptors.get("height")?.get).toBe("function");
130
- expect(typeof descriptors.get("height")?.set).toBe("function");
135
+ expect(descriptors.has('height')).toBe(true);
136
+ expect(typeof descriptors.get('height')?.get).toBe('function');
137
+ expect(typeof descriptors.get('height')?.set).toBe('function');
131
138
 
132
- expect(descriptors.has("testProperty")).toBe(true);
133
- expect(typeof descriptors.get("testProperty")?.get).toBe("undefined");
134
- expect(typeof descriptors.get("testProperty")?.set).toBe("function");
139
+ expect(descriptors.has('testProperty')).toBe(true);
140
+ expect(typeof descriptors.get('testProperty')?.get).toBe('undefined');
141
+ expect(typeof descriptors.get('testProperty')?.set).toBe('function');
135
142
  });
136
143
 
137
- it("getAllClassDescriptors correctly resolves all grand parent descriptors", () => {
144
+ it('getAllClassDescriptors correctly resolves all grand parent descriptors', () => {
138
145
  const descriptors = getAllClassDescriptors(ProductItem);
139
146
 
140
- expect(descriptors.has("width")).toBe(true);
141
- expect(typeof descriptors.get("width")?.get).toBe("function");
142
- expect(typeof descriptors.get("width")?.set).toBe("function");
147
+ expect(descriptors.has('width')).toBe(true);
148
+ expect(typeof descriptors.get('width')?.get).toBe('function');
149
+ expect(typeof descriptors.get('width')?.set).toBe('function');
143
150
 
144
- expect(descriptors.has("height")).toBe(true);
145
- expect(typeof descriptors.get("height")?.get).toBe("function");
146
- expect(typeof descriptors.get("height")?.set).toBe("function");
151
+ expect(descriptors.has('height')).toBe(true);
152
+ expect(typeof descriptors.get('height')?.get).toBe('function');
153
+ expect(typeof descriptors.get('height')?.set).toBe('function');
147
154
 
148
- expect(descriptors.has("testProperty")).toBe(true);
149
- expect(typeof descriptors.get("testProperty")?.get).toBe("undefined");
150
- expect(typeof descriptors.get("testProperty")?.set).toBe("function");
155
+ expect(descriptors.has('testProperty')).toBe(true);
156
+ expect(typeof descriptors.get('testProperty')?.get).toBe('undefined');
157
+ expect(typeof descriptors.get('testProperty')?.set).toBe('function');
151
158
 
152
- expect(descriptors.has("productType")).toBe(true);
153
- expect(typeof descriptors.get("productType")?.get).toBe("function");
154
- expect(typeof descriptors.get("productType")?.set).toBe("function");
159
+ expect(descriptors.has('productType')).toBe(true);
160
+ expect(typeof descriptors.get('productType')?.get).toBe('function');
161
+ expect(typeof descriptors.get('productType')?.set).toBe('function');
155
162
 
156
- expect(descriptors.has("productFeel")).toBe(true);
157
- expect(typeof descriptors.get("productFeel")?.get).toBe("function");
158
- expect(typeof descriptors.get("productFeel")?.set).toBe("undefined");
163
+ expect(descriptors.has('productFeel')).toBe(true);
164
+ expect(typeof descriptors.get('productFeel')?.get).toBe('function');
165
+ expect(typeof descriptors.get('productFeel')?.set).toBe('undefined');
159
166
 
160
- expect(descriptors.has("productId")).toBe(true);
161
- expect(typeof descriptors.get("productId")?.get).toBe("undefined");
162
- expect(typeof descriptors.get("productId")?.set).toBe("function");
167
+ expect(descriptors.has('productId')).toBe(true);
168
+ expect(typeof descriptors.get('productId')?.get).toBe('undefined');
169
+ expect(typeof descriptors.get('productId')?.set).toBe('function');
163
170
  });
164
171
 
165
- it("getAllClassProperties correctly resolves all parent properties", () => {
172
+ it('getAllClassProperties correctly resolves all parent properties', () => {
166
173
  const item = ivue(Item);
167
174
  const props = getAllClassProperties(item);
168
175
 
169
- expect(props.has("_width")).toBe(true);
170
- expect(props.has("_height")).toBe(true);
171
- expect(props.has("_testProperty")).toBe(true);
172
- expect(props.has("width")).toBe(true);
173
- expect(props.has("height")).toBe(true);
174
- expect(props.has("testProperty")).toBe(true);
176
+ expect(props.has('_width')).toBe(true);
177
+ expect(props.has('_height')).toBe(true);
178
+ expect(props.has('_testProperty')).toBe(true);
179
+ expect(props.has('width')).toBe(true);
180
+ expect(props.has('height')).toBe(true);
181
+ expect(props.has('testProperty')).toBe(true);
175
182
  });
176
183
 
177
- it("getAllClassProperties correctly resolves all grand parent properties", () => {
184
+ it('getAllClassProperties correctly resolves all grand parent properties', () => {
178
185
  const item = ivue(ProductItem);
179
186
  const props = getAllClassProperties(item);
180
187
 
181
- expect(props.has("_width")).toBe(true);
182
- expect(props.has("_height")).toBe(true);
183
- expect(props.has("_testProperty")).toBe(true);
184
- expect(props.has("_productType")).toBe(true);
185
- expect(props.has("_productFit")).toBe(true);
186
- expect(props.has("_productId")).toBe(true);
187
- expect(props.has("width")).toBe(true);
188
- expect(props.has("height")).toBe(true);
189
- expect(props.has("testProperty")).toBe(true);
190
- expect(props.has("productType")).toBe(true);
191
- expect(props.has("productFit")).toBe(true);
192
- expect(props.has("productId")).toBe(true);
188
+ expect(props.has('_width')).toBe(true);
189
+ expect(props.has('_height')).toBe(true);
190
+ expect(props.has('_testProperty')).toBe(true);
191
+ expect(props.has('_productType')).toBe(true);
192
+ expect(props.has('_productFit')).toBe(true);
193
+ expect(props.has('_productId')).toBe(true);
194
+ expect(props.has('width')).toBe(true);
195
+ expect(props.has('height')).toBe(true);
196
+ expect(props.has('testProperty')).toBe(true);
197
+ expect(props.has('productType')).toBe(true);
198
+ expect(props.has('productFit')).toBe(true);
199
+ expect(props.has('productId')).toBe(true);
193
200
  });
194
201
  });
195
202
 
196
- describe("ivue full class reactivity inheritance", () => {
197
- it("basic refs are working", () => {
203
+ describe('ivue full class reactivity inheritance', () => {
204
+ it('basic refs are working', () => {
198
205
  const basic = ivue(Basic);
199
206
 
200
- expect(basic.id).toBe("id");
201
- basic.id = "test";
202
- expect(basic.id).toBe("test");
207
+ expect(basic.id).toBe('id');
208
+ basic.id = 'test';
209
+ expect(basic.id).toBe('test');
203
210
  });
204
211
 
205
- it("basic refs are unwrapped inside reactive ivue object", () => {
212
+ it('basic refs are unwrapped inside reactive ivue object', () => {
206
213
  const item = ivue(Item);
207
214
 
208
215
  expect(item._height).toBe(5);
@@ -210,46 +217,46 @@ describe("ivue", () => {
210
217
  expect(isReactive(item)).toBe(true);
211
218
  });
212
219
 
213
- it("basic getter as computed is working", () => {
220
+ it('basic getter as computed is working', () => {
214
221
  const item = ivue(Item);
215
222
 
216
223
  expect(item._height).toBe(5);
217
- expect(item.height).toBe("5px");
224
+ expect(item.height).toBe('5px');
218
225
  expect(item._width).toBe(5);
219
- expect(item.width).toBe("5px");
226
+ expect(item.width).toBe('5px');
220
227
  });
221
228
 
222
- it("basic setter is working", () => {
229
+ it('basic setter is working', () => {
223
230
  const item = ivue(Item);
224
231
 
225
232
  expect(item._height).toBe(5);
226
233
  /** SET VIA SETTER */
227
234
  item.height = 10;
228
- expect(item.height).toBe("10px");
235
+ expect(item.height).toBe('10px');
229
236
 
230
237
  expect(item._width).toBe(5);
231
238
  /** SET VIA SETTER */
232
239
  item.width = 10;
233
- expect(item.width).toBe("10px");
240
+ expect(item.width).toBe('10px');
234
241
  });
235
242
 
236
- it("parent getters from the prototype chain are working", () => {
243
+ it('parent getters from the prototype chain are working', () => {
237
244
  const item = ivue(RetailStoreItem);
238
245
 
239
- expect(item.productType).toBe("sleek:retail");
246
+ expect(item.productType).toBe('sleek:retail');
240
247
  });
241
248
 
242
- it("parent setters from the prototype chain are working", () => {
249
+ it('parent setters from the prototype chain are working', () => {
243
250
  const item = ivue(RetailStoreItem);
244
251
 
245
- expect(item.productType).toBe("sleek:retail");
252
+ expect(item.productType).toBe('sleek:retail');
246
253
  /** SET VIA SETTER */
247
254
  // @ts-expect-error ivue supports setting set and get separately in different levels of class prototype chain
248
- item.productType = "new-retail";
249
- expect(item.productType).toBe("sleek:new-retail");
255
+ item.productType = 'new-retail';
256
+ expect(item.productType).toBe('sleek:new-retail');
250
257
  });
251
258
 
252
- it("parent setters that are set at different levels in the prototype chain work together in harmony", () => {
259
+ it('parent setters that are set at different levels in the prototype chain work together in harmony', () => {
253
260
  const item = ivue(RetailStoreItem);
254
261
  /**
255
262
  * Setter for product feel is set on @see {StoreItem} class,
@@ -257,34 +264,34 @@ describe("ivue", () => {
257
264
  * but in ivue they still work together just as they should,
258
265
  * completely emulating native JavaScript implementation.
259
266
  */
260
- item.productFeel = "new-feel";
261
- expect(item.productType).toBe("new-feel:retail");
267
+ item.productFeel = 'new-feel';
268
+ expect(item.productType).toBe('new-feel:retail');
262
269
  });
263
270
 
264
- it("parent setters are working even without getters", () => {
271
+ it('parent setters are working even without getters', () => {
265
272
  const item = ivue(RetailStoreItem);
266
273
 
267
- expect(item._testProperty).toBe("test-value");
274
+ expect(item._testProperty).toBe('test-value');
268
275
  /** SET VIA SETTER */
269
276
  // @ts-expect-error ivue supports setting set and get separately in different levels of class prototype chain
270
- item.testProperty = "new-test-value";
271
- expect(item._testProperty).toBe("new-test-value");
277
+ item.testProperty = 'new-test-value';
278
+ expect(item._testProperty).toBe('new-test-value');
272
279
  });
273
280
  });
274
281
 
275
- describe("ivue toRefs conversion", () => {
276
- it("toRefs all properties", () => {
282
+ describe('ivue toRefs conversion', () => {
283
+ it('toRefs all properties', () => {
277
284
  const { _height, _width, height, width, calculateSize } =
278
285
  ivue(RetailStoreItem).toRefs();
279
286
 
280
287
  expect(_height.value).toBe(5);
281
288
  expect(_width.value).toBe(5);
282
- expect(height.value).toBe("5px");
283
- expect(width.value).toBe("5px");
289
+ expect(height.value).toBe('5px');
290
+ expect(width.value).toBe('5px');
284
291
  expect(calculateSize()).toBe(10);
285
292
  });
286
293
 
287
- it("toRefs all properties with pre-calculated computeds", () => {
294
+ it('toRefs all properties with pre-calculated computeds', () => {
288
295
  const item = ivue(RetailStoreItem);
289
296
 
290
297
  /** Access computeds to pre-calculate them before toRefs() */
@@ -293,8 +300,8 @@ describe("ivue", () => {
293
300
 
294
301
  const { height, width, calculateSize } = item.toRefs();
295
302
 
296
- expect(height.value).toBe("5px");
297
- expect(width.value).toBe("5px");
303
+ expect(height.value).toBe('5px');
304
+ expect(width.value).toBe('5px');
298
305
  expect(calculateSize()).toBe(10);
299
306
  });
300
307
 
@@ -302,16 +309,16 @@ describe("ivue", () => {
302
309
  const item = ivue(ProductItem);
303
310
 
304
311
  const { _height, _width, height, width } = item.toRefs([
305
- "_width",
306
- "_height",
307
- "height",
308
- "width",
312
+ '_width',
313
+ '_height',
314
+ 'height',
315
+ 'width',
309
316
  ]);
310
317
 
311
318
  expect(_height.value).toBe(5);
312
319
  expect(_width.value).toBe(5);
313
- expect(height.value).toBe("5px");
314
- expect(width.value).toBe("5px");
320
+ expect(height.value).toBe('5px');
321
+ expect(width.value).toBe('5px');
315
322
  });
316
323
 
317
324
  it("toRefs(['prop', ...]) specific properties with pre-calculated computeds", () => {
@@ -322,31 +329,31 @@ describe("ivue", () => {
322
329
  item.width;
323
330
 
324
331
  const { _height, _width, height, width } = item.toRefs([
325
- "_width",
326
- "_height",
327
- "height",
328
- "width",
332
+ '_width',
333
+ '_height',
334
+ 'height',
335
+ 'width',
329
336
  ]);
330
337
 
331
338
  expect(_height.value).toBe(5);
332
339
  expect(_width.value).toBe(5);
333
- expect(height.value).toBe("5px");
334
- expect(width.value).toBe("5px");
340
+ expect(height.value).toBe('5px');
341
+ expect(width.value).toBe('5px');
335
342
  });
336
343
 
337
344
  it("toRefs(['prop', ...]) specific functions", () => {
338
- const { calculateSize } = ivue(RetailStoreItem).toRefs(["calculateSize"]);
345
+ const { calculateSize } = ivue(RetailStoreItem).toRefs(['calculateSize']);
339
346
 
340
347
  expect(calculateSize()).toBe(10);
341
348
  });
342
349
 
343
- it("toRefs() all properties with using a computed as a setter without a getter", () => {
350
+ it('toRefs() all properties with using a computed as a setter without a getter', () => {
344
351
  const item = ivue(ProductItem);
345
352
 
346
353
  const { testProperty } = item.toRefs();
347
354
 
348
- testProperty.value = "changed-test-value";
349
- expect(item._testProperty).toBe("changed-test-value");
355
+ testProperty.value = 'changed-test-value';
356
+ expect(item._testProperty).toBe('changed-test-value');
350
357
  const call = () => testProperty.value;
351
358
  expect(() => call()).toThrowError(TypeError);
352
359
  });
@@ -354,13 +361,13 @@ describe("ivue", () => {
354
361
  it("toRefs(['prop', ...]) specific properties with using a computed as a setter without a getter", () => {
355
362
  const item = ivue(ProductItem);
356
363
 
357
- const { testProperty } = item.toRefs(["testProperty"]);
364
+ const { testProperty } = item.toRefs(['testProperty']);
358
365
 
359
- testProperty.value = "changed-test-value";
360
- expect(item._testProperty).toBe("changed-test-value");
366
+ testProperty.value = 'changed-test-value';
367
+ expect(item._testProperty).toBe('changed-test-value');
361
368
  });
362
369
 
363
- it("toRefs() all properties with a computed that has a setter without a getter, should throw error when accessed as a getter", () => {
370
+ it('toRefs() all properties with a computed that has a setter without a getter, should throw error when accessed as a getter', () => {
364
371
  const item = ivue(ProductItem);
365
372
 
366
373
  const { testProperty } = item.toRefs();
@@ -372,30 +379,30 @@ describe("ivue", () => {
372
379
  it("toRefs(['prop', ...]) with specific properties with a computed that has a setter without a getter, should throw error when accessed as a getter", () => {
373
380
  const item = ivue(ProductItem);
374
381
 
375
- const { testProperty } = item.toRefs(["testProperty"]);
382
+ const { testProperty } = item.toRefs(['testProperty']);
376
383
 
377
384
  const call = () => testProperty.value;
378
385
  expect(() => call()).toThrowError(TypeError);
379
386
  });
380
387
  });
381
388
 
382
- describe("ivue constructor", () => {
383
- it("ivue constructor arguments get passed to the constructor work", () => {
389
+ describe('ivue constructor', () => {
390
+ it('ivue constructor arguments get passed to the constructor work', () => {
384
391
  const entity = ivue(Entity, 10, 20);
385
392
  expect(entity.height).toBe(10);
386
393
  expect(entity.width).toBe(20);
387
394
  });
388
395
  });
389
396
 
390
- describe("ivue init method", () => {
391
- it("init works", () => {
397
+ describe('ivue init method', () => {
398
+ it('init works', () => {
392
399
  const entity = ivue(Entity, 10, 20);
393
400
  expect(entity.key).toBe(5);
394
401
  });
395
402
  });
396
403
 
397
- describe("ivue disabled getters", () => {
398
- it("ivue active getter is a computed", () => {
404
+ describe('ivue disabled getters', () => {
405
+ it('ivue active getter is a computed', () => {
399
406
  computedCalls = 0;
400
407
  notComputedCalls = 0;
401
408
 
@@ -409,7 +416,7 @@ describe("ivue", () => {
409
416
  expect(computedCalls).toBe(2); // Computed call increments to 2, because dependency changed
410
417
  });
411
418
 
412
- it("ivue disabled getter is not a computed", () => {
419
+ it('ivue disabled getter is not a computed', () => {
413
420
  computedCalls = 0;
414
421
  notComputedCalls = 0;
415
422
 
@@ -423,4 +430,93 @@ describe("ivue", () => {
423
430
  expect(notComputedCalls).toBe(3); // Always incrementing
424
431
  });
425
432
  });
433
+
434
+ describe('util functions', () => {
435
+ it('isClass correctly determines if a value is a class', () => {
436
+ expect(isClass('string')).toBe(false);
437
+ expect(isClass(10)).toBe(false);
438
+ expect(isClass(null)).toBe(false);
439
+ expect(isClass(() => {})).toBe(false);
440
+ expect(isClass(function () {})).toBe(false);
441
+ expect(
442
+ isClass(
443
+ class {
444
+ prop = 1;
445
+ }
446
+ )
447
+ ).toBe(true);
448
+ });
449
+
450
+ it('propsWithDefaults correctly assigns defaults to typed props', () => {
451
+ class SampleClass {}
452
+ const defaultTypes = {
453
+ updateEntity: { type: [Boolean, String] as PropType<boolean | string> },
454
+ updatePath: { type: String as PropType<string> },
455
+ updateFieldsTemplate: { type: [Array, Object] as PropType<any[]> },
456
+ updateFieldsParams: { type: [Object] as PropType<Record<string, any>> },
457
+ updateLabel: { type: String as PropType<string> },
458
+ /** Drag and Drop */
459
+ draggable: { type: Boolean as PropType<boolean> },
460
+ /** Runtime Class Runner */
461
+ runner: {
462
+ type: [Object, Function, Boolean] as PropType<
463
+ any | SampleClass | false
464
+ >,
465
+ },
466
+ fn: {
467
+ type: [Function] as PropType<(...args: any[]) => any>,
468
+ },
469
+ };
470
+
471
+ /** Example Params Defaults */
472
+ const defaults: ExtractPropDefaultTypes<typeof defaultTypes> = {
473
+ updatePath: '', // String
474
+ updateEntity: false, // Boolean
475
+ updateFieldsTemplate: [], // Array
476
+ updateFieldsParams: { // Object
477
+ active: true,
478
+ },
479
+ updateLabel: 'Update Item', // String
480
+ draggable: true, // Boolean
481
+ /** Runtime Class Runner */
482
+ runner: SampleClass, // Class
483
+ fn: () => {}, // Function
484
+ };
485
+
486
+ const _propsWithDefaults = propsWithDefaults(defaults, defaultTypes);
487
+ // Boolean
488
+ expect(_propsWithDefaults.updateEntity.default).toBe(false);
489
+ expect(_propsWithDefaults.draggable.default).toBe(true);
490
+
491
+ // String
492
+ expect(_propsWithDefaults.updatePath.default).toBe('');
493
+
494
+ // Array
495
+ expect(_propsWithDefaults.updateFieldsTemplate.default).toBeTypeOf(
496
+ 'function'
497
+ );
498
+ expect(
499
+ Array.isArray(
500
+ (_propsWithDefaults.updateFieldsTemplate.default as () => any)()
501
+ )
502
+ ).toBe(true);
503
+
504
+ // Object
505
+ expect(
506
+ (_propsWithDefaults.updateFieldsParams.default as () => any)().active
507
+ ).toBe(true);
508
+
509
+ // Class
510
+ expect(_propsWithDefaults.runner.default).toBeTypeOf('function');
511
+ expect(isClass((_propsWithDefaults.runner.default as () => any)())).toBe(
512
+ true
513
+ );
514
+
515
+ // Function
516
+ expect(_propsWithDefaults.fn.default).toBeTypeOf('function');
517
+ expect(isClass((_propsWithDefaults.fn.default as () => any)())).toBe(
518
+ false
519
+ );
520
+ });
521
+ });
426
522
  });