@transitive-sdk/utils-web 0.7.6 → 0.7.7

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
@@ -8,4 +8,4 @@
8
8
 
9
9
  Utilities used by the web components of [Transitive Robotics](https://transitiverobotics.com) capabilities.
10
10
 
11
- [API Documentation](./docs/index.md)
11
+ [Documentation](https://transitiverobotics.com/docs/sdk/utils-web)
package/docs/index.md CHANGED
@@ -1,9 +1,74 @@
1
+ # Web (browser)
2
+
3
+ These classes and functions are available via the `@transitive-sdk/utils-web` npm package and are for use in the browser or other browser based front-ends.
4
+
5
+ ### Example
6
+
7
+ In this example we create a new web-component (custom element) from a React component using mqttSync to subscribe to some data and re-rendering it in real-time whenever it changes.
8
+
9
+ ```js
10
+ import React, { useEffect } from 'react';
11
+
12
+ import { createWebComponent, useTransitive, getLogger }
13
+ from '@transitive-sdk/utils-web';
14
+
15
+ const log = getLogger('my-new-capability');
16
+ log.setLevel('debug');
17
+
18
+ // Get the name of the package we are part of. TR_PKG_NAME is set by esbuild.
19
+ const [scope, capabilityName] = TR_PKG_NAME.split('/');
20
+
21
+ const Device = ({jwt, id, host, ssl}) => {
22
+
23
+ const { mqttSync, data, StatusComponent, prefixVersion } =
24
+ useTransitive({ jwt, id, host, ssl,
25
+ capability: TR_PKG_NAME,
26
+ versionNS: TR_PKG_VERSION_NS
27
+ });
28
+
29
+ // once mqttSync is connected, subscribe to some topics
30
+ useEffect(() => {
31
+ if (!mqttSync) return;
32
+ mqttSync.subscribe(`${prefixVersion}/device`);
33
+ mqttSync.subscribe(`${prefixVersion}/cloud`);
34
+ }, [mqttSync]);
35
+
36
+ log.debug({prefixVersion, data, TR_PKG_NAME, TR_PKG_VERSION, TR_PKG_VERSION_NS});
37
+
38
+ return <div>
39
+ <StatusComponent />
40
+ <pre>
41
+ {/* Render the data. This updates automatically whenever data changes. */}
42
+ {JSON.stringify(data, true, 2)}
43
+ </pre>
44
+ </div>;
45
+ };
46
+
47
+ createWebComponent(Device, `${capabilityName}-device`, ['jwt']);
48
+ ```
49
+
1
50
  <!-- Generated by documentation.js. Update this documentation by updating the source code. -->
2
51
 
3
52
  ## DataCache
4
53
 
5
54
  A class implementing a local data cache, used as a local data store with
6
- deduplication detection and update events.
55
+ deduplication detection and update events. While this class is very handy
56
+ you probably won't need to create instances of it directly. Instead use
57
+ the mqttSync.data instance which holds the locally stored data
58
+ subscribed/published from/to MQTTSync.
59
+ For example on the robot:
60
+
61
+ ```js
62
+ // update/publish our status:
63
+ mqttSync.data.update('status', {changed: Date.now(), msg: 'OK'});
64
+ // subscribe to new user requests (e.g., from UI):
65
+ mqttSync.data.subscribePath('+user/request', (request, key, {user}) => {
66
+ log.debug(`user ${user} made request`, request);
67
+ });
68
+ ```
69
+
70
+ In the cloud or in a web component you would need to use the full topic including
71
+ org, device, scope, cap-name, and version.
7
72
 
8
73
  #### Parameters
9
74
 
@@ -11,7 +76,7 @@ deduplication detection and update events.
11
76
 
12
77
  ### filter
13
78
 
14
- filter the object using path with wildcards
79
+ Filter the object using path with wildcards
15
80
 
16
81
  ##### Parameters
17
82
 
@@ -19,7 +84,7 @@ filter the object using path with wildcards
19
84
 
20
85
  ### filterByTopic
21
86
 
22
- filter the object using topic with wildcards
87
+ Filter the object using topic with wildcards
23
88
 
24
89
  ##### Parameters
25
90
 
@@ -27,8 +92,8 @@ filter the object using topic with wildcards
27
92
 
28
93
  ### forMatch
29
94
 
30
- for each topic match, invoke the callback with the value, topic, and match
31
- just like subscribePath
95
+ For each topic match, invoke the callback with the value, topic, and match
96
+ just like subscribePath, but on the current data rather than future changes.
32
97
 
33
98
  ##### Parameters
34
99
 
@@ -37,7 +102,7 @@ just like subscribePath
37
102
 
38
103
  ### forPathMatch
39
104
 
40
- for each path match, invoke the callback with the value, topic, and match
105
+ For each path match, invoke the callback with the value, topic, and match
41
106
  just like subscribePath
42
107
 
43
108
  ##### Parameters
@@ -47,15 +112,23 @@ just like subscribePath
47
112
 
48
113
  ### get
49
114
 
50
- get sub-value at path, or entire object if none given
115
+ Get sub-value at path, or entire object if none given
51
116
 
52
117
  ##### Parameters
53
118
 
54
119
  * `path` (optional, default `[]`)
55
120
 
121
+ ### getByTopic
122
+
123
+ Get sub-value specified by topic
124
+
125
+ ##### Parameters
126
+
127
+ * `topic` &#x20;
128
+
56
129
  ### subscribe
57
130
 
58
- add a callback for change events
131
+ Add a callback for all change events.
59
132
 
60
133
  ##### Parameters
61
134
 
@@ -63,8 +136,8 @@ add a callback for change events
63
136
 
64
137
  ### subscribePath
65
138
 
66
- Subscribe to a specific topic only. Unlike in `subscribe`, here callback
67
- only receives the value.
139
+ Subscribe to a specific topic only. Callback receives
140
+ `value, key, matched, tags`.
68
141
 
69
142
  ##### Parameters
70
143
 
@@ -82,7 +155,7 @@ Same as subscribePath but always get all changes in flat form
82
155
 
83
156
  ### unsubscribe
84
157
 
85
- remove a callback
158
+ Remove a callback previously registered using `subscribe`.
86
159
 
87
160
  ##### Parameters
88
161
 
@@ -90,7 +163,7 @@ remove a callback
90
163
 
91
164
  ### update
92
165
 
93
- update the value at the given path (array or dot separated string)
166
+ Update the value at the given path (array or dot separated string)
94
167
 
95
168
  ##### Parameters
96
169
 
@@ -100,7 +173,7 @@ update the value at the given path (array or dot separated string)
100
173
 
101
174
  ### updateFromArray
102
175
 
103
- update the object with the given value at the given path, remove empty;
176
+ Update the object with the given value at the given path, remove empty;
104
177
  return the flat changes (see toFlatObject). Add `tags` to updates to mark
105
178
  them somehow based on the context, e.g., so that some subscriptions can choose
106
179
  to ignore updates with a certain tag.
@@ -113,7 +186,7 @@ to ignore updates with a certain tag.
113
186
 
114
187
  ### updateFromModifier
115
188
 
116
- update data from a modifier object where keys are topic names to be
189
+ Update data from a modifier object where keys are topic names to be
117
190
  interpreted as paths, and values are the values to set
118
191
 
119
192
  ##### Parameters
@@ -123,7 +196,7 @@ interpreted as paths, and values are the values to set
123
196
 
124
197
  ### updateFromTopic
125
198
 
126
- set value from the given topic (with or without leading or trailing slash)
199
+ Set value from the given topic (with or without leading or trailing slash)
127
200
 
128
201
  ##### Parameters
129
202
 
@@ -148,14 +221,31 @@ feature over the latter. Relies on retained messages in mqtt for persistence.
148
221
 
149
222
  #### Parameters
150
223
 
151
- * `$0` **[Object][1]**&#x20;
152
-
153
- * `$0.mqttClient` &#x20;
154
- * `$0.onChange` &#x20;
155
- * `$0.ignoreRetain` &#x20;
156
- * `$0.migrate` &#x20;
157
- * `$0.onReady` &#x20;
158
- * `$0.sliceTopic` &#x20;
224
+ * `options` **[object][1]**&#x20;
225
+
226
+ * `options.mqttClient` **[object][1]** An already connected mqtt.js client.
227
+ * `options.onChange` **[function][2]?** A function that is called any time there
228
+ is a change to the shared data. This is not usually used. It's usually better to
229
+ use the finer grained `MqttSync.data.subscribePath` instead, that allows you to
230
+ subscribe to changes just on a specific sun-object instead, see DataCache.
231
+ * `options.ignoreRetain` **[boolean][3]?** retain all messages, ignorant of the retain
232
+ flag.
233
+ * `options.migrate` **[array][4]?** an array of objects of the form
234
+ `{topic, newVersion, level}`. Only meaningful in the cloud. Instructs MQTTSync
235
+ to first migrate existing topics to a new version namespace, publishing at the
236
+ designated level down from the version level. For example:```js
237
+ [{ topic: `/myorg/mydevice/@local/my-cap/+/config`,
238
+ newVersion: this.version,
239
+ level: 1
240
+ }]
241
+ ```Would migrate any existing data in the capability's `config` namespace to the
242
+ current version of the package, publishing at the `config/+` level (rather than
243
+ atomically at the config level itself).
244
+ * `options.onReady` **[function][2]?** A function that is called when the MQTTSync
245
+ client is ready and has completed any requested migrations.
246
+ * `options.sliceTopic` **[number][5]?** a number indicating at what level to
247
+ slice the topic, i.e., only use a suffix. Used in robot-capabilities to slice
248
+ off the topic prefix (namespaces).
159
249
 
160
250
  ### beforeDisconnect
161
251
 
@@ -229,7 +319,7 @@ before calling this or set the data all at once afterwards.
229
319
 
230
320
  With option "atomic" this will always send the whole sub-document,
231
321
  not flat changes. Useful, e.g., for desiredPackages, see
232
- [https://github.com/chfritz/transitive/issues/85][2].
322
+ [https://github.com/chfritz/transitive/issues/85][6].
233
323
 
234
324
  ##### Parameters
235
325
 
@@ -276,39 +366,6 @@ register a callback for the next heartbeat from the broker
276
366
 
277
367
  * `callback` &#x20;
278
368
 
279
- ### heartbeatWaitersOnce
280
-
281
- List of callbacks waiting for next heartbeat, gets purged with each
282
- heartbeat
283
-
284
- ### publishedMessages
285
-
286
- Store messages retained on mqtt so we can publish what is necessary to
287
- achieve the "should-be" state. Note that we cannot use a structured document
288
- for storing these publishedMessages since we need to be able to store separate
289
- values at non-leaf nodes in the object (just like mqtt, where you can have
290
- /a/b = 1 and /a/b/c = 1 at the same time). Note: not used in atomic mode.
291
-
292
- ### publishQueue
293
-
294
- The order in which we send retained messages matters, which is why we use
295
- a queue for sending things. Note that we here use the property of Map that it
296
- remembers insertion order of keys.
297
-
298
- ### subscribedPaths
299
-
300
- Directory of paths we've subscribed to in this class; this matters
301
- because the same mqtt client may have subscriptions to paths that we don't
302
- care to store (sync).
303
-
304
- ## clone
305
-
306
- clone a mqtt payload, if necessary
307
-
308
- #### Parameters
309
-
310
- * `payload` &#x20;
311
-
312
369
  ## clone
313
370
 
314
371
  Deep-clone the given object. All functionality is lost, just data is kept.
@@ -357,14 +414,6 @@ reduce wildcards with Ids, such as `+sessionId`, to just +
357
414
 
358
415
  * `x` &#x20;
359
416
 
360
- ## ensureHashSuffix
361
-
362
- return new string that ends in /# for sure
363
-
364
- #### Parameters
365
-
366
- * `topic` &#x20;
367
-
368
417
  ## fetchJson
369
418
 
370
419
  get or post (if body given) json
@@ -390,7 +439,9 @@ named wildcards)
390
439
 
391
440
  ## getLogger
392
441
 
393
- get a new logger; call with a name, e.g., `module.id`
442
+ Get a new loglevel logger; call with a name, e.g., `module.id`. The returned
443
+ logger has methods trace, debug, info, warn, error. See
444
+ [https://www.npmjs.com/package/loglevel][7] for details.
394
445
 
395
446
  ## isPrefixOf
396
447
 
@@ -444,10 +495,6 @@ not owned by us. Harmless within capabilities, which are namespaced already.
444
495
  * `callback` &#x20;
445
496
  * `delay` (optional, default `1000`)
446
497
 
447
- ## oneDown
448
-
449
- called each time one item is done
450
-
451
498
  ## parseCookie
452
499
 
453
500
  parse document cookies
@@ -480,14 +527,6 @@ convert a path array to mqtt topic; reduces +id identifiers to +
480
527
 
481
528
  * `pathArray` &#x20;
482
529
 
483
- ## resolveDoubleSlashes
484
-
485
- given a path, replace any double slashes, '//', with single ones
486
-
487
- #### Parameters
488
-
489
- * `path` &#x20;
490
-
491
530
  ## selectFromObject
492
531
 
493
532
  given an object and a path with wildcards (\* and +), *modify* the object
@@ -497,7 +536,7 @@ to only contain elements matched by the path, e.g.,
497
536
  #### Parameters
498
537
 
499
538
  * `obj` **[object][1]** The object to select from
500
- * `path` **[array][3]** An array specifying the path to select, potentially
539
+ * `path` **[array][4]** An array specifying the path to select, potentially
501
540
  containing mqtt wildcards ('+').
502
541
 
503
542
  ## setFromPath
@@ -512,11 +551,17 @@ Like \_.set but without arrays. This allows using numbers as keys.
512
551
 
513
552
  ## toFlatObject
514
553
 
515
- given an object, return a new object where all sub-objects are
516
- replaced by topic-values, e.g.:
517
- {a: {b: 1, c: 2}, d: 3} -> {'/a/b': 1, '/a/c': 2, d: 3}
554
+ Given an object, return a new flat object of topic+value pairs, e.g.:
555
+
556
+ ```js
557
+ {a: {b: 1, c: 2}, d: 3} → {'/a/b': 1, '/a/c': 2, '/d': 3}
558
+ ```
559
+
518
560
  Note: not idempotent!
519
- {'/a/b': 1, '/a/c': 2, d: 3} -> {'%2Fa%2Fb': 1, '%2Fa%2Fc': 2, d: 3}
561
+
562
+ ```js
563
+ {'/a/b': 1, '/a/c': 2, d: 3} → {'%2Fa%2Fb': 1, '%2Fa%2Fc': 2, '/d': 3}
564
+ ```
520
565
 
521
566
  #### Parameters
522
567
 
@@ -544,7 +589,7 @@ convert topic to path array
544
589
 
545
590
  ## tryJSONParse
546
591
 
547
- try parsing JSON, return null if unsuccessful
592
+ Try parsing JSON, return null if unsuccessful
548
593
 
549
594
  #### Parameters
550
595
 
@@ -612,7 +657,7 @@ comparison. Hence, 2.0 < 2.0.1.
612
657
 
613
658
  ## visit
614
659
 
615
- reusable visitor pattern: iteratively visits all nodes in the tree
660
+ Reusable visitor pattern: iteratively visits all nodes in the tree
616
661
  described by `object`, where `childField` indicates the child-of predicate.
617
662
 
618
663
  #### Parameters
@@ -623,22 +668,12 @@ described by `object`, where `childField` indicates the child-of predicate.
623
668
 
624
669
  ## wait
625
670
 
626
- wait for delay ms, usable in async functions
671
+ Wait for delay ms, for use in async functions.
627
672
 
628
673
  #### Parameters
629
674
 
630
675
  * `delay` &#x20;
631
676
 
632
- ## create
633
-
634
- #### Parameters
635
-
636
- * `wrapper` **JSX.Element** : the wrapper component class to be instantiated and wrapped
637
- * `tagName` **[string][4]** The name of the web component. Has to be minus "-" delimited.
638
- * `useShadowDom` **[boolean][5]** If the value is set to "true" the web component will use the `shadowDom`. The default value is true. (optional, default `true`)
639
- * `observedAttributes` **[Array][3]<[string][4]>** The observed attributes of the web component (optional, default `[]`)
640
- * `compRef` (optional, default `undefined`)
641
-
642
677
  ## extractAttributes
643
678
 
644
679
  Takes in a node attributes map and returns an object with camelCased
@@ -656,14 +691,6 @@ An optional library which is conditionally added
656
691
 
657
692
  Returns **\[]**&#x20;
658
693
 
659
- ## setAll
660
-
661
- convenience function to set all loggers to the given level
662
-
663
- #### Parameters
664
-
665
- * `level` &#x20;
666
-
667
694
  ## setConfig
668
695
 
669
696
  method exposed to the wrapped component via prop that allows setting
@@ -699,10 +726,14 @@ and update props.
699
726
 
700
727
  [1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
701
728
 
702
- [2]: https://github.com/chfritz/transitive/issues/85
729
+ [2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function
730
+
731
+ [3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean
732
+
733
+ [4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array
703
734
 
704
- [3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array
735
+ [5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
705
736
 
706
- [4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String
737
+ [6]: https://github.com/chfritz/transitive/issues/85
707
738
 
708
- [5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean
739
+ [7]: https://www.npmjs.com/package/loglevel
package/docs_header.md ADDED
@@ -0,0 +1,49 @@
1
+ # Web (browser)
2
+
3
+ These classes and functions are available via the `@transitive-sdk/utils-web` npm package and are for use in the browser or other browser based front-ends.
4
+
5
+ ### Example
6
+
7
+ In this example we create a new web-component (custom element) from a React component using mqttSync to subscribe to some data and re-rendering it in real-time whenever it changes.
8
+
9
+ ```js
10
+ import React, { useEffect } from 'react';
11
+
12
+ import { createWebComponent, useTransitive, getLogger }
13
+ from '@transitive-sdk/utils-web';
14
+
15
+ const log = getLogger('my-new-capability');
16
+ log.setLevel('debug');
17
+
18
+ // Get the name of the package we are part of. TR_PKG_NAME is set by esbuild.
19
+ const [scope, capabilityName] = TR_PKG_NAME.split('/');
20
+
21
+ const Device = ({jwt, id, host, ssl}) => {
22
+
23
+ const { mqttSync, data, StatusComponent, prefixVersion } =
24
+ useTransitive({ jwt, id, host, ssl,
25
+ capability: TR_PKG_NAME,
26
+ versionNS: TR_PKG_VERSION_NS
27
+ });
28
+
29
+ // once mqttSync is connected, subscribe to some topics
30
+ useEffect(() => {
31
+ if (!mqttSync) return;
32
+ mqttSync.subscribe(`${prefixVersion}/device`);
33
+ mqttSync.subscribe(`${prefixVersion}/cloud`);
34
+ }, [mqttSync]);
35
+
36
+ log.debug({prefixVersion, data, TR_PKG_NAME, TR_PKG_VERSION, TR_PKG_VERSION_NS});
37
+
38
+ return <div>
39
+ <StatusComponent />
40
+ <pre>
41
+ {/* Render the data. This updates automatically whenever data changes. */}
42
+ {JSON.stringify(data, true, 2)}
43
+ </pre>
44
+ </div>;
45
+ };
46
+
47
+ createWebComponent(Device, `${capabilityName}-device`, ['jwt']);
48
+ ```
49
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transitive-sdk/utils-web",
3
- "version": "0.7.6",
3
+ "version": "0.7.7",
4
4
  "description": "Web utils for the Transitive framework",
5
5
  "homepage": "https://transitiverobotics.com",
6
6
  "author": {
@@ -16,7 +16,7 @@ const lifeCycleHooks = {
16
16
  };
17
17
 
18
18
  module.exports = {
19
- /**
19
+ /*
20
20
  * @param {JSX.Element} wrapper: the wrapper component class to be instantiated and wrapped
21
21
  * @param {string} tagName - The name of the web component. Has to be minus "-" delimited.
22
22
  * @param {boolean} useShadowDom - If the value is set to "true" the web component will use the `shadowDom`. The default value is true.
@@ -90,13 +90,13 @@ module.exports = {
90
90
  this.callLifeCycleHook('adoptedCallback', [oldDocument, newDocument]);
91
91
  }
92
92
 
93
- /** call a function defined in the component, either as a class method, or
93
+ /* call a function defined in the component, either as a class method, or
94
94
  * via useImperativeHandle */
95
95
  call(functionName, args) {
96
96
  return compRef?.current?.[functionName]?.call(compRef?.current, args);
97
97
  }
98
98
 
99
- /** predefined function to retrieve the pre-defined config object of the
99
+ /* predefined function to retrieve the pre-defined config object of the
100
100
  * state, populated via the pre-defined `setConfig` method given as prop
101
101
  * to the wrapped component. */
102
102
  getConfig() {