@gravito/flux 1.0.0-beta.1 → 1.0.0-beta.3

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 (69) hide show
  1. package/README.zh-TW.md +409 -1
  2. package/assets/flux-branching.svg +84 -0
  3. package/bin/flux.js +96 -0
  4. package/dev/viewer/app.js +131 -0
  5. package/dev/viewer/index.html +52 -0
  6. package/dev/viewer/styles.css +163 -0
  7. package/dist/bun.cjs +7 -0
  8. package/dist/bun.cjs.map +1 -0
  9. package/dist/{storage/BunSQLiteStorage.d.ts → bun.d.cts} +8 -5
  10. package/dist/bun.d.ts +72 -5
  11. package/dist/bun.js +2 -2
  12. package/dist/bun.js.map +1 -0
  13. package/dist/chunk-J37UUMLM.js +858 -0
  14. package/dist/chunk-J37UUMLM.js.map +1 -0
  15. package/dist/chunk-RPECIW7O.cjs +858 -0
  16. package/dist/chunk-RPECIW7O.cjs.map +1 -0
  17. package/dist/chunk-SJSPR4ZU.cjs +173 -0
  18. package/dist/chunk-SJSPR4ZU.cjs.map +1 -0
  19. package/dist/{chunk-qjdtqchy.js → chunk-ZAMVC732.js} +35 -7
  20. package/dist/chunk-ZAMVC732.js.map +1 -0
  21. package/dist/index.cjs +121 -0
  22. package/dist/index.cjs.map +1 -0
  23. package/dist/index.d.cts +43 -0
  24. package/dist/index.d.ts +40 -35
  25. package/dist/index.js +102 -460
  26. package/dist/index.js.map +1 -0
  27. package/dist/index.node.cjs +28 -0
  28. package/dist/index.node.cjs.map +1 -0
  29. package/dist/index.node.d.cts +499 -0
  30. package/dist/index.node.d.ts +494 -13
  31. package/dist/index.node.js +28 -0
  32. package/dist/index.node.js.map +1 -0
  33. package/dist/{types.d.ts → types-DvVHBmP6.d.cts} +59 -18
  34. package/dist/types-DvVHBmP6.d.ts +235 -0
  35. package/package.json +32 -21
  36. package/dist/builder/WorkflowBuilder.d.ts +0 -96
  37. package/dist/builder/WorkflowBuilder.d.ts.map +0 -1
  38. package/dist/builder/index.d.ts +0 -2
  39. package/dist/builder/index.d.ts.map +0 -1
  40. package/dist/bun.d.ts.map +0 -1
  41. package/dist/core/ContextManager.d.ts +0 -40
  42. package/dist/core/ContextManager.d.ts.map +0 -1
  43. package/dist/core/StateMachine.d.ts +0 -43
  44. package/dist/core/StateMachine.d.ts.map +0 -1
  45. package/dist/core/StepExecutor.d.ts +0 -34
  46. package/dist/core/StepExecutor.d.ts.map +0 -1
  47. package/dist/core/index.d.ts +0 -4
  48. package/dist/core/index.d.ts.map +0 -1
  49. package/dist/engine/FluxEngine.d.ts +0 -66
  50. package/dist/engine/FluxEngine.d.ts.map +0 -1
  51. package/dist/engine/index.d.ts +0 -2
  52. package/dist/engine/index.d.ts.map +0 -1
  53. package/dist/index.d.ts.map +0 -1
  54. package/dist/index.node.d.ts.map +0 -1
  55. package/dist/logger/FluxLogger.d.ts +0 -40
  56. package/dist/logger/FluxLogger.d.ts.map +0 -1
  57. package/dist/logger/index.d.ts +0 -2
  58. package/dist/logger/index.d.ts.map +0 -1
  59. package/dist/node/index.mjs +0 -619
  60. package/dist/orbit/OrbitFlux.d.ts +0 -107
  61. package/dist/orbit/OrbitFlux.d.ts.map +0 -1
  62. package/dist/orbit/index.d.ts +0 -2
  63. package/dist/orbit/index.d.ts.map +0 -1
  64. package/dist/storage/BunSQLiteStorage.d.ts.map +0 -1
  65. package/dist/storage/MemoryStorage.d.ts +0 -28
  66. package/dist/storage/MemoryStorage.d.ts.map +0 -1
  67. package/dist/storage/index.d.ts +0 -3
  68. package/dist/storage/index.d.ts.map +0 -1
  69. package/dist/types.d.ts.map +0 -1
@@ -0,0 +1,131 @@
1
+ const pathEl = document.getElementById('tracePath')
2
+ const updateEl = document.getElementById('lastUpdate')
3
+ const pathElContainer = document.getElementById('path')
4
+ const statusEl = document.getElementById('status')
5
+ const eventsEl = document.getElementById('events')
6
+
7
+ const state = {
8
+ events: [],
9
+ lastHash: '',
10
+ }
11
+
12
+ const formatTime = (ts) => new Date(ts).toLocaleTimeString()
13
+
14
+ const parseNdjson = (text) =>
15
+ text
16
+ .split('\n')
17
+ .map((line) => line.trim())
18
+ .filter(Boolean)
19
+ .map((line) => {
20
+ try {
21
+ return JSON.parse(line)
22
+ } catch {
23
+ return null
24
+ }
25
+ })
26
+ .filter(Boolean)
27
+
28
+ const hashText = (text) => {
29
+ let hash = 0
30
+ for (let i = 0; i < text.length; i += 1) {
31
+ hash = (hash << 5) - hash + text.charCodeAt(i)
32
+ hash |= 0
33
+ }
34
+ return String(hash)
35
+ }
36
+
37
+ const renderPath = (events) => {
38
+ const steps = []
39
+ const seen = new Set()
40
+ for (const event of events) {
41
+ if (event.stepName && event.type.startsWith('step:')) {
42
+ if (!seen.has(event.stepName)) {
43
+ seen.add(event.stepName)
44
+ steps.push(event.stepName)
45
+ }
46
+ }
47
+ }
48
+
49
+ if (!steps.length) {
50
+ pathElContainer.innerHTML = '<div class="empty">No execution data yet.</div>'
51
+ return
52
+ }
53
+
54
+ pathElContainer.innerHTML = steps
55
+ .map((step, index) => {
56
+ const node = `<span class="node">${step}</span>`
57
+ const arrow = index < steps.length - 1 ? '<span class="arrow">-&gt;</span>' : ''
58
+ return `${node}${arrow}`
59
+ })
60
+ .join('')
61
+ }
62
+
63
+ const renderStatus = (events) => {
64
+ if (!events.length) {
65
+ statusEl.innerHTML = '<div class="empty">No trace events.</div>'
66
+ return
67
+ }
68
+
69
+ const lastWorkflow = [...events]
70
+ .reverse()
71
+ .find((event) => event.type.startsWith('workflow:'))
72
+
73
+ const status = lastWorkflow?.status ?? 'unknown'
74
+ const badgeClass = status === 'completed' ? 'ok' : status === 'failed' ? 'fail' : ''
75
+
76
+ statusEl.innerHTML = `
77
+ <div>Workflow: <span class="badge ${badgeClass}">${status}</span></div>
78
+ <div>Workflow ID: ${lastWorkflow?.workflowId ?? '-'}</div>
79
+ <div>Workflow Name: ${lastWorkflow?.workflowName ?? '-'}</div>
80
+ <div>Duration: ${lastWorkflow?.duration ? `${lastWorkflow.duration}ms` : '-'}</div>
81
+ `
82
+ }
83
+
84
+ const renderEvents = (events) => {
85
+ if (!events.length) {
86
+ eventsEl.innerHTML = '<tr><td colspan="6" class="empty">No events yet.</td></tr>'
87
+ return
88
+ }
89
+
90
+ eventsEl.innerHTML = events
91
+ .slice()
92
+ .reverse()
93
+ .map((event) => {
94
+ const retry =
95
+ typeof event.retries === 'number'
96
+ ? `${event.retries}${event.maxRetries ? `/${event.maxRetries}` : ''}`
97
+ : '-'
98
+ const duration = event.duration ? `${event.duration}ms` : '-'
99
+ const msg = event.error ?? ''
100
+ return `
101
+ <tr>
102
+ <td>${formatTime(event.timestamp)}</td>
103
+ <td>${event.type}</td>
104
+ <td>${event.stepName ?? '-'}</td>
105
+ <td>${retry}</td>
106
+ <td>${duration}</td>
107
+ <td>${msg}</td>
108
+ </tr>
109
+ `
110
+ })
111
+ .join('')
112
+ }
113
+
114
+ const refresh = async () => {
115
+ const res = await fetch('/trace', { cache: 'no-store' })
116
+ const text = await res.text()
117
+ const hash = hashText(text)
118
+ if (hash === state.lastHash) return
119
+
120
+ state.lastHash = hash
121
+ state.events = parseNdjson(text)
122
+ pathEl.textContent = 'Trace: /trace'
123
+ updateEl.textContent = `Updated: ${new Date().toLocaleTimeString()}`
124
+
125
+ renderPath(state.events)
126
+ renderStatus(state.events)
127
+ renderEvents(state.events)
128
+ }
129
+
130
+ refresh()
131
+ setInterval(refresh, 1500)
@@ -0,0 +1,52 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
6
+ <title>Flux Dev Viewer</title>
7
+ <link rel="stylesheet" href="/styles.css" />
8
+ </head>
9
+ <body>
10
+ <header class="topbar">
11
+ <div>
12
+ <h1>Flux Dev Viewer</h1>
13
+ <p class="subtitle">Local workflow trace explorer</p>
14
+ </div>
15
+ <div class="meta">
16
+ <div id="tracePath">Trace: -</div>
17
+ <div id="lastUpdate">Updated: -</div>
18
+ </div>
19
+ </header>
20
+
21
+ <main class="grid">
22
+ <section class="card">
23
+ <h2>Execution Path</h2>
24
+ <div id="path" class="path"></div>
25
+ </section>
26
+
27
+ <section class="card">
28
+ <h2>Status</h2>
29
+ <div id="status" class="status"></div>
30
+ </section>
31
+
32
+ <section class="card full">
33
+ <h2>Timeline</h2>
34
+ <table class="timeline">
35
+ <thead>
36
+ <tr>
37
+ <th>Time</th>
38
+ <th>Event</th>
39
+ <th>Step</th>
40
+ <th>Retry</th>
41
+ <th>Duration</th>
42
+ <th>Message</th>
43
+ </tr>
44
+ </thead>
45
+ <tbody id="events"></tbody>
46
+ </table>
47
+ </section>
48
+ </main>
49
+
50
+ <script src="/app.js"></script>
51
+ </body>
52
+ </html>
@@ -0,0 +1,163 @@
1
+ * {
2
+ box-sizing: border-box;
3
+ }
4
+
5
+ body {
6
+ margin: 0;
7
+ font-family: ui-sans-serif, system-ui, -apple-system, sans-serif;
8
+ background: #0c0f14;
9
+ color: #e6eaf2;
10
+ }
11
+
12
+ .topbar {
13
+ display: flex;
14
+ justify-content: space-between;
15
+ align-items: center;
16
+ padding: 20px 32px;
17
+ border-bottom: 1px solid #1d2330;
18
+ background: linear-gradient(120deg, #111826, #0f1420);
19
+ }
20
+
21
+ .topbar h1 {
22
+ margin: 0 0 6px;
23
+ font-size: 20px;
24
+ letter-spacing: 0.04em;
25
+ }
26
+
27
+ .subtitle {
28
+ margin: 0;
29
+ color: #93a0b4;
30
+ font-size: 13px;
31
+ }
32
+
33
+ .meta {
34
+ text-align: right;
35
+ font-size: 12px;
36
+ color: #9aa6ba;
37
+ line-height: 1.6;
38
+ }
39
+
40
+ .grid {
41
+ display: grid;
42
+ gap: 18px;
43
+ padding: 24px 32px 40px;
44
+ grid-template-columns: repeat(2, minmax(0, 1fr));
45
+ }
46
+
47
+ .card {
48
+ background: #131a26;
49
+ border: 1px solid #1d2330;
50
+ border-radius: 14px;
51
+ padding: 18px 18px 12px;
52
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.25);
53
+ }
54
+
55
+ .card.full {
56
+ grid-column: 1 / -1;
57
+ }
58
+
59
+ .card h2 {
60
+ margin: 0 0 14px;
61
+ font-size: 14px;
62
+ color: #c7d1e6;
63
+ letter-spacing: 0.08em;
64
+ text-transform: uppercase;
65
+ }
66
+
67
+ .path {
68
+ display: flex;
69
+ flex-wrap: wrap;
70
+ gap: 10px;
71
+ align-items: center;
72
+ }
73
+
74
+ .node {
75
+ padding: 8px 12px;
76
+ border-radius: 999px;
77
+ background: #1a2333;
78
+ border: 1px solid #2b3a52;
79
+ font-size: 12px;
80
+ color: #d6deec;
81
+ }
82
+
83
+ .arrow {
84
+ color: #7c8da7;
85
+ font-size: 14px;
86
+ }
87
+
88
+ .status {
89
+ display: grid;
90
+ gap: 8px;
91
+ font-size: 13px;
92
+ color: #b9c5d9;
93
+ }
94
+
95
+ .badge {
96
+ display: inline-block;
97
+ padding: 2px 8px;
98
+ border-radius: 999px;
99
+ font-size: 11px;
100
+ text-transform: uppercase;
101
+ letter-spacing: 0.08em;
102
+ background: #1e2532;
103
+ color: #9db0cc;
104
+ border: 1px solid #2b364a;
105
+ }
106
+
107
+ .badge.ok {
108
+ background: rgba(34, 197, 94, 0.15);
109
+ color: #7ee4a6;
110
+ border-color: rgba(34, 197, 94, 0.3);
111
+ }
112
+
113
+ .badge.fail {
114
+ background: rgba(248, 113, 113, 0.15);
115
+ color: #fca5a5;
116
+ border-color: rgba(248, 113, 113, 0.3);
117
+ }
118
+
119
+ .timeline {
120
+ width: 100%;
121
+ border-collapse: collapse;
122
+ font-size: 12px;
123
+ }
124
+
125
+ .timeline th,
126
+ .timeline td {
127
+ padding: 10px 8px;
128
+ border-bottom: 1px solid #1d2330;
129
+ text-align: left;
130
+ }
131
+
132
+ .timeline th {
133
+ color: #91a0b7;
134
+ font-weight: 600;
135
+ font-size: 11px;
136
+ text-transform: uppercase;
137
+ letter-spacing: 0.08em;
138
+ }
139
+
140
+ .timeline tr:last-child td {
141
+ border-bottom: none;
142
+ }
143
+
144
+ .empty {
145
+ color: #7f8ba3;
146
+ font-size: 12px;
147
+ padding: 10px 0;
148
+ }
149
+
150
+ @media (max-width: 900px) {
151
+ .grid {
152
+ grid-template-columns: 1fr;
153
+ }
154
+ .meta {
155
+ text-align: left;
156
+ margin-top: 10px;
157
+ }
158
+ .topbar {
159
+ flex-direction: column;
160
+ align-items: flex-start;
161
+ gap: 12px;
162
+ }
163
+ }
package/dist/bun.cjs ADDED
@@ -0,0 +1,7 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+ var _chunkSJSPR4ZUcjs = require('./chunk-SJSPR4ZU.cjs');
4
+
5
+
6
+ exports.BunSQLiteStorage = _chunkSJSPR4ZUcjs.BunSQLiteStorage;
7
+ //# sourceMappingURL=bun.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/carl/Dev/Carl/gravito-core/packages/flux/dist/bun.cjs"],"names":[],"mappings":"AAAA;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,8DAAC","file":"/Users/carl/Dev/Carl/gravito-core/packages/flux/dist/bun.cjs"}
@@ -1,3 +1,6 @@
1
+ import { Database } from 'bun:sqlite';
2
+ import { n as WorkflowStorage, l as WorkflowState, k as WorkflowFilter } from './types-DvVHBmP6.cjs';
3
+
1
4
  /**
2
5
  * @fileoverview Bun SQLite Storage Adapter
3
6
  *
@@ -5,12 +8,11 @@
5
8
  *
6
9
  * @module @gravito/flux/storage
7
10
  */
8
- import { Database } from 'bun:sqlite';
9
- import type { WorkflowFilter, WorkflowState, WorkflowStorage } from '../types';
11
+
10
12
  /**
11
13
  * SQLite Storage Options
12
14
  */
13
- export interface BunSQLiteStorageOptions {
15
+ interface BunSQLiteStorageOptions {
14
16
  /** Database file path (default: ':memory:') */
15
17
  path?: string;
16
18
  /** Table name (default: 'flux_workflows') */
@@ -28,7 +30,7 @@ export interface BunSQLiteStorageOptions {
28
30
  * })
29
31
  * ```
30
32
  */
31
- export declare class BunSQLiteStorage implements WorkflowStorage {
33
+ declare class BunSQLiteStorage implements WorkflowStorage {
32
34
  private db;
33
35
  private tableName;
34
36
  private initialized;
@@ -70,4 +72,5 @@ export declare class BunSQLiteStorage implements WorkflowStorage {
70
72
  */
71
73
  vacuum(): void;
72
74
  }
73
- //# sourceMappingURL=BunSQLiteStorage.d.ts.map
75
+
76
+ export { BunSQLiteStorage, type BunSQLiteStorageOptions };
package/dist/bun.d.ts CHANGED
@@ -1,9 +1,76 @@
1
+ import { Database } from 'bun:sqlite';
2
+ import { n as WorkflowStorage, l as WorkflowState, k as WorkflowFilter } from './types-DvVHBmP6.js';
3
+
1
4
  /**
2
- * @fileoverview Bun-specific exports
5
+ * @fileoverview Bun SQLite Storage Adapter
3
6
  *
4
- * This entry exports Bun-optimized components.
7
+ * High-performance storage using Bun's built-in SQLite.
5
8
  *
6
- * @module @gravito/flux/bun
9
+ * @module @gravito/flux/storage
7
10
  */
8
- export { BunSQLiteStorage, type BunSQLiteStorageOptions } from './storage/BunSQLiteStorage';
9
- //# sourceMappingURL=bun.d.ts.map
11
+
12
+ /**
13
+ * SQLite Storage Options
14
+ */
15
+ interface BunSQLiteStorageOptions {
16
+ /** Database file path (default: ':memory:') */
17
+ path?: string;
18
+ /** Table name (default: 'flux_workflows') */
19
+ tableName?: string;
20
+ }
21
+ /**
22
+ * Bun SQLite Storage
23
+ *
24
+ * High-performance storage adapter using Bun's built-in SQLite.
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * const engine = new FluxEngine({
29
+ * storage: new BunSQLiteStorage({ path: './data/flux.db' })
30
+ * })
31
+ * ```
32
+ */
33
+ declare class BunSQLiteStorage implements WorkflowStorage {
34
+ private db;
35
+ private tableName;
36
+ private initialized;
37
+ constructor(options?: BunSQLiteStorageOptions);
38
+ /**
39
+ * Initialize storage (create tables)
40
+ */
41
+ init(): Promise<void>;
42
+ /**
43
+ * Save workflow state
44
+ */
45
+ save(state: WorkflowState): Promise<void>;
46
+ /**
47
+ * Load workflow state by ID
48
+ */
49
+ load(id: string): Promise<WorkflowState | null>;
50
+ /**
51
+ * List workflow states with optional filter
52
+ */
53
+ list(filter?: WorkflowFilter): Promise<WorkflowState[]>;
54
+ /**
55
+ * Delete workflow state
56
+ */
57
+ delete(id: string): Promise<void>;
58
+ /**
59
+ * Close database connection
60
+ */
61
+ close(): Promise<void>;
62
+ /**
63
+ * Convert SQLite row to WorkflowState
64
+ */
65
+ private rowToState;
66
+ /**
67
+ * Get raw database (for advanced usage)
68
+ */
69
+ getDatabase(): Database;
70
+ /**
71
+ * Run a vacuum to optimize database
72
+ */
73
+ vacuum(): void;
74
+ }
75
+
76
+ export { BunSQLiteStorage, type BunSQLiteStorageOptions };
package/dist/bun.js CHANGED
@@ -1,7 +1,7 @@
1
- // @bun
2
1
  import {
3
2
  BunSQLiteStorage
4
- } from "./chunk-qjdtqchy.js";
3
+ } from "./chunk-ZAMVC732.js";
5
4
  export {
6
5
  BunSQLiteStorage
7
6
  };
7
+ //# sourceMappingURL=bun.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}