@tuongaz/seeflow 0.1.26 → 0.1.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/seeflow +0 -0
- package/bin/seeflow-mcp +0 -0
- package/dist/web/assets/{index-BMaMEi2a.js → index--9KvdiJU.js} +1584 -1584
- package/dist/web/assets/index-XIY68z9O.css +1 -0
- package/dist/web/assets/{index.es-M1iBDKG6.js → index.es-CehYgUiq.js} +1 -1
- package/dist/web/assets/{jspdf.es.min-xZpq8bcn.js → jspdf.es.min-CaFlbpn0.js} +3 -3
- package/dist/web/index.html +2 -2
- package/examples/ecommerce-platform/.seeflow/{seeflow.json → architecture.json} +22 -77
- package/examples/ecommerce-platform/.seeflow/details/api-gateway.md +14 -0
- package/examples/ecommerce-platform/.seeflow/details/auth-service.md +9 -0
- package/examples/ecommerce-platform/.seeflow/details/cart-service.md +10 -0
- package/examples/ecommerce-platform/.seeflow/details/notification-service.md +13 -0
- package/examples/ecommerce-platform/.seeflow/details/order-service.md +16 -0
- package/examples/ecommerce-platform/.seeflow/details/payment-service.md +16 -0
- package/examples/ecommerce-platform/.seeflow/details/product-service.md +10 -0
- package/examples/ecommerce-platform/.seeflow/scripts/platform-health.html +42 -0
- package/examples/ecommerce-platform/.seeflow/style.json +98 -0
- package/examples/order-pipeline/.seeflow/architecture.json +93 -0
- package/examples/order-pipeline/.seeflow/details/fulfillment-service.md +21 -0
- package/examples/order-pipeline/.seeflow/details/inventory-service.md +23 -0
- package/examples/order-pipeline/.seeflow/details/payment-service.md +23 -0
- package/examples/order-pipeline/.seeflow/details/post-orders.md +19 -0
- package/examples/order-pipeline/.seeflow/scripts/play.ts +2 -2
- package/examples/order-pipeline/.seeflow/style.json +42 -0
- package/package.json +4 -2
- package/public/runtime/tailwind.js +931 -24378
- package/src/api.ts +118 -118
- package/src/cli.ts +13 -13
- package/src/demo.ts +6 -6
- package/src/diagram.ts +4 -4
- package/src/events.ts +14 -14
- package/src/file-ref.ts +79 -0
- package/src/mcp.ts +117 -89
- package/src/merge.ts +190 -0
- package/src/operations.ts +415 -416
- package/src/proxy.ts +31 -31
- package/src/registry.ts +32 -20
- package/src/schema.ts +252 -8
- package/src/sdk-template.ts +2 -2
- package/src/sdk-writer.ts +2 -2
- package/src/server.ts +14 -7
- package/src/status-runner.ts +34 -38
- package/src/watcher.ts +165 -114
- package/dist/web/assets/index-BotEftAD.css +0 -1
- package/examples/order-pipeline/.seeflow/seeflow.json +0 -123
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<div class="h-full w-full p-3 font-sans text-slate-200">
|
|
2
|
+
<div class="mb-2 flex items-center justify-between">
|
|
3
|
+
<div class="flex items-center gap-2">
|
|
4
|
+
<span class="relative flex h-2 w-2">
|
|
5
|
+
<span class="absolute inline-flex h-full w-full animate-ping rounded-full bg-emerald-400 opacity-75"></span>
|
|
6
|
+
<span class="relative inline-flex h-2 w-2 rounded-full bg-emerald-500"></span>
|
|
7
|
+
</span>
|
|
8
|
+
<span class="text-[10px] font-semibold tracking-widest text-emerald-400 uppercase">Platform Health</span>
|
|
9
|
+
</div>
|
|
10
|
+
<span class="text-[10px] text-slate-400">live · 5s</span>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="grid grid-cols-2 gap-2">
|
|
13
|
+
<div class="rounded border border-emerald-500/30 bg-slate-900/40 p-2">
|
|
14
|
+
<div class="text-[10px] tracking-wide text-slate-400 uppercase">Orders / sec</div>
|
|
15
|
+
<div class="mt-1 flex items-baseline justify-between">
|
|
16
|
+
<span class="text-lg font-semibold text-slate-100">142</span>
|
|
17
|
+
<span class="rounded bg-emerald-500/15 px-1.5 py-0.5 text-[10px] font-medium text-emerald-400">↑ 12%</span>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
<div class="rounded border border-emerald-500/30 bg-slate-900/40 p-2">
|
|
21
|
+
<div class="text-[10px] tracking-wide text-slate-400 uppercase">Success rate</div>
|
|
22
|
+
<div class="mt-1 flex items-baseline justify-between">
|
|
23
|
+
<span class="text-lg font-semibold text-slate-100">99.4%</span>
|
|
24
|
+
<span class="rounded bg-emerald-500/15 px-1.5 py-0.5 text-[10px] font-medium text-emerald-400">✓ ok</span>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
<div class="rounded border border-amber-500/30 bg-slate-900/40 p-2">
|
|
28
|
+
<div class="text-[10px] tracking-wide text-slate-400 uppercase">p95 latency</div>
|
|
29
|
+
<div class="mt-1 flex items-baseline justify-between">
|
|
30
|
+
<span class="text-lg font-semibold text-slate-100">87 ms</span>
|
|
31
|
+
<span class="rounded bg-amber-500/15 px-1.5 py-0.5 text-[10px] font-medium text-amber-400">warn</span>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
<div class="rounded border border-slate-500/30 bg-slate-900/40 p-2">
|
|
35
|
+
<div class="text-[10px] tracking-wide text-slate-400 uppercase">Active carts</div>
|
|
36
|
+
<div class="mt-1 flex items-baseline justify-between">
|
|
37
|
+
<span class="text-lg font-semibold text-slate-100">3,210</span>
|
|
38
|
+
<span class="rounded bg-slate-500/20 px-1.5 py-0.5 text-[10px] font-medium text-slate-300">live</span>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
{
|
|
2
|
+
"nodes": {
|
|
3
|
+
"client": {
|
|
4
|
+
"position": {
|
|
5
|
+
"x": 80,
|
|
6
|
+
"y": 215.5
|
|
7
|
+
},
|
|
8
|
+
"fontSize": 15,
|
|
9
|
+
"borderColor": "green",
|
|
10
|
+
"borderSize": 1
|
|
11
|
+
},
|
|
12
|
+
"api-gateway": {
|
|
13
|
+
"position": {
|
|
14
|
+
"x": 320,
|
|
15
|
+
"y": 227
|
|
16
|
+
},
|
|
17
|
+
"fontSize": 15,
|
|
18
|
+
"borderColor": "green",
|
|
19
|
+
"borderSize": 1
|
|
20
|
+
},
|
|
21
|
+
"auth-service": {
|
|
22
|
+
"position": {
|
|
23
|
+
"x": 660,
|
|
24
|
+
"y": 50
|
|
25
|
+
},
|
|
26
|
+
"fontSize": 15,
|
|
27
|
+
"borderColor": "green",
|
|
28
|
+
"borderSize": 1
|
|
29
|
+
},
|
|
30
|
+
"product-service": {
|
|
31
|
+
"position": {
|
|
32
|
+
"x": 660,
|
|
33
|
+
"y": 218
|
|
34
|
+
},
|
|
35
|
+
"fontSize": 15,
|
|
36
|
+
"borderColor": "green",
|
|
37
|
+
"borderSize": 1
|
|
38
|
+
},
|
|
39
|
+
"cart-service": {
|
|
40
|
+
"position": {
|
|
41
|
+
"x": 660,
|
|
42
|
+
"y": 413
|
|
43
|
+
},
|
|
44
|
+
"fontSize": 15,
|
|
45
|
+
"borderColor": "green",
|
|
46
|
+
"borderSize": 1
|
|
47
|
+
},
|
|
48
|
+
"order-service": {
|
|
49
|
+
"position": {
|
|
50
|
+
"x": 1000,
|
|
51
|
+
"y": 413
|
|
52
|
+
},
|
|
53
|
+
"fontSize": 15,
|
|
54
|
+
"borderColor": "green",
|
|
55
|
+
"borderSize": 1
|
|
56
|
+
},
|
|
57
|
+
"payment-service": {
|
|
58
|
+
"position": {
|
|
59
|
+
"x": 1340,
|
|
60
|
+
"y": 349
|
|
61
|
+
},
|
|
62
|
+
"fontSize": 15,
|
|
63
|
+
"borderColor": "green",
|
|
64
|
+
"borderSize": 1
|
|
65
|
+
},
|
|
66
|
+
"notification-service": {
|
|
67
|
+
"position": {
|
|
68
|
+
"x": 1680,
|
|
69
|
+
"y": 339
|
|
70
|
+
},
|
|
71
|
+
"fontSize": 15,
|
|
72
|
+
"borderColor": "green",
|
|
73
|
+
"borderSize": 1
|
|
74
|
+
},
|
|
75
|
+
"postgresql": {
|
|
76
|
+
"position": {
|
|
77
|
+
"x": 1720,
|
|
78
|
+
"y": 507
|
|
79
|
+
},
|
|
80
|
+
"fontSize": 15,
|
|
81
|
+
"borderColor": "green",
|
|
82
|
+
"borderSize": 1
|
|
83
|
+
},
|
|
84
|
+
"platform-health": {
|
|
85
|
+
"position": {
|
|
86
|
+
"x": 1340,
|
|
87
|
+
"y": 50
|
|
88
|
+
},
|
|
89
|
+
"width": 380,
|
|
90
|
+
"height": 220,
|
|
91
|
+
"backgroundColor": "slate",
|
|
92
|
+
"borderColor": "green",
|
|
93
|
+
"borderSize": 1,
|
|
94
|
+
"cornerRadius": 8,
|
|
95
|
+
"autoSize": false
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 2,
|
|
3
|
+
"name": "Order Pipeline",
|
|
4
|
+
"nodes": [
|
|
5
|
+
{
|
|
6
|
+
"id": "post-orders",
|
|
7
|
+
"type": "playNode",
|
|
8
|
+
"data": {
|
|
9
|
+
"name": "POST /orders",
|
|
10
|
+
"kind": "service",
|
|
11
|
+
"stateSource": {
|
|
12
|
+
"kind": "request"
|
|
13
|
+
},
|
|
14
|
+
"description": "Creates order, kicks off the pipeline.",
|
|
15
|
+
"detail": "file://details/post-orders.md",
|
|
16
|
+
"playAction": {
|
|
17
|
+
"kind": "script",
|
|
18
|
+
"interpreter": "bun",
|
|
19
|
+
"args": [
|
|
20
|
+
"run"
|
|
21
|
+
],
|
|
22
|
+
"scriptPath": "scripts/play.ts"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"id": "inventory-service",
|
|
28
|
+
"type": "stateNode",
|
|
29
|
+
"data": {
|
|
30
|
+
"name": "Inventory Service",
|
|
31
|
+
"kind": "worker",
|
|
32
|
+
"stateSource": {
|
|
33
|
+
"kind": "event"
|
|
34
|
+
},
|
|
35
|
+
"description": "Reserves stock.",
|
|
36
|
+
"detail": "file://details/inventory-service.md",
|
|
37
|
+
"icon": "a-arrow-down-icon"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"id": "payment-service",
|
|
42
|
+
"type": "stateNode",
|
|
43
|
+
"data": {
|
|
44
|
+
"name": "Payment Service",
|
|
45
|
+
"kind": "worker",
|
|
46
|
+
"stateSource": {
|
|
47
|
+
"kind": "event"
|
|
48
|
+
},
|
|
49
|
+
"description": "Charges card.",
|
|
50
|
+
"detail": "file://details/payment-service.md"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"id": "fulfillment-service",
|
|
55
|
+
"type": "stateNode",
|
|
56
|
+
"data": {
|
|
57
|
+
"name": "Fulfillment Service",
|
|
58
|
+
"kind": "worker",
|
|
59
|
+
"stateSource": {
|
|
60
|
+
"kind": "event"
|
|
61
|
+
},
|
|
62
|
+
"description": "Enqueues shipment.",
|
|
63
|
+
"detail": "file://details/fulfillment-service.md"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
"connectors": [
|
|
68
|
+
{
|
|
69
|
+
"id": "c1",
|
|
70
|
+
"source": "post-orders",
|
|
71
|
+
"target": "inventory-service",
|
|
72
|
+
"kind": "event",
|
|
73
|
+
"eventName": "order.created",
|
|
74
|
+
"label": "order.created"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"id": "c2",
|
|
78
|
+
"source": "inventory-service",
|
|
79
|
+
"target": "payment-service",
|
|
80
|
+
"kind": "event",
|
|
81
|
+
"eventName": "stock.reserved",
|
|
82
|
+
"label": "stock.reserved"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"id": "c3",
|
|
86
|
+
"source": "payment-service",
|
|
87
|
+
"target": "fulfillment-service",
|
|
88
|
+
"kind": "event",
|
|
89
|
+
"eventName": "payment.captured",
|
|
90
|
+
"label": "payment.captured"
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
## Fulfillment Service
|
|
2
|
+
|
|
3
|
+
Listens for `payment.captured` and enqueues a shipment job for the warehouse to pick, pack, and dispatch the order. Assigns a tracking ID and notifies the customer.
|
|
4
|
+
|
|
5
|
+
### Triggered by
|
|
6
|
+
- `payment.captured`
|
|
7
|
+
|
|
8
|
+
### Logic
|
|
9
|
+
1. Convert the stock reservation into a pick list
|
|
10
|
+
2. Assign a carrier and service level
|
|
11
|
+
3. Generate a shipment ID and tracking number
|
|
12
|
+
4. Push the job to the warehouse queue
|
|
13
|
+
5. Send dispatch confirmation to the customer
|
|
14
|
+
|
|
15
|
+
### Payload
|
|
16
|
+
```json
|
|
17
|
+
{
|
|
18
|
+
"shipmentId": "shp_1234567890",
|
|
19
|
+
"orderId": "ord_1234567890"
|
|
20
|
+
}
|
|
21
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
## Inventory Service
|
|
2
|
+
|
|
3
|
+
Listens for `order.created` and attempts to reserve the requested stock in the warehouse. Checks available quantity, places a hold on the items, and records the warehouse location.
|
|
4
|
+
|
|
5
|
+
### Triggered by
|
|
6
|
+
- `order.created`
|
|
7
|
+
|
|
8
|
+
### Logic
|
|
9
|
+
1. Look up each SKU in the warehouse
|
|
10
|
+
2. Verify sufficient quantity is available
|
|
11
|
+
3. Place a reservation hold
|
|
12
|
+
4. Record the fulfilling warehouse ID
|
|
13
|
+
|
|
14
|
+
### Emits
|
|
15
|
+
- `stock.reserved` → Payment Service
|
|
16
|
+
|
|
17
|
+
### Payload
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"reserved": true,
|
|
21
|
+
"warehouseId": "wh_sydney"
|
|
22
|
+
}
|
|
23
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
## Payment Service
|
|
2
|
+
|
|
3
|
+
Listens for `stock.reserved` and charges the customer's card on file. Integrates with the payment gateway to authorise and capture funds for the order total.
|
|
4
|
+
|
|
5
|
+
### Triggered by
|
|
6
|
+
- `stock.reserved`
|
|
7
|
+
|
|
8
|
+
### Logic
|
|
9
|
+
1. Retrieve customer's saved payment method
|
|
10
|
+
2. Calculate order total (items + tax + shipping)
|
|
11
|
+
3. Authorise charge with payment gateway
|
|
12
|
+
4. Capture funds and record the charge ID
|
|
13
|
+
|
|
14
|
+
### Emits
|
|
15
|
+
- `payment.captured` → Fulfillment Service
|
|
16
|
+
|
|
17
|
+
### Payload
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"chargeId": "ch_1234567890",
|
|
21
|
+
"amount": 4999
|
|
22
|
+
}
|
|
23
|
+
```
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
## POST /orders
|
|
2
|
+
|
|
3
|
+
Entry point for the order pipeline. Accepts a customer ID and list of line items, creates an order record, and publishes the `order.created` event to kick off downstream processing.
|
|
4
|
+
|
|
5
|
+
### Request
|
|
6
|
+
```json
|
|
7
|
+
{
|
|
8
|
+
"customerId": "cust_123",
|
|
9
|
+
"items": [{ "sku": "WIDGET-1", "qty": 2 }]
|
|
10
|
+
}
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Response
|
|
14
|
+
```json
|
|
15
|
+
{ "orderId": "ord_1234567890" }
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### Emits
|
|
19
|
+
- `order.created` → Inventory Service
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const flowId = process.env.SEEFLOW_DEMO_ID ?? '';
|
|
2
2
|
const runId = process.env.SEEFLOW_RUN_ID ?? '';
|
|
3
3
|
const studioUrl = (process.env.SEEFLOW_STUDIO_URL ?? 'http://localhost:4321').replace(/\/+$/, '');
|
|
4
4
|
|
|
@@ -6,7 +6,7 @@ const res = await fetch(`${studioUrl}/demo/orders`, {
|
|
|
6
6
|
method: 'POST',
|
|
7
7
|
headers: {
|
|
8
8
|
'content-type': 'application/json',
|
|
9
|
-
'x-seeflow-demo-id':
|
|
9
|
+
'x-seeflow-demo-id': flowId,
|
|
10
10
|
'x-seeflow-run-id': runId,
|
|
11
11
|
},
|
|
12
12
|
body: JSON.stringify({ customerId: 'cust_123', items: [{ sku: 'WIDGET-1', qty: 2 }] }),
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"nodes": {
|
|
3
|
+
"post-orders": {
|
|
4
|
+
"position": {
|
|
5
|
+
"x": -181.96549037838943,
|
|
6
|
+
"y": 138.95644990042385
|
|
7
|
+
},
|
|
8
|
+
"fontSize": 15,
|
|
9
|
+
"borderColor": "green",
|
|
10
|
+
"borderSize": 1
|
|
11
|
+
},
|
|
12
|
+
"inventory-service": {
|
|
13
|
+
"position": {
|
|
14
|
+
"x": 66.21484197841792,
|
|
15
|
+
"y": -126.31035925520507
|
|
16
|
+
},
|
|
17
|
+
"width": 201,
|
|
18
|
+
"height": 118,
|
|
19
|
+
"fontSize": 15,
|
|
20
|
+
"borderColor": "green",
|
|
21
|
+
"borderSize": 1
|
|
22
|
+
},
|
|
23
|
+
"payment-service": {
|
|
24
|
+
"position": {
|
|
25
|
+
"x": 469.1422114437386,
|
|
26
|
+
"y": 206.48855752663212
|
|
27
|
+
},
|
|
28
|
+
"borderSize": 1,
|
|
29
|
+
"fontSize": 15,
|
|
30
|
+
"borderColor": "green"
|
|
31
|
+
},
|
|
32
|
+
"fulfillment-service": {
|
|
33
|
+
"position": {
|
|
34
|
+
"x": 747.51321046746,
|
|
35
|
+
"y": -37.78865629343234
|
|
36
|
+
},
|
|
37
|
+
"fontSize": 15,
|
|
38
|
+
"borderColor": "green",
|
|
39
|
+
"borderSize": 1
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tuongaz/seeflow",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.28",
|
|
4
4
|
"description": "Local studio that hosts file-defined demos as React Flow canvases wired to a running app via REST + SSE + Zod schema.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"seeflow",
|
|
@@ -38,7 +38,8 @@
|
|
|
38
38
|
"start": "bun run src/cli.ts start",
|
|
39
39
|
"test": "bun test",
|
|
40
40
|
"build:web": "cd ../web && bun run build",
|
|
41
|
-
"
|
|
41
|
+
"vendor:tailwind-runtime": "cp ../../node_modules/@tailwindcss/browser/dist/index.global.js public/runtime/tailwind.js",
|
|
42
|
+
"prepublishOnly": "bun run vendor:tailwind-runtime && bun run build:web && cp ../../README.md ./README.md"
|
|
42
43
|
},
|
|
43
44
|
"dependencies": {
|
|
44
45
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
@@ -48,6 +49,7 @@
|
|
|
48
49
|
"zod-to-json-schema": "^3.25.2"
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
|
52
|
+
"@tailwindcss/browser": "^4.3.0",
|
|
51
53
|
"@types/bun": "^1.1.14",
|
|
52
54
|
"@types/dagre": "^0.7.54",
|
|
53
55
|
"typescript": "^5.6.3"
|