tgo-widget-miniprogram 1.0.0

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.
Files changed (55) hide show
  1. package/README.md +81 -0
  2. package/miniprogram_dist/adapters/request.js +38 -0
  3. package/miniprogram_dist/adapters/storage.js +42 -0
  4. package/miniprogram_dist/adapters/systemInfo.js +22 -0
  5. package/miniprogram_dist/chat/index.js +164 -0
  6. package/miniprogram_dist/chat/index.json +7 -0
  7. package/miniprogram_dist/chat/index.wxml +48 -0
  8. package/miniprogram_dist/chat/index.wxss +92 -0
  9. package/miniprogram_dist/components/json-render-element/index.js +374 -0
  10. package/miniprogram_dist/components/json-render-element/index.json +6 -0
  11. package/miniprogram_dist/components/json-render-element/index.wxml +218 -0
  12. package/miniprogram_dist/components/json-render-element/index.wxss +450 -0
  13. package/miniprogram_dist/components/json-render-message/index.js +89 -0
  14. package/miniprogram_dist/components/json-render-message/index.json +7 -0
  15. package/miniprogram_dist/components/json-render-message/index.wxml +25 -0
  16. package/miniprogram_dist/components/json-render-message/index.wxss +26 -0
  17. package/miniprogram_dist/components/json-render-surface/index.js +116 -0
  18. package/miniprogram_dist/components/json-render-surface/index.json +6 -0
  19. package/miniprogram_dist/components/json-render-surface/index.wxml +10 -0
  20. package/miniprogram_dist/components/json-render-surface/index.wxss +6 -0
  21. package/miniprogram_dist/components/markdown-text/index.js +23 -0
  22. package/miniprogram_dist/components/markdown-text/index.json +3 -0
  23. package/miniprogram_dist/components/markdown-text/index.wxml +1 -0
  24. package/miniprogram_dist/components/markdown-text/index.wxss +6 -0
  25. package/miniprogram_dist/components/message-bubble/index.js +12 -0
  26. package/miniprogram_dist/components/message-bubble/index.json +3 -0
  27. package/miniprogram_dist/components/message-bubble/index.wxml +3 -0
  28. package/miniprogram_dist/components/message-bubble/index.wxss +17 -0
  29. package/miniprogram_dist/components/message-input/index.js +76 -0
  30. package/miniprogram_dist/components/message-input/index.json +3 -0
  31. package/miniprogram_dist/components/message-input/index.wxml +28 -0
  32. package/miniprogram_dist/components/message-input/index.wxss +56 -0
  33. package/miniprogram_dist/components/message-list/index.js +113 -0
  34. package/miniprogram_dist/components/message-list/index.json +9 -0
  35. package/miniprogram_dist/components/message-list/index.wxml +108 -0
  36. package/miniprogram_dist/components/message-list/index.wxss +113 -0
  37. package/miniprogram_dist/components/system-message/index.js +8 -0
  38. package/miniprogram_dist/components/system-message/index.json +3 -0
  39. package/miniprogram_dist/components/system-message/index.wxml +3 -0
  40. package/miniprogram_dist/components/system-message/index.wxss +15 -0
  41. package/miniprogram_dist/core/chatStore.js +758 -0
  42. package/miniprogram_dist/core/i18n.js +66 -0
  43. package/miniprogram_dist/core/platformStore.js +86 -0
  44. package/miniprogram_dist/core/types.js +192 -0
  45. package/miniprogram_dist/services/chat.js +67 -0
  46. package/miniprogram_dist/services/messageHistory.js +46 -0
  47. package/miniprogram_dist/services/platform.js +27 -0
  48. package/miniprogram_dist/services/upload.js +74 -0
  49. package/miniprogram_dist/services/visitor.js +67 -0
  50. package/miniprogram_dist/services/wukongim.js +183 -0
  51. package/miniprogram_dist/utils/jsonRender.js +158 -0
  52. package/miniprogram_dist/utils/markdown.js +31 -0
  53. package/miniprogram_dist/utils/time.js +85 -0
  54. package/miniprogram_dist/utils/uid.js +11 -0
  55. package/package.json +37 -0
@@ -0,0 +1,450 @@
1
+ /* ====== Text ====== */
2
+ .jr-text {
3
+ font-size: 28rpx;
4
+ color: #1a1a1a;
5
+ line-height: 1.6;
6
+ }
7
+
8
+ .jr-text-title {
9
+ font-size: 32rpx;
10
+ font-weight: 600;
11
+ color: #1a1a1a;
12
+ }
13
+
14
+ .jr-text-caption {
15
+ font-size: 24rpx;
16
+ color: #999;
17
+ }
18
+
19
+ .jr-section-title {
20
+ padding-top: 8rpx;
21
+ font-size: 28rpx;
22
+ font-weight: 600;
23
+ color: #1a1a1a;
24
+ }
25
+
26
+ .jr-text-kv {
27
+ display: flex;
28
+ align-items: baseline;
29
+ justify-content: space-between;
30
+ gap: 12rpx;
31
+ }
32
+
33
+ .jr-text-kv-label {
34
+ font-size: 28rpx;
35
+ color: #666;
36
+ }
37
+
38
+ .jr-text-kv-value {
39
+ font-size: 28rpx;
40
+ font-weight: 500;
41
+ color: #1a1a1a;
42
+ text-align: right;
43
+ }
44
+
45
+ /* ====== Divider ====== */
46
+ .jr-divider {
47
+ height: 1rpx;
48
+ background-color: #e5e5e5;
49
+ margin: 8rpx 0;
50
+ }
51
+
52
+ /* ====== Badge ====== */
53
+ .jr-badge {
54
+ display: inline-flex;
55
+ align-items: center;
56
+ border-radius: 24rpx;
57
+ padding: 4rpx 16rpx;
58
+ font-size: 24rpx;
59
+ font-weight: 500;
60
+ }
61
+
62
+ .jr-badge-info {
63
+ background-color: #dbeafe;
64
+ color: #1d4ed8;
65
+ }
66
+
67
+ .jr-badge-success {
68
+ background-color: #d1fae5;
69
+ color: #047857;
70
+ }
71
+
72
+ .jr-badge-warning {
73
+ background-color: #fef3c7;
74
+ color: #b45309;
75
+ }
76
+
77
+ .jr-badge-danger {
78
+ background-color: #fee2e2;
79
+ color: #b91c1c;
80
+ }
81
+
82
+ /* ====== KV ====== */
83
+ .jr-kv {
84
+ display: flex;
85
+ align-items: baseline;
86
+ justify-content: space-between;
87
+ gap: 12rpx;
88
+ }
89
+
90
+ .jr-kv-highlight {
91
+ padding-top: 8rpx;
92
+ border-top: 1rpx solid #e5e5e5;
93
+ }
94
+
95
+ .jr-kv-label {
96
+ font-size: 28rpx;
97
+ color: #666;
98
+ }
99
+
100
+ .jr-kv-value {
101
+ font-size: 28rpx;
102
+ font-weight: 500;
103
+ color: #1a1a1a;
104
+ text-align: right;
105
+ }
106
+
107
+ .jr-kv-value-highlight {
108
+ font-size: 32rpx;
109
+ font-weight: 600;
110
+ color: #dc2626;
111
+ }
112
+
113
+ /* ====== PriceRow ====== */
114
+ .jr-price-row {
115
+ display: flex;
116
+ align-items: baseline;
117
+ justify-content: space-between;
118
+ gap: 12rpx;
119
+ }
120
+
121
+ .jr-price-emphasis {
122
+ padding-top: 8rpx;
123
+ border-top: 1rpx solid #e5e5e5;
124
+ margin-top: 4rpx;
125
+ }
126
+
127
+ .jr-price-label {
128
+ font-size: 28rpx;
129
+ color: #666;
130
+ }
131
+
132
+ .jr-price-label-emphasis {
133
+ font-weight: 500;
134
+ color: #1a1a1a;
135
+ }
136
+
137
+ .jr-price-value {
138
+ font-size: 28rpx;
139
+ font-weight: 500;
140
+ color: #1a1a1a;
141
+ text-align: right;
142
+ }
143
+
144
+ .jr-price-value-emphasis {
145
+ font-size: 36rpx;
146
+ font-weight: 600;
147
+ color: #dc2626;
148
+ }
149
+
150
+ .jr-price-discount {
151
+ color: #059669;
152
+ font-weight: 500;
153
+ }
154
+
155
+ /* ====== OrderItem ====== */
156
+ .jr-order-item {
157
+ display: flex;
158
+ align-items: flex-start;
159
+ justify-content: space-between;
160
+ gap: 12rpx;
161
+ border-radius: 16rpx;
162
+ border: 1rpx solid #f0f0f0;
163
+ background-color: rgba(255, 255, 255, 0.7);
164
+ padding: 16rpx;
165
+ }
166
+
167
+ .jr-order-info {
168
+ min-width: 0;
169
+ flex: 1;
170
+ }
171
+
172
+ .jr-order-name {
173
+ font-size: 28rpx;
174
+ font-weight: 500;
175
+ color: #1a1a1a;
176
+ overflow: hidden;
177
+ text-overflow: ellipsis;
178
+ white-space: nowrap;
179
+ display: block;
180
+ }
181
+
182
+ .jr-order-sku {
183
+ font-size: 24rpx;
184
+ color: #999;
185
+ margin-top: 4rpx;
186
+ display: block;
187
+ }
188
+
189
+ .jr-order-right {
190
+ flex-shrink: 0;
191
+ text-align: right;
192
+ }
193
+
194
+ .jr-order-qty {
195
+ font-size: 24rpx;
196
+ color: #999;
197
+ display: block;
198
+ }
199
+
200
+ .jr-order-price {
201
+ font-size: 28rpx;
202
+ font-weight: 600;
203
+ color: #1a1a1a;
204
+ display: block;
205
+ }
206
+
207
+ /* ====== Image ====== */
208
+ .jr-image {
209
+ max-width: 100%;
210
+ border-radius: 12rpx;
211
+ }
212
+
213
+ /* ====== Button ====== */
214
+ .jr-button {
215
+ margin-top: 8rpx;
216
+ padding: 16rpx 32rpx;
217
+ border-radius: 16rpx;
218
+ font-size: 28rpx;
219
+ font-weight: 500;
220
+ text-align: center;
221
+ transition: opacity 0.2s;
222
+ }
223
+
224
+ .jr-button:active {
225
+ opacity: 0.7;
226
+ }
227
+
228
+ .jr-button-primary {
229
+ background-color: #2563eb;
230
+ color: #ffffff;
231
+ }
232
+
233
+ .jr-button-danger {
234
+ background-color: #ef4444;
235
+ color: #ffffff;
236
+ }
237
+
238
+ .jr-button-link {
239
+ background: transparent;
240
+ color: #2563eb;
241
+ text-decoration: underline;
242
+ padding: 8rpx 0;
243
+ }
244
+
245
+ .jr-button-default {
246
+ background-color: #ffffff;
247
+ color: #374151;
248
+ border: 1rpx solid #e5e5e5;
249
+ }
250
+
251
+ .jr-button-disabled {
252
+ opacity: 0.5;
253
+ }
254
+
255
+ /* ====== ButtonGroup ====== */
256
+ .jr-button-group {
257
+ display: flex;
258
+ flex-wrap: wrap;
259
+ align-items: center;
260
+ gap: 12rpx;
261
+ margin-top: 12rpx;
262
+ }
263
+
264
+ /* ====== Card ====== */
265
+ .jr-card {
266
+ border-radius: 24rpx;
267
+ border: 1rpx solid #e5e5e5;
268
+ padding: 24rpx;
269
+ background-color: rgba(255, 255, 255, 0.9);
270
+ display: flex;
271
+ flex-direction: column;
272
+ gap: 8rpx;
273
+ }
274
+
275
+ .jr-card-order {
276
+ border-color: #dbeafe;
277
+ background: linear-gradient(to bottom, #ffffff, rgba(219, 234, 254, 0.4));
278
+ }
279
+
280
+ /* ====== Section ====== */
281
+ .jr-section {
282
+ border-radius: 16rpx;
283
+ border: 1rpx solid #f0f0f0;
284
+ background-color: rgba(249, 250, 251, 0.7);
285
+ padding: 16rpx;
286
+ }
287
+
288
+ .jr-section-header {
289
+ margin-bottom: 8rpx;
290
+ }
291
+
292
+ .jr-section-title-text {
293
+ font-size: 28rpx;
294
+ font-weight: 600;
295
+ color: #1a1a1a;
296
+ }
297
+
298
+ .jr-section-body {
299
+ display: flex;
300
+ flex-direction: column;
301
+ gap: 12rpx;
302
+ }
303
+
304
+ .jr-section-body-with-title {
305
+ margin-top: 12rpx;
306
+ }
307
+
308
+ /* ====== Row ====== */
309
+ .jr-row {
310
+ display: flex;
311
+ flex-direction: row;
312
+ }
313
+
314
+ .jr-row-justify-start { justify-content: flex-start; }
315
+ .jr-row-justify-center { justify-content: center; }
316
+ .jr-row-justify-end { justify-content: flex-end; }
317
+ .jr-row-justify-between { justify-content: space-between; }
318
+
319
+ .jr-row-align-start { align-items: flex-start; }
320
+ .jr-row-align-center { align-items: center; }
321
+ .jr-row-align-end { align-items: flex-end; }
322
+
323
+ .jr-row-gap-sm { gap: 6rpx; }
324
+ .jr-row-gap-md { gap: 16rpx; }
325
+ .jr-row-gap-lg { gap: 24rpx; }
326
+
327
+ .jr-row-wrap { flex-wrap: wrap; }
328
+
329
+ /* ====== Column ====== */
330
+ .jr-column {
331
+ display: flex;
332
+ flex-direction: column;
333
+ }
334
+
335
+ .jr-col-gap-sm { gap: 6rpx; }
336
+ .jr-col-gap-md { gap: 16rpx; }
337
+ .jr-col-gap-lg { gap: 24rpx; }
338
+
339
+ /* ====== Input ====== */
340
+ .jr-input-wrap {
341
+ display: flex;
342
+ flex-direction: column;
343
+ gap: 8rpx;
344
+ }
345
+
346
+ .jr-input-label {
347
+ font-size: 28rpx;
348
+ color: #374151;
349
+ }
350
+
351
+ .jr-input {
352
+ border: 1rpx solid #d1d5db;
353
+ border-radius: 12rpx;
354
+ padding: 16rpx 20rpx;
355
+ font-size: 28rpx;
356
+ background-color: #ffffff;
357
+ }
358
+
359
+ /* ====== Checkbox ====== */
360
+ .jr-checkbox {
361
+ display: flex;
362
+ align-items: center;
363
+ gap: 12rpx;
364
+ }
365
+
366
+ .jr-checkbox-box {
367
+ width: 36rpx;
368
+ height: 36rpx;
369
+ border: 2rpx solid #d1d5db;
370
+ border-radius: 6rpx;
371
+ display: flex;
372
+ align-items: center;
373
+ justify-content: center;
374
+ flex-shrink: 0;
375
+ }
376
+
377
+ .jr-checkbox-checked {
378
+ background-color: #2563eb;
379
+ border-color: #2563eb;
380
+ }
381
+
382
+ .jr-checkbox-mark {
383
+ font-size: 24rpx;
384
+ color: #ffffff;
385
+ }
386
+
387
+ .jr-checkbox-label {
388
+ font-size: 28rpx;
389
+ color: #374151;
390
+ }
391
+
392
+ /* ====== MultipleChoice ====== */
393
+ .jr-mc-wrap {
394
+ display: flex;
395
+ flex-direction: column;
396
+ gap: 8rpx;
397
+ }
398
+
399
+ .jr-mc-label {
400
+ font-size: 28rpx;
401
+ color: #374151;
402
+ }
403
+
404
+ .jr-mc-picker {
405
+ display: flex;
406
+ align-items: center;
407
+ justify-content: space-between;
408
+ border: 1rpx solid #d1d5db;
409
+ border-radius: 12rpx;
410
+ padding: 16rpx 20rpx;
411
+ font-size: 28rpx;
412
+ background-color: #ffffff;
413
+ }
414
+
415
+ .jr-mc-arrow {
416
+ font-size: 20rpx;
417
+ color: #999;
418
+ }
419
+
420
+ /* ====== DateTimeInput ====== */
421
+ .jr-dt-wrap {
422
+ display: flex;
423
+ flex-direction: column;
424
+ gap: 8rpx;
425
+ }
426
+
427
+ .jr-dt-label {
428
+ font-size: 28rpx;
429
+ color: #374151;
430
+ }
431
+
432
+ .jr-dt-picker {
433
+ border: 1rpx solid #d1d5db;
434
+ border-radius: 12rpx;
435
+ padding: 16rpx 20rpx;
436
+ font-size: 28rpx;
437
+ background-color: #ffffff;
438
+ }
439
+
440
+ /* ====== Unknown / fallback ====== */
441
+ .jr-unknown {
442
+ display: flex;
443
+ flex-direction: column;
444
+ gap: 8rpx;
445
+ }
446
+
447
+ .jr-too-deep {
448
+ font-size: 24rpx;
449
+ color: #999;
450
+ }
@@ -0,0 +1,89 @@
1
+ /**
2
+ * json-render-message: groups uiParts into text/spec groups and renders them.
3
+ * Ported from tgo-widget-app JSONRenderMessage.tsx
4
+ */
5
+ var jsonRenderUtils = require('../../utils/jsonRender')
6
+
7
+ Component({
8
+ options: {
9
+ virtualHost: true
10
+ },
11
+
12
+ properties: {
13
+ uiParts: {
14
+ type: Array,
15
+ value: null
16
+ },
17
+ payloadContent: {
18
+ type: String,
19
+ value: ''
20
+ },
21
+ showCursor: {
22
+ type: Boolean,
23
+ value: false
24
+ },
25
+ themeColor: {
26
+ type: String,
27
+ value: '#2f80ed'
28
+ }
29
+ },
30
+
31
+ data: {
32
+ groups: [],
33
+ hasGroups: false,
34
+ fallbackText: '',
35
+ lastIndex: -1
36
+ },
37
+
38
+ observers: {
39
+ 'uiParts, payloadContent': function () {
40
+ this._rebuild()
41
+ }
42
+ },
43
+
44
+ methods: {
45
+ _rebuild: function () {
46
+ var parts = this.properties.uiParts
47
+ if (!Array.isArray(parts) || parts.length === 0) {
48
+ // Fallback: use payloadContent, strip spec fences
49
+ var raw = this.properties.payloadContent
50
+ var fallback = raw
51
+ if (raw && raw.indexOf('```spec') >= 0) {
52
+ fallback = raw.replace(/```spec[\s\S]*?```/g, '').replace(/```spec[\s\S]*/g, '').trim()
53
+ }
54
+ this.setData({
55
+ groups: [],
56
+ hasGroups: false,
57
+ fallbackText: fallback || '',
58
+ lastIndex: -1
59
+ })
60
+ return
61
+ }
62
+
63
+ var partGroups = jsonRenderUtils.groupParts(parts)
64
+ var groups = []
65
+ for (var i = 0; i < partGroups.length; i++) {
66
+ var g = partGroups[i]
67
+ if (g.type === 'text') {
68
+ groups.push({ type: 'text', text: g.text, spec: null })
69
+ } else if (g.type === 'spec') {
70
+ var spec = jsonRenderUtils.buildSpecFromParts(g.parts)
71
+ if (spec) {
72
+ groups.push({ type: 'spec', text: '', spec: spec })
73
+ }
74
+ }
75
+ }
76
+
77
+ this.setData({
78
+ groups: groups,
79
+ hasGroups: groups.length > 0,
80
+ fallbackText: '',
81
+ lastIndex: groups.length - 1
82
+ })
83
+ },
84
+
85
+ onSendMessage: function (e) {
86
+ this.triggerEvent('sendmessage', e.detail)
87
+ }
88
+ }
89
+ })
@@ -0,0 +1,7 @@
1
+ {
2
+ "component": true,
3
+ "usingComponents": {
4
+ "json-render-surface": "../json-render-surface/index",
5
+ "markdown-text": "../markdown-text/index"
6
+ }
7
+ }
@@ -0,0 +1,25 @@
1
+ <block wx:if="{{hasGroups}}">
2
+ <block wx:for="{{groups}}" wx:key="index">
3
+ <!-- Text group -->
4
+ <view wx:if="{{item.type === 'text' && item.text}}" class="jr-text-group">
5
+ <markdown-text content="{{item.text}}" />
6
+ <view wx:if="{{showCursor && index === lastIndex}}" class="cursor"></view>
7
+ </view>
8
+ <!-- Spec group -->
9
+ <json-render-surface
10
+ wx:elif="{{item.type === 'spec' && item.spec}}"
11
+ spec="{{item.spec}}"
12
+ loading="{{showCursor}}"
13
+ themeColor="{{themeColor}}"
14
+ bind:sendmessage="onSendMessage"
15
+ />
16
+ </block>
17
+ </block>
18
+
19
+ <!-- Fallback text when no groups -->
20
+ <block wx:elif="{{fallbackText}}">
21
+ <view class="jr-fallback">
22
+ <markdown-text content="{{fallbackText}}" />
23
+ <view wx:if="{{showCursor}}" class="cursor"></view>
24
+ </view>
25
+ </block>
@@ -0,0 +1,26 @@
1
+ .jr-text-group {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: 4rpx;
5
+ }
6
+
7
+ .jr-fallback {
8
+ display: flex;
9
+ flex-direction: column;
10
+ gap: 4rpx;
11
+ }
12
+
13
+ .cursor {
14
+ display: inline-block;
15
+ width: 4rpx;
16
+ height: 28rpx;
17
+ background: #333;
18
+ margin-left: 4rpx;
19
+ animation: blink 1s step-end infinite;
20
+ vertical-align: text-bottom;
21
+ }
22
+
23
+ @keyframes blink {
24
+ 0%, 100% { opacity: 1; }
25
+ 50% { opacity: 0; }
26
+ }
@@ -0,0 +1,116 @@
1
+ /**
2
+ * json-render-surface: manages state store and renders root element.
3
+ * Handles action dispatch and state change events.
4
+ * Ported from tgo-widget-app JSONRenderSurface.tsx
5
+ */
6
+ var jsonRenderUtils = require('../../utils/jsonRender')
7
+
8
+ Component({
9
+ options: {
10
+ virtualHost: true
11
+ },
12
+
13
+ properties: {
14
+ spec: {
15
+ type: Object,
16
+ value: null
17
+ },
18
+ loading: {
19
+ type: Boolean,
20
+ value: false
21
+ },
22
+ themeColor: {
23
+ type: String,
24
+ value: '#2f80ed'
25
+ }
26
+ },
27
+
28
+ data: {
29
+ stateSnapshot: {},
30
+ hasRoot: false
31
+ },
32
+
33
+ observers: {
34
+ 'spec': function (spec) {
35
+ this._initStore(spec)
36
+ }
37
+ },
38
+
39
+ lifetimes: {
40
+ detached: function () {
41
+ if (this._unsub) {
42
+ this._unsub()
43
+ this._unsub = null
44
+ }
45
+ }
46
+ },
47
+
48
+ methods: {
49
+ _initStore: function (spec) {
50
+ var self = this
51
+ // Clean up previous subscription
52
+ if (this._unsub) {
53
+ this._unsub()
54
+ this._unsub = null
55
+ }
56
+
57
+ if (!spec || !spec.root) {
58
+ this.setData({ hasRoot: false, stateSnapshot: {} })
59
+ return
60
+ }
61
+
62
+ var store = jsonRenderUtils.createStateStore(spec.state || {})
63
+ this._store = store
64
+ this._actionNames = jsonRenderUtils.collectActionNames(spec)
65
+
66
+ this.setData({
67
+ hasRoot: true,
68
+ stateSnapshot: store.getSnapshot()
69
+ })
70
+
71
+ this._unsub = store.subscribe(function () {
72
+ self.setData({ stateSnapshot: store.getSnapshot() })
73
+ })
74
+ },
75
+
76
+ onAction: function (e) {
77
+ var detail = e.detail || {}
78
+ var actionName = detail.actionName
79
+ var params = detail.params || {}
80
+
81
+ if (!actionName) return
82
+
83
+ // Built-in state actions
84
+ if (actionName === 'setState' && this._store) {
85
+ if (params.statePath && typeof params.statePath === 'string') {
86
+ this._store.set(params.statePath, params.value)
87
+ }
88
+ return
89
+ }
90
+ if (actionName === 'pushState' && this._store) {
91
+ return
92
+ }
93
+ if (actionName === 'removeState' && this._store) {
94
+ return
95
+ }
96
+
97
+ // Contains statePath → treat as state update
98
+ if (params.statePath && typeof params.statePath === 'string' && this._store) {
99
+ this._store.set(params.statePath, params.value)
100
+ return
101
+ }
102
+
103
+ // External action → format as text message
104
+ var snapshot = this._store ? this._store.getSnapshot() : {}
105
+ var text = jsonRenderUtils.formatActionMessage(actionName, params, snapshot)
106
+ this.triggerEvent('sendmessage', { text: text })
107
+ },
108
+
109
+ onStateChange: function (e) {
110
+ var detail = e.detail || {}
111
+ if (detail.path && this._store) {
112
+ this._store.set(detail.path, detail.value)
113
+ }
114
+ }
115
+ }
116
+ })
@@ -0,0 +1,6 @@
1
+ {
2
+ "component": true,
3
+ "usingComponents": {
4
+ "json-render-element": "../json-render-element/index"
5
+ }
6
+ }