cumstack 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +3 -0
- package/cli/build.js +19 -0
- package/cli/builder.js +172 -0
- package/cli/create.js +36 -0
- package/cli/dev.js +109 -0
- package/cli/index.js +65 -0
- package/index.js +22 -0
- package/package.json +67 -0
- package/src/app/client/Twink.js +57 -0
- package/src/app/client/components.js +28 -0
- package/src/app/client/hmr.js +161 -0
- package/src/app/client/index.js +144 -0
- package/src/app/client.js +599 -0
- package/src/app/index.js +8 -0
- package/src/app/server/hono-utils.js +292 -0
- package/src/app/server/index.js +457 -0
- package/src/app/server/jsx.js +168 -0
- package/src/app/server.js +373 -0
- package/src/app/shared/i18n.js +271 -0
- package/src/app/shared/language-codes.js +199 -0
- package/src/app/shared/reactivity.js +259 -0
- package/src/app/shared/router.js +153 -0
- package/src/app/shared/utils.js +127 -0
- package/templates/monorepo/README.md +27 -0
- package/templates/monorepo/api/package.json +13 -0
- package/templates/monorepo/app/package.json +19 -0
- package/templates/monorepo/app/src/entry.client.jsx +4 -0
- package/templates/monorepo/app/src/entry.server.jsx +14 -0
- package/templates/monorepo/app/src/main.css +7 -0
- package/templates/monorepo/app/src/pages/404.jsx +9 -0
- package/templates/monorepo/app/src/pages/Home.jsx +8 -0
- package/templates/monorepo/app/wrangler.toml +35 -0
- package/templates/monorepo/package.json +18 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cumstack Utilities
|
|
3
|
+
* common helper functions
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* class names helper (similar to clsx)
|
|
8
|
+
* @param {...any} args - Class arguments
|
|
9
|
+
* @returns {string}
|
|
10
|
+
*/
|
|
11
|
+
export function cn(...args) {
|
|
12
|
+
return args
|
|
13
|
+
.flat()
|
|
14
|
+
.filter(Boolean)
|
|
15
|
+
.map((arg) => {
|
|
16
|
+
if (typeof arg === 'string') return arg;
|
|
17
|
+
if (typeof arg === 'object')
|
|
18
|
+
return Object.entries(arg)
|
|
19
|
+
.filter(([, value]) => Boolean(value))
|
|
20
|
+
.map(([key]) => key)
|
|
21
|
+
.join(' ');
|
|
22
|
+
return '';
|
|
23
|
+
})
|
|
24
|
+
.join(' ')
|
|
25
|
+
.trim();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* debounce function
|
|
30
|
+
* @param {Function} fn - Function to debounce
|
|
31
|
+
* @param {number} delay - Delay in ms
|
|
32
|
+
* @returns {Function}
|
|
33
|
+
*/
|
|
34
|
+
export function debounce(fn, delay) {
|
|
35
|
+
let timeoutId;
|
|
36
|
+
return (...args) => {
|
|
37
|
+
clearTimeout(timeoutId);
|
|
38
|
+
timeoutId = setTimeout(() => fn(...args), delay);
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* throttle function
|
|
44
|
+
* @param {Function} fn - Function to throttle
|
|
45
|
+
* @param {number} delay - Delay in ms
|
|
46
|
+
* @returns {Function}
|
|
47
|
+
*/
|
|
48
|
+
export function throttle(fn, delay) {
|
|
49
|
+
let lastCall = 0;
|
|
50
|
+
return (...args) => {
|
|
51
|
+
const now = Date.now();
|
|
52
|
+
if (now - lastCall >= delay) {
|
|
53
|
+
lastCall = now;
|
|
54
|
+
fn(...args);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* sleep/delay function
|
|
61
|
+
* @param {number} ms - Milliseconds to sleep
|
|
62
|
+
* @returns {Promise<void>}
|
|
63
|
+
*/
|
|
64
|
+
export function sleep(ms) {
|
|
65
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* generate unique id
|
|
70
|
+
* @returns {string}
|
|
71
|
+
*/
|
|
72
|
+
export function generateId() {
|
|
73
|
+
return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* deep clone object
|
|
78
|
+
* @template T
|
|
79
|
+
* @param {T} obj - Object to clone
|
|
80
|
+
* @returns {T}
|
|
81
|
+
*/
|
|
82
|
+
export function deepClone(obj) {
|
|
83
|
+
if (obj === null || typeof obj !== 'object') return obj;
|
|
84
|
+
if (obj instanceof Date) return new Date(obj.getTime());
|
|
85
|
+
if (obj instanceof Array) return obj.map((item) => deepClone(item));
|
|
86
|
+
const cloned = {};
|
|
87
|
+
for (const key in obj) if (obj.hasOwnProperty(key)) cloned[key] = deepClone(obj[key]);
|
|
88
|
+
return cloned;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* check if value is empty
|
|
93
|
+
* @param {any} value - Value to check
|
|
94
|
+
* @returns {boolean}
|
|
95
|
+
*/
|
|
96
|
+
export function isEmpty(value) {
|
|
97
|
+
if (value == null) return true;
|
|
98
|
+
if (typeof value === 'string') return value.trim().length === 0;
|
|
99
|
+
if (Array.isArray(value)) return value.length === 0;
|
|
100
|
+
if (typeof value === 'object') return Object.keys(value).length === 0;
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* format date
|
|
106
|
+
* @param {Date|string|number} date - Date to format
|
|
107
|
+
* @param {string} locale - Locale
|
|
108
|
+
* @returns {string}
|
|
109
|
+
*/
|
|
110
|
+
export function formatDate(date, locale = 'en-US') {
|
|
111
|
+
const d = new Date(date);
|
|
112
|
+
return d.toLocaleDateString(locale);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* format currency
|
|
117
|
+
* @param {number} amount - Amount
|
|
118
|
+
* @param {string} currency - Currency code
|
|
119
|
+
* @param {string} locale - Locale
|
|
120
|
+
* @returns {string}
|
|
121
|
+
*/
|
|
122
|
+
export function formatCurrency(amount, currency = 'USD', locale = 'en-US') {
|
|
123
|
+
return new Intl.NumberFormat(locale, {
|
|
124
|
+
style: 'currency',
|
|
125
|
+
currency,
|
|
126
|
+
}).format(amount);
|
|
127
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# My cumstack App
|
|
2
|
+
|
|
3
|
+
A monorepo project with cumstack frontend and API backend.
|
|
4
|
+
|
|
5
|
+
## Structure
|
|
6
|
+
|
|
7
|
+
- `app/` - cumstack frontend application
|
|
8
|
+
- `api/` - API backend (to be implemented)
|
|
9
|
+
|
|
10
|
+
## Getting Started
|
|
11
|
+
|
|
12
|
+
1. Install dependencies:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
bun install
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
2. Start development server:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
bun run dev
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
3. Build for production:
|
|
25
|
+
```bash
|
|
26
|
+
bun run build
|
|
27
|
+
```
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "api",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "API backend (placeholder)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "echo 'API not implemented yet'",
|
|
8
|
+
"build": "echo 'API not implemented yet'"
|
|
9
|
+
},
|
|
10
|
+
"devDependencies": {
|
|
11
|
+
"bun": "^1.0.0"
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "app",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "cumstack dev",
|
|
7
|
+
"build": "cumstack build",
|
|
8
|
+
"start": "bun run dist/server.js"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"cumstack": "^"
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"bun": "^1.3.5",
|
|
15
|
+
"@tailwindcss/postcss": "^4.1.18",
|
|
16
|
+
"postcss": "^8.5.6",
|
|
17
|
+
"wrangler": "^4.54.0"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { FoxgirlCreampie, Router, Route } from 'cumstack';
|
|
2
|
+
import Home from './pages/Home.jsx';
|
|
3
|
+
import NotFound from './pages/404.jsx';
|
|
4
|
+
|
|
5
|
+
export default function () {
|
|
6
|
+
return (
|
|
7
|
+
<FoxgirlCreampie>
|
|
8
|
+
<Router>
|
|
9
|
+
<Route path="/" component={Home} />
|
|
10
|
+
<Route path="/404" component={NotFound} />
|
|
11
|
+
</Router>
|
|
12
|
+
</FoxgirlCreampie>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name = "my-cumstack-app"
|
|
2
|
+
main = "./dist/dev/server/main.server.js"
|
|
3
|
+
compatibility_date = "2024-12-01"
|
|
4
|
+
compatibility_flags = ["global_fetch_strictly_public"]
|
|
5
|
+
|
|
6
|
+
[dev]
|
|
7
|
+
port = 7277
|
|
8
|
+
|
|
9
|
+
[assets]
|
|
10
|
+
directory = "./dist/dev/client"
|
|
11
|
+
|
|
12
|
+
[observability]
|
|
13
|
+
enabled = true
|
|
14
|
+
|
|
15
|
+
[vars]
|
|
16
|
+
ENVIRONMENT = "production"
|
|
17
|
+
APP_DOMAIN = "example.com"
|
|
18
|
+
API_DOMAIN = "api.example.com"
|
|
19
|
+
CDN_DOMAIN = "cdn.example.com"
|
|
20
|
+
APP_NAME = "Example"
|
|
21
|
+
STRIPE_PUBLISHABLE_KEY = ""
|
|
22
|
+
TURNSTILE_SITE_KEY = ""
|
|
23
|
+
|
|
24
|
+
[env.dev.vars]
|
|
25
|
+
ENVIRONMENT = "development"
|
|
26
|
+
APP_DOMAIN = "127.0.0.1:7277"
|
|
27
|
+
API_DOMAIN = "127.0.0.1:7278"
|
|
28
|
+
CDN_DOMAIN = "127.0.0.1:7279"
|
|
29
|
+
APP_NAME = "Example (Local)"
|
|
30
|
+
STRIPE_PUBLISHABLE_KEY = ""
|
|
31
|
+
TURNSTILE_SITE_KEY = ""
|
|
32
|
+
|
|
33
|
+
[[r2_buckets]]
|
|
34
|
+
binding = "R2"
|
|
35
|
+
bucket_name = "r2-example"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "my-cumstack-app",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A monorepo project using cumstack framework",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "bun run --cwd app dev",
|
|
8
|
+
"build": "bun run --cwd app build",
|
|
9
|
+
"start": "bun run --cwd app start"
|
|
10
|
+
},
|
|
11
|
+
"workspaces": [
|
|
12
|
+
"app",
|
|
13
|
+
"api"
|
|
14
|
+
],
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"bun": "^1.3.5"
|
|
17
|
+
}
|
|
18
|
+
}
|