targetj 1.0.201 → 1.0.202

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
@@ -26,26 +26,20 @@ Targets unlock a fundamentally new way of coding that simplifies everything from
26
26
  2. Declarative Reactive Targets: Targets can explicitly declare reactive execution triggered by the run or completion of their immediately preceding targets, whether synchronous or asynchronous.
27
27
  3. All-in-One Solution: Offers a unified approach to UI rendering, API integration, state management, event handling, and animation.
28
28
  4. Code-Ordered Execution: Targets are chained top to bottom and the execution flow generally follows the order in which the code is written.
29
- 5. Autonomous Methods: Methods in TargetJS are not directly callable. Instead, they are designed to execute themselves or react dynamically to the execution or completion of preedings targets. This paradigm shift enables a declarative programming style and inherently supports asynchronous operations without explicit plumbing like using async/await keywords.
29
+ 5. Autonomous Methods: Methods in TargetJS are not directly callable. Instead, they are designed to execute themselves or react dynamically to the execution or completion of preedings targets. This enables declarative programming that inherently supports asynchronous operations without explicit plumbing like using async/await keywords.
30
30
  6. Compactness: TargetJS allows developers to achieve interactive UIs with significantly less code.
31
31
 
32
32
 
33
33
  ## Examples: From like button → animated like + API (in 7 steps)
34
34
 
35
- > **Postfixes**
36
- >
37
- > * **`$`** = *reactive*: runs every time the **immediately previous** target updates.
38
- > * **`$$`** = *deferred*: runs after all prior targets complete including animations and fetches.
39
- >
40
- > **Reordering**
41
- > Targets execute in the order they’re written. You can reorder them like LEGO bricks to change the flow. `$$` automatically follow the new sequence.
42
-
43
35
  ---
44
36
 
45
37
  ## 1) Like button (view only)
46
38
 
47
39
  **What this shows:** One object defines a UI element without separate HTML/CSS. Static targets map directly to DOM styles/attributes.
48
40
 
41
+ <img src="https://targetjs.io/img/likeButton.png" width="130" />
42
+
49
43
  ```javascript
50
44
  import { App } from "targetj";
51
45
 
@@ -65,7 +59,10 @@ App({
65
59
 
66
60
  ## 2) Animation
67
61
 
68
- **What this shows:** A mount-time animation that scales and changes the background over 12 steps, with 12ms pauses between steps.
62
+ **What this shows:** A mount-time animation that scales and changes the background over 12 steps, with 12ms pauses between steps. Targets without (`$`, `$$`, `_`) execute immediately in the order they are defined.
63
+
64
+ <img src="https://targetjs.io/img/likeButton6.gif" width="130" />
65
+
69
66
  ```javascript
70
67
  import { App } from "targetj";
71
68
 
@@ -76,14 +73,16 @@ App({
76
73
  textAlign: "center",
77
74
  borderRadius: 10,
78
75
  html: "♡ Like",
79
- scale: [ { list: [1.2, 1] }, 8, 12 ],
76
+ scale: [ { list: [1.2, 1] }, 12, 12 ],
80
77
  background: [ { list: ["#ffe8ec", "#f5f5f5"] }, 12, 12 ]
81
78
  });
82
79
  ```
83
80
 
84
81
  ## 3) Click → animation (imperative `setTarget`)
85
82
 
86
- **What this shows:** Clicking plays the animations from the previous step and swaps the text.
83
+ **What this shows:** Clicking plays the animations from the previous step using imperative `setTarget`.
84
+
85
+ <img src="https://targetjs.io/img/likeButton4.gif" width="130" />
87
86
 
88
87
  ```javascript
89
88
  import { App } from "targetj";
@@ -95,7 +94,7 @@ App({
95
94
  html: "♡ Like",
96
95
 
97
96
  onClick() {
98
- this.setTarget("scale", { list: [1.2, 1] }, 8, 12);
97
+ this.setTarget("scale", { list: [1.2, 1] }, 12, 12);
99
98
  this.setTarget("background", { list: ["#ffe8ec", "#f5f5f5"] }, 12, 12);
100
99
  this.setTarget("html", "♥ Liked");
101
100
  }
@@ -104,10 +103,11 @@ App({
104
103
 
105
104
  ---
106
105
 
107
- ## 4) Sequencing with `$$`: small heart
106
+ ## 4) Sequencing with `$$`: Adding a small heart after click
108
107
 
109
- **What this shows:** A `$$` target (deferred) runs only after all prior targets finish (including `onClick` and animations). Here it adds a new heart element and runs its fly motion only once the click sequence has completed.
108
+ **What this shows:** A `$$` target (deferred) runs only after all prior targets finish (including `onClick()` and its animations). Here it adds a new heart element and runs its fly motion only once the click sequence has completed.
110
109
 
110
+ <img src="https://targetjs.io/img/likeButton7.gif" width="130" />
111
111
 
112
112
  ```javascript
113
113
  import { App } from "targetj";
@@ -117,7 +117,7 @@ App({
117
117
  borderRadius: 10, background: "#f5f5f5", cursor: "pointer", userSelect: "none",
118
118
  html: "♡ Like",
119
119
  onClick() {
120
- this.setTarget("scale", { list: [1.2, 1] }, 8, 12);
120
+ this.setTarget("scale", { list: [1.2, 1] }, 12, 12);
121
121
  this.setTarget("background", { list: ["#ffe8ec", "#f5f5f5"] }, 12, 12);
122
122
  this.setTarget("html", "♥ Liked");
123
123
  },
@@ -141,7 +141,9 @@ App({
141
141
 
142
142
  ## 5) Another `$$`: big heart, different motion
143
143
 
144
- **What this shows:** **Chained `$$`**. `bigHeart$$` waits for `heart$$` to finish, then runs its own, distinct animation.
144
+ **What this shows:** Deferred addition of a new element using $$. `bigHeart$$` waits for `heart$$` to complete its animation, then adds a larger heart and runs its own animation.
145
+
146
+ <img src="https://targetjs.io/img/likeButton8.gif" width="130" />
145
147
 
146
148
  ```javascript
147
149
  import { App } from "targetj";
@@ -152,7 +154,7 @@ App({
152
154
  html: "♡ Like",
153
155
 
154
156
  onClick() {
155
- this.setTarget("scale", { list: [1.2, 1] }, 8, 12);
157
+ this.setTarget("scale", { list: [1.2, 1] }, 12, 12);
156
158
  this.setTarget("background", { list: ["#ffe8ec", "#f5f5f5"] }, 12, 12);
157
159
  this.setTarget("html", "♥ Liked");
158
160
  },
@@ -190,11 +192,11 @@ App({
190
192
 
191
193
  ## 6) `fetch$$`
192
194
 
193
- **What this shows:** Networking is just another target. The POST happens **only after** all prior visual steps complete.
195
+ **What this shows:** Networking is just another target. The POST happens **only after** all prior visual steps complete, since the target is postfixed with `$$`.
194
196
 
195
197
  ```javascript
196
198
  App({
197
- // …same as step 4
199
+ // …same as step 5
198
200
 
199
201
  fetch$$: { method: "POST", id: 123, url: "/api/like" }
200
202
  });
@@ -202,9 +204,11 @@ App({
202
204
 
203
205
  ---
204
206
 
205
- ## 7) Final version with a cleanup utility (`removeHearts$$`) + keyboard
207
+ ## 7) Final version
206
208
 
207
- **What this shows:** A like button component that encapsulates the previous steps, adds a post-chain cleanup target. It also ncludes basic accessibility (role, tabIndex, and Enter to activate).
209
+ **What this shows:** A Like button that consolidates the previous steps into a single component. After the POST completes, a cleanup `removeHearts$$` target runs to remove the two heart elements. The button also includes basic accessibility (role, tabIndex, and Enter to activate).
210
+
211
+ <img src="https://targetjs.io/img/likeButton9.gif" width="130" />
208
212
 
209
213
  ```javascript
210
214
  import { App } from "targetj";
@@ -216,7 +220,7 @@ App({
216
220
  role: "button", tabIndex: 0,
217
221
  html: "♡ Like",
218
222
  onClick() {
219
- this.setTarget("scale", { list: [1.2, 1] }, 8, 12);
223
+ this.setTarget("scale", { list: [1.2, 1] }, 12, 12);
220
224
  this.setTarget("background", { list: ["#ffe8ec", "#f5f5f5"] }, 12, 12);
221
225
  this.setTarget("html", "♥ Liked");
222
226
  },
@@ -272,7 +276,7 @@ Or in HTML (no JavaScript required), using tg- attributes that mirror object lit
272
276
  tg-html="♡ Like"
273
277
  tg-tabIndex="0"
274
278
  tg-onClick="function() {
275
- this.setTarget('scale', { list: [1.2, 1] }, 8, 12);
279
+ this.setTarget('scale', { list: [1.2, 1] }, 12, 12);
276
280
  this.setTarget('background', { list: ['#ffe8ec', '#f5f5f5'] }, 12, 12);
277
281
  this.setTarget('html', '♥ Liked');
278
282
  }"
@@ -316,11 +320,11 @@ Or in HTML (no JavaScript required), using tg- attributes that mirror object lit
316
320
 
317
321
  ## Final takeaway
318
322
 
319
- TargetJS treats time as a first-class concept. Instead of wiring callbacks and effects, you write a sequence of targets.
323
+ - TargetJS treats time as a first-class concept. Instead of wiring callbacks and effects, you write a sequence of targets.
320
324
  $ reacts to the previous step; $$ defers until all prior steps finish. Animations, API calls, and child creation are all the same kind of thing: targets.
321
- So complex flows read top-to-bottom, no glue code.
322
-
323
-
325
+ So complex flows read top-to-bottom.
326
+ - Minimal plumbing yet full control to manage a flow of complex asynchronous operations.
327
+
324
328
  ## Table of Contents
325
329
 
326
330
  1. [Targets: The Building Blocks of TargetJS](#targets-the-building-blocks-of-targetjs)
@@ -416,53 +420,75 @@ TargetJS addresses several common pain points in front-end development:
416
420
 
417
421
  ## More Examples
418
422
 
419
- ## Loading Two Users Example
423
+ ## Loading Five Users Example
420
424
 
421
- In this example, we load two separate users and display two purple boxes, each containing a user's name, based on our first example.
425
+ In this example, we load five separate users and display five boxes, each containing a user's name and email.
422
426
 
423
- - `fetch` calls two APIs to retrieve details for two users.
424
- - `children` is a special target that adds new items to the parent each time it executes. Because it ends with `$` in this example, it executes every time an API call returns a result.
425
- - TargetJS ensures that API results are processed in the same sequence as the API calls. For example, if the user1 API result arrives before user0, `children` will not execute until the result for user0 has been received.
426
-
427
- ![first example](https://targetjs.io/img/quick3_1.gif)
427
+ - `fetch` calls five APIs to retrieve details for five users.
428
+ - `child` is a special target that adds a new item to the parent each time it executes. Because it ends with `$` in this example, it executes every time an API call returns a result.
429
+ - TargetJS ensures that API results are processed in the same sequence as the API calls. For example, if the user1 API result arrives before user0, `child` will not execute until the result for user0 has been received.
430
+
431
+ <img src="https://targetjs.io/img/fetch-5-users.gif" width="130" />
428
432
 
429
433
  ```javascript
430
- import { App, fetch } from "targetj";
434
+ import { App } from "targetj";
431
435
 
432
436
  App({
437
+ gap: 10,
433
438
  fetch: ['https://targetjs.io/api/randomUser?id=user0',
434
- 'https://targetjs.io/api/randomUser?id=user1'],
435
- children$() {
436
- return {
437
- background: "mediumpurple",
438
- html: this.prevTargetValue.name,
439
- width: [{ list: [100, 250, 100] }, 50, 10],
440
- height$() { return this.prevTargetValue / 2; },
441
- };
439
+ 'https://targetjs.io/api/randomUser?id=user1',
440
+ 'https://targetjs.io/api/randomUser?id=user2',
441
+ 'https://targetjs.io/api/randomUser?id=user3',
442
+ 'https://targetjs.io/api/randomUser?id=user4'
443
+ ],
444
+ child$() {
445
+ const user = this.prevTargetValue;
446
+ return {
447
+ width: 200,
448
+ height: 65,
449
+ borderRadius: 10,
450
+ boxSizing: "border-box",
451
+ padding: 10,
452
+ fontSize: 14,
453
+ background: "#f0f0f0",
454
+ scale: [{ list: [0.8, 1] }, 14, 12],
455
+ html$() {
456
+ return `<div style="font-weight:600">${user.name}</div>
457
+ <div style="opacity:.65">${user.email}</div>`;
458
+ },
459
+ };
460
+ }
461
+ });
462
+ ```
463
+
464
+ It can also be written using a target’s `cycles` and `intervals` properties/methods to fetch users at intervals instead of in a single batch. In this example, we set interval to 1000, making the API call once every second.
465
+
466
+ <img src="https://targetjs.io/img/fetch-5-users2.gif" width="130" />
467
+
468
+
469
+ ```javascript
470
+ App({
471
+ gap: 10,
472
+ fetch: {
473
+ interval: 1000,
474
+ cycles: 4,
475
+ value(i) { return `https://targetjs.io/api/randomUser?id=user${i}`; }
476
+ },
477
+ child$() {
478
+ return {
479
+ // …same as the previous example…
480
+ };
442
481
  }
443
482
  });
444
483
  ```
445
- Or in HTML:
446
-
447
- ```html
448
- <div tg-fetch="['https://targetjs.io/api/randomUser?id=user0', 'https://targetjs.io/api/randomUser?id=user1']">
449
- <div
450
- tg-background="mediumpurple"
451
- tg-html="function(index) { return this.getParentValue('fetch')[index].name; }"
452
- tg-width="[{ list: [100, 250, 100] }, 50, 10]"
453
- tg-height$="return this.prevTargetValue / 2;"
454
- >
455
- </div>
456
- </div>
457
- ```
458
484
 
459
485
  ### Infinite Loading and Scrolling Example
460
486
 
461
487
  In this advanced example, we demonstrate an infinite scrolling application where each item is animated, and upon completing its animation, it dynamically triggers an API call to fetch and display its details.
462
488
 
463
- - children: `children` is a special target that adds items to the container's children each time it is executed. The `onVisibleChildrenChange` event function detects changes in the visible children and activates the `children` target to add new items that fill the gaps.
489
+ - children: `children` is a special target that adds several items to the container's children each time it is executed. The `onVisibleChildrenChange` event function detects changes in the visible children and activates the `children` target to add new items that fill the gaps.
464
490
 
465
- loadItems: Since the target name ends with `$$`, it executes only after the newly created children finish their animations. It then iterates over all visible children and fetches their details. The result is an array of users. TargetJS ensures that this array preserves the order in which the API calls were made, not the order in which responses were received.
491
+ - loadItems: Since the target name ends with `$$`, it executes only after the newly created children finish their animations. It then iterates over all visible children and fetches their details. The result is an array of users. TargetJS ensures that this array preserves the order in which the API calls were made, not the order in which responses were received.
466
492
 
467
493
  - populate: Since the target name ends with `$$`, it executes only after all API calls have completed. It updates the content of each scrollable item with the name returned by the API.
468
494
 
@@ -470,7 +496,7 @@ TargetJS employs a tree-like structure to track visible branches, optimizing the
470
496
 
471
497
  We use the TModel class instead of a plain object to demonstrate how it can provide additional functionality and control. A plain object would also have worked in this example.
472
498
 
473
- ![Single page app](https://targetjs.io/img/infiniteScrolling11.gif)
499
+ <img src="https://targetjs.io/img/infiniteScrolling.gif" width="130" />
474
500
 
475
501
  ```javascript
476
502
  import { App, TModel, getEvents, fetch, getScreenWidth, getScreenHeight } from "targetj";
@@ -344,7 +344,7 @@ var BaseModel = exports.BaseModel = /*#__PURE__*/function () {
344
344
  var nextKey = keyIndex < this.originalTargetNames.length - 1 ? this.originalTargetNames[keyIndex + 1] : undefined;
345
345
  doesNextTargetUsePrevValue = nextKey && nextKey.endsWith('$') ? true : false;
346
346
  if (doesNextTargetUsePrevValue || isInactiveKey || isExternalEvent || isInternalEvent || targetType === 'object' || targetType === 'function') {
347
- if (!target.value && !_TargetParser.TargetParser.isChildObjectTarget(key, target) && !_TargetParser.TargetParser.isIntervalTarget(target)) {
347
+ if (!_TUtil.TUtil.isDefined(target.value) && !_TargetParser.TargetParser.isChildObjectTarget(key, target) && !_TargetParser.TargetParser.isIntervalTarget(target)) {
348
348
  needsTargetExecution = true;
349
349
  target = _TargetUtil.TargetUtil.wrapTarget(this, target, key);
350
350
  }