@transitive-sdk/utils-web 0.7.5 → 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 ADDED
@@ -0,0 +1,11 @@
1
+ <p align="center">
2
+ <a href="https://transitiverobotics.com">
3
+ <img src="https://transitiverobotics.com/img/logo.svg" style="height: 64px">
4
+ </a>
5
+ </p>
6
+
7
+ ## Transitive Web Utils
8
+
9
+ Utilities used by the web components of [Transitive Robotics](https://transitiverobotics.com) capabilities.
10
+
11
+ [Documentation](https://transitiverobotics.com/docs/sdk/utils-web)
package/client.js CHANGED
@@ -18,7 +18,7 @@ export const parseCookie = str =>
18
18
  return acc;
19
19
  }, {});
20
20
 
21
- /* get or post (if body given) json */
21
+ /** get or post (if body given) json */
22
22
  export const fetchJson = (url, callback, options = {}) => {
23
23
  fetch(url, {
24
24
  method: options.method || (options.body ? 'post' : 'get'),
package/docs/index.md ADDED
@@ -0,0 +1,739 @@
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
+
50
+ <!-- Generated by documentation.js. Update this documentation by updating the source code. -->
51
+
52
+ ## DataCache
53
+
54
+ A class implementing a local data cache, used as a local data store with
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.
72
+
73
+ #### Parameters
74
+
75
+ * `data` (optional, default `{}`)
76
+
77
+ ### filter
78
+
79
+ Filter the object using path with wildcards
80
+
81
+ ##### Parameters
82
+
83
+ * `path` &#x20;
84
+
85
+ ### filterByTopic
86
+
87
+ Filter the object using topic with wildcards
88
+
89
+ ##### Parameters
90
+
91
+ * `topic` &#x20;
92
+
93
+ ### forMatch
94
+
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.
97
+
98
+ ##### Parameters
99
+
100
+ * `topic` &#x20;
101
+ * `callback` &#x20;
102
+
103
+ ### forPathMatch
104
+
105
+ For each path match, invoke the callback with the value, topic, and match
106
+ just like subscribePath
107
+
108
+ ##### Parameters
109
+
110
+ * `path` &#x20;
111
+ * `callback` &#x20;
112
+
113
+ ### get
114
+
115
+ Get sub-value at path, or entire object if none given
116
+
117
+ ##### Parameters
118
+
119
+ * `path` (optional, default `[]`)
120
+
121
+ ### getByTopic
122
+
123
+ Get sub-value specified by topic
124
+
125
+ ##### Parameters
126
+
127
+ * `topic` &#x20;
128
+
129
+ ### subscribe
130
+
131
+ Add a callback for all change events.
132
+
133
+ ##### Parameters
134
+
135
+ * `callback` &#x20;
136
+
137
+ ### subscribePath
138
+
139
+ Subscribe to a specific topic only. Callback receives
140
+ `value, key, matched, tags`.
141
+
142
+ ##### Parameters
143
+
144
+ * `topic` &#x20;
145
+ * `callback` &#x20;
146
+
147
+ ### subscribePathFlat
148
+
149
+ Same as subscribePath but always get all changes in flat form
150
+
151
+ ##### Parameters
152
+
153
+ * `topic` &#x20;
154
+ * `callback` &#x20;
155
+
156
+ ### unsubscribe
157
+
158
+ Remove a callback previously registered using `subscribe`.
159
+
160
+ ##### Parameters
161
+
162
+ * `callback` &#x20;
163
+
164
+ ### update
165
+
166
+ Update the value at the given path (array or dot separated string)
167
+
168
+ ##### Parameters
169
+
170
+ * `path` &#x20;
171
+ * `value` &#x20;
172
+ * `tags` &#x20;
173
+
174
+ ### updateFromArray
175
+
176
+ Update the object with the given value at the given path, remove empty;
177
+ return the flat changes (see toFlatObject). Add `tags` to updates to mark
178
+ them somehow based on the context, e.g., so that some subscriptions can choose
179
+ to ignore updates with a certain tag.
180
+
181
+ ##### Parameters
182
+
183
+ * `path` &#x20;
184
+ * `value` &#x20;
185
+ * `tags` (optional, default `{}`)
186
+
187
+ ### updateFromModifier
188
+
189
+ Update data from a modifier object where keys are topic names to be
190
+ interpreted as paths, and values are the values to set
191
+
192
+ ##### Parameters
193
+
194
+ * `modifier` &#x20;
195
+ * `tags` &#x20;
196
+
197
+ ### updateFromTopic
198
+
199
+ Set value from the given topic (with or without leading or trailing slash)
200
+
201
+ ##### Parameters
202
+
203
+ * `topic` &#x20;
204
+ * `value` &#x20;
205
+ * `tags` &#x20;
206
+
207
+ ## ErrorBoundary
208
+
209
+ **Extends React.Component**
210
+
211
+ A simple error boundary. Usage: <ErrorBoundary message="Something went wrong"> <SomeFlakyComponent /> </ErrorBoundary>
212
+
213
+ #### Parameters
214
+
215
+ * `props` &#x20;
216
+
217
+ ## MqttSync
218
+
219
+ A class that combines DataCache and MQTT to implement a data synchronization
220
+ feature over the latter. Relies on retained messages in mqtt for persistence.
221
+
222
+ #### Parameters
223
+
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).
249
+
250
+ ### beforeDisconnect
251
+
252
+ Run all registered hooks before disconnecting
253
+
254
+ ### clear
255
+
256
+ Delete all retained messages in a certain topic prefix, waiting for
257
+ a mqtt broker heartbeat to collect existing retained. Use with care, never
258
+ delete topics not owned by us. Harmless within capabilities, which are
259
+ namespaced already.
260
+
261
+ `options.filter(topic)`: a function that can be provided to further,
262
+ programmatically filter the set of topics to clear, e.g., to onlt clear
263
+ topics of old versions.
264
+
265
+ Note: This may not yet work in robot-capabilities, since the subscription
266
+ prefix and received topic prefix don't match (the device prefix is added to
267
+ subscription by localMQTT.
268
+
269
+ ##### Parameters
270
+
271
+ * `prefixes` &#x20;
272
+ * `callback` (optional, default `undefined`)
273
+ * `options` (optional, default `{}`)
274
+
275
+ ### clearThrottle
276
+
277
+ clear the set throttling delay
278
+
279
+ ### isPublished
280
+
281
+ Check whether we are publishing the given topic in a non-atomic way.
282
+ This is used to determine whether to store the published value or not.
283
+
284
+ ##### Parameters
285
+
286
+ * `topic` &#x20;
287
+
288
+ ### isSubscribed
289
+
290
+ check whether we are subscribed to the given topic
291
+
292
+ ##### Parameters
293
+
294
+ * `topic` &#x20;
295
+
296
+ ### migrate
297
+
298
+ Migrate a list of {topic, newVersion, transform}. The version number in
299
+ topic will be ignored, and all versions' values will be merged, applied in
300
+ order, such that the latest version is applied last.
301
+
302
+ ##### Parameters
303
+
304
+ * `list` &#x20;
305
+ * `onReady` (optional, default `undefined`)
306
+
307
+ ### onBeforeDisconnect
308
+
309
+ register a new hook to be called before disconnecting
310
+
311
+ ##### Parameters
312
+
313
+ * `fn` &#x20;
314
+
315
+ ### publish
316
+
317
+ Register a listener for path in data. Make sure to populate the data
318
+ before calling this or set the data all at once afterwards.
319
+
320
+ With option "atomic" this will always send the whole sub-document,
321
+ not flat changes. Useful, e.g., for desiredPackages, see
322
+ [https://github.com/chfritz/transitive/issues/85][6].
323
+
324
+ ##### Parameters
325
+
326
+ * `topic` &#x20;
327
+ * `options` (optional, default `{atomic:false}`)
328
+
329
+ Returns **any** true if publication added (false, e.g., when already present)
330
+
331
+ ### publishAtLevel
332
+
333
+ Publish all values at the given level of the given object under the given
334
+ topic (plus sub-key, of course).
335
+ TODO: Is this OK, or do we need to go through this.publish?
336
+
337
+ ##### Parameters
338
+
339
+ * `topic` &#x20;
340
+ * `value` &#x20;
341
+ * `level` &#x20;
342
+
343
+ ### setThrottle
344
+
345
+ set min delay between processing of queue
346
+
347
+ ##### Parameters
348
+
349
+ * `delay` &#x20;
350
+
351
+ ### subscribe
352
+
353
+ Subscribe to the given topic (and all sub-topics). The callback will
354
+ indicate success/failure, *not* a message on the topic.
355
+
356
+ ##### Parameters
357
+
358
+ * `topic` &#x20;
359
+ * `callback` (optional, default `noop`)
360
+
361
+ ### waitForHeartbeatOnce
362
+
363
+ register a callback for the next heartbeat from the broker
364
+
365
+ ##### Parameters
366
+
367
+ * `callback` &#x20;
368
+
369
+ ## clone
370
+
371
+ Deep-clone the given object. All functionality is lost, just data is kept.
372
+
373
+ #### Parameters
374
+
375
+ * `obj` &#x20;
376
+
377
+ ## Code
378
+
379
+ reusable component for showing code
380
+
381
+ #### Parameters
382
+
383
+ * `$0` **[Object][1]**&#x20;
384
+
385
+ * `$0.children` &#x20;
386
+
387
+ ## componentPermitsRefs
388
+
389
+ whether or not the given react component allows refs, i.e., is either
390
+ a functional component wrapped with forwardRef or a class component
391
+
392
+ #### Parameters
393
+
394
+ * `Component` &#x20;
395
+
396
+ ## createWebComponent
397
+
398
+ Create a WebComponent from the given react component and name that is
399
+ reactive to the given attributes (if any).
400
+
401
+ #### Parameters
402
+
403
+ * `Component` &#x20;
404
+ * `name` &#x20;
405
+ * `reactiveAttributes` (optional, default `[]`)
406
+ * `version` (optional, default `'0.0.0'`)
407
+ * `options` (optional, default `{}`)
408
+
409
+ ## dropWildcardIds
410
+
411
+ reduce wildcards with Ids, such as `+sessionId`, to just +
412
+
413
+ #### Parameters
414
+
415
+ * `x` &#x20;
416
+
417
+ ## fetchJson
418
+
419
+ get or post (if body given) json
420
+
421
+ #### Parameters
422
+
423
+ * `url` &#x20;
424
+ * `callback` &#x20;
425
+ * `options` (optional, default `{}`)
426
+
427
+ ## forMatchIterator
428
+
429
+ Iterate through the object and invoke callback for each match of path (with
430
+ named wildcards)
431
+
432
+ #### Parameters
433
+
434
+ * `obj` &#x20;
435
+ * `path` &#x20;
436
+ * `callback` &#x20;
437
+ * `pathSoFar` (optional, default `[]`)
438
+ * `matchSoFar` (optional, default `{}`)
439
+
440
+ ## getLogger
441
+
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.
445
+
446
+ ## isPrefixOf
447
+
448
+ prefixArray is a prefix of the array
449
+
450
+ #### Parameters
451
+
452
+ * `prefixArray` &#x20;
453
+ * `array` &#x20;
454
+
455
+ ## isSubTopicOf
456
+
457
+ sub is a strict sub-topic of parent, and in particular not equal
458
+
459
+ #### Parameters
460
+
461
+ * `sub` &#x20;
462
+ * `parent` &#x20;
463
+
464
+ ## LevelBadge
465
+
466
+ The right badge for the level
467
+
468
+ #### Parameters
469
+
470
+ * `$0` **[Object][1]**&#x20;
471
+
472
+ * `$0.level` &#x20;
473
+
474
+ ## mergeVersions
475
+
476
+ given an object where the keys are versions, merge this into one object
477
+ where the latest version of each subfield overwrites any previous
478
+
479
+ #### Parameters
480
+
481
+ * `versionsObject` &#x20;
482
+ * `subTopic` (optional, default `undefined`)
483
+ * `options` (optional, default `{}`)
484
+
485
+ ## mqttClearRetained
486
+
487
+ delete all retained messages in a certain topic prefix, waiting for
488
+ a given delay to collect existing retained. Use with care, never delete topics
489
+ not owned by us. Harmless within capabilities, which are namespaced already.
490
+
491
+ #### Parameters
492
+
493
+ * `mqttClient` &#x20;
494
+ * `prefixes` &#x20;
495
+ * `callback` &#x20;
496
+ * `delay` (optional, default `1000`)
497
+
498
+ ## parseCookie
499
+
500
+ parse document cookies
501
+
502
+ #### Parameters
503
+
504
+ * `str` &#x20;
505
+
506
+ ## parseMQTTTopic
507
+
508
+ parse an MQTT topic according to our topic schema
509
+
510
+ #### Parameters
511
+
512
+ * `topic` &#x20;
513
+
514
+ ## parseMQTTUsername
515
+
516
+ parse usernames used in MQTT
517
+
518
+ #### Parameters
519
+
520
+ * `username` &#x20;
521
+
522
+ ## pathToTopic
523
+
524
+ convert a path array to mqtt topic; reduces +id identifiers to +
525
+
526
+ #### Parameters
527
+
528
+ * `pathArray` &#x20;
529
+
530
+ ## selectFromObject
531
+
532
+ given an object and a path with wildcards (\* and +), *modify* the object
533
+ to only contain elements matched by the path, e.g.,
534
+ {a: {b: 1, c: 2}, d: 2} and \['a','+'] would give {a: {b: 1, c: 2}}
535
+
536
+ #### Parameters
537
+
538
+ * `obj` **[object][1]** The object to select from
539
+ * `path` **[array][4]** An array specifying the path to select, potentially
540
+ containing mqtt wildcards ('+').
541
+
542
+ ## setFromPath
543
+
544
+ Like \_.set but without arrays. This allows using numbers as keys.
545
+
546
+ #### Parameters
547
+
548
+ * `obj` &#x20;
549
+ * `path` &#x20;
550
+ * `value` &#x20;
551
+
552
+ ## toFlatObject
553
+
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
+
560
+ Note: not idempotent!
561
+
562
+ ```js
563
+ {'/a/b': 1, '/a/c': 2, d: 3} → {'%2Fa%2Fb': 1, '%2Fa%2Fc': 2, '/d': 3}
564
+ ```
565
+
566
+ #### Parameters
567
+
568
+ * `obj` &#x20;
569
+ * `prefix` (optional, default `[]`)
570
+ * `rtv` (optional, default `{}`)
571
+
572
+ ## topicMatch
573
+
574
+ match a slash-separated topic with a selector using +XYZ for (named)
575
+ wildcards. Return the matching result.
576
+
577
+ #### Parameters
578
+
579
+ * `selector` &#x20;
580
+ * `topic` &#x20;
581
+
582
+ ## topicToPath
583
+
584
+ convert topic to path array
585
+
586
+ #### Parameters
587
+
588
+ * `topic` &#x20;
589
+
590
+ ## tryJSONParse
591
+
592
+ Try parsing JSON, return null if unsuccessful
593
+
594
+ #### Parameters
595
+
596
+ * `string` &#x20;
597
+
598
+ ## unset
599
+
600
+ Unset the topic in that obj, and clean up parent if empty, recursively.
601
+ Return the path to the removed node.
602
+
603
+ #### Parameters
604
+
605
+ * `obj` &#x20;
606
+ * `path` &#x20;
607
+
608
+ ## updateObject
609
+
610
+ given a modifier {"a/b/c": "xyz"} update the object `obj` such that
611
+ obj.a.b.c = "xyz"
612
+
613
+ #### Parameters
614
+
615
+ * `obj` &#x20;
616
+ * `modifier` &#x20;
617
+
618
+ ## useMqttSync
619
+
620
+ hook for using MqttSync in React
621
+
622
+ #### Parameters
623
+
624
+ * `$0` **[Object][1]**&#x20;
625
+
626
+ * `$0.jwt` &#x20;
627
+ * `$0.id` &#x20;
628
+ * `$0.mqttUrl` &#x20;
629
+
630
+ ## useTransitive
631
+
632
+ Hook for using Transitive in React. Connects to MQTT, establishes sync, and
633
+ exposes reactive `data` state variable.
634
+
635
+ #### Parameters
636
+
637
+ * `$0` **[Object][1]**&#x20;
638
+
639
+ * `$0.jwt` &#x20;
640
+ * `$0.id` &#x20;
641
+ * `$0.host` &#x20;
642
+ * `$0.ssl` &#x20;
643
+ * `$0.capability` &#x20;
644
+ * `$0.versionNS` &#x20;
645
+
646
+ ## versionCompare
647
+
648
+ Compare to version strings. Return -1 if a is lower than b,
649
+ 0 if they are equal, and 1 otherwise. If either is not a complete version,
650
+ e.g., 2.0, interpret it as a range and use its minimum version for the
651
+ comparison. Hence, 2.0 < 2.0.1.
652
+
653
+ #### Parameters
654
+
655
+ * `a` &#x20;
656
+ * `b` &#x20;
657
+
658
+ ## visit
659
+
660
+ Reusable visitor pattern: iteratively visits all nodes in the tree
661
+ described by `object`, where `childField` indicates the child-of predicate.
662
+
663
+ #### Parameters
664
+
665
+ * `object` &#x20;
666
+ * `childField` &#x20;
667
+ * `visitor` &#x20;
668
+
669
+ ## wait
670
+
671
+ Wait for delay ms, for use in async functions.
672
+
673
+ #### Parameters
674
+
675
+ * `delay` &#x20;
676
+
677
+ ## extractAttributes
678
+
679
+ Takes in a node attributes map and returns an object with camelCased
680
+ properties and values
681
+
682
+ #### Parameters
683
+
684
+ * `nodeMap` &#x20;
685
+
686
+ Returns **{}**&#x20;
687
+
688
+ ## getStyleElementsFromReactWebComponentStyleLoader
689
+
690
+ An optional library which is conditionally added
691
+
692
+ Returns **\[]**&#x20;
693
+
694
+ ## setConfig
695
+
696
+ method exposed to the wrapped component via prop that allows setting
697
+ the "config" state variable inside the wrapper (not the component
698
+ itself). This config is retrieved by the portal for inclusion in the
699
+ embedding instructions.
700
+
701
+ #### Parameters
702
+
703
+ * `config` &#x20;
704
+
705
+ ## setOnDisconnect
706
+
707
+ function used by `Component` to register a onDisconnect handler
708
+
709
+ #### Parameters
710
+
711
+ * `fn` &#x20;
712
+
713
+ ## webComponentAttributeChanged
714
+
715
+ Note this relies on the changes made in
716
+ github:amay0048/react-web-component#780950800e2962f45f0f029be618bb8b84610c89
717
+ that we used in our copy.
718
+ TODO: move this into our copy, i.e., do it internally to react-web-component
719
+ and update props.
720
+
721
+ #### Parameters
722
+
723
+ * `name` &#x20;
724
+ * `oldValue` &#x20;
725
+ * `newValue` &#x20;
726
+
727
+ [1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
728
+
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
734
+
735
+ [5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
736
+
737
+ [6]: https://github.com/chfritz/transitive/issues/85
738
+
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.5",
3
+ "version": "0.7.7",
4
4
  "description": "Web utils for the Transitive framework",
5
5
  "homepage": "https://transitiverobotics.com",
6
6
  "author": {
@@ -18,7 +18,8 @@
18
18
  "scripts": {
19
19
  "test": "webpack serve -c webpack-test.config.js",
20
20
  "build-test": "webpack -c webpack-test.config.js",
21
- "prepare": "webpack --no-watch --mode=production"
21
+ "prepare": "webpack --no-watch --mode=production",
22
+ "prepack": "cat ../docs.js | node --input-type=module"
22
23
  },
23
24
  "dependencies": {
24
25
  "@babel/runtime": "^7.16.7",
@@ -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() {