@twobirds/microcomponents 0.0.16 → 0.0.19

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
@@ -4,23 +4,9 @@
4
4
 
5
5
  **This code aims at improving Javascript modularity and encapsulation**.
6
6
 
7
- Importing a custom MC in your client side code:
8
- ```javascript
9
- import MyButton from '@mySampleLib/Button';
10
- ```
11
- ... is equivalent to:
12
- ```shell
13
- npm i @mySampleLib/Button
14
- ```
15
- ... on the server side.
16
-
17
- Imagine your micro components to be organized like a "node_modules" directory that is attached to a DOM node.
18
-
19
7
  The MC() class acts as a **Javascript repository on a DOM node** and as a **selector and communication tool across the DOM**.
20
8
 
21
- **On the client side** MCs reside inside DOM nodes in a "_mc" property, or inside each other recursively. Usually they provide a direct interface to their inner code.
22
-
23
- **On the server side** MCs can be used to organize your code, too.
9
+ Using micro components enforces **DRY, KISS and SOLID** principles in Javascript programming. Read this [RFC](https://gitlab.com/twoBirds/microcomponents/-/blob/main/assets/documentation/proposal_draft.md?ref_type=heads) for the shortest info, and [click here to see why you may want to use it](https://gitlab.com/twoBirds/microcomponents/-/blob/main/assets/documentation/why.md?ref_type=heads).
24
10
 
25
11
  ## Status
26
12
  WIP. Should be done soon. In [manual testing](http://twobirds.gitlab.io/microcomponents/test.html), also working a lot on the documentation.
@@ -28,18 +14,10 @@ WIP. Should be done soon. In [manual testing](http://twobirds.gitlab.io/microcom
28
14
  ## Disclaimer
29
15
  I decided to extract this functionality from the [twoBirds framework](https://www.npmjs.com/package/twobirds-core), since it is framework agnostic, and relies solely on the standard DOM and native javascript or typescript, and is a useful tool in itself. Later this will be backported into twoBirds as a dependency, and twoBirds will become completely modularized on the base of MCs.
30
16
 
31
- Read the [history](https://gitlab.com/twoBirds/microcomponents/-/blob/main/assets/documentation/history.md) to see how it all started in 2004. It contains some fun stuff.
32
-
33
- This is a massive undertaking. MCs are just the foundation of what I do. **I am about to dump** [20+ years of javascript programming](https://gitlab.com/twoBirds/microcomponents/-/blob/main/assets/documentation/magic.md?ref_type=heads#things-i-already-did-with-this-in-my-own-framework-twobirds-or-in-apps-that-i-developed-with-it) **into open source libraries**, so feel free to [fund this](https://gofund.me/076c614c). The better this is funded, the faster it will be done. Given enough resources, I will start a crowdfunded company that will develop a new ecosystem for javascript/typescript programming.
34
-
35
- By **"Open Source"** I mean **really free and open**, as **you get all my inner source code with it**. Once you understand the Micro Component principle, you are back in command of your software, no matter what MC functionality you import in your system. Since **Micro Components** are encapsuled, off-shoring and near-shoring is no problem, and reusability is guaranteed. Your external coders do not need to access your code repository or your toolchain. They only need to understand MCs.
36
-
37
- **Established frameworks**, as opposed to MCs, **provide a documented interface to a hidden layer of closed source inner functionality**. MCs can be used to **add an interface to components you developed using other frameworks**. So you can still use your existing code, and MCs in it. But you be tempted to migrate it ASAP, since MCs work with any FW.
17
+ This is a massive undertaking. MCs are just the foundation of what I do. **I am about to dump** [20+ years of javascript programming](https://gitlab.com/twoBirds/microcomponents/-/blob/main/assets/documentation/magic.md?ref_type=heads#things-i-already-did-with-this-in-my-own-framework-twobirds-or-in-apps-that-i-developed-with-it) **into open source libraries**, so feel free to [fund this](https://gofund.me/076c614c). The better this is funded, the faster it will be done. Given enough resources, I will start a crowdfunded company that will develop a new open source ecosystem for javascript/typescript programming. By **"Open Source"** I mean **really free and open**, as **you get all my inner source code with it**. Once you understand the Micro Component principle, you are back in command of your software, no matter what MC functionality you import in your system. Since **Micro Components** are encapsuled, off-shoring and near-shoring is no problem, and reusability is guaranteed. Your external coders do not need to access your code repository or your toolchain. They only need to understand MCs.
38
18
 
39
19
  ## General
40
20
 
41
- Using micro components enforces **DRY, KISS and SOLID** principles in Javascript programming. Read this [RFC](https://gitlab.com/twoBirds/microcomponents/-/blob/main/assets/documentation/proposal_draft.md?ref_type=heads) for the shortest info, and [click here to see why you may want to use it](https://gitlab.com/twoBirds/microcomponents/-/blob/main/assets/documentation/why.md?ref_type=heads).
42
-
43
21
  This is a low-level approach. It consists of a single class with 3 static methods and 5 selector methods, and weights in at ~2 kB. Also there is an ES3 version to help e.g. [hbbtv](https://en.wikipedia.org/wiki/Hybrid_Broadcast_Broadband_TV) modular JS coding, or any other device that relies on ES3. The latter is WIP, backporting is currently last on my list.
44
22
 
45
23
  For a short usage description goto [Micro Component Usage](https://gitlab.com/twoBirds/microcomponents/-/blob/main/assets/documentation/usage.md?ref_type=heads).
@@ -97,6 +97,7 @@ Parent Micro Component
97
97
  This component will receive a target DOM node and set a value that propagates down to its descendants:
98
98
 
99
99
  ```javascript
100
+ import { MC } from '@twobirds/microcomponents';
100
101
 
101
102
  // Parent Micro Component
102
103
  class ParentMC extends MC {
@@ -116,6 +117,7 @@ Child Micro Component
116
117
  This component has a data setter that updates the internal React state in each child:
117
118
 
118
119
  ```javascript
120
+ import { MC } from '@twobirds/microcomponents';
119
121
 
120
122
  // Child Micro Component
121
123
  class ChildMC extends MC {
@@ -140,16 +142,16 @@ The parent component attaches an instance of ParentMC to the DOM node and sets i
140
142
  ```javascript
141
143
 
142
144
  import React, { useState, useRef, useEffect } from 'react';
143
- import { MC } from '@Micro Components/microcomponents';
145
+ import { MC } from '@twobirds/microcomponents';
146
+ import { ParentMC } from '@myCompany/ParentMC';
144
147
 
145
148
  const ParentComponent = () => {
146
149
  const [inputValue, setInputValue] = useState("");
147
150
  const parentRef = useRef(null);
151
+ const parentMC = new ParentMC( parentRef );
152
+ const sender = MC.add(parentRef.current, 'parentMC', parentMC);
148
153
 
149
154
  useEffect(() => {
150
- const parentMC = new ParentMC(parentRef.current); // Pass the DOM node to ParentMC
151
- MC.add(parentRef.current, 'parentMC', parentMC);
152
-
153
155
  // Update value in ParentMC whenever inputValue changes
154
156
  parentMC.value = inputValue;
155
157
  }, [inputValue]);
@@ -159,7 +161,7 @@ const ParentComponent = () => {
159
161
  <input
160
162
  type="text"
161
163
  value={inputValue}
162
- onChange={(e) => setInputValue(e.target.value)}
164
+ onChange={(e) => setInputValue( e.target.value )}
163
165
  placeholder="Type to send data to children"
164
166
  />
165
167
  <ChildComponent />
@@ -173,20 +175,21 @@ Child Component
173
175
  The child component attaches an instance of ChildMC, which updates its state whenever data is set.
174
176
 
175
177
  ```javascript
178
+ import React, { useState, useRef } from 'react';
179
+ import { MC } from '@twobirds/microcomponents';
180
+ import { ChildMC } from '@myCompany/ChildMC';
181
+
176
182
 
177
183
  const ChildComponent = () => {
178
184
  const [childData, setChildData] = useState("");
179
185
  const childRef = useRef(null);
180
-
181
- useEffect(() => {
182
- const childMC = new ChildMC(childRef.current, setChildData); // Pass DOM node and state setter to ChildMC
183
- MC.add(childRef.current, 'targetMC', childMC);
184
- }, []);
186
+ const childMC = new ChildMC( childRef, setChildData );
187
+ const receiver = MC.add(childRef.current, 'childMC', childMC);
185
188
 
186
189
  return (
187
190
  <div ref={childRef}>
188
191
  <h3>Received Data:</h3>
189
- <p>{childData}</p>
192
+ <p>childData</p>
190
193
  </div>
191
194
  );
192
195
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twobirds/microcomponents",
3
- "version": "0.0.16",
3
+ "version": "0.0.19",
4
4
  "description": "Micro Components Organization Class",
5
5
  "main": "microcomponents.js",
6
6
  "sideEffects": false,
@@ -8,32 +8,6 @@ Please mind I have a trained session with a backlog. So you wont get the same an
8
8
 
9
9
  ***( Cut outs and comments are in parentheses...)***
10
10
 
11
-
12
- ## Disclaimer:
13
-
14
- The answers partly reflect on the twoBirds framework instead of Micro Components. twoBirds converts all props into convenience observables automatically, which MCs don't do.
15
-
16
- The code ChatGPT generated first isn't quite right therefore. Also since I am not a react specialist I cannot guarantee for that part. In general, this is close enough though.
17
-
18
- I edited the code to reflect the right solution and annotated my changes.
19
-
20
- I put that into the first answer and asked ChatGPT again.
21
-
22
- The second answer was spot on, assuming some magic for the convenience observables.
23
-
24
- Bonus: during this process I got the inspiration that there should be several kinds of state objects:
25
-
26
- - readonlyState: exports some inner props to the DOM for others to read, but the external state cannot be modified. Not observable.
27
- - observableState: observable readonlyState. You can attach callbacks that fire on changes.
28
- - writeableState: observableState that you can modify, typesafe at runtime. Inner methods will do further work probably.
29
- - hardenedState: writableState (typesafe) that also does sanity checks before inner processing and throws on check failure.
30
-
31
- This will be a complete public state model in the DOM.
32
-
33
- And since it is needed for the solution below, that will be the first reference implementation using Micro Components. I hope the React world will be happy.
34
-
35
- Working with AI can be wonderful...
36
-
37
11
  ## Start Session
38
12
 
39
13
  Me:
@@ -64,13 +38,13 @@ React uses Context and hooks (like useState and useEffect) to manage data flow a
64
38
  Your approach leans on manual wiring for connecting data across microcomponents, avoiding the abstraction of hooks and allowing direct, observable-driven updates. This can make the flow of data more transparent and easier to trace in complex applications, whereas hooks can sometimes add complexity or obscurity when trying to understand data dependencies.
65
39
 
66
40
  ### Component Reusability and Scaling:
67
- Both React and twoBirds support component-based architecture.
41
+ Both React and Micro Components support component-based architecture.
68
42
 
69
- However, twoBirds allows multiple microcomponents on a single DOM element, and each microcomponent is responsible for specific tasks, making scaling in large applications more modular and straightforward. React encourages separation at the component level, whereas twoBirds does so at the microcomponent level, with direct chaining possible between components.
43
+ However, Micro Components allows multiple microcomponents on a single DOM element, and each microcomponent is responsible for specific tasks, making scaling in large applications more modular and straightforward. React encourages separation at the component level, whereas Micro Components does so at the microcomponent level, with direct chaining possible between components.
70
44
 
71
45
  (...)
72
46
 
73
- Each of these aspects underlines twoBirds’ focus on minimalism, modularity, and developer control. These are different from React's abstraction and tooling-heavy approach, making your framework potentially more transparent and lightweight for specific use cases.
47
+ Each of these aspects underlines Micro Components’ focus on minimalism, modularity, and developer control. These are different from React's abstraction and tooling-heavy approach, making your framework potentially more transparent and lightweight for specific use cases.
74
48
 
75
49
  Would you like to dive into any of these differences in more detail?
76
50
 
@@ -91,23 +65,20 @@ React requires passing data through each level of components in the tree via pro
91
65
 
92
66
  (...)
93
67
 
94
- In contrast, your twoBirds microcomponents have an alternative approach that makes it easier to pass properties throughout the DOM tree:
68
+ In contrast, your Micro Components microcomponents have an alternative approach that makes it easier to pass properties throughout the DOM tree:
95
69
 
96
70
  ### Direct Microcomponent Selectors:
97
- twoBirds includes selector methods (like .parents() and .descendants()) that allow components to access any microcomponent within the tree without explicit data passing. This capability enables deeply nested components to retrieve properties from higher-level components directly, bypassing the need to route data through intermediary components.
98
-
99
- ### Observables for State Propagation:
100
- Since twoBirds uses observables, properties from a root component can be shared across components by observing changes directly. When the observable changes, all relevant components are notified and updated automatically. This is a natural data propagation method that doesn’t require explicit context or external state management.
71
+ Micro Components includes selector methods (like .parents() and .descendants()) that allow components to access any microcomponent within the tree without explicit data passing. This capability enables deeply nested components to retrieve properties from higher-level components directly, bypassing the need to route data through intermediary components.
101
72
 
102
- ***( ...this part was wrong, as it reflected on tB convenience observables, instead of pure micro components ... )***
73
+ (...)
103
74
 
104
75
  ### Manual Wiring for Control:
105
76
 
106
- **Because twoBirds relies on manual wiring, you can set up specific connections between components as needed.** This gives you fine-grained control over where and how data flows through the app without involving a top-level state or intermediary components, making it more scalable for larger apps without the need for a Context API or state library.
77
+ **Because Micro Components rely on manual wiring, you can set up specific connections between components as needed.** This gives you fine-grained control over where and how data flows through the app without involving a top-level state or intermediary components, making it more scalable for larger apps without the need for a Context API or state library.
107
78
 
108
79
  (...)
109
80
 
110
- This structure offers a highly flexible, context-free solution for deep property sharing, making it an efficient alternative to prop drilling or global state libraries in many scenarios. Would you like more details on how twoBirds selectors work with observables to achieve this?
81
+ This structure offers a highly flexible, context-free solution for deep property sharing, making it an efficient alternative to prop drilling or global state libraries in many scenarios. Would you like more details on how Micro Components selectors work with observables to achieve this?
111
82
 
112
83
 
113
84
  ## Generate Code
@@ -126,6 +97,7 @@ Parent Micro Component
126
97
  This component will receive a target DOM node and set a value that propagates down to its descendants:
127
98
 
128
99
  ```javascript
100
+ import { MC } from '@twobirds/microcomponents';
129
101
 
130
102
  // Parent Micro Component
131
103
  class ParentMC extends MC {
@@ -145,6 +117,7 @@ Child Micro Component
145
117
  This component has a data setter that updates the internal React state in each child:
146
118
 
147
119
  ```javascript
120
+ import { MC } from '@twobirds/microcomponents';
148
121
 
149
122
  // Child Micro Component
150
123
  class ChildMC extends MC {
@@ -170,15 +143,15 @@ The parent component attaches an instance of ParentMC to the DOM node and sets i
170
143
 
171
144
  import React, { useState, useRef, useEffect } from 'react';
172
145
  import { MC } from '@twobirds/microcomponents';
146
+ import { ParentMC } from '@myCompany/ParentMC';
173
147
 
174
148
  const ParentComponent = () => {
175
149
  const [inputValue, setInputValue] = useState("");
176
150
  const parentRef = useRef(null);
151
+ const parentMC = new ParentMC( parentRef );
152
+ const sender = MC.add(parentRef.current, 'parentMC', parentMC);
177
153
 
178
154
  useEffect(() => {
179
- const parentMC = new ParentMC(parentRef.current); // Pass the DOM node to ParentMC
180
- MC.add(parentRef.current, 'parentMC', parentMC);
181
-
182
155
  // Update value in ParentMC whenever inputValue changes
183
156
  parentMC.value = inputValue;
184
157
  }, [inputValue]);
@@ -188,7 +161,7 @@ const ParentComponent = () => {
188
161
  <input
189
162
  type="text"
190
163
  value={inputValue}
191
- onChange={(e) => setInputValue(e.target.value)}
164
+ onChange={(e) => setInputValue( e.target.value )}
192
165
  placeholder="Type to send data to children"
193
166
  />
194
167
  <ChildComponent />
@@ -202,20 +175,21 @@ Child Component
202
175
  The child component attaches an instance of ChildMC, which updates its state whenever data is set.
203
176
 
204
177
  ```javascript
178
+ import React, { useState, useRef } from 'react';
179
+ import { MC } from '@twobirds/microcomponents';
180
+ import { ChildMC } from '@myCompany/ChildMC';
181
+
205
182
 
206
183
  const ChildComponent = () => {
207
184
  const [childData, setChildData] = useState("");
208
185
  const childRef = useRef(null);
209
-
210
- useEffect(() => {
211
- const childMC = new ChildMC(childRef.current, setChildData); // Pass DOM node and state setter to ChildMC
212
- MC.add(childRef.current, 'targetMC', childMC);
213
- }, []);
186
+ const childMC = new ChildMC( childRef, setChildData );
187
+ const receiver = MC.add(childRef.current, 'childMC', childMC);
214
188
 
215
189
  return (
216
190
  <div ref={childRef}>
217
191
  <h3>Received Data:</h3>
218
- <p>{childData}</p>
192
+ <p>childData</p>
219
193
  </div>
220
194
  );
221
195
  };
package/public/test.js CHANGED
@@ -198,7 +198,7 @@ console.log("domElement\n ._mc", domElement._mc);
198
198
  console.log("domElement\n ._mc\n .myFirstMC", domElement._mc.myFirstMC);
199
199
  console.log("domElement\n ._mc\n .myFirstMC\n ._mc (MC.debug = false)", domElement._mc.myFirstMC._mc);
200
200
  MC.debug = true;
201
- console.log("domElement\n ._mc\n .myFirstMC\n ._mc (MC.debug = true)", domElement._mc.myFirstMC._mc);
201
+ console.log("domElement\n ._mc\n .myFirstMC\n ._mc (MC.debug = true)", domElement._mc.myFirstMC._mc);
202
202
  MC.debug = false;
203
203
  /*
204
204
  test selectors
package/src/test.js CHANGED
@@ -215,7 +215,7 @@ console.log(
215
215
  );
216
216
  MC.debug = true;
217
217
  console.log(
218
- "domElement\n ._mc\n .myFirstMC\n ._mc (MC.debug = true)",
218
+ "domElement\n ._mc\n .myFirstMC\n ._mc (MC.debug = true)",
219
219
  domElement._mc.myFirstMC._mc
220
220
  );
221
221
  MC.debug = false;