@arcanejs/react-toolkit 0.1.3 → 0.1.5

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
@@ -3,7 +3,7 @@
3
3
  [![NPM Version](https://img.shields.io/npm/v/%40arcanejs%2Freact-toolkit)](https://www.npmjs.com/package/@arcanejs/react-toolkit)
4
4
 
5
5
  `@arcanejs/react-toolkit` Allows you to quickly create real-time control panels
6
- for your JavaScript / TypeScript single-server apps,
6
+ for your single-process Node.js apps,
7
7
  using a custom react renderer, and WebSockets.
8
8
 
9
9
  Control panels can be accessed by any number of
@@ -15,23 +15,20 @@ The UI has also been designed primarily with touch devices in mind,
15
15
  but also works well with a cursor and keyboard.
16
16
 
17
17
  <p align="center">
18
- <img src="./docs/architecture.svg" alt="Architecture Diagram">
18
+ <img src="https://raw.githubusercontent.com/arcanejs/arcanejs/main/packages/react-toolkit/docs/architecture.svg" alt="Architecture Diagram">
19
19
  </p>
20
20
 
21
- ## Status / Suitability / Security Disclaimer
21
+ ## What
22
22
 
23
- This project is **experimental**,
24
- and takes advantage of unstable `react` APIs exposed via `react-render`.
25
- It's not suitable for production or commercial projects yet,
26
- especially those that rely on regular updates of dependencies
27
- for security reasons,
28
- as usage of this project may make it difficult to keep `react` up-to-date
29
- (that being said, the license does not prohibit this,
30
- so feel free to at-your-own-risk).
23
+ - Easily create controller UIs for Node.js processes
31
24
 
32
- There are also no authentication mechanisms implemented yet,
33
- so be careful when exposing your control panels over the network,
34
- as this will allow anyone to interact with your processes.
25
+ - Uses server-side **React** for state management and UI composition
26
+
27
+ - This is not SSR, you can use `useState()` hooks etc...
28
+
29
+ - Instantly updates all clients using WebSockets
30
+
31
+ - Collection of 9+ components to build your UIs
35
32
 
36
33
  ## Why
37
34
 
@@ -117,7 +114,7 @@ ToolkitRenderer.render(<ControlPanel />, toolkit);
117
114
  You would then be able to access the following control panel
118
115
  from [localhost:3000](http://localhost:3000):
119
116
 
120
- ![Control Panel Screenshot](./docs/example-controller.png)
117
+ ![Control Panel Screenshot](https://raw.githubusercontent.com/arcanejs/arcanejs/main/packages/react-toolkit/docs/example-controller.png)
121
118
 
122
119
  Please note:
123
120
 
@@ -291,3 +288,18 @@ TODO
291
288
  For a comprehensive list of examples,
292
289
  please see the example directory in the arcane monorepo:
293
290
  <https://github.com/arcanejs/arcanejs/tree/main/examples/react>
291
+
292
+ ## Status / Suitability / Security Disclaimer
293
+
294
+ This project is **experimental**,
295
+ and takes advantage of unstable `react` APIs exposed via `react-render`.
296
+ It's not suitable for production or commercial projects yet,
297
+ especially those that rely on regular updates of dependencies
298
+ for security reasons,
299
+ as usage of this project may make it difficult to keep `react` up-to-date
300
+ (that being said, the license does not prohibit this,
301
+ so feel free to at-your-own-risk).
302
+
303
+ There are also no authentication mechanisms implemented yet,
304
+ so be careful when exposing your control panels over the network,
305
+ as this will allow anyone to interact with your processes.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcanejs/react-toolkit",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "private": false,
5
5
  "description": "Build web-accessible control interfaces for your long-running Node.js processes",
6
6
  "keywords": [
@@ -43,8 +43,7 @@
43
43
  "@arcanejs/toolkit": "^0.2.0"
44
44
  },
45
45
  "files": [
46
- "dist",
47
- "docs"
46
+ "dist"
48
47
  ],
49
48
  "publishConfig": {
50
49
  "access": "public"
@@ -1,271 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg"
2
- xmlns:xlink="http://www.w3.org/1999/xlink" id="svg8" version="1.1" viewBox="0 0 800 200" width="800" height="200">
3
- <style>
4
- * {
5
- font-size: 14px;
6
- font-family: sans-serif;
7
- }
8
-
9
- #labels * {
10
- font-size: 14px;
11
- font-weight: bold;
12
- }
13
-
14
- #code * {
15
- font-size: 12px;
16
- font-family: monospace;
17
- }
18
-
19
- .black-border {
20
- stroke: #151516;
21
- stroke-width: 1;
22
- }
23
-
24
- @keyframes btn-move-keyframes {
25
- 5% {
26
- transform: translate(0, 0);
27
- }
28
- 10% {
29
- transform: translate(40px, 0);
30
- }
31
- 55% {
32
- transform: translate(40px, 0);
33
- }
34
- 60% {
35
- transform: translate(0, 0);
36
- }
37
- }
38
-
39
- .btn-move {
40
- animation: 6s linear 0s infinite normal none running btn-move-keyframes;
41
- }
42
-
43
- @keyframes mouse-anim-keyframes {
44
- 0% {
45
- opacity: 1;
46
- transform: scale(1);
47
- }
48
- 2.5% {
49
- opacity: 1;
50
- transform: scale(0.8);
51
- }
52
- 5% {
53
- opacity: 1;
54
- transform: scale(1);
55
- }
56
- 7.5% {
57
- opacity: 1;
58
- transform: scale(1);
59
- }
60
- 10% {
61
- opacity: 0;
62
- transform: scale(1);
63
- }
64
- 90% {
65
- opacity: 0;
66
- transform: scale(1);
67
- }
68
- 100% {
69
- opacity: 1;
70
- transform: scale(1);
71
- }
72
- }
73
-
74
- @keyframes highlight-keyframes {
75
- 0% {
76
- opacity: 0;
77
- }
78
- 2.45% {
79
- opacity: 0;
80
- }
81
- 2.5% {
82
- opacity: 1;
83
- }
84
- 10% {
85
- opacity: 0;
86
- }
87
- 100% {
88
- opacity: 0;
89
- }
90
- }
91
-
92
- .mouse-anim-1 {
93
- opacity: 0;
94
- transform-origin: 60px 75px;
95
- animation: 6s linear 0s infinite normal none running mouse-anim-keyframes;
96
- }
97
-
98
- .highlight-anim-1 {
99
- opacity: 0;
100
- animation: 6s linear 0s infinite normal none running highlight-keyframes;
101
- }
102
-
103
- .mouse-anim-2 {
104
- opacity: 0;
105
- transform-origin: 620px 75px;
106
- animation: 6s linear 3s infinite normal none running mouse-anim-keyframes;
107
- }
108
-
109
- .highlight-anim-2 {
110
- opacity: 0;
111
- animation: 6s linear 3s infinite normal none running highlight-keyframes;
112
- }
113
-
114
- @keyframes state-keyframes {
115
- 4.9% {
116
- opacity: 0;
117
- fill: #aaa;
118
- }
119
- 5% {
120
- opacity: 1;
121
- fill: #4286f4;
122
- }
123
- 10% {
124
- opacity: 1;
125
- fill: #aaa;
126
- }
127
- 54.9% {
128
- opacity: 1;
129
- fill: #aaa;
130
- }
131
- 55% {
132
- opacity: 0;
133
- fill: #aaa;
134
- }
135
- }
136
-
137
- .text-off {
138
- font-weight: bold;
139
- opacity: 0;
140
- animation: 6s linear 3s infinite normal none running state-keyframes;
141
- }
142
-
143
- .text-on {
144
- font-weight: bold;
145
- opacity: 0;
146
- animation: 6s linear 0s infinite normal none running state-keyframes;
147
- }
148
- </style>
149
- <defs>
150
- <linearGradient id="buttonOnGrad" x1="0%" y1="0%" x2="0%" y2="100%">
151
- <stop offset="0%" style="stop-color:#2a77f3;stop-opacity:1" />
152
- <stop offset="100%" style="stop-color:#4286f4;stop-opacity:1" />
153
- </linearGradient>
154
- <linearGradient id="buttonOffGrad" x1="0%" y1="0%" x2="0%" y2="100%">
155
- <stop offset="0%" style="stop-color:#242525;stop-opacity:1" />
156
- <stop offset="100%" style="stop-color:#37383a;stop-opacity:1" />
157
- </linearGradient>
158
- <linearGradient id="buttonGrad" x1="0%" y1="0%" x2="0%" y2="100%">
159
- <stop offset="0%" style="stop-color:#4f5053;stop-opacity:1" />
160
- <stop offset="100%" style="stop-color:#343436;stop-opacity:1" />
161
- </linearGradient>
162
- <filter id="textShadow" x="-50%" y="-50%" width="200%" height="200%">
163
- <feGaussianBlur in="SourceAlpha" stdDeviation="1"/>
164
- <feOffset dx="0" dy="-1" result="offsetblur"/>
165
- <feFlood flood-color="rgba(0,0,0,0.4)"/>
166
- <feComposite in2="offsetblur" operator="in"/>
167
- <feMerge>
168
- <feMergeNode/>
169
- <feMergeNode in="SourceGraphic"/>
170
- </feMerge>
171
- </filter>
172
- <filter id="inset-shadow" x="-50%" y="-50%" width="200%" height="200%">
173
- <feComponentTransfer in="SourceAlpha">
174
- <feFuncA type="table" tableValues="1 0" />
175
- </feComponentTransfer>
176
- <feGaussianBlur stdDeviation="5" />
177
- <feOffset dx="0" dy="0" result="offsetblur" />
178
- <feFlood flood-color="black" result="color" />
179
- <feComposite in2="offsetblur" operator="in" />
180
- <feComposite in2="SourceAlpha" operator="in" />
181
- <feMerge>
182
- <feMergeNode in="SourceGraphic" />
183
- <feMergeNode />
184
- </feMerge>
185
- </filter>
186
- <marker id="arrow" viewBox="0 0 10 10" refX="5" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
187
- <path d="M 0 0 L 10 5 L 0 10 z" fill="#777" />
188
- </marker>
189
- <g id="button_slider">
190
- <rect x="-40" y="0" width="40" height="30" fill="url(#buttonOnGrad)" />
191
- <text x="-20" y="15" width="40" height="30" dy="0.35em" text-anchor="middle" fill="white" filter="url(#textShadow)">ON</text>
192
- <rect x="29" y="0" width="41" height="30" fill="url(#buttonOffGrad)" />
193
- <text x="50" y="15" width="40" height="30" dy="0.35em" text-anchor="middle" fill="white" filter="url(#textShadow)">OFF</text>
194
- <rect x="-1" y="0" class="black-border" width="31" height="30" fill="url(#buttonGrad)" rx="3" ry="3" />
195
- </g>
196
- <g id="screen">
197
- <rect x="0" y="0" width="200" height="100" fill="#252524" filter="url(#inset-shadow)" rx="3" ry="3" />
198
- <mask id="button_slider_1_mask">
199
- <rect x="10.5" y="10.5" width="70" height="30" fill="#ffffff" rx="3" ry="3" />
200
- </mask>
201
- <g mask="url(#button_slider_1_mask)">
202
- <g class="btn-move">
203
- <use x="10.5" y="10.5" href="#button_slider" />
204
- </g>
205
- </g>
206
- <rect class="black-border" x="10.5" y="10.5" width="70" height="30" fill="none" rx="3" ry="3" />
207
- </g>
208
- <g id="browser">
209
- <rect x="-10" y="0" width="220" height="150" fill="#ccc" rx="5" ry="5" stroke-width="2" stroke="#aaa" />
210
- <rect x="40.5" y="10.5" width="160" height="20" fill="#fff" rx="3" ry="3" stroke-width="1" stroke="#aaa" />
211
- <path d="M 10 15 L 0 20 L 10 25 Z" fill="#777" />
212
- <path d="M 20 15 L 30 20 L 20 25 Z" fill="#777" />
213
- <text x="120" y="20" height="30" dy="0.35em" text-anchor="middle" fill="#777">10.10.10.10:8080</text>
214
- </g>
215
- <g id="switch_highlight">
216
- <rect x="0.5" y="0.5" width="82" height="42" fill="none" stroke="#4286f4" stroke-width="2" rx="6" ry="6" />
217
- </g>
218
- <g id="mouse">
219
- <g style="transform: scale(3)">
220
- <path fill="#fefefe" d="M5.986 21.07v-2.155h-.958V17H4.07v-1.915h-.957V12.93H1.915v-.958H.958v-1.916h2.155v.958h.957v2.873h.958V.957h1.916v9.1H7.9V5.985h2.155v4.07h.958V6.944h1.916v4.07h.957V7.901h1.198V9.1h.957v6.943h-.957v2.873h-1.198v2.155H5.986z"/>
221
- <path d="M5.028 22.028v-3.113H4.07V17h-.957v-1.915H1.915V12.93H.958v-.958H0V9.099h3.113v.957h.957V.958h.958V0h1.916v.958H7.9v4.07h2.155v.958h2.874v.958h2.155V7.9h.957V9.1H17v6.943h-.958v2.873h-.957v3.113H5.028zm8.86-.958v-2.155h1.197v-2.873h.957V9.1h-.957V7.9h-1.198v3.113h-.957v-4.07h-1.916v3.112h-.958v-4.07H7.901v4.07h-.957V.958H5.028v12.93H4.07v-2.874h-.957v-.958H.958v1.916h.957v.958h1.198v2.155h.957V17h.958v1.915h.958v2.155h7.901z" />
222
- </g>
223
- </g>
224
- </defs>
225
-
226
- <g>
227
- <use y="10" x="20" href="#browser" />
228
- <use y="50" x="20" href="#screen" />
229
-
230
- <use y="10" x="580" href="#browser" />
231
- <use y="50" x="580" href="#screen" />
232
-
233
- <use y="54" x="24" href="#switch_highlight" class="highlight-anim-1" />
234
- <use y="75" x="50.5" href="#mouse" class="mouse-anim-1" />
235
- <use y="54" x="584" href="#switch_highlight" class="highlight-anim-2" />
236
- <use y="75" x="610.5" href="#mouse" class="mouse-anim-2" />
237
- </g>
238
-
239
- <g>
240
- <rect x="290" y="10" width="220" height="150" fill="#333" rx="5" ry="5" stroke-width="2" stroke="#050505" />
241
- <g id="code">
242
- <text x="300" y="30" text-anchor="start" fill="#f5f5f5">const &#91;state, setState&#93; &#61;</text>
243
- <text x="300" y="50" text-anchor="start" fill="#f5f5f5">&#160;&#160;useState&#40;&#39;off&#39;&#41;&#59;</text>
244
- <text x="300" y="80" text-anchor="start" fill="#aaa" class="text-off">&#47;&#47; state &#61;&#61; &#39;off&#39;</text>
245
- <text x="300" y="80" text-anchor="start" fill="#aaa" class="text-on">&#47;&#47; state &#61;&#61; &#39;on&#39;</text>
246
- <text x="300" y="110" text-anchor="start" fill="#f5f5f5">&lt;Switch</text>
247
- <text x="300" y="130" text-anchor="start" fill="#f5f5f5">&#160;&#160;state&#61;&#123;state&#125;</text>
248
- <text x="300" y="150" text-anchor="start" fill="#f5f5f5">&#160;&#160;onChange&#61;&#123;setState&#125; &#47;&#62;</text>
249
- </g>
250
- </g>
251
-
252
- <g id="labels">
253
- <!-- WS -->
254
- <line x1="235" y1="90" x2="285" y2="90" stroke="#777" stroke-width="2" marker-start="url(#arrow)" marker-end="url(#arrow)" />
255
- <rect x="235" y="52.5" width="50" height="25" fill="#f5f5f5" rx="6" ry="6" />
256
- <text x="260" y="70" height="30" text-anchor="middle" fill="#333">WS</text>
257
-
258
- <line x1="515" y1="90" x2="565" y2="90" stroke="#777" stroke-width="2" marker-start="url(#arrow)" marker-end="url(#arrow)" />
259
- <rect x="515" y="52.5" width="50" height="25" fill="#f5f5f5" rx="6" ry="6" />
260
- <text x="540" y="70" height="30" text-anchor="middle" fill="#333">WS</text>
261
-
262
- <!-- Bottom -->
263
- <rect x="35" y="167.5" width="170" height="25" fill="#f5f5f5" rx="6" ry="6" />
264
- <text x="120" y="185" height="30" text-anchor="middle" fill="#333">Browser Client 1</text>
265
- <rect x="315" y="167.5" width="170" height="25" fill="#f5f5f5" rx="6" ry="6" />
266
- <text x="400" y="185" height="30" text-anchor="middle" fill="#333">Node.js Process</text>
267
- <rect x="595" y="167.5" width="170" height="25" fill="#f5f5f5" rx="6" ry="6" />
268
- <text x="680" y="185" height="30" text-anchor="middle" fill="#333">Browser Client 2</text>
269
- </g>
270
-
271
- </svg>
Binary file