@kizmann/pico-js 2.0.13 → 2.1.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": "@kizmann/pico-js",
3
- "version": "2.0.13",
3
+ "version": "2.1.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "private": false,
package/src/index.esm.ts CHANGED
@@ -28,12 +28,12 @@ export {
28
28
  }
29
29
 
30
30
  // Work in progress (not started yet)
31
- // import { default as Map } from "./wip/Map.ts";
32
- // import { default as Element } from "./wip/Element.ts";
31
+ import { default as Map } from "./wip/Map.ts";
32
+ import { default as Element } from "./wip/Element.ts";
33
33
 
34
- // export {
35
- // Map, Element
36
- // }
34
+ export {
35
+ Map, Element
36
+ }
37
37
 
38
38
  /**
39
39
  * @type {Mix}
@@ -20,11 +20,36 @@ export interface PicoNowDefault extends PicoNowInterface
20
20
  */
21
21
  export class PicoNowDefault
22
22
  {
23
- static test(value : any) : boolean
23
+ calc(value : any, scope : string) : PicoNow
24
24
  {
25
- return value instanceof Date;
26
- }
25
+ if ( ! Mix.isNum(value) ) {
26
+ value = Mix.int(value);
27
+ }
28
+
29
+ let result = 0;
30
+
31
+ if ( /^seconds?$/i.test(scope) ) {
32
+ result = value * 1000;
33
+ }
34
+
35
+ if ( /^minutes?$/i.test(scope) ) {
36
+ result = value * 1000 * 60;
37
+ }
38
+
39
+ if ( /^hours?$/i.test(scope) ) {
40
+ result = value * 1000 * 60 * 60;
41
+ }
42
+
43
+ if ( /^dates?$/i.test(scope) ) {
44
+ result = value * 1000 * 60 * 60 * 24;
45
+ }
46
+
47
+ this.value.setTime(...[
48
+ this.value.getTime() + result
49
+ ]);
27
50
 
51
+ return <PicoNow> <unknown> this;
52
+ }
28
53
  /**
29
54
  * Get value by scope
30
55
  *
@@ -293,6 +318,22 @@ export class PicoNowDefault
293
318
  scope = 'date';
294
319
  }
295
320
 
321
+ if ( /^seconds?$/i.test(scope) ) {
322
+ return this.calc(value, scope);
323
+ }
324
+
325
+ if ( /^minutes?$/i.test(scope) ) {
326
+ return this.calc(value, scope);
327
+ }
328
+
329
+ if ( /^hours?$/i.test(scope) ) {
330
+ return this.calc(value, scope);
331
+ }
332
+
333
+ if ( /^dates?$/i.test(scope) ) {
334
+ return this.calc(value, scope);
335
+ }
336
+
296
337
  this.set(this.get(scope) + Mix.int(value), scope);
297
338
 
298
339
  return <PicoNow> <unknown> this;
@@ -313,7 +354,25 @@ export class PicoNowDefault
313
354
  scope = 'date';
314
355
  }
315
356
 
316
- this.set(this.get(scope) - Mix.int(value), scope);
357
+ if ( /^seconds?$/i.test(scope) ) {
358
+ return this.calc(value * -1, scope);
359
+ }
360
+
361
+ if ( /^minutes?$/i.test(scope) ) {
362
+ return this.calc(value * -1, scope);
363
+ }
364
+
365
+ if ( /^hours?$/i.test(scope) ) {
366
+ return this.calc(value * -1, scope);
367
+ }
368
+
369
+ if ( /^dates?$/i.test(scope) ) {
370
+ return this.calc(value * -1, scope);
371
+ }
372
+
373
+ this.set(...[
374
+ this.get(scope) - Mix.int(value), scope
375
+ ]);
317
376
 
318
377
  return <PicoNow> <unknown> this;
319
378
  }
@@ -0,0 +1,122 @@
1
+ import { Arr, Mix, Now, Obj, Str } from "../index.esm.ts";
2
+ import { PicoNow, PicoNowInterface } from "../utils/Now.ts";
3
+ import PicoNowDefault from "./NowDefault.ts";
4
+ import PicoNowFormat from "./NowFormat.ts";
5
+
6
+ export interface PicoNowDuration extends PicoNowInterface,
7
+ PicoNowDefault,
8
+ PicoNowFormat
9
+ {
10
+ //
11
+ }
12
+
13
+ /**
14
+ * @memberof PicoNow
15
+ */
16
+ export class PicoNowDuration
17
+ {
18
+
19
+ /**
20
+ * Calculate duration between two dates
21
+ *
22
+ * @example Now.make("2026-01-01").duration("2026-02-01") // => { years: 0, months: 1, ... }
23
+ *
24
+ * @param {any} value End date
25
+ * @returns {any} Duration object
26
+ */
27
+ duration(value : any) : any
28
+ {
29
+ if ( Mix.isNum(value) ) {
30
+ value = this.clone().add(value, 'seconds');
31
+ }
32
+
33
+ const date = Now.make(value);
34
+
35
+ const keys = [
36
+ 'years', 'months', 'dates', 'hours', 'minutes', 'seconds'
37
+ ];
38
+
39
+ let result : any = {};
40
+
41
+ Arr.each(keys, (key : string) => {
42
+ result[key] = date.get(key) - this.get(key);
43
+ });
44
+
45
+ const last = date.clone().sub(1, 'month')
46
+ .last('date').date();
47
+
48
+ if ( result.minutes && result.seconds < 0 ) {
49
+ result.minutes -= 1, result.seconds += 60;
50
+ }
51
+
52
+ if ( result.hours && result.minutes < 0 ) {
53
+ result.hours -= 1, result.minutes += 60;
54
+ }
55
+
56
+ if ( result.dates && result.hours < 0 ) {
57
+ result.dates -= 1, result.hours += 24;
58
+ }
59
+
60
+ if ( result.months && result.dates < 0 ) {
61
+ result.months -= 1, result.dates += last;
62
+ }
63
+
64
+ if ( result.years && result.months < 0 ) {
65
+ result.years -= 1, result.months += 12;
66
+ }
67
+
68
+ return result;
69
+ }
70
+
71
+ /**
72
+ * Normalize seconds into duration parts
73
+ *
74
+ * @example Now.make().safeDuration(3661) // => { dates: 0, hours: 1, minutes: 1, seconds: 1 }
75
+ *
76
+ * @param {number} value Seconds value
77
+ * @returns {any} Duration object
78
+ */
79
+ safeDuration(value : number) : any
80
+ {
81
+ let result : any = {
82
+ dates: 0,
83
+ hours: 0,
84
+ minutes: 0,
85
+ seconds: Mix.int(value)
86
+ };
87
+
88
+ if ( result.seconds >= 60 ) {
89
+ result.minutes = Math.floor(result.seconds / 60);
90
+ result.seconds %= 60;
91
+ }
92
+
93
+ if ( result.minutes >= 60 ) {
94
+ result.hours = Math.floor(result.minutes / 60);
95
+ result.minutes %= 60;
96
+ }
97
+
98
+ if ( result.hours >= 24 ) {
99
+ result.dates = Math.floor(result.hours / 24);
100
+ result.hours %= 24;
101
+ }
102
+
103
+ return result;
104
+ }
105
+
106
+ /**
107
+ * Get difference between two dates in seconds
108
+ *
109
+ * @example Now.make("2026-01-02").diffrence("2026-01-01") // => 86400
110
+ *
111
+ * @param {any} [value=null] Compare date
112
+ * @returns {number} Seconds difference
113
+ */
114
+ diffrence(value : any = null) : number
115
+ {
116
+ return this.code('x') - Now.make(value).code('x');
117
+ }
118
+
119
+ }
120
+
121
+
122
+ export default PicoNowDuration;
@@ -107,7 +107,7 @@ export class PicoArray
107
107
  return 0;
108
108
  }
109
109
 
110
- if ( index + 1 > target.length ) {
110
+ if ( index + 1 > target.length - 1 ) {
111
111
  return 0;
112
112
  }
113
113
 
package/src/utils/Dom.ts CHANGED
@@ -28,11 +28,35 @@ export const PicoDomPlugins = [
28
28
 
29
29
  export interface PicoDomInterface
30
30
  {
31
+ /**
32
+ * @type {any}
33
+ */
31
34
  el: any;
35
+
36
+ /**
37
+ * @type {any[]}
38
+ */
32
39
  els: any[];
40
+
41
+ /**
42
+ * @param {Function} plugin
43
+ * @returns {void}
44
+ */
33
45
  extend(plugin : Function) : void;
46
+
47
+ /**
48
+ * @returns {any}
49
+ */
34
50
  win() : any;
51
+
52
+ /**
53
+ * @returns {any}
54
+ */
35
55
  doc() : any;
56
+
57
+ /**
58
+ * @returns {any}
59
+ */
36
60
  body() : any;
37
61
  }
38
62
 
@@ -199,6 +223,18 @@ export class PicoDom extends trait(PicoDomPlugins)
199
223
  return this.doc().body;
200
224
  }
201
225
 
226
+ /**
227
+ * Remove elements from DOM
228
+ *
229
+ * @example Dom.find("div").remove()
230
+ *
231
+ * @returns {void} No return value
232
+ */
233
+ remove() : void
234
+ {
235
+ this.each((el : any) => el.remove());
236
+ }
237
+
202
238
  }
203
239
 
204
240
  export default PicoDom;
@@ -27,6 +27,13 @@ export interface PicoFormat extends PicoFormatParser,
27
27
  //
28
28
  }
29
29
 
30
+ /**
31
+ * @class PicoFormat
32
+ * @extends PicoFormatParam
33
+ * @extends PicoFormatOption
34
+ * @extends PicoFormatUrl
35
+ * @extends PicoFormatFile
36
+ */
30
37
  export class PicoFormat extends trait(PicoFormatPlugins)
31
38
  {
32
39
 
package/src/utils/Hash.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Str } from "../index.esm.ts";
1
+ import { Mix, Str } from "../index.esm.ts";
2
2
 
3
3
  /**
4
4
  * @var {string[]} RADIX_NUMBER Radix from 0 to 9
@@ -159,6 +159,25 @@ export class PicoHash
159
159
  return hash;
160
160
  }
161
161
 
162
+ /**
163
+ * Get a numeric hash for object
164
+ *
165
+ * @example Hash.object({ a: 1 }) // => '8823432'
166
+ *
167
+ * @param {any} value Object to hash
168
+ * @returns {string} String numeric hash
169
+ */
170
+ static object(value : any) : string
171
+ {
172
+ let conv = JSON.stringify(value), hash = 0;
173
+
174
+ for (let i = 0; i < conv.length; i++) {
175
+ hash = (hash << 5) - hash + conv.charCodeAt(i) | 0;
176
+ }
177
+
178
+ return Mix.str(hash).replace('-', 'X');
179
+ }
180
+
162
181
  }
163
182
 
164
183
  export default PicoHash;
package/src/utils/Now.ts CHANGED
@@ -7,6 +7,7 @@ import { PicoNowGrid } from "../now/NowGrid.ts";
7
7
  import { PicoNowWalker } from "../now/NowWalker.ts";
8
8
  import { PicoNowRange } from "../now/NowRange.ts";
9
9
  import { PicoNowHuman } from "../now/NowHuman.ts";
10
+ import PicoNowDuration from "../now/NowDuration.ts";
10
11
 
11
12
  export const PicoNowPlugins = [
12
13
  PicoNowDefault,
@@ -16,6 +17,7 @@ export const PicoNowPlugins = [
16
17
  PicoNowWalker,
17
18
  PicoNowRange,
18
19
  PicoNowHuman,
20
+ PicoNowDuration,
19
21
  ];
20
22
 
21
23
  export interface PicoNowInterface
@@ -148,7 +148,13 @@ export class PicoNumber
148
148
  */
149
149
  static combine(value : number[]) : number
150
150
  {
151
- return Arr.reduce(value, (acc : number, val : any) => acc + val, 0);
151
+ const iter = Arr.slice(...[
152
+ value, 1, value.length
153
+ ]);
154
+
155
+ return Arr.reduce(iter, (acc : number, val : any) => {
156
+ return acc + val;
157
+ }, Arr.first(value) ?? 0);
152
158
  }
153
159
 
154
160
  /**
@@ -162,7 +168,13 @@ export class PicoNumber
162
168
  */
163
169
  static subtract(value : number[]) : number
164
170
  {
165
- return Arr.reduce(value, (acc : number, val : any) => acc - val, 0);
171
+ const iter = Arr.slice(...[
172
+ value, 1, value.length
173
+ ]);
174
+
175
+ return Arr.reduce(iter, (acc : number, val : any) => {
176
+ return acc - val;
177
+ }, Arr.first(value) ?? 0);
166
178
  }
167
179
 
168
180
  /**
@@ -221,7 +221,7 @@ export class PicoRunner
221
221
  */
222
222
  static framerate(cb : Function, fps : number = 30, finish : boolean = true) : Function
223
223
  {
224
- let timer : any, last = 0, hertz = 1000 / fps;
224
+ let timer : any, frame : any, last = 0, hertz = 1000 / fps;
225
225
 
226
226
  const fn = (...args : any) => {
227
227
 
@@ -231,7 +231,13 @@ export class PicoRunner
231
231
  return finish && (timer = setTimeout(fn, hertz + 1));
232
232
  }
233
233
 
234
- (this.frame(() => cb(...args)), last = Date.now());
234
+ cancelAnimationFrame(frame);
235
+
236
+ frame = requestAnimationFrame(() => {
237
+ cb(...args);
238
+ });
239
+
240
+ last = Date.now()
235
241
  };
236
242
 
237
243
  return fn;
@@ -285,6 +285,10 @@ export class PicoString
285
285
  */
286
286
  static has(value : any, search : any) : boolean
287
287
  {
288
+ if ( Mix.isEmpty(search) ) {
289
+ return true;
290
+ }
291
+
288
292
  return this.lc(value).indexOf(this.lc(search)) !== -1;
289
293
  }
290
294
 
@@ -17,6 +17,9 @@ export { go, browser, device, trait };
17
17
  import { default as Data } from "./utils/Data.ts";
18
18
  import { default as Route } from "./utils/Route.ts";
19
19
  export { Route, Data };
20
+ import { default as Map } from "./wip/Map.ts";
21
+ import { default as Element } from "./wip/Element.ts";
22
+ export { Map, Element };
20
23
  /**
21
24
  * @type {Mix}
22
25
  */
@@ -6,7 +6,7 @@ export interface PicoNowDefault extends PicoNowInterface {
6
6
  * @memberof PicoNow
7
7
  */
8
8
  export declare class PicoNowDefault {
9
- static test(value: any): boolean;
9
+ calc(value: any, scope: string): PicoNow;
10
10
  /**
11
11
  * Get value by scope
12
12
  *
@@ -0,0 +1,38 @@
1
+ import { PicoNowInterface } from "../utils/Now.ts";
2
+ import PicoNowDefault from "./NowDefault.ts";
3
+ import PicoNowFormat from "./NowFormat.ts";
4
+ export interface PicoNowDuration extends PicoNowInterface, PicoNowDefault, PicoNowFormat {
5
+ }
6
+ /**
7
+ * @memberof PicoNow
8
+ */
9
+ export declare class PicoNowDuration {
10
+ /**
11
+ * Calculate duration between two dates
12
+ *
13
+ * @example Now.make("2026-01-01").duration("2026-02-01") // => { years: 0, months: 1, ... }
14
+ *
15
+ * @param {any} value End date
16
+ * @returns {any} Duration object
17
+ */
18
+ duration(value: any): any;
19
+ /**
20
+ * Normalize seconds into duration parts
21
+ *
22
+ * @example Now.make().safeDuration(3661) // => { dates: 0, hours: 1, minutes: 1, seconds: 1 }
23
+ *
24
+ * @param {number} value Seconds value
25
+ * @returns {any} Duration object
26
+ */
27
+ safeDuration(value: number): any;
28
+ /**
29
+ * Get difference between two dates in seconds
30
+ *
31
+ * @example Now.make("2026-01-02").diffrence("2026-01-01") // => 86400
32
+ *
33
+ * @param {any} [value=null] Compare date
34
+ * @returns {number} Seconds difference
35
+ */
36
+ diffrence(value?: any): number;
37
+ }
38
+ export default PicoNowDuration;
@@ -11,11 +11,30 @@ import { PicoDomObserver } from "../dom/DomObserver.ts";
11
11
  import { PicoDomPopover } from "../dom/DomPopover.ts";
12
12
  export declare const PicoDomPlugins: (typeof PicoDomObserver)[];
13
13
  export interface PicoDomInterface {
14
+ /**
15
+ * @type {any}
16
+ */
14
17
  el: any;
18
+ /**
19
+ * @type {any[]}
20
+ */
15
21
  els: any[];
22
+ /**
23
+ * @param {Function} plugin
24
+ * @returns {void}
25
+ */
16
26
  extend(plugin: Function): void;
27
+ /**
28
+ * @returns {any}
29
+ */
17
30
  win(): any;
31
+ /**
32
+ * @returns {any}
33
+ */
18
34
  doc(): any;
35
+ /**
36
+ * @returns {any}
37
+ */
19
38
  body(): any;
20
39
  }
21
40
  export interface PicoDom extends PicoDomFinder, PicoDomGlobal, PicoDomForm, PicoDomEvent, PicoDomBuilder, PicoDomRectangle, PicoDomAttribute, PicoDomInview, PicoDomMeta, PicoDomObserver, PicoDomPopover {
@@ -107,5 +126,13 @@ export declare class PicoDom extends PicoDom_base {
107
126
  * @returns {any} Body or {}
108
127
  */
109
128
  static body(): any;
129
+ /**
130
+ * Remove elements from DOM
131
+ *
132
+ * @example Dom.find("div").remove()
133
+ *
134
+ * @returns {void} No return value
135
+ */
136
+ remove(): void;
110
137
  }
111
138
  export default PicoDom;
@@ -10,6 +10,13 @@ export interface PicoFormatInterface {
10
10
  export interface PicoFormat extends PicoFormatParser, PicoFormatParam, PicoFormatOption, PicoFormatUrl, PicoFormatFile {
11
11
  }
12
12
  declare const PicoFormat_base: any;
13
+ /**
14
+ * @class PicoFormat
15
+ * @extends PicoFormatParam
16
+ * @extends PicoFormatOption
17
+ * @extends PicoFormatUrl
18
+ * @extends PicoFormatFile
19
+ */
13
20
  export declare class PicoFormat extends PicoFormat_base {
14
21
  /**
15
22
  * Extend format with a plugin
@@ -77,5 +77,14 @@ export declare class PicoHash {
77
77
  * @returns {string} A random password with fixed length
78
78
  */
79
79
  static password(length?: number, symbols?: string[]): string;
80
+ /**
81
+ * Get a numeric hash for object
82
+ *
83
+ * @example Hash.object({ a: 1 }) // => '8823432'
84
+ *
85
+ * @param {any} value Object to hash
86
+ * @returns {string} String numeric hash
87
+ */
88
+ static object(value: any): string;
80
89
  }
81
90
  export default PicoHash;
@@ -5,7 +5,7 @@ import { PicoNowGrid } from "../now/NowGrid.ts";
5
5
  import { PicoNowWalker } from "../now/NowWalker.ts";
6
6
  import { PicoNowRange } from "../now/NowRange.ts";
7
7
  import { PicoNowHuman } from "../now/NowHuman.ts";
8
- export declare const PicoNowPlugins: (typeof PicoNowDefault | typeof PicoNowWalker | typeof PicoNowRange | typeof PicoNowHuman)[];
8
+ export declare const PicoNowPlugins: (typeof PicoNowDefault | typeof PicoNowRange)[];
9
9
  export interface PicoNowInterface {
10
10
  value: Date;
11
11
  input: any;