aprog 2.1.9 → 2.2.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/README.md CHANGED
@@ -22,6 +22,16 @@ or
22
22
  npm i aprog -D
23
23
  ```
24
24
 
25
+ Завантаження `Constructs`
26
+ ```shell
27
+ node node_modules/aprog/publish.js
28
+ ```
29
+
30
+ Завантаження `Constructs` з перезаписом
31
+ ```shell
32
+ node node_modules/aprog/publish.js --force
33
+ ```
34
+
25
35
  ### Basic Usage
26
36
 
27
37
  Підключення router:
@@ -139,16 +149,6 @@ onInput: (event) => {
139
149
  <input value="4">
140
150
  ```
141
151
 
142
- Завантаження `Constructs`
143
- ```shell
144
- node node_modules/aprog/publish.js
145
- ```
146
-
147
- Завантаження `Constructs` з перезаписом
148
- ```shell
149
- node node_modules/aprog/publish.js --force
150
- ```
151
-
152
152
  ########## ########## ########## ########## ##########
153
153
 
154
154
  Загальний список методів:
@@ -175,6 +175,9 @@ node node_modules/aprog/publish.js --force
175
175
 
176
176
  - *uniquePage({key: "default", callbackTrue: () => {"empty"}, callbackFalse: () => {"empty"}, timer: "default")*
177
177
 
178
+ - *const wrap = (value) => new SmartWrapper(value);*
179
+ - *wrap(data).get("key").val*
180
+
178
181
  ### Info
179
182
 
180
183
  - Додано безплатний чат із `Gemini`
package/index.js CHANGED
@@ -22,5 +22,6 @@ export {
22
22
  } from './src/html.js';
23
23
  export { prism } from "./src/prism.js";
24
24
  export { uniquePage } from "./src/pages.js";
25
- export { default as AprogClass } from './src/classes/AprogClass.js';
25
+ export { state, wrap } from "./src/helper.js";
26
+ export { default as StateWrapper } from './src/classes/StateWrapper.js';
26
27
  export { default as SmartWrapper } from './src/classes/SmartWrapper.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aprog",
3
- "version": "2.1.9",
3
+ "version": "2.2.1",
4
4
  "description": "Допоміжна JavaScript-бібліотека для проєктів",
5
5
  "main": "index.js",
6
6
  "exports": {
@@ -1,39 +1,158 @@
1
1
  class SmartWrapper {
2
2
  constructor(value) {
3
3
  this._value = value;
4
+ }
5
+
6
+ /**
7
+ * Отримати значення по ключу
8
+ * @param {string|number} key
9
+ * @param {*} def
10
+ * @returns {SmartWrapper}
11
+ */
12
+ get(key, def = null) {
13
+ if (this._value === null || this._value === undefined) {
14
+ return new SmartWrapper(def);
15
+ }
16
+
17
+ if (typeof this._value === 'object') {
18
+ if (Array.isArray(this._value)) {
19
+ return new SmartWrapper(this._value[key] ?? def);
20
+ }
4
21
 
5
- return new Proxy(this, {
6
- get: (target, prop) => {
7
- if (prop === 'val') return () => target._value;
8
- if (prop === 'isNull') return () => target._value === null || target._value === undefined;
9
- if (prop === 'toArray') return () => Array.isArray(target._value) ? target._value : Object.values(target._value ?? {});
10
- if (prop === 'toObject') return () => (typeof target._value === 'object' ? target._value : {});
11
- if (prop === 'toString') return () => typeof target._value === 'string' ? target._value : String(target._value ?? '');
12
- if (prop === 'get') {
13
- // підтримка dot notation
14
- return (path, def = null) => {
15
- const keys = path.split('.');
16
- let current = target._value;
17
- for (const key of keys) {
18
- if (current && (typeof current === 'object') && key in current) {
19
- current = current[key];
20
- } else {
21
- return new SmartWrapper(def);
22
- }
23
- }
24
- return new SmartWrapper(current);
25
- };
26
- }
27
-
28
- // доступ до властивості як ланцюг
29
- if (target._value && typeof target._value === 'object' && prop in target._value) {
30
- return new SmartWrapper(target._value[prop]);
31
- }
32
-
33
- // fallback — undefined
34
- return new SmartWrapper(undefined);
22
+ if (Object.prototype.hasOwnProperty.call(this._value, key)) {
23
+ return new SmartWrapper(this._value[key]);
35
24
  }
36
- });
25
+ }
26
+
27
+ return new SmartWrapper(def);
28
+ }
29
+
30
+ /**
31
+ * Отримати вкладене значення за шляхом 'a.b.c'
32
+ * @param {string} path
33
+ * @param {*} def
34
+ * @returns {SmartWrapper}
35
+ */
36
+ path(path, def = null) {
37
+ const keys = path.split('.');
38
+ let current = new SmartWrapper(this._value);
39
+ for (const key of keys) {
40
+ current = current.get(key);
41
+ }
42
+ return current.isNull ? new SmartWrapper(def) : current;
43
+ }
44
+
45
+ /**
46
+ * Перевірити чи існує ключ
47
+ * @param {string|number} key
48
+ * @returns {boolean}
49
+ */
50
+ has(key) {
51
+ if (this._value === null || this._value === undefined) return false;
52
+ if (Array.isArray(this._value)) return key in this._value;
53
+ if (typeof this._value === 'object') return Object.prototype.hasOwnProperty.call(this._value, key);
54
+ return false;
55
+ }
56
+
57
+ /**
58
+ * Повернути тільки вказані ключі
59
+ * @param {string[]} keys
60
+ * @returns {SmartWrapper}
61
+ */
62
+ only(keys = []) {
63
+ if (typeof this._value !== 'object' || this._value === null) {
64
+ return new SmartWrapper({});
65
+ }
66
+
67
+ const result = {};
68
+ for (const key of keys) {
69
+ if (Object.prototype.hasOwnProperty.call(this._value, key)) {
70
+ result[key] = this._value[key];
71
+ }
72
+ }
73
+
74
+ return new SmartWrapper(result);
75
+ }
76
+
77
+ /**
78
+ * Встановити нове значення по ключу
79
+ * @param {string|number} key
80
+ * @param {*} val
81
+ * @returns {SmartWrapper}
82
+ */
83
+ set(key, val) {
84
+ if (typeof this._value === 'object' && this._value !== null) {
85
+ return new SmartWrapper({ ...this._value, [key]: val });
86
+ }
87
+ return new SmartWrapper({ [key]: val });
88
+ }
89
+
90
+ /**
91
+ * Пройтись по значеннях як по масиву або об'єкту
92
+ * @param {function(*, string|number): *} callback
93
+ * @returns {SmartWrapper}
94
+ */
95
+ map(callback) {
96
+ if (Array.isArray(this._value)) {
97
+ return new SmartWrapper(this._value.map(callback));
98
+ }
99
+
100
+ if (typeof this._value === 'object' && this._value !== null) {
101
+ return new SmartWrapper(
102
+ Object.entries(this._value).map(([key, val]) => callback(val, key))
103
+ );
104
+ }
105
+
106
+ return new SmartWrapper([]);
107
+ }
108
+
109
+ /**
110
+ * Отримати реальне значення
111
+ * @returns {*}
112
+ */
113
+ get val() {
114
+ return this._value;
115
+ }
116
+
117
+ /**
118
+ * Чи є значення null або undefined
119
+ * @returns {boolean}
120
+ */
121
+ get isNull() {
122
+ return this._value === null || this._value === undefined;
123
+ }
124
+
125
+ /**
126
+ * Привести до масиву (рекурсивно)
127
+ * @returns {Array}
128
+ */
129
+ get toArray() {
130
+ if (Array.isArray(this._value)) return this._value;
131
+ if (typeof this._value === 'object' && this._value !== null) return Object.values(this._value);
132
+ return [];
133
+ }
134
+
135
+ /**
136
+ * Привести до об'єкта (рекурсивно)
137
+ * @returns {Object}
138
+ */
139
+ get toObject() {
140
+ if (typeof this._value === 'object' && this._value !== null) return this._value;
141
+ return {};
142
+ }
143
+
144
+ /**
145
+ * Привести до рядка
146
+ * @returns {string}
147
+ */
148
+ get toString() {
149
+ if (typeof this._value === 'string') return this._value;
150
+ if (typeof this._value === 'number' || typeof this._value === 'boolean') {
151
+ return String(this._value);
152
+ }
153
+ if (Array.isArray(this._value)) return JSON.stringify(this._value);
154
+ if (typeof this._value === 'object' && this._value !== null) return JSON.stringify(Object.values(this._value));
155
+ return '';
37
156
  }
38
157
  }
39
158
 
@@ -0,0 +1,59 @@
1
+ class StateWrapper {
2
+ #value;
3
+
4
+ constructor(initialValue) {
5
+ this.#value = initialValue;
6
+
7
+ return new Proxy(this, {
8
+ get: (target, prop) => {
9
+ if (prop === 'set') {
10
+ return (newValue) => {
11
+ target.#value = typeof newValue === 'function'
12
+ ? newValue(target.#value)
13
+ : newValue;
14
+ };
15
+ }
16
+
17
+ if (prop === 'value') {
18
+ return target.#value;
19
+ }
20
+
21
+ if (typeof target.#value === 'object' && target.#value !== null && prop in target.#value) {
22
+ return target.#value[prop];
23
+ }
24
+
25
+ return Reflect.get(target, prop);
26
+ },
27
+
28
+ set: (target, prop, val) => {
29
+ if (typeof target.#value === 'object' && target.#value !== null) {
30
+ target.#value[prop] = val;
31
+ return true;
32
+ }
33
+ return false;
34
+ },
35
+
36
+ apply: (_, __, ___) => {
37
+ return target.#value;
38
+ },
39
+
40
+ getPrototypeOf: (target) => {
41
+ return Object.getPrototypeOf(target.#value);
42
+ },
43
+
44
+ has: (target, key) => {
45
+ return key in target.#value;
46
+ },
47
+
48
+ ownKeys: (target) => {
49
+ return Reflect.ownKeys(target.#value);
50
+ },
51
+
52
+ getOwnPropertyDescriptor: (target, key) => {
53
+ return Object.getOwnPropertyDescriptor(target.#value, key);
54
+ }
55
+ });
56
+ }
57
+ }
58
+
59
+ export default StateWrapper;
@@ -28,7 +28,7 @@ export const ButtonConstructor = {
28
28
  } = {}) {
29
29
  return this.is = button({
30
30
  id: id || GUID(),
31
- class: `${this.class} btn ${className} disabled`,
31
+ class: `${this.class} btn ${className} disabled`.trim(),
32
32
  style: style,
33
33
  ...(type && {type: type}),
34
34
  value: text,
@@ -31,7 +31,7 @@ export const InputConstructor = {
31
31
  } = {}) {
32
32
  return this.is = input({
33
33
  id: id || GUID(),
34
- class: `${this.class} input ${className}`,
34
+ class: `${this.class} input ${className}`.trim(),
35
35
  style: style,
36
36
  ...(type && {type: type}),
37
37
  focus: focus,
@@ -0,0 +1,45 @@
1
+ import {GUID, select} from "aprog";
2
+
3
+ /**
4
+ * AprogJS Constructor
5
+ * --- SelectConstructor ---
6
+ * Copyright (c) 2025 AlexProger.
7
+ */
8
+ export const SelectConstructor = {
9
+ /**
10
+ * create HTMLElement
11
+ */
12
+ constructor() {
13
+ const instance = Object.create(this);
14
+ instance.class = GUID();
15
+ return instance;
16
+ },
17
+
18
+ /**
19
+ * set HTMLElement
20
+ */
21
+ element({
22
+ id = undefined,
23
+ className = "",
24
+ style = {},
25
+ option = undefined,
26
+ options = undefined,
27
+ callback = () => {},
28
+ } = {}) {
29
+ return this.is = select({
30
+ id: id || GUID(),
31
+ class: `${this.class} input ${className}`.trim(),
32
+ style: style,
33
+ ...(option && {option: option}),
34
+ ...(options && {options: options}),
35
+ onChange: callback,
36
+ });
37
+ },
38
+
39
+ /**
40
+ * get target [HTMLElement]
41
+ */
42
+ get target() {
43
+ return this?.is;
44
+ }
45
+ };
package/src/helper.js ADDED
@@ -0,0 +1,6 @@
1
+ import StateWrapper from "./classes/StateWrapper.js";
2
+ import SmartWrapper from "./classes/SmartWrapper.js";
3
+
4
+ export const state = (value) => new StateWrapper(value);
5
+
6
+ export const wrap = (value) => new SmartWrapper(value);
@@ -1,23 +0,0 @@
1
- class AprogClass {
2
- #states = [];
3
- #cursor = 0;
4
-
5
- useState(initialValue) {
6
- const index = this.#cursor;
7
-
8
- if (this.#states[index] === undefined) {
9
- this.#states[index] = initialValue;
10
- }
11
-
12
- const setState = (newValue) => {
13
- const current = this.#states[index];
14
- this.#states[index] = typeof newValue === "function" ? newValue(current) : newValue;
15
- };
16
-
17
- const value = this.#states[index];
18
- this.#cursor++;
19
- return [value, setState];
20
- }
21
- }
22
-
23
- export default AprogClass;