Skip to content
Open

V2 #37

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules
dist
.git
.gitignore
Dockerfile
README.md
38 changes: 38 additions & 0 deletions .github/workflows/deploy-pages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Deploy to GitHub Pages

on:
push:
branches: [main, master]

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: "pages"
cancel-in-progress: false

jobs:
deploy:
runs-on: ubuntu-latest
environment: github-pages
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm

- run: npm ci

- run: npm run build

- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: dist

- name: Deploy to GitHub Pages
uses: actions/deploy-pages@v4
43 changes: 43 additions & 0 deletions .github/workflows/static.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Simple workflow for deploying static content to GitHub Pages
name: Deploy static content to Pages

on:
# Runs on pushes targeting the default branch
push:
branches: ["feature/functions"]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write

# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "pages"
cancel-in-progress: false

jobs:
# Single deploy job since we're just deploying
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Pages
uses: actions/configure-pages@v5
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
# Upload entire repository
path: 'src'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,4 @@ fabric.properties
# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
.idea/**/azureSettings.xml
/node_modules/
/dist/
54 changes: 54 additions & 0 deletions CONVENTIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# CodeWire – Branch & Commit Conventions

## Branch names

Use lowercase with a type prefix and short description:

- **Format:** `type/short-description` (e.g. `feature/node-registry`, `fix/context-menu`)
- **Allowed types:** `feature`, `fix`, `chore`, `docs`, `refactor`, `test`
- **Protected:** `master` and `main` are allowed as-is (no validation when pushing them)

**Examples:** `feature/visual-script-export`, `fix/compiler-edge-case`, `chore/deps`

---

## Commit messages

Use [Conventional Commits](https://www.conventionalcommits.org/):

- **Format:** `type(scope): short description` or `type: short description`
- **Types:** `feat`, `fix`, `chore`, `docs`, `refactor`, `style`, `test`, `perf`
- **Scope (optional):** e.g. `feat(nodes): add custom node type`
- **Length:** First line should be under 72 characters.

**Examples:**
- `feat: add node registry and definitions`
- `fix(compiler): handle empty script output`
- `chore: update dependencies`

---

## File and folder naming

- **Domain folders:** Use lowercase for domain group folders under `src/js/` (e.g. `core`, `nodes`, `registry`, `compiler`, `editor`, `ui`, `persistence`).
- **JavaScript files:** Use camelCase (e.g. `nodeFactory.js`, `contextMenu.js`, `stage.js`, `saveAndLoad.js`). Match the main export or feature name. Use `index.js` for module entry points.
- **App layout:** App source lives under `src/`: entry point `src/index.html`, styles and images in `src/`, app JavaScript in `src/js/` (domain folders as above), app entry point at `src/js/app.js`. Third-party libraries live in `src/vendor/` (e.g. `codemirror`, `jquery`, `konva`). Use lowercase for vendor subfolders to avoid case-sensitivity issues.
- **Avoid:** Typos in filenames; mixing casing for the same concept (e.g. `Dependencies` vs `dependencies`).

---

## Enforcing conventions

After cloning the repo, install the Git hooks once:

```bash
npm run setup:hooks
```

This installs:

- **commit-msg** – Rejects commits that don’t match the commit message format.
- **pre-push** – Rejects pushes if the current branch name doesn’t match the branch format (except when pushing `master` or `main`).

To skip hook checks in rare cases (e.g. emergency fix):
`git commit --no-verify` or `git push --no-verify` (use sparingly).
151 changes: 44 additions & 107 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,43 @@
![Forks](https://img.shields.io/github/forks/ayushk7/CodeWire?style=social)

<p align="center">
<img src="images/Code%20Wire%20Logo.png" alt="CodeWire" />
<img src="src/images/Code%20Wire%20Logo.png" alt="CodeWire" />
</p>

Try at https://ayushk7.github.io/CodeWire/

## Getting Started

```bash
npm install
```

### Local Development

```bash
npm run dev
```

Starts the Vite dev server at http://localhost:5173 with hot module replacement.

### Production Build

```bash
npm run build
```

Bundles and minifies everything into the `dist/` folder. To preview the production build locally:

```bash
npm run preview
```

### Deployment

The `dist/` folder is the deployable output — upload it to any static host (Netlify, Vercel, S3, etc.).

For GitHub Pages, the included workflow (`.github/workflows/deploy-pages.yml`) automatically builds and deploys on push to `main`/`master`.

CodeWire is a node based editor inspired by UE4 Blueprints which helps in better visualization of the code,
and faster scripting of complex and repetitive tasks.
It doesn't bind to any particular language.
Expand All @@ -28,130 +61,34 @@ Tutorial:

## Fibonacci Series

![Fibonacci Series](images/fib.png)
![Fibonacci Series](src/images/fib.png)

## HTTP REQUEST/Compiled Code

![HTTP REQUEST/Compiled Code](images/httpreq.png)
![HTTP REQUEST/Compiled Code](src/images/httpreq.png)



## Documentation

### Node Anatomy
![](images/Untitled%20Diagram.drawio.png)
![](src/images/Untitled%20Diagram.drawio.png)




### Adding New Nodes
1. Add the description of node in the [javascript/Nodes/nodes.js](javascript/Nodes/nodes.js)
```js
//description of the Print node
if (type == 'Print') {
nodeDescription.nodeTitle = 'Print';
nodeDescription.execIn = true;
nodeDescription.pinExecInId = null;
nodeDescription.execOut = {
execOut0: {
execOutTitle: null,
pinExecOutId: null,
outOrder: 0,
},
}
nodeDescription.inputs = {
input0: {
inputTitle: 'Value',
dataType: 'Data',
defValue: "'hello'",
pinInId: null,
}
}
// styling for the node
nodeDescription.color = 'Print';
nodeDescription.rows = 3;
nodeDescription.colums = 12;
}

//NOTE: this same object is furthur used for serialization and deserialization of the graph, so we have some meta info like pinIds
```
<b>But still the node is not available in the context menu</b>
![](images/print_ctx_menu.JPG)


2. To make this node available in the context menu you need to add it to the markup in [index.html](index.html)
```html
<div class="context-menu-items">Begin</div>
<div class="context-menu-items">Print</div> <!-- this is the title of the newly added node -->
<div class="context-menu-items">Alert</div>
<div class="context-menu-items">Confirm</div>
```
<b>Result</b>
![](images/print_node.JPG)

3. Now only thing left is to add the logic for the node, that is what code it should generate on it's turn
With the node registry, adding a new node only requires editing one file: [src/js/registry/nodeDefinitions.js](src/js/registry/nodeDefinitions.js).

For this you need add the logic in [VisualScriptToJavascript.js](javascript/VisualScriptToJavascript/VisualScriptToJavascript.js) in <b>coreAlgorithm(node)</b> method
1. Call `registerNode({ id, schema, execCodegen?, exprCodegen? })` with the node's schema (inputs, outputs, exec pins, color, rows, columns).
2. Add the node id to the `registerMenuOrder()` array at the bottom of the file (use `null` for a separator).
3. If the node has execution flow, provide an `execCodegen(compiler, node)` function.
4. If the node produces an expression output, provide an `exprCodegen(compiler, inputNode)` function.

```js
case "Print": {
this.script += `console.log(${this.handleInp(inputPins[0])});\n
`;
this.coreAlgorithm(execOutPins[0]); // this tells algo to go to the next node which is connected at first pin(triangle shaped)
}
See existing definitions in [src/js/registry/nodeDefinitions.js](src/js/registry/nodeDefinitions.js) for examples (e.g. Print, Add, Branch).

// this will append the console.log(input) in the generated js
```
<b>Result</b>
![](images/print_example.JPG)


#### NOTE: The above node only takes input, but if the node also do outputs, then that logic is needed to be added separately
Example: Add Node

Description:
```js
if (type == 'Add') { // this type should match the entry in the context menu's markup in index.html
nodeDescription.nodeTitle = 'Add';
nodeDescription.inputs = {
input0: {
inputTitle: 'ValueA',
dataType: 'Number',
defValue: 0,
pinInId: null,
},
input1: {
inputTitle: 'ValueB',
dataType: 'Number',
defValue: 0,
pinInId: null,
}
}
nodeDescription.outputs = {
output0: {
outputTitle: 'Result',
dataType: 'Number',
pinOutId: null,
outOrder: 0,
}
}
nodeDescription.color = 'Math';
nodeDescription.rows = 2;
nodeDescription.colums = 10;
}
```

And In [VisualScriptToJavascript.js](javascript/VisualScriptToJavascript/VisualScriptToJavascript.js)

in <b>handleInputs()</b> method

```js
case "Add": {
expr = `(${this.handleInputs(inputPins[0])} + ${this.handleInputs(inputPins[1])})`;
}
// this will generate and return (inp1 + inp2) expression
```
![](images/add_ex.JPG)
The node factory ([src/js/nodes/nodeFactory.js](src/js/nodes/nodeFactory.js)) and compiler ([src/js/compiler/compiler.js](src/js/compiler/compiler.js)) automatically pick up any registered node.



Expand Down
26 changes: 26 additions & 0 deletions dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# ---------- Build Stage ----------
FROM node:22 AS builder

WORKDIR /app

RUN npm install -g pnpm

COPY package.json pnpm-lock.yaml* ./

RUN pnpm install

COPY . .

RUN pnpm run build


# ---------- Production Stage ----------
FROM nginx:alpine

RUN rm -rf /usr/share/nginx/html/*

COPY --from=builder /app/dist /usr/share/nginx/html

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]
Loading