@almadar/std 2.1.1 → 2.4.1

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 (86) hide show
  1. package/dist/behaviors/async.d.ts +12 -7
  2. package/dist/behaviors/async.js +1085 -312
  3. package/dist/behaviors/async.js.map +1 -1
  4. package/dist/behaviors/data-management.d.ts +27 -13
  5. package/dist/behaviors/data-management.js +600 -244
  6. package/dist/behaviors/data-management.js.map +1 -1
  7. package/dist/behaviors/domain/commerce.d.ts +51 -0
  8. package/dist/behaviors/domain/commerce.js +1093 -0
  9. package/dist/behaviors/domain/commerce.js.map +1 -0
  10. package/dist/behaviors/domain/content.d.ts +51 -0
  11. package/dist/behaviors/domain/content.js +1294 -0
  12. package/dist/behaviors/domain/content.js.map +1 -0
  13. package/dist/behaviors/domain/dashboard.d.ts +45 -0
  14. package/dist/behaviors/domain/dashboard.js +783 -0
  15. package/dist/behaviors/domain/dashboard.js.map +1 -0
  16. package/dist/behaviors/domain/education.d.ts +41 -0
  17. package/dist/behaviors/domain/education.js +738 -0
  18. package/dist/behaviors/domain/education.js.map +1 -0
  19. package/dist/behaviors/domain/finance.d.ts +49 -0
  20. package/dist/behaviors/domain/finance.js +660 -0
  21. package/dist/behaviors/domain/finance.js.map +1 -0
  22. package/dist/behaviors/domain/game-2d-platformer.d.ts +50 -0
  23. package/dist/behaviors/domain/game-2d-platformer.js +810 -0
  24. package/dist/behaviors/domain/game-2d-platformer.js.map +1 -0
  25. package/dist/behaviors/domain/game-2d-puzzle.d.ts +42 -0
  26. package/dist/behaviors/domain/game-2d-puzzle.js +622 -0
  27. package/dist/behaviors/domain/game-2d-puzzle.js.map +1 -0
  28. package/dist/behaviors/domain/game-2d-rpg.d.ts +48 -0
  29. package/dist/behaviors/domain/game-2d-rpg.js +860 -0
  30. package/dist/behaviors/domain/game-2d-rpg.js.map +1 -0
  31. package/dist/behaviors/domain/game-2d-strategy.d.ts +48 -0
  32. package/dist/behaviors/domain/game-2d-strategy.js +692 -0
  33. package/dist/behaviors/domain/game-2d-strategy.js.map +1 -0
  34. package/dist/behaviors/domain/geospatial.d.ts +35 -0
  35. package/dist/behaviors/domain/geospatial.js +634 -0
  36. package/dist/behaviors/domain/geospatial.js.map +1 -0
  37. package/dist/behaviors/domain/healthcare.d.ts +36 -0
  38. package/dist/behaviors/domain/healthcare.js +1068 -0
  39. package/dist/behaviors/domain/healthcare.js.map +1 -0
  40. package/dist/behaviors/domain/iot.d.ts +45 -0
  41. package/dist/behaviors/domain/iot.js +589 -0
  42. package/dist/behaviors/domain/iot.js.map +1 -0
  43. package/dist/behaviors/domain/media.d.ts +41 -0
  44. package/dist/behaviors/domain/media.js +771 -0
  45. package/dist/behaviors/domain/media.js.map +1 -0
  46. package/dist/behaviors/domain/scheduling.d.ts +41 -0
  47. package/dist/behaviors/domain/scheduling.js +930 -0
  48. package/dist/behaviors/domain/scheduling.js.map +1 -0
  49. package/dist/behaviors/domain/simulation.d.ts +36 -0
  50. package/dist/behaviors/domain/simulation.js +706 -0
  51. package/dist/behaviors/domain/simulation.js.map +1 -0
  52. package/dist/behaviors/domain/social.d.ts +41 -0
  53. package/dist/behaviors/domain/social.js +840 -0
  54. package/dist/behaviors/domain/social.js.map +1 -0
  55. package/dist/behaviors/domain/workflow.d.ts +41 -0
  56. package/dist/behaviors/domain/workflow.js +879 -0
  57. package/dist/behaviors/domain/workflow.js.map +1 -0
  58. package/dist/behaviors/feedback.d.ts +10 -5
  59. package/dist/behaviors/feedback.js +279 -194
  60. package/dist/behaviors/feedback.js.map +1 -1
  61. package/dist/behaviors/game-core.d.ts +15 -8
  62. package/dist/behaviors/game-core.js +412 -80
  63. package/dist/behaviors/game-core.js.map +1 -1
  64. package/dist/behaviors/game-entity.d.ts +17 -10
  65. package/dist/behaviors/game-entity.js +544 -237
  66. package/dist/behaviors/game-entity.js.map +1 -1
  67. package/dist/behaviors/game-ui.d.ts +16 -8
  68. package/dist/behaviors/game-ui.js +451 -316
  69. package/dist/behaviors/game-ui.js.map +1 -1
  70. package/dist/behaviors/index.d.ts +18 -1
  71. package/dist/behaviors/index.js +18905 -2140
  72. package/dist/behaviors/index.js.map +1 -1
  73. package/dist/behaviors/infrastructure.d.ts +9 -8
  74. package/dist/behaviors/infrastructure.js +597 -169
  75. package/dist/behaviors/infrastructure.js.map +1 -1
  76. package/dist/behaviors/registry.d.ts +11 -11
  77. package/dist/behaviors/registry.js +18904 -2139
  78. package/dist/behaviors/registry.js.map +1 -1
  79. package/dist/behaviors/types.d.ts +19 -2
  80. package/dist/behaviors/types.js.map +1 -1
  81. package/dist/behaviors/ui-interaction.d.ts +20 -14
  82. package/dist/behaviors/ui-interaction.js +928 -518
  83. package/dist/behaviors/ui-interaction.js.map +1 -1
  84. package/dist/index.js +18906 -2141
  85. package/dist/index.js.map +1 -1
  86. package/package.json +1 -1
@@ -1,579 +1,1352 @@
1
1
  // behaviors/async.ts
2
+ var ASYNC_THEME = {
3
+ name: "async-blue",
4
+ tokens: {
5
+ colors: {
6
+ primary: "#2563eb",
7
+ "primary-hover": "#1d4ed8",
8
+ "primary-foreground": "#ffffff",
9
+ accent: "#3b82f6",
10
+ "accent-foreground": "#ffffff",
11
+ success: "#22c55e",
12
+ warning: "#f59e0b",
13
+ error: "#ef4444"
14
+ }
15
+ }
16
+ };
17
+ var loadingDashboardEffects = [
18
+ ["render-ui", "main", { type: "stack", direction: "vertical", gap: "lg", children: [
19
+ // Header: icon + title
20
+ { type: "stack", direction: "horizontal", justify: "space-between", children: [
21
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
22
+ { type: "icon", name: "loader", size: "lg" },
23
+ { type: "typography", variant: "h2", content: "Loading Dashboard" }
24
+ ] },
25
+ { type: "button", label: "Start", icon: "play", variant: "primary", action: "START" }
26
+ ] },
27
+ { type: "divider" },
28
+ // Stats row
29
+ { type: "stack", direction: "horizontal", gap: "md", children: [
30
+ { type: "stats", label: "Records", icon: "database", entity: "LoadingRecord" },
31
+ { type: "stats", label: "Status", icon: "activity", entity: "LoadingRecord" }
32
+ ] },
33
+ { type: "divider" },
34
+ // Data grid
35
+ {
36
+ type: "data-grid",
37
+ entity: "LoadingRecord",
38
+ cols: 2,
39
+ gap: "md",
40
+ fields: [
41
+ { name: "label", label: "Label", icon: "tag", variant: "h4" },
42
+ { name: "status", label: "Status", icon: "circle", variant: "badge" },
43
+ { name: "message", label: "Message", icon: "message-square", variant: "body" }
44
+ ],
45
+ actions: [
46
+ { label: "View", event: "VIEW", icon: "eye", variant: "ghost" }
47
+ ]
48
+ }
49
+ ] }]
50
+ ];
51
+ var loadingInProgressEffects = [
52
+ ["render-ui", "main", { type: "stack", direction: "vertical", gap: "lg", children: [
53
+ // Header: spinner + title
54
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
55
+ { type: "icon", name: "loader", size: "lg" },
56
+ { type: "typography", variant: "h2", content: "Loading..." }
57
+ ] },
58
+ { type: "divider" },
59
+ // Loading indicator with icon and descriptive text
60
+ { type: "stack", direction: "vertical", gap: "sm", align: "center", children: [
61
+ { type: "icon", name: "loader", size: "xl" },
62
+ { type: "typography", variant: "body", content: "Please wait while your data is being loaded." }
63
+ ] },
64
+ { type: "progress-bar", value: 0, label: "Processing", icon: "clock" },
65
+ { type: "divider" },
66
+ // Data grid
67
+ {
68
+ type: "data-grid",
69
+ entity: "LoadingRecord",
70
+ cols: 2,
71
+ gap: "md",
72
+ fields: [
73
+ { name: "label", label: "Label", icon: "tag", variant: "h4" },
74
+ { name: "status", label: "Status", icon: "circle", variant: "badge" },
75
+ { name: "message", label: "Message", icon: "message-square", variant: "body" }
76
+ ],
77
+ actions: [
78
+ { label: "View", event: "VIEW", icon: "eye", variant: "ghost" }
79
+ ]
80
+ }
81
+ ] }]
82
+ ];
83
+ var loadingSuccessEffects = [
84
+ ["render-ui", "main", { type: "stack", direction: "vertical", gap: "lg", children: [
85
+ // Header: success icon + title + reset
86
+ { type: "stack", direction: "horizontal", justify: "space-between", children: [
87
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
88
+ { type: "icon", name: "check-circle", size: "lg" },
89
+ { type: "typography", variant: "h2", content: "Loaded" }
90
+ ] },
91
+ { type: "button", label: "Reset", icon: "refresh-cw", variant: "secondary", action: "RESET" }
92
+ ] },
93
+ { type: "divider" },
94
+ { type: "badge", label: "Complete", variant: "success", icon: "check" },
95
+ { type: "divider" },
96
+ // Data grid
97
+ {
98
+ type: "data-grid",
99
+ entity: "LoadingRecord",
100
+ cols: 2,
101
+ gap: "md",
102
+ fields: [
103
+ { name: "label", label: "Label", icon: "tag", variant: "h4" },
104
+ { name: "status", label: "Status", icon: "circle", variant: "badge" },
105
+ { name: "message", label: "Message", icon: "message-square", variant: "body" }
106
+ ],
107
+ actions: [
108
+ { label: "View", event: "VIEW", icon: "eye", variant: "ghost" }
109
+ ]
110
+ }
111
+ ] }]
112
+ ];
113
+ var loadingErrorEffects = [
114
+ ["render-ui", "main", { type: "stack", direction: "vertical", gap: "lg", children: [
115
+ // Header: error icon + title + reset
116
+ { type: "stack", direction: "horizontal", justify: "space-between", children: [
117
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
118
+ { type: "icon", name: "alert-circle", size: "lg" },
119
+ { type: "typography", variant: "h2", content: "Error" }
120
+ ] },
121
+ { type: "button", label: "Reset", icon: "refresh-cw", variant: "secondary", action: "RESET" }
122
+ ] },
123
+ { type: "divider" },
124
+ { type: "badge", label: "Failed", variant: "error", icon: "x-circle" },
125
+ { type: "divider" },
126
+ // Data grid
127
+ {
128
+ type: "data-grid",
129
+ entity: "LoadingRecord",
130
+ cols: 2,
131
+ gap: "md",
132
+ fields: [
133
+ { name: "label", label: "Label", icon: "tag", variant: "h4" },
134
+ { name: "status", label: "Status", icon: "circle", variant: "badge" },
135
+ { name: "message", label: "Message", icon: "message-square", variant: "body" }
136
+ ],
137
+ actions: [
138
+ { label: "View", event: "VIEW", icon: "eye", variant: "ghost" }
139
+ ]
140
+ }
141
+ ] }]
142
+ ];
143
+ var loadingViewEffects = [
144
+ ["render-ui", "main", { type: "stack", direction: "vertical", gap: "lg", children: [
145
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
146
+ { type: "icon", name: "loader", size: "lg" },
147
+ { type: "typography", variant: "h2", content: "Loading Dashboard" }
148
+ ] },
149
+ { type: "divider" },
150
+ {
151
+ type: "data-grid",
152
+ entity: "LoadingRecord",
153
+ cols: 2,
154
+ gap: "md",
155
+ fields: [
156
+ { name: "label", label: "Label", icon: "tag", variant: "h4" },
157
+ { name: "status", label: "Status", icon: "circle", variant: "badge" },
158
+ { name: "message", label: "Message", icon: "message-square", variant: "body" }
159
+ ],
160
+ actions: [
161
+ { label: "View", event: "VIEW", icon: "eye", variant: "ghost" }
162
+ ]
163
+ }
164
+ ] }]
165
+ ];
2
166
  var LOADING_BEHAVIOR = {
3
167
  name: "std-loading",
4
168
  version: "1.0.0",
5
169
  description: "Loading state management with success/error handling",
170
+ theme: ASYNC_THEME,
6
171
  orbitals: [
7
172
  {
8
173
  name: "LoadingOrbital",
9
174
  entity: {
10
- name: "LoadingState",
11
- persistence: "runtime",
175
+ name: "LoadingRecord",
176
+ persistence: "persistent",
177
+ collection: "loading_records",
12
178
  fields: [
13
179
  { name: "id", type: "string", required: true },
14
- { name: "isLoading", type: "boolean", default: false },
15
- { name: "error", type: "object", default: null },
16
- { name: "data", type: "object", default: null },
17
- { name: "startTime", type: "number", default: null }
180
+ { name: "label", type: "string", default: "" },
181
+ { name: "status", type: "string", default: "idle" },
182
+ { name: "message", type: "string", default: "" }
18
183
  ]
19
184
  },
20
185
  traits: [
21
186
  {
22
- name: "Loading",
23
- linkedEntity: "LoadingState",
24
- category: "lifecycle",
187
+ name: "LoadingManagement",
188
+ linkedEntity: "LoadingRecord",
189
+ category: "interaction",
25
190
  stateMachine: {
26
191
  states: [
27
- { name: "Idle", isInitial: true },
28
- { name: "Loading" },
29
- { name: "Success" },
30
- { name: "Error" }
192
+ { name: "idle", isInitial: true },
193
+ { name: "loading" },
194
+ { name: "loaded" },
195
+ { name: "error" }
31
196
  ],
32
197
  events: [
33
- { key: "START", name: "Start" },
34
- { key: "SUCCESS", name: "Success" },
35
- { key: "ERROR", name: "Error" },
36
- { key: "RETRY", name: "Retry" },
37
- { key: "RESET", name: "Reset" }
198
+ { key: "INIT", name: "Initialize" },
199
+ { key: "START", name: "Start Loading" },
200
+ { key: "COMPLETE", name: "Complete" },
201
+ { key: "FAIL", name: "Fail", payloadSchema: [{ name: "message", type: "string", required: true }] },
202
+ { key: "RESET", name: "Reset" },
203
+ { key: "VIEW", name: "View", payloadSchema: [{ name: "id", type: "string", required: true }] }
38
204
  ],
39
205
  transitions: [
40
206
  {
41
- from: "Idle",
42
- to: "Loading",
43
- event: "START",
207
+ from: "idle",
208
+ to: "idle",
209
+ event: "INIT",
44
210
  effects: [
45
- ["set", "@entity.isLoading", true],
46
- ["set", "@entity.error", null],
47
- ["set", "@entity.startTime", ["time/now"]],
48
- ["render-ui", "content", {
49
- type: "loading-state"
50
- }]
211
+ ["fetch", "LoadingRecord"],
212
+ ...loadingDashboardEffects
51
213
  ]
52
214
  },
53
215
  {
54
- from: "Loading",
55
- to: "Success",
56
- event: "SUCCESS",
216
+ from: "idle",
217
+ to: "loading",
218
+ event: "START",
57
219
  effects: [
58
- ["set", "@entity.isLoading", false],
59
- ["set", "@entity.data", "@payload.data"]
220
+ ["fetch", "LoadingRecord"],
221
+ ["set", "@entity.status", "loading"],
222
+ ...loadingInProgressEffects
60
223
  ]
61
224
  },
62
225
  {
63
- from: "Loading",
64
- to: "Error",
65
- event: "ERROR",
226
+ from: "loading",
227
+ to: "loaded",
228
+ event: "COMPLETE",
66
229
  effects: [
67
- ["set", "@entity.isLoading", false],
68
- ["set", "@entity.error", "@payload.error"],
69
- ["render-ui", "content", {
70
- type: "error-state",
71
- message: "@entity.error",
72
- onRetry: "RETRY"
73
- }]
230
+ ["fetch", "LoadingRecord"],
231
+ ["set", "@entity.status", "loaded"],
232
+ ...loadingSuccessEffects
74
233
  ]
75
234
  },
76
235
  {
77
- from: "Error",
78
- to: "Loading",
79
- event: "RETRY",
236
+ from: "loading",
237
+ to: "error",
238
+ event: "FAIL",
80
239
  effects: [
81
- ["set", "@entity.isLoading", true],
82
- ["set", "@entity.error", null],
83
- ["set", "@entity.startTime", ["time/now"]],
84
- ["render-ui", "content", {
85
- type: "loading-state"
86
- }]
240
+ ["fetch", "LoadingRecord"],
241
+ ["set", "@entity.status", "error"],
242
+ ["set", "@entity.message", "@payload.message"],
243
+ ...loadingErrorEffects
87
244
  ]
88
245
  },
89
246
  {
90
- from: "Success",
91
- to: "Idle",
247
+ from: "loaded",
248
+ to: "idle",
92
249
  event: "RESET",
93
250
  effects: [
94
- ["set", "@entity.isLoading", false],
95
- ["set", "@entity.error", null],
96
- ["set", "@entity.data", null]
251
+ ["fetch", "LoadingRecord"],
252
+ ["set", "@entity.status", "idle"],
253
+ ...loadingDashboardEffects
97
254
  ]
98
255
  },
99
256
  {
100
- from: "Error",
101
- to: "Idle",
257
+ from: "error",
258
+ to: "idle",
102
259
  event: "RESET",
103
260
  effects: [
104
- ["set", "@entity.isLoading", false],
105
- ["set", "@entity.error", null],
106
- ["set", "@entity.data", null]
261
+ ["fetch", "LoadingRecord"],
262
+ ["set", "@entity.status", "idle"],
263
+ ["set", "@entity.message", ""],
264
+ ...loadingDashboardEffects
107
265
  ]
108
- }
266
+ },
267
+ // VIEW self-transitions for each state
268
+ { from: "idle", to: "idle", event: "VIEW", effects: [["fetch", "LoadingRecord"], ...loadingViewEffects] },
269
+ { from: "loading", to: "loading", event: "VIEW", effects: [["fetch", "LoadingRecord"], ...loadingViewEffects] },
270
+ { from: "loaded", to: "loaded", event: "VIEW", effects: [["fetch", "LoadingRecord"], ...loadingViewEffects] },
271
+ { from: "error", to: "error", event: "VIEW", effects: [["fetch", "LoadingRecord"], ...loadingViewEffects] }
109
272
  ]
110
273
  }
111
274
  }
112
275
  ],
113
- pages: []
276
+ pages: [{ name: "LoadingPage", path: "/loading", isInitial: true, traits: [{ ref: "LoadingManagement" }] }]
114
277
  }
115
278
  ]
116
279
  };
280
+ var fetchIdleEffects = [
281
+ ["render-ui", "main", { type: "stack", direction: "vertical", gap: "lg", children: [
282
+ // Header: icon + title + fetch button
283
+ { type: "stack", direction: "horizontal", justify: "space-between", children: [
284
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
285
+ { type: "icon", name: "download-cloud", size: "lg" },
286
+ { type: "typography", variant: "h2", content: "Data Browser" }
287
+ ] },
288
+ { type: "button", label: "Fetch", icon: "download", variant: "primary", action: "FETCH" }
289
+ ] },
290
+ { type: "divider" },
291
+ // Stats
292
+ { type: "stack", direction: "horizontal", gap: "md", children: [
293
+ { type: "stats", label: "Records", icon: "database", entity: "FetchRecord" },
294
+ { type: "stats", label: "Status", icon: "activity", entity: "FetchRecord" }
295
+ ] },
296
+ { type: "divider" },
297
+ // Data list
298
+ {
299
+ type: "data-list",
300
+ entity: "FetchRecord",
301
+ fields: [
302
+ { name: "name", label: "Name", icon: "tag", variant: "h4" },
303
+ { name: "status", label: "Status", icon: "circle", variant: "badge" },
304
+ { name: "message", label: "Message", icon: "message-square", variant: "body" }
305
+ ],
306
+ actions: [
307
+ { label: "View", event: "VIEW", icon: "eye", variant: "ghost" }
308
+ ]
309
+ }
310
+ ] }]
311
+ ];
312
+ var fetchingEffects = [
313
+ ["render-ui", "main", { type: "stack", direction: "vertical", gap: "lg", children: [
314
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
315
+ { type: "icon", name: "download-cloud", size: "lg" },
316
+ { type: "typography", variant: "h2", content: "Fetching..." }
317
+ ] },
318
+ { type: "divider" },
319
+ { type: "progress-bar", value: 0, label: "Fetching data", icon: "clock" },
320
+ { type: "divider" },
321
+ {
322
+ type: "data-list",
323
+ entity: "FetchRecord",
324
+ fields: [
325
+ { name: "name", label: "Name", icon: "tag", variant: "h4" },
326
+ { name: "status", label: "Status", icon: "circle", variant: "badge" },
327
+ { name: "message", label: "Message", icon: "message-square", variant: "body" }
328
+ ],
329
+ actions: [
330
+ { label: "View", event: "VIEW", icon: "eye", variant: "ghost" }
331
+ ]
332
+ }
333
+ ] }]
334
+ ];
335
+ var fetchFreshEffects = [
336
+ ["render-ui", "main", { type: "stack", direction: "vertical", gap: "lg", children: [
337
+ { type: "stack", direction: "horizontal", justify: "space-between", children: [
338
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
339
+ { type: "icon", name: "check-circle", size: "lg" },
340
+ { type: "typography", variant: "h2", content: "Data Browser" }
341
+ ] },
342
+ { type: "button", label: "Refresh", icon: "refresh-cw", variant: "secondary", action: "REFRESH" }
343
+ ] },
344
+ { type: "divider" },
345
+ { type: "badge", label: "Fresh", variant: "success", icon: "check" },
346
+ { type: "divider" },
347
+ {
348
+ type: "data-list",
349
+ entity: "FetchRecord",
350
+ fields: [
351
+ { name: "name", label: "Name", icon: "tag", variant: "h4" },
352
+ { name: "status", label: "Status", icon: "circle", variant: "badge" },
353
+ { name: "message", label: "Message", icon: "message-square", variant: "body" }
354
+ ],
355
+ actions: [
356
+ { label: "View", event: "VIEW", icon: "eye", variant: "ghost" }
357
+ ]
358
+ }
359
+ ] }]
360
+ ];
361
+ var fetchStaleEffects = [
362
+ ["render-ui", "main", { type: "stack", direction: "vertical", gap: "lg", children: [
363
+ { type: "stack", direction: "horizontal", justify: "space-between", children: [
364
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
365
+ { type: "icon", name: "clock", size: "lg" },
366
+ { type: "typography", variant: "h2", content: "Data Stale" }
367
+ ] },
368
+ { type: "button", label: "Refresh", icon: "refresh-cw", variant: "primary", action: "REFRESH" }
369
+ ] },
370
+ { type: "divider" },
371
+ { type: "badge", label: "Stale", variant: "warning", icon: "alert-triangle" },
372
+ { type: "divider" },
373
+ {
374
+ type: "data-list",
375
+ entity: "FetchRecord",
376
+ fields: [
377
+ { name: "name", label: "Name", icon: "tag", variant: "h4" },
378
+ { name: "status", label: "Status", icon: "circle", variant: "badge" },
379
+ { name: "message", label: "Message", icon: "message-square", variant: "body" }
380
+ ],
381
+ actions: [
382
+ { label: "View", event: "VIEW", icon: "eye", variant: "ghost" }
383
+ ]
384
+ }
385
+ ] }]
386
+ ];
387
+ var fetchErrorEffects = [
388
+ ["render-ui", "main", { type: "stack", direction: "vertical", gap: "lg", children: [
389
+ { type: "stack", direction: "horizontal", justify: "space-between", children: [
390
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
391
+ { type: "icon", name: "alert-circle", size: "lg" },
392
+ { type: "typography", variant: "h2", content: "Fetch Error" }
393
+ ] },
394
+ { type: "button", label: "Refresh", icon: "refresh-cw", variant: "secondary", action: "REFRESH" }
395
+ ] },
396
+ { type: "divider" },
397
+ { type: "badge", label: "Error", variant: "error", icon: "x-circle" },
398
+ { type: "divider" },
399
+ {
400
+ type: "data-list",
401
+ entity: "FetchRecord",
402
+ fields: [
403
+ { name: "name", label: "Name", icon: "tag", variant: "h4" },
404
+ { name: "status", label: "Status", icon: "circle", variant: "badge" },
405
+ { name: "message", label: "Message", icon: "message-square", variant: "body" }
406
+ ],
407
+ actions: [
408
+ { label: "View", event: "VIEW", icon: "eye", variant: "ghost" }
409
+ ]
410
+ }
411
+ ] }]
412
+ ];
413
+ var fetchViewEffects = [
414
+ ["render-ui", "main", { type: "stack", direction: "vertical", gap: "lg", children: [
415
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
416
+ { type: "icon", name: "download-cloud", size: "lg" },
417
+ { type: "typography", variant: "h2", content: "Data Browser" }
418
+ ] },
419
+ { type: "divider" },
420
+ {
421
+ type: "data-list",
422
+ entity: "FetchRecord",
423
+ fields: [
424
+ { name: "name", label: "Name", icon: "tag", variant: "h4" },
425
+ { name: "status", label: "Status", icon: "circle", variant: "badge" },
426
+ { name: "message", label: "Message", icon: "message-square", variant: "body" }
427
+ ],
428
+ actions: [
429
+ { label: "View", event: "VIEW", icon: "eye", variant: "ghost" }
430
+ ]
431
+ }
432
+ ] }]
433
+ ];
117
434
  var FETCH_BEHAVIOR = {
118
435
  name: "std-fetch",
119
436
  version: "1.0.0",
120
- description: "Data fetching with caching and refresh capabilities",
437
+ description: "Data fetching with refresh capabilities",
438
+ theme: ASYNC_THEME,
121
439
  orbitals: [
122
440
  {
123
441
  name: "FetchOrbital",
124
442
  entity: {
125
- name: "FetchState",
126
- persistence: "runtime",
443
+ name: "FetchRecord",
444
+ persistence: "persistent",
445
+ collection: "fetch_records",
127
446
  fields: [
128
447
  { name: "id", type: "string", required: true },
129
- { name: "data", type: "object", default: null },
130
- { name: "error", type: "object", default: null },
131
- { name: "isFetching", type: "boolean", default: false },
132
- { name: "lastFetchedAt", type: "number", default: null }
448
+ { name: "name", type: "string", default: "" },
449
+ { name: "status", type: "string", default: "idle" },
450
+ { name: "message", type: "string", default: "" }
133
451
  ]
134
452
  },
135
453
  traits: [
136
454
  {
137
- name: "Fetch",
138
- linkedEntity: "FetchState",
139
- category: "lifecycle",
455
+ name: "FetchManagement",
456
+ linkedEntity: "FetchRecord",
457
+ category: "interaction",
140
458
  stateMachine: {
141
459
  states: [
142
- { name: "Idle", isInitial: true },
143
- { name: "Fetching" },
144
- { name: "Stale" },
145
- { name: "Fresh" },
146
- { name: "Error" }
460
+ { name: "idle", isInitial: true },
461
+ { name: "fetching" },
462
+ { name: "fresh" },
463
+ { name: "stale" },
464
+ { name: "error" }
147
465
  ],
148
466
  events: [
149
- { key: "FETCH", name: "Fetch" },
150
- { key: "FETCH_SUCCESS", name: "Fetch Success" },
151
- { key: "FETCH_ERROR", name: "Fetch Error" },
467
+ { key: "INIT", name: "Initialize" },
468
+ { key: "FETCH", name: "Fetch Data" },
469
+ { key: "COMPLETE", name: "Fetch Complete" },
470
+ { key: "FAIL", name: "Fetch Fail", payloadSchema: [{ name: "message", type: "string", required: true }] },
471
+ { key: "INVALIDATE", name: "Invalidate" },
152
472
  { key: "REFRESH", name: "Refresh" },
153
- { key: "INVALIDATE", name: "Invalidate" }
473
+ { key: "RESET", name: "Reset" },
474
+ { key: "VIEW", name: "View", payloadSchema: [{ name: "id", type: "string", required: true }] }
154
475
  ],
155
476
  transitions: [
156
477
  {
157
- from: "Idle",
158
- to: "Fetching",
159
- event: "FETCH",
478
+ from: "idle",
479
+ to: "idle",
480
+ event: "INIT",
160
481
  effects: [
161
- ["set", "@entity.isFetching", true],
162
- ["set", "@entity.error", null]
482
+ ["fetch", "FetchRecord"],
483
+ ...fetchIdleEffects
163
484
  ]
164
485
  },
165
486
  {
166
- from: "Stale",
167
- to: "Fetching",
487
+ from: "idle",
488
+ to: "fetching",
168
489
  event: "FETCH",
169
490
  effects: [
170
- ["set", "@entity.isFetching", true],
171
- ["set", "@entity.error", null]
491
+ ["fetch", "FetchRecord"],
492
+ ["set", "@entity.status", "fetching"],
493
+ ...fetchingEffects
172
494
  ]
173
495
  },
174
496
  {
175
- from: "Fetching",
176
- to: "Fresh",
177
- event: "FETCH_SUCCESS",
497
+ from: "fetching",
498
+ to: "fresh",
499
+ event: "COMPLETE",
178
500
  effects: [
179
- ["set", "@entity.isFetching", false],
180
- ["set", "@entity.data", "@payload.data"],
181
- ["set", "@entity.lastFetchedAt", ["time/now"]]
501
+ ["fetch", "FetchRecord"],
502
+ ["set", "@entity.status", "fresh"],
503
+ ...fetchFreshEffects
182
504
  ]
183
505
  },
184
506
  {
185
- from: "Fetching",
186
- to: "Error",
187
- event: "FETCH_ERROR",
507
+ from: "fetching",
508
+ to: "error",
509
+ event: "FAIL",
188
510
  effects: [
189
- ["set", "@entity.isFetching", false],
190
- ["set", "@entity.error", "@payload.error"]
511
+ ["fetch", "FetchRecord"],
512
+ ["set", "@entity.status", "error"],
513
+ ["set", "@entity.message", "@payload.message"],
514
+ ...fetchErrorEffects
191
515
  ]
192
516
  },
193
517
  {
194
- from: "Fresh",
195
- to: "Stale",
518
+ from: "fresh",
519
+ to: "stale",
196
520
  event: "INVALIDATE",
197
- effects: [["set", "@entity.lastFetchedAt", null]]
521
+ effects: [
522
+ ["fetch", "FetchRecord"],
523
+ ["set", "@entity.status", "stale"],
524
+ ...fetchStaleEffects
525
+ ]
198
526
  },
199
527
  {
200
- from: "Fresh",
201
- to: "Fetching",
528
+ from: "fresh",
529
+ to: "fetching",
202
530
  event: "REFRESH",
203
531
  effects: [
204
- ["set", "@entity.isFetching", true],
205
- ["set", "@entity.error", null]
532
+ ["fetch", "FetchRecord"],
533
+ ["set", "@entity.status", "fetching"],
534
+ ...fetchingEffects
206
535
  ]
207
536
  },
208
537
  {
209
- from: "Stale",
210
- to: "Fetching",
538
+ from: "stale",
539
+ to: "fetching",
211
540
  event: "REFRESH",
212
541
  effects: [
213
- ["set", "@entity.isFetching", true],
214
- ["set", "@entity.error", null]
542
+ ["fetch", "FetchRecord"],
543
+ ["set", "@entity.status", "fetching"],
544
+ ...fetchingEffects
215
545
  ]
216
546
  },
217
547
  {
218
- from: "Error",
219
- to: "Fetching",
548
+ from: "error",
549
+ to: "fetching",
220
550
  event: "REFRESH",
221
551
  effects: [
222
- ["set", "@entity.isFetching", true],
223
- ["set", "@entity.error", null]
552
+ ["fetch", "FetchRecord"],
553
+ ["set", "@entity.status", "fetching"],
554
+ ["set", "@entity.message", ""],
555
+ ...fetchingEffects
556
+ ]
557
+ },
558
+ {
559
+ from: "error",
560
+ to: "idle",
561
+ event: "RESET",
562
+ effects: [
563
+ ["fetch", "FetchRecord"],
564
+ ["set", "@entity.status", "idle"],
565
+ ["set", "@entity.message", ""],
566
+ ...fetchIdleEffects
224
567
  ]
225
- }
568
+ },
569
+ // VIEW self-transitions for each state
570
+ { from: "idle", to: "idle", event: "VIEW", effects: [["fetch", "FetchRecord"], ...fetchViewEffects] },
571
+ { from: "fetching", to: "fetching", event: "VIEW", effects: [["fetch", "FetchRecord"], ...fetchViewEffects] },
572
+ { from: "fresh", to: "fresh", event: "VIEW", effects: [["fetch", "FetchRecord"], ...fetchViewEffects] },
573
+ { from: "stale", to: "stale", event: "VIEW", effects: [["fetch", "FetchRecord"], ...fetchViewEffects] },
574
+ { from: "error", to: "error", event: "VIEW", effects: [["fetch", "FetchRecord"], ...fetchViewEffects] }
226
575
  ]
227
576
  }
228
577
  }
229
578
  ],
230
- pages: []
579
+ pages: [{ name: "DataBrowserPage", path: "/data-browser", isInitial: true, traits: [{ ref: "FetchManagement" }] }]
231
580
  }
232
581
  ]
233
582
  };
583
+ var submitIdleEffects = [
584
+ ["render-ui", "main", { type: "stack", direction: "vertical", gap: "lg", children: [
585
+ // Header: icon + title
586
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
587
+ { type: "icon", name: "send", size: "lg" },
588
+ { type: "typography", variant: "h2", content: "Submissions" }
589
+ ] },
590
+ { type: "divider" },
591
+ // Stats
592
+ { type: "stack", direction: "horizontal", gap: "md", children: [
593
+ { type: "stats", label: "Total", icon: "hash", entity: "Submission" },
594
+ { type: "stats", label: "Status", icon: "activity", entity: "Submission" }
595
+ ] },
596
+ { type: "divider" },
597
+ // Submission list
598
+ {
599
+ type: "data-list",
600
+ entity: "Submission",
601
+ fields: [
602
+ { name: "name", label: "Name", icon: "file-text", variant: "h4" },
603
+ { name: "status", label: "Status", icon: "circle", variant: "badge" },
604
+ { name: "message", label: "Message", icon: "message-square", variant: "body" }
605
+ ],
606
+ actions: [
607
+ { label: "View", event: "VIEW", icon: "eye", variant: "ghost" }
608
+ ]
609
+ }
610
+ ] }]
611
+ ];
612
+ var submittingEffects = [
613
+ ["render-ui", "main", { type: "stack", direction: "vertical", gap: "lg", children: [
614
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
615
+ { type: "icon", name: "send", size: "lg" },
616
+ { type: "typography", variant: "h2", content: "Submitting..." }
617
+ ] },
618
+ { type: "divider" },
619
+ { type: "progress-bar", value: 0, label: "Sending", icon: "upload" },
620
+ { type: "divider" },
621
+ {
622
+ type: "data-list",
623
+ entity: "Submission",
624
+ fields: [
625
+ { name: "name", label: "Name", icon: "file-text", variant: "h4" },
626
+ { name: "status", label: "Status", icon: "circle", variant: "badge" },
627
+ { name: "message", label: "Message", icon: "message-square", variant: "body" }
628
+ ],
629
+ actions: [
630
+ { label: "View", event: "VIEW", icon: "eye", variant: "ghost" }
631
+ ]
632
+ }
633
+ ] }]
634
+ ];
635
+ var submitSuccessEffects = [
636
+ ["render-ui", "main", { type: "stack", direction: "vertical", gap: "lg", children: [
637
+ { type: "stack", direction: "horizontal", justify: "space-between", children: [
638
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
639
+ { type: "icon", name: "check-circle", size: "lg" },
640
+ { type: "typography", variant: "h2", content: "Success" }
641
+ ] },
642
+ { type: "button", label: "Reset", icon: "refresh-cw", variant: "secondary", action: "RESET" }
643
+ ] },
644
+ { type: "divider" },
645
+ { type: "badge", label: "Submitted", variant: "success", icon: "check" },
646
+ { type: "divider" },
647
+ {
648
+ type: "data-list",
649
+ entity: "Submission",
650
+ fields: [
651
+ { name: "name", label: "Name", icon: "file-text", variant: "h4" },
652
+ { name: "status", label: "Status", icon: "circle", variant: "badge" },
653
+ { name: "message", label: "Message", icon: "message-square", variant: "body" }
654
+ ],
655
+ actions: [
656
+ { label: "View", event: "VIEW", icon: "eye", variant: "ghost" }
657
+ ]
658
+ }
659
+ ] }]
660
+ ];
661
+ var submitErrorEffects = [
662
+ ["render-ui", "main", { type: "stack", direction: "vertical", gap: "lg", children: [
663
+ { type: "stack", direction: "horizontal", justify: "space-between", children: [
664
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
665
+ { type: "icon", name: "alert-circle", size: "lg" },
666
+ { type: "typography", variant: "h2", content: "Submission Failed" }
667
+ ] },
668
+ { type: "button", label: "Reset", icon: "refresh-cw", variant: "secondary", action: "RESET" }
669
+ ] },
670
+ { type: "divider" },
671
+ { type: "badge", label: "Error", variant: "error", icon: "x-circle" },
672
+ { type: "divider" },
673
+ {
674
+ type: "data-list",
675
+ entity: "Submission",
676
+ fields: [
677
+ { name: "name", label: "Name", icon: "file-text", variant: "h4" },
678
+ { name: "status", label: "Status", icon: "circle", variant: "badge" },
679
+ { name: "message", label: "Message", icon: "message-square", variant: "body" }
680
+ ],
681
+ actions: [
682
+ { label: "View", event: "VIEW", icon: "eye", variant: "ghost" }
683
+ ]
684
+ }
685
+ ] }]
686
+ ];
687
+ var submitViewEffects = [
688
+ ["render-ui", "main", { type: "stack", direction: "vertical", gap: "lg", children: [
689
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
690
+ { type: "icon", name: "send", size: "lg" },
691
+ { type: "typography", variant: "h2", content: "Submissions" }
692
+ ] },
693
+ { type: "divider" },
694
+ {
695
+ type: "data-list",
696
+ entity: "Submission",
697
+ fields: [
698
+ { name: "name", label: "Name", icon: "file-text", variant: "h4" },
699
+ { name: "status", label: "Status", icon: "circle", variant: "badge" },
700
+ { name: "message", label: "Message", icon: "message-square", variant: "body" }
701
+ ],
702
+ actions: [
703
+ { label: "View", event: "VIEW", icon: "eye", variant: "ghost" }
704
+ ]
705
+ }
706
+ ] }]
707
+ ];
234
708
  var SUBMIT_BEHAVIOR = {
235
709
  name: "std-submit",
236
710
  version: "1.0.0",
237
- description: "Async submission with retry capabilities",
711
+ description: "Form submission with success/error handling",
712
+ theme: ASYNC_THEME,
238
713
  orbitals: [
239
714
  {
240
715
  name: "SubmitOrbital",
241
716
  entity: {
242
- name: "SubmitState",
243
- persistence: "runtime",
717
+ name: "Submission",
718
+ persistence: "persistent",
719
+ collection: "submissions",
244
720
  fields: [
245
721
  { name: "id", type: "string", required: true },
246
- { name: "isSubmitting", type: "boolean", default: false },
247
- { name: "error", type: "object", default: null },
248
- { name: "lastSubmittedData", type: "object", default: null },
249
- { name: "successMessage", type: "string", default: "Submitted successfully" },
250
- { name: "errorMessage", type: "string", default: "Submission failed" },
251
- { name: "resetOnSuccess", type: "boolean", default: false }
722
+ { name: "name", type: "string", default: "" },
723
+ { name: "status", type: "string", default: "idle" },
724
+ { name: "message", type: "string", default: "" }
252
725
  ]
253
726
  },
254
727
  traits: [
255
728
  {
256
- name: "Submit",
257
- linkedEntity: "SubmitState",
258
- category: "lifecycle",
729
+ name: "SubmitManagement",
730
+ linkedEntity: "Submission",
731
+ category: "interaction",
259
732
  stateMachine: {
260
733
  states: [
261
- { name: "Idle", isInitial: true },
262
- { name: "Submitting" },
263
- { name: "Success" },
264
- { name: "Error" }
734
+ { name: "idle", isInitial: true },
735
+ { name: "submitting" },
736
+ { name: "success" },
737
+ { name: "error" }
265
738
  ],
266
739
  events: [
267
- { key: "SUBMIT", name: "Submit" },
268
- { key: "SUBMIT_SUCCESS", name: "Submit Success" },
269
- { key: "SUBMIT_ERROR", name: "Submit Error" },
270
- { key: "RETRY", name: "Retry" },
271
- { key: "RESET", name: "Reset" }
740
+ { key: "INIT", name: "Initialize" },
741
+ { key: "SUBMIT", name: "Submit", payloadSchema: [{ name: "name", type: "string", required: true }] },
742
+ { key: "COMPLETE", name: "Submit Complete" },
743
+ { key: "FAIL", name: "Submit Fail", payloadSchema: [{ name: "message", type: "string", required: true }] },
744
+ { key: "RESET", name: "Reset" },
745
+ { key: "CLOSE", name: "Close" },
746
+ { key: "VIEW", name: "View", payloadSchema: [{ name: "id", type: "string", required: true }] }
272
747
  ],
273
748
  transitions: [
274
749
  {
275
- from: "Idle",
276
- to: "Submitting",
277
- event: "SUBMIT",
750
+ from: "idle",
751
+ to: "idle",
752
+ event: "INIT",
278
753
  effects: [
279
- ["set", "@entity.isSubmitting", true],
280
- ["set", "@entity.error", null],
281
- ["set", "@entity.lastSubmittedData", "@payload.data"]
754
+ ["fetch", "Submission"],
755
+ ...submitIdleEffects
282
756
  ]
283
757
  },
284
758
  {
285
- from: "Submitting",
286
- to: "Success",
287
- event: "SUBMIT_SUCCESS",
759
+ from: "idle",
760
+ to: "submitting",
761
+ event: "SUBMIT",
288
762
  effects: [
289
- ["set", "@entity.isSubmitting", false],
290
- ["notify", "in_app", "@entity.successMessage"],
291
- ["when", "@entity.resetOnSuccess", ["emit", "RESET"]]
763
+ ["fetch", "Submission"],
764
+ ["set", "@entity.status", "submitting"],
765
+ ["set", "@entity.name", "@payload.name"],
766
+ ...submittingEffects
292
767
  ]
293
768
  },
294
769
  {
295
- from: "Submitting",
296
- to: "Error",
297
- event: "SUBMIT_ERROR",
770
+ from: "submitting",
771
+ to: "success",
772
+ event: "COMPLETE",
298
773
  effects: [
299
- ["set", "@entity.isSubmitting", false],
300
- ["set", "@entity.error", "@payload.error"],
301
- ["notify", "in_app", "@entity.errorMessage"]
774
+ ["fetch", "Submission"],
775
+ ["set", "@entity.status", "success"],
776
+ ["persist", "create", "Submission", { name: "@entity.name", status: "success" }],
777
+ ...submitSuccessEffects
302
778
  ]
303
779
  },
304
780
  {
305
- from: "Error",
306
- to: "Submitting",
307
- event: "RETRY",
781
+ from: "submitting",
782
+ to: "error",
783
+ event: "FAIL",
308
784
  effects: [
309
- ["set", "@entity.isSubmitting", true],
310
- ["set", "@entity.error", null]
785
+ ["fetch", "Submission"],
786
+ ["set", "@entity.status", "error"],
787
+ ["set", "@entity.message", "@payload.message"],
788
+ ...submitErrorEffects
311
789
  ]
312
790
  },
313
791
  {
314
- from: "Success",
315
- to: "Idle",
792
+ from: "success",
793
+ to: "idle",
316
794
  event: "RESET",
317
795
  effects: [
318
- ["set", "@entity.isSubmitting", false],
319
- ["set", "@entity.error", null],
320
- ["set", "@entity.lastSubmittedData", null]
796
+ ["fetch", "Submission"],
797
+ ["set", "@entity.status", "idle"],
798
+ ...submitIdleEffects
321
799
  ]
322
800
  },
323
801
  {
324
- from: "Error",
325
- to: "Idle",
802
+ from: "error",
803
+ to: "idle",
326
804
  event: "RESET",
327
805
  effects: [
328
- ["set", "@entity.isSubmitting", false],
329
- ["set", "@entity.error", null],
330
- ["set", "@entity.lastSubmittedData", null]
806
+ ["fetch", "Submission"],
807
+ ["set", "@entity.status", "idle"],
808
+ ["set", "@entity.message", ""],
809
+ ...submitIdleEffects
331
810
  ]
332
- }
811
+ },
812
+ {
813
+ from: "success",
814
+ to: "idle",
815
+ event: "CLOSE",
816
+ effects: [
817
+ ["fetch", "Submission"],
818
+ ["set", "@entity.status", "idle"],
819
+ ...submitIdleEffects
820
+ ]
821
+ },
822
+ // VIEW self-transitions for each state
823
+ { from: "idle", to: "idle", event: "VIEW", effects: [["fetch", "Submission"], ...submitViewEffects] },
824
+ { from: "submitting", to: "submitting", event: "VIEW", effects: [["fetch", "Submission"], ...submitViewEffects] },
825
+ { from: "success", to: "success", event: "VIEW", effects: [["fetch", "Submission"], ...submitViewEffects] },
826
+ { from: "error", to: "error", event: "VIEW", effects: [["fetch", "Submission"], ...submitViewEffects] }
333
827
  ]
334
828
  }
335
829
  }
336
830
  ],
337
- pages: []
831
+ pages: [{ name: "SubmissionsPage", path: "/submissions", isInitial: true, traits: [{ ref: "SubmitManagement" }] }]
338
832
  }
339
833
  ]
340
834
  };
835
+ var retryIdleEffects = [
836
+ ["render-ui", "main", { type: "stack", direction: "vertical", gap: "lg", children: [
837
+ // Header: icon + title + start button
838
+ { type: "stack", direction: "horizontal", justify: "space-between", children: [
839
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
840
+ { type: "icon", name: "repeat", size: "lg" },
841
+ { type: "typography", variant: "h2", content: "Operations" }
842
+ ] },
843
+ { type: "button", label: "Start", icon: "play", variant: "primary", action: "START" }
844
+ ] },
845
+ { type: "divider" },
846
+ // Stats row
847
+ { type: "stack", direction: "horizontal", gap: "md", children: [
848
+ { type: "stats", label: "Records", icon: "database", entity: "RetryRecord" },
849
+ { type: "stats", label: "Attempts", icon: "repeat", entity: "RetryRecord" }
850
+ ] },
851
+ { type: "divider" },
852
+ // Data grid
853
+ {
854
+ type: "data-grid",
855
+ entity: "RetryRecord",
856
+ cols: 2,
857
+ gap: "md",
858
+ fields: [
859
+ { name: "name", label: "Name", icon: "tag", variant: "h4" },
860
+ { name: "status", label: "Status", icon: "circle", variant: "badge" },
861
+ { name: "attempt", label: "Attempt", icon: "hash", variant: "body", format: "number" },
862
+ { name: "message", label: "Message", icon: "message-square", variant: "body" }
863
+ ],
864
+ actions: [
865
+ { label: "View", event: "VIEW", icon: "eye", variant: "ghost" }
866
+ ]
867
+ }
868
+ ] }]
869
+ ];
870
+ var retryAttemptingEffects = [
871
+ ["render-ui", "main", { type: "stack", direction: "vertical", gap: "lg", children: [
872
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
873
+ { type: "icon", name: "repeat", size: "lg" },
874
+ { type: "typography", variant: "h2", content: "Attempting..." }
875
+ ] },
876
+ { type: "divider" },
877
+ { type: "progress-bar", value: 0, label: "Processing", icon: "clock" },
878
+ { type: "divider" },
879
+ {
880
+ type: "data-grid",
881
+ entity: "RetryRecord",
882
+ cols: 2,
883
+ gap: "md",
884
+ fields: [
885
+ { name: "name", label: "Name", icon: "tag", variant: "h4" },
886
+ { name: "status", label: "Status", icon: "circle", variant: "badge" },
887
+ { name: "attempt", label: "Attempt", icon: "hash", variant: "body", format: "number" },
888
+ { name: "message", label: "Message", icon: "message-square", variant: "body" }
889
+ ],
890
+ actions: [
891
+ { label: "View", event: "VIEW", icon: "eye", variant: "ghost" }
892
+ ]
893
+ }
894
+ ] }]
895
+ ];
896
+ var retrySuccessEffects = [
897
+ ["render-ui", "main", { type: "stack", direction: "vertical", gap: "lg", children: [
898
+ { type: "stack", direction: "horizontal", justify: "space-between", children: [
899
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
900
+ { type: "icon", name: "check-circle", size: "lg" },
901
+ { type: "typography", variant: "h2", content: "Success" }
902
+ ] },
903
+ { type: "button", label: "Reset", icon: "refresh-cw", variant: "secondary", action: "RESET" }
904
+ ] },
905
+ { type: "divider" },
906
+ { type: "badge", label: "Complete", variant: "success", icon: "check" },
907
+ { type: "divider" },
908
+ {
909
+ type: "data-grid",
910
+ entity: "RetryRecord",
911
+ cols: 2,
912
+ gap: "md",
913
+ fields: [
914
+ { name: "name", label: "Name", icon: "tag", variant: "h4" },
915
+ { name: "status", label: "Status", icon: "circle", variant: "badge" },
916
+ { name: "attempt", label: "Attempt", icon: "hash", variant: "body", format: "number" },
917
+ { name: "message", label: "Message", icon: "message-square", variant: "body" }
918
+ ],
919
+ actions: [
920
+ { label: "View", event: "VIEW", icon: "eye", variant: "ghost" }
921
+ ]
922
+ }
923
+ ] }]
924
+ ];
925
+ var retryFailedEffects = [
926
+ ["render-ui", "main", { type: "stack", direction: "vertical", gap: "lg", children: [
927
+ { type: "stack", direction: "horizontal", justify: "space-between", children: [
928
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
929
+ { type: "icon", name: "alert-circle", size: "lg" },
930
+ { type: "typography", variant: "h2", content: "Failed" }
931
+ ] },
932
+ { type: "button", label: "Retry", icon: "repeat", variant: "primary", action: "RETRY" }
933
+ ] },
934
+ { type: "divider" },
935
+ { type: "badge", label: "Failed", variant: "error", icon: "x-circle" },
936
+ { type: "divider" },
937
+ {
938
+ type: "data-grid",
939
+ entity: "RetryRecord",
940
+ cols: 2,
941
+ gap: "md",
942
+ fields: [
943
+ { name: "name", label: "Name", icon: "tag", variant: "h4" },
944
+ { name: "status", label: "Status", icon: "circle", variant: "badge" },
945
+ { name: "attempt", label: "Attempt", icon: "hash", variant: "body", format: "number" },
946
+ { name: "message", label: "Message", icon: "message-square", variant: "body" }
947
+ ],
948
+ actions: [
949
+ { label: "View", event: "VIEW", icon: "eye", variant: "ghost" }
950
+ ]
951
+ }
952
+ ] }]
953
+ ];
954
+ var retryViewEffects = [
955
+ ["render-ui", "main", { type: "stack", direction: "vertical", gap: "lg", children: [
956
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
957
+ { type: "icon", name: "repeat", size: "lg" },
958
+ { type: "typography", variant: "h2", content: "Operations" }
959
+ ] },
960
+ { type: "divider" },
961
+ {
962
+ type: "data-grid",
963
+ entity: "RetryRecord",
964
+ cols: 2,
965
+ gap: "md",
966
+ fields: [
967
+ { name: "name", label: "Name", icon: "tag", variant: "h4" },
968
+ { name: "status", label: "Status", icon: "circle", variant: "badge" },
969
+ { name: "attempt", label: "Attempt", icon: "hash", variant: "body", format: "number" },
970
+ { name: "message", label: "Message", icon: "message-square", variant: "body" }
971
+ ],
972
+ actions: [
973
+ { label: "View", event: "VIEW", icon: "eye", variant: "ghost" }
974
+ ]
975
+ }
976
+ ] }]
977
+ ];
341
978
  var RETRY_BEHAVIOR = {
342
979
  name: "std-retry",
343
980
  version: "1.0.0",
344
- description: "Automatic retry with exponential backoff",
981
+ description: "Operation with retry capability",
982
+ theme: ASYNC_THEME,
345
983
  orbitals: [
346
984
  {
347
985
  name: "RetryOrbital",
348
986
  entity: {
349
- name: "RetryState",
350
- persistence: "runtime",
987
+ name: "RetryRecord",
988
+ persistence: "persistent",
989
+ collection: "retry_records",
351
990
  fields: [
352
991
  { name: "id", type: "string", required: true },
992
+ { name: "name", type: "string", default: "" },
993
+ { name: "status", type: "string", default: "idle" },
353
994
  { name: "attempt", type: "number", default: 0 },
354
- { name: "error", type: "object", default: null },
355
- { name: "nextRetryAt", type: "number", default: null },
356
- { name: "maxAttempts", type: "number", default: 3 },
357
- { name: "initialDelayMs", type: "number", default: 1e3 },
358
- { name: "backoffMultiplier", type: "number", default: 2 },
359
- { name: "maxDelayMs", type: "number", default: 3e4 }
995
+ { name: "message", type: "string", default: "" }
360
996
  ]
361
997
  },
362
998
  traits: [
363
999
  {
364
- name: "Retry",
365
- linkedEntity: "RetryState",
366
- category: "lifecycle",
1000
+ name: "RetryManagement",
1001
+ linkedEntity: "RetryRecord",
1002
+ category: "interaction",
367
1003
  stateMachine: {
368
1004
  states: [
369
- { name: "Idle", isInitial: true },
370
- { name: "Attempting" },
371
- { name: "Waiting" },
372
- { name: "Success", isTerminal: true },
373
- { name: "Failed", isTerminal: true }
1005
+ { name: "idle", isInitial: true },
1006
+ { name: "attempting" },
1007
+ { name: "success" },
1008
+ { name: "failed" }
374
1009
  ],
375
1010
  events: [
376
- { key: "START", name: "Start" },
377
- { key: "ATTEMPT_SUCCESS", name: "Attempt Success" },
378
- { key: "ATTEMPT_ERROR", name: "Attempt Error" },
379
- { key: "RETRY_TICK", name: "Retry Tick" },
380
- { key: "GIVE_UP", name: "Give Up" },
381
- { key: "RESET", name: "Reset" }
1011
+ { key: "INIT", name: "Initialize" },
1012
+ { key: "START", name: "Start Operation" },
1013
+ { key: "COMPLETE", name: "Operation Complete" },
1014
+ { key: "FAIL", name: "Operation Fail", payloadSchema: [{ name: "message", type: "string", required: true }] },
1015
+ { key: "RETRY", name: "Retry" },
1016
+ { key: "RESET", name: "Reset" },
1017
+ { key: "VIEW", name: "View", payloadSchema: [{ name: "id", type: "string", required: true }] }
382
1018
  ],
383
1019
  transitions: [
384
1020
  {
385
- from: "Idle",
386
- to: "Attempting",
387
- event: "START",
1021
+ from: "idle",
1022
+ to: "idle",
1023
+ event: "INIT",
388
1024
  effects: [
389
- ["set", "@entity.attempt", 1],
390
- ["set", "@entity.error", null]
1025
+ ["fetch", "RetryRecord"],
1026
+ ...retryIdleEffects
391
1027
  ]
392
1028
  },
393
1029
  {
394
- from: "Attempting",
395
- to: "Success",
396
- event: "ATTEMPT_SUCCESS",
397
- effects: []
398
- },
399
- {
400
- from: "Attempting",
401
- to: "Waiting",
402
- event: "ATTEMPT_ERROR",
403
- guard: ["<", "@entity.attempt", "@entity.maxAttempts"],
1030
+ from: "idle",
1031
+ to: "attempting",
1032
+ event: "START",
404
1033
  effects: [
405
- ["set", "@entity.error", "@payload.error"],
406
- [
407
- "let",
408
- [["delay", [
409
- "math/min",
410
- ["*", "@entity.initialDelayMs", ["math/pow", "@entity.backoffMultiplier", "@entity.attempt"]],
411
- "@entity.maxDelayMs"
412
- ]]],
413
- ["set", "@entity.nextRetryAt", ["+", ["time/now"], "@delay"]],
414
- ["async/delay", "@delay", ["emit", "RETRY_TICK"]]
415
- ]
1034
+ ["fetch", "RetryRecord"],
1035
+ ["set", "@entity.status", "attempting"],
1036
+ ["set", "@entity.attempt", 1],
1037
+ ...retryAttemptingEffects
416
1038
  ]
417
1039
  },
418
1040
  {
419
- from: "Attempting",
420
- to: "Failed",
421
- event: "ATTEMPT_ERROR",
422
- guard: [">=", "@entity.attempt", "@entity.maxAttempts"],
1041
+ from: "attempting",
1042
+ to: "success",
1043
+ event: "COMPLETE",
423
1044
  effects: [
424
- ["set", "@entity.error", "@payload.error"],
425
- ["notify", "in_app", "All retry attempts failed"]
1045
+ ["fetch", "RetryRecord"],
1046
+ ["set", "@entity.status", "success"],
1047
+ ...retrySuccessEffects
426
1048
  ]
427
1049
  },
428
1050
  {
429
- from: "Waiting",
430
- to: "Attempting",
431
- event: "RETRY_TICK",
432
- effects: [["set", "@entity.attempt", ["+", "@entity.attempt", 1]]]
1051
+ from: "attempting",
1052
+ to: "failed",
1053
+ event: "FAIL",
1054
+ effects: [
1055
+ ["fetch", "RetryRecord"],
1056
+ ["set", "@entity.status", "failed"],
1057
+ ["set", "@entity.message", "@payload.message"],
1058
+ ...retryFailedEffects
1059
+ ]
433
1060
  },
434
1061
  {
435
- from: "Waiting",
436
- to: "Failed",
437
- event: "GIVE_UP",
438
- effects: [["notify", "in_app", "Retry cancelled"]]
1062
+ from: "failed",
1063
+ to: "attempting",
1064
+ event: "RETRY",
1065
+ effects: [
1066
+ ["fetch", "RetryRecord"],
1067
+ ["set", "@entity.status", "attempting"],
1068
+ ["set", "@entity.message", ""],
1069
+ ...retryAttemptingEffects
1070
+ ]
439
1071
  },
440
1072
  {
441
- from: "Success",
442
- to: "Idle",
1073
+ from: "success",
1074
+ to: "idle",
443
1075
  event: "RESET",
444
1076
  effects: [
1077
+ ["fetch", "RetryRecord"],
1078
+ ["set", "@entity.status", "idle"],
445
1079
  ["set", "@entity.attempt", 0],
446
- ["set", "@entity.error", null],
447
- ["set", "@entity.nextRetryAt", null]
1080
+ ...retryIdleEffects
448
1081
  ]
449
1082
  },
450
1083
  {
451
- from: "Failed",
452
- to: "Idle",
1084
+ from: "failed",
1085
+ to: "idle",
453
1086
  event: "RESET",
454
1087
  effects: [
1088
+ ["fetch", "RetryRecord"],
1089
+ ["set", "@entity.status", "idle"],
455
1090
  ["set", "@entity.attempt", 0],
456
- ["set", "@entity.error", null],
457
- ["set", "@entity.nextRetryAt", null]
1091
+ ["set", "@entity.message", ""],
1092
+ ...retryIdleEffects
458
1093
  ]
459
- }
1094
+ },
1095
+ // VIEW self-transitions for each state
1096
+ { from: "idle", to: "idle", event: "VIEW", effects: [["fetch", "RetryRecord"], ...retryViewEffects] },
1097
+ { from: "attempting", to: "attempting", event: "VIEW", effects: [["fetch", "RetryRecord"], ...retryViewEffects] },
1098
+ { from: "success", to: "success", event: "VIEW", effects: [["fetch", "RetryRecord"], ...retryViewEffects] },
1099
+ { from: "failed", to: "failed", event: "VIEW", effects: [["fetch", "RetryRecord"], ...retryViewEffects] }
460
1100
  ]
461
1101
  }
462
1102
  }
463
1103
  ],
464
- pages: []
1104
+ pages: [{ name: "OperationsPage", path: "/operations", isInitial: true, traits: [{ ref: "RetryManagement" }] }]
465
1105
  }
466
1106
  ]
467
1107
  };
1108
+ var pollStoppedEffects = [
1109
+ ["render-ui", "main", { type: "stack", direction: "vertical", gap: "lg", children: [
1110
+ // Header: icon + title + start button
1111
+ { type: "stack", direction: "horizontal", justify: "space-between", children: [
1112
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
1113
+ { type: "icon", name: "radio", size: "lg" },
1114
+ { type: "typography", variant: "h2", content: "Poll Monitor" }
1115
+ ] },
1116
+ { type: "button", label: "Start", icon: "play", variant: "primary", action: "START" }
1117
+ ] },
1118
+ { type: "divider" },
1119
+ // Stats
1120
+ { type: "stack", direction: "horizontal", gap: "md", children: [
1121
+ { type: "stats", label: "Records", icon: "database", entity: "PollRecord" },
1122
+ { type: "stats", label: "Poll Count", icon: "hash", entity: "PollRecord" }
1123
+ ] },
1124
+ { type: "divider" },
1125
+ { type: "badge", label: "Stopped", variant: "secondary", icon: "square" },
1126
+ { type: "divider" },
1127
+ // Data grid for poll records
1128
+ {
1129
+ type: "data-grid",
1130
+ entity: "PollRecord",
1131
+ cols: 2,
1132
+ gap: "md",
1133
+ fields: [
1134
+ { name: "name", label: "Name", icon: "tag", variant: "h4" },
1135
+ { name: "status", label: "Status", icon: "circle", variant: "badge" },
1136
+ { name: "count", label: "Count", icon: "hash", variant: "body", format: "number" }
1137
+ ],
1138
+ actions: [
1139
+ { label: "View", event: "VIEW", icon: "eye", variant: "ghost" }
1140
+ ]
1141
+ }
1142
+ ] }]
1143
+ ];
1144
+ var pollActiveEffects = [
1145
+ ["render-ui", "main", { type: "stack", direction: "vertical", gap: "lg", children: [
1146
+ // Header: icon + title + pause/stop buttons
1147
+ { type: "stack", direction: "horizontal", justify: "space-between", children: [
1148
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
1149
+ { type: "icon", name: "radio", size: "lg" },
1150
+ { type: "typography", variant: "h2", content: "Polling..." }
1151
+ ] },
1152
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
1153
+ { type: "button", label: "Pause", icon: "pause", variant: "secondary", action: "PAUSE" },
1154
+ { type: "button", label: "Stop", icon: "square", variant: "ghost", action: "STOP" }
1155
+ ] }
1156
+ ] },
1157
+ { type: "divider" },
1158
+ { type: "progress-bar", value: 0, label: "Polling active", icon: "activity" },
1159
+ { type: "divider" },
1160
+ // Stats
1161
+ { type: "stack", direction: "horizontal", gap: "md", children: [
1162
+ { type: "stats", label: "Records", icon: "database", entity: "PollRecord" },
1163
+ { type: "stats", label: "Poll Count", icon: "hash", entity: "PollRecord" }
1164
+ ] },
1165
+ { type: "divider" },
1166
+ {
1167
+ type: "data-grid",
1168
+ entity: "PollRecord",
1169
+ cols: 2,
1170
+ gap: "md",
1171
+ fields: [
1172
+ { name: "name", label: "Name", icon: "tag", variant: "h4" },
1173
+ { name: "status", label: "Status", icon: "circle", variant: "badge" },
1174
+ { name: "count", label: "Count", icon: "hash", variant: "body", format: "number" }
1175
+ ],
1176
+ actions: [
1177
+ { label: "View", event: "VIEW", icon: "eye", variant: "ghost" }
1178
+ ]
1179
+ }
1180
+ ] }]
1181
+ ];
1182
+ var pollPausedEffects = [
1183
+ ["render-ui", "main", { type: "stack", direction: "vertical", gap: "lg", children: [
1184
+ // Header: icon + title + resume/stop buttons
1185
+ { type: "stack", direction: "horizontal", justify: "space-between", children: [
1186
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
1187
+ { type: "icon", name: "pause-circle", size: "lg" },
1188
+ { type: "typography", variant: "h2", content: "Paused" }
1189
+ ] },
1190
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
1191
+ { type: "button", label: "Resume", icon: "play", variant: "primary", action: "RESUME" },
1192
+ { type: "button", label: "Stop", icon: "square", variant: "ghost", action: "STOP" }
1193
+ ] }
1194
+ ] },
1195
+ { type: "divider" },
1196
+ { type: "badge", label: "Paused", variant: "warning", icon: "pause" },
1197
+ { type: "divider" },
1198
+ { type: "stack", direction: "horizontal", gap: "md", children: [
1199
+ { type: "stats", label: "Records", icon: "database", entity: "PollRecord" },
1200
+ { type: "stats", label: "Poll Count", icon: "hash", entity: "PollRecord" }
1201
+ ] },
1202
+ { type: "divider" },
1203
+ {
1204
+ type: "data-grid",
1205
+ entity: "PollRecord",
1206
+ cols: 2,
1207
+ gap: "md",
1208
+ fields: [
1209
+ { name: "name", label: "Name", icon: "tag", variant: "h4" },
1210
+ { name: "status", label: "Status", icon: "circle", variant: "badge" },
1211
+ { name: "count", label: "Count", icon: "hash", variant: "body", format: "number" }
1212
+ ],
1213
+ actions: [
1214
+ { label: "View", event: "VIEW", icon: "eye", variant: "ghost" }
1215
+ ]
1216
+ }
1217
+ ] }]
1218
+ ];
1219
+ var pollViewEffects = [
1220
+ ["render-ui", "main", { type: "stack", direction: "vertical", gap: "lg", children: [
1221
+ { type: "stack", direction: "horizontal", gap: "sm", children: [
1222
+ { type: "icon", name: "radio", size: "lg" },
1223
+ { type: "typography", variant: "h2", content: "Poll Monitor" }
1224
+ ] },
1225
+ { type: "divider" },
1226
+ {
1227
+ type: "data-grid",
1228
+ entity: "PollRecord",
1229
+ cols: 2,
1230
+ gap: "md",
1231
+ fields: [
1232
+ { name: "name", label: "Name", icon: "tag", variant: "h4" },
1233
+ { name: "status", label: "Status", icon: "circle", variant: "badge" },
1234
+ { name: "count", label: "Count", icon: "hash", variant: "body", format: "number" }
1235
+ ],
1236
+ actions: [
1237
+ { label: "View", event: "VIEW", icon: "eye", variant: "ghost" }
1238
+ ]
1239
+ }
1240
+ ] }]
1241
+ ];
468
1242
  var POLL_BEHAVIOR = {
469
1243
  name: "std-poll",
470
1244
  version: "1.0.0",
471
- description: "Periodic polling with start/stop control",
1245
+ description: "Polling monitor with start/stop/pause control",
1246
+ theme: ASYNC_THEME,
472
1247
  orbitals: [
473
1248
  {
474
1249
  name: "PollOrbital",
475
1250
  entity: {
476
- name: "PollState",
477
- persistence: "runtime",
1251
+ name: "PollRecord",
1252
+ persistence: "persistent",
1253
+ collection: "poll_records",
478
1254
  fields: [
479
1255
  { name: "id", type: "string", required: true },
480
- { name: "isPolling", type: "boolean", default: false },
481
- { name: "pollCount", type: "number", default: 0 },
482
- { name: "lastPollAt", type: "number", default: null },
483
- { name: "error", type: "object", default: null },
484
- { name: "intervalMs", type: "number", default: 5e3 },
485
- { name: "maxPolls", type: "number", default: null },
486
- { name: "stopOnError", type: "boolean", default: false }
1256
+ { name: "name", type: "string", default: "" },
1257
+ { name: "status", type: "string", default: "stopped" },
1258
+ { name: "count", type: "number", default: 0 }
487
1259
  ]
488
1260
  },
489
1261
  traits: [
490
1262
  {
491
- name: "Poll",
492
- linkedEntity: "PollState",
493
- category: "lifecycle",
1263
+ name: "PollManagement",
1264
+ linkedEntity: "PollRecord",
1265
+ category: "interaction",
494
1266
  stateMachine: {
495
1267
  states: [
496
- { name: "Stopped", isInitial: true },
497
- { name: "Polling" },
498
- { name: "Paused" }
1268
+ { name: "stopped", isInitial: true },
1269
+ { name: "polling" },
1270
+ { name: "paused" }
499
1271
  ],
500
1272
  events: [
501
- { key: "START", name: "Start" },
502
- { key: "STOP", name: "Stop" },
503
- { key: "PAUSE", name: "Pause" },
504
- { key: "RESUME", name: "Resume" },
505
- { key: "POLL_TICK", name: "Poll Tick" },
506
- { key: "POLL_SUCCESS", name: "Poll Success" },
507
- { key: "POLL_ERROR", name: "Poll Error" }
1273
+ { key: "INIT", name: "Initialize" },
1274
+ { key: "START", name: "Start Polling" },
1275
+ { key: "STOP", name: "Stop Polling" },
1276
+ { key: "PAUSE", name: "Pause Polling" },
1277
+ { key: "RESUME", name: "Resume Polling" },
1278
+ { key: "VIEW", name: "View", payloadSchema: [{ name: "id", type: "string", required: true }] }
508
1279
  ],
509
1280
  transitions: [
510
1281
  {
511
- from: "Stopped",
512
- to: "Polling",
513
- event: "START",
1282
+ from: "stopped",
1283
+ to: "stopped",
1284
+ event: "INIT",
514
1285
  effects: [
515
- ["set", "@entity.isPolling", true],
516
- ["set", "@entity.pollCount", 0],
517
- ["async/interval", "@entity.intervalMs", ["emit", "POLL_TICK"]]
1286
+ ["fetch", "PollRecord"],
1287
+ ...pollStoppedEffects
518
1288
  ]
519
1289
  },
520
1290
  {
521
- from: "Polling",
522
- to: "Polling",
523
- event: "POLL_TICK",
524
- guard: ["or", ["=", "@entity.maxPolls", null], ["<", "@entity.pollCount", "@entity.maxPolls"]],
525
- effects: [["set", "@entity.lastPollAt", ["time/now"]]]
526
- },
527
- {
528
- from: "Polling",
529
- to: "Polling",
530
- event: "POLL_SUCCESS",
1291
+ from: "stopped",
1292
+ to: "polling",
1293
+ event: "START",
531
1294
  effects: [
532
- ["set", "@entity.pollCount", ["+", "@entity.pollCount", 1]],
533
- ["set", "@entity.error", null]
1295
+ ["fetch", "PollRecord"],
1296
+ ["set", "@entity.status", "polling"],
1297
+ ["set", "@entity.count", 0],
1298
+ ...pollActiveEffects
534
1299
  ]
535
1300
  },
536
1301
  {
537
- from: "Polling",
538
- to: "Polling",
539
- event: "POLL_ERROR",
1302
+ from: "polling",
1303
+ to: "paused",
1304
+ event: "PAUSE",
540
1305
  effects: [
541
- ["set", "@entity.error", "@payload.error"],
542
- ["when", "@entity.stopOnError", ["emit", "STOP"]]
1306
+ ["fetch", "PollRecord"],
1307
+ ["set", "@entity.status", "paused"],
1308
+ ...pollPausedEffects
543
1309
  ]
544
1310
  },
545
1311
  {
546
- from: "Polling",
547
- to: "Paused",
548
- event: "PAUSE",
549
- effects: [["set", "@entity.isPolling", false]]
550
- },
551
- {
552
- from: "Paused",
553
- to: "Polling",
1312
+ from: "paused",
1313
+ to: "polling",
554
1314
  event: "RESUME",
555
1315
  effects: [
556
- ["set", "@entity.isPolling", true],
557
- ["async/interval", "@entity.intervalMs", ["emit", "POLL_TICK"]]
1316
+ ["fetch", "PollRecord"],
1317
+ ["set", "@entity.status", "polling"],
1318
+ ...pollActiveEffects
558
1319
  ]
559
1320
  },
560
1321
  {
561
- from: "Polling",
562
- to: "Stopped",
1322
+ from: "polling",
1323
+ to: "stopped",
563
1324
  event: "STOP",
564
- effects: [["set", "@entity.isPolling", false]]
1325
+ effects: [
1326
+ ["fetch", "PollRecord"],
1327
+ ["set", "@entity.status", "stopped"],
1328
+ ...pollStoppedEffects
1329
+ ]
565
1330
  },
566
1331
  {
567
- from: "Paused",
568
- to: "Stopped",
1332
+ from: "paused",
1333
+ to: "stopped",
569
1334
  event: "STOP",
570
- effects: [["set", "@entity.isPolling", false]]
571
- }
1335
+ effects: [
1336
+ ["fetch", "PollRecord"],
1337
+ ["set", "@entity.status", "stopped"],
1338
+ ...pollStoppedEffects
1339
+ ]
1340
+ },
1341
+ // VIEW self-transitions for each state
1342
+ { from: "stopped", to: "stopped", event: "VIEW", effects: [["fetch", "PollRecord"], ...pollViewEffects] },
1343
+ { from: "polling", to: "polling", event: "VIEW", effects: [["fetch", "PollRecord"], ...pollViewEffects] },
1344
+ { from: "paused", to: "paused", event: "VIEW", effects: [["fetch", "PollRecord"], ...pollViewEffects] }
572
1345
  ]
573
1346
  }
574
1347
  }
575
1348
  ],
576
- pages: []
1349
+ pages: [{ name: "PollMonitorPage", path: "/poll-monitor", isInitial: true, traits: [{ ref: "PollManagement" }] }]
577
1350
  }
578
1351
  ]
579
1352
  };