@b9g/shovel 0.1.10 โ†’ 0.2.0-beta.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.
package/CHANGELOG.md ADDED
@@ -0,0 +1,198 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.2.0-beta] - 2025-11-05
9
+
10
+ ### Added
11
+
12
+ #### ๐Ÿš€ Directly Executable Production Builds
13
+ - **Self-contained deployment**: `shovel build` now creates directly executable production builds that don't require `shovel serve`
14
+ - **2-file output**: Production builds generate only `server.js` (executable) and `package.json` (dependencies)
15
+ - **Platform bootstrapping**: Automatic platform detection and ServiceWorker environment setup
16
+ - **Zero-config deployment**: Run `chmod +x server.js && ./server.js` after `npm install` in the dist directory
17
+
18
+ #### ๐ŸŒ Complete ServiceWorker API Implementation
19
+ - **Full ServiceWorker globals**: Implemented `self`, `addEventListener`, `removeEventListener`, `dispatchEvent`
20
+ - **ServiceWorker lifecycle**: Proper `install` and `activate` event handling
21
+ - **ServiceWorker APIs**: Implemented `self.skipWaiting()` and `self.clients` with environment-aware behavior
22
+ - **Web standards compliance**: All APIs follow web platform standards, not runtime-specific implementations
23
+
24
+ #### ๐Ÿ—๏ธ New Bucket Architecture
25
+ - **`self.buckets` API**: Replaced `self.dirs` with standardized bucket interface for filesystem access
26
+ - **Factory pattern**: Dynamic adapter loading for different storage backends (memory, local, S3, R2)
27
+ - **Unified interface**: All storage adapters implement the same `Bucket` interface
28
+ - **`getDirectoryHandle(name)` API**: Standardized directory access following File System Access API patterns
29
+
30
+ #### ๐Ÿ“ฆ Asset Import Improvements
31
+ - **`assetBase` import attribute**: New syntax for asset imports with base path resolution
32
+ - **Automatic asset processing**: Assets are automatically copied and processed during build
33
+ - **Import transformation**: `import './style.css' with { assetBase: true }` generates proper asset URLs
34
+ - **Manifest generation**: Asset manifests track all processed assets with metadata
35
+
36
+ #### ๐Ÿงช Enhanced Cache System
37
+ - **Redis cache adapter**: Full Redis support with connection pooling and error handling
38
+ - **Multi-threaded coordination**: PostMessage-based cache coordination for worker environments
39
+ - **Platform-agnostic types**: Separated web standard types from platform-specific implementations
40
+ - **Factory pattern**: Dynamic cache adapter loading matching filesystem patterns
41
+
42
+ #### ๐Ÿ”ง Type System Improvements
43
+ - **Separated type imports**: Platform-specific types only in platform packages, web standard types in shared packages
44
+ - **TypeScript configuration**: Fixed Headers iteration and other compatibility issues with proper lib configuration
45
+ - **Comprehensive type checking**: All packages now pass strict TypeScript compilation
46
+ - **Web standard prioritization**: Chose webworker types over runtime-specific types for compatibility
47
+
48
+ #### โšก Performance & Production Features
49
+ - **TechEmpower Framework Benchmarks**: Official implementation and testing completed
50
+ - **Production scaling**: Multi-worker support with proper resource coordination
51
+ - **Docker deployment**: Complete containerization support with optimized builds
52
+ - **Cloudflare Workers**: Enhanced support with proper ES module bundling
53
+
54
+ ### Changed
55
+
56
+ #### ๐Ÿ’ฅ Breaking Changes
57
+ - **BREAKING**: Replaced `self.dirs` with `self.buckets` API
58
+ - **BREAKING**: Changed `getBucket()` to `getDirectoryHandle(name: string)` for standardization
59
+ - **BREAKING**: Asset imports now require explicit `assetBase` attribute for base path resolution
60
+ - **BREAKING**: Updated all filesystem adapters to implement new `Bucket` interface
61
+
62
+ #### ๐Ÿ—๏ธ Build System Overhaul
63
+ - **Simplified output**: Moved from complex templating to clean esbuild banner approach
64
+ - **Self-contained bundling**: Framework dependencies bundled, app dependencies preserved
65
+ - **Platform detection**: Automatic runtime detection and appropriate adapter loading
66
+ - **Production runtime**: Uses proven development patterns for production consistency
67
+
68
+ #### ๐Ÿ“ Architecture Improvements
69
+ - **Clean separation**: Platform-specific code isolated from shared/core packages
70
+ - **Consistent interfaces**: All adapters follow same patterns (cache, filesystem, platform)
71
+ - **Dynamic loading**: Runtime adapter detection and loading
72
+ - **Environment awareness**: Proper detection of worker vs main thread contexts
73
+
74
+ ### Fixed
75
+
76
+ - **TypeScript compilation**: Resolved Headers.entries() iteration issues with DOM.Iterable configuration
77
+ - **Cache exports**: Fixed missing factory functions in multi-threaded cache coordination
78
+ - **Platform contamination**: Removed Node.js-specific imports from platform-agnostic packages
79
+ - **Build loops**: Fixed infinite loading where worker.js was trying to load itself
80
+ - **Worker globals**: Proper ServiceWorker environment setup in all execution contexts
81
+ - **Dependency resolution**: Fixed workspace dependency resolution and external bundling
82
+
83
+ ### Technical Details
84
+
85
+ #### ServiceWorker Implementation
86
+ The ServiceWorker implementation provides full web platform compatibility:
87
+
88
+ ```typescript
89
+ // Environment-aware skipWaiting implementation
90
+ const skipWaiting = async (): Promise<void> => {
91
+ if (options.isDevelopment && options.hotReload) {
92
+ console.info('[ServiceWorker] skipWaiting() - triggering hot reload');
93
+ await options.hotReload();
94
+ } else if (!options.isDevelopment) {
95
+ console.info('[ServiceWorker] skipWaiting() - production graceful restart not implemented');
96
+ }
97
+ };
98
+ ```
99
+
100
+ #### Build System Architecture
101
+ The new build system uses esbuild banners for clean, self-contained executables:
102
+
103
+ ```javascript
104
+ // Production bootstrap injected via esbuild banner
105
+ buildConfig.banner = {
106
+ js: `#!/usr/bin/env node
107
+ import { ServiceWorkerRuntime, createServiceWorkerGlobals, createBucketStorage } from '@b9g/platform';
108
+
109
+ if (import.meta.url === \`file://\${process.argv[1]}\`) {
110
+ const runtime = new ServiceWorkerRuntime();
111
+ const buckets = createBucketStorage(process.cwd());
112
+
113
+ createServiceWorkerGlobals(runtime, { buckets });
114
+ // ... HTTP server setup using proven patterns
115
+ }
116
+ // User's ServiceWorker code follows...`
117
+ };
118
+ ```
119
+
120
+ #### Type Architecture
121
+ Clean separation ensures web standard compatibility:
122
+
123
+ ```typescript
124
+ // Platform-agnostic cache using web standards
125
+ interface WorkerLike {
126
+ postMessage(value: any): void;
127
+ on(event: string, listener: (data: any) => void): void;
128
+ }
129
+
130
+ // Web standard encoding instead of Node.js Buffer
131
+ body: btoa(String.fromCharCode(...new Uint8Array(body))),
132
+ totalSize += new TextEncoder().encode(value).length;
133
+ ```
134
+
135
+ ### Migration Guide
136
+
137
+ #### From `self.dirs` to `self.buckets`
138
+ ```typescript
139
+ // Before
140
+ const distDir = await self.dirs.getBucket();
141
+
142
+ // After
143
+ const distBucket = await self.buckets.getDirectoryHandle('dist');
144
+ ```
145
+
146
+ #### Asset Imports
147
+ ```typescript
148
+ // Before
149
+ import './style.css' with { url: true };
150
+
151
+ // After
152
+ import './style.css' with { assetBase: true };
153
+ ```
154
+
155
+ #### Deployment
156
+ ```bash
157
+ # Before
158
+ shovel build
159
+ shovel serve dist/
160
+
161
+ # After
162
+ shovel build
163
+ cd dist && npm install
164
+ chmod +x server.js && ./server.js
165
+ ```
166
+
167
+ ### Performance
168
+
169
+ - **TechEmpower Benchmarks**: Competitive performance in official framework benchmarks
170
+ - **Production scaling**: Multi-worker coordination with proper resource management
171
+ - **Build optimization**: Faster builds with simplified bundling strategy
172
+ - **Runtime efficiency**: Direct execution without CLI overhead
173
+
174
+ ### Developer Experience
175
+
176
+ - **Zero-config deployment**: No configuration required for basic deployment
177
+ - **Proven patterns**: Production builds use same patterns as development
178
+ - **Better error messages**: Improved error handling and diagnostics
179
+ - **Type safety**: Comprehensive TypeScript support across all packages
180
+
181
+ ---
182
+
183
+ ## [0.1.10] - Previous Release
184
+
185
+ ### Added
186
+ - Initial CLI implementation
187
+ - Basic platform abstraction
188
+ - Development server functionality
189
+ - Asset processing pipeline
190
+
191
+ ### Fixed
192
+ - Various development workflow issues
193
+ - Build system stability
194
+ - Type definitions
195
+
196
+ ---
197
+
198
+ For detailed technical documentation, see the [README.md](README.md) and individual package documentation.
package/README.md CHANGED
@@ -1,12 +1,144 @@
1
1
  # Shovel
2
2
 
3
- Shovel is a CLI for building web applications.
3
+ **The ServiceWorker platform for server-side JavaScript.**
4
4
 
5
- ## Commands
5
+ Same code. Any runtime. Node.js, Bun, Cloudflare Workers.
6
6
 
7
- - `shovel develop`
7
+ ```javascript
8
+ // app.js
9
+ self.addEventListener("fetch", (event) => {
10
+ event.respondWith(new Response("Hello World"));
11
+ });
12
+ ```
8
13
 
9
- - `shovel build`
14
+ ```bash
15
+ npx @b9g/shovel develop app.js
16
+ ```
10
17
 
11
- - `shovel static`
12
- Build a static website.
18
+ ## Why Shovel?
19
+
20
+ Browsers have ServiceWorker. Cloudflare has Workers. Node.js and Bun have... Express?
21
+
22
+ Shovel brings the ServiceWorker programming model to server-side JavaScript. Write your app once using web standards, deploy it anywhere.
23
+
24
+ ## Web Standards
25
+
26
+ Shovel implements web platform APIs that server-side JavaScript is missing:
27
+
28
+ | API | Standard | What it does |
29
+ |-----|----------|--------------|
30
+ | `fetch` event | [Service Workers](https://w3c.github.io/ServiceWorker/) | Request handling |
31
+ | `self.caches` | [Cache API](https://w3c.github.io/ServiceWorker/#cache-interface) | Response caching |
32
+ | `self.buckets` | [FileSystemDirectoryHandle](https://fs.spec.whatwg.org/#api-filesystemdirectoryhandle) | Storage (local, S3, R2) |
33
+ | `self.cookieStore` | [Cookie Store API](https://wicg.github.io/cookie-store/) | Cookie management |
34
+ | `URLPattern` | [URLPattern](https://urlpattern.spec.whatwg.org/) | Route matching (100% WPT) |
35
+ | `AsyncContext.Variable` | [TC39 Stage 2](https://github.com/tc39/proposal-async-context) | Request-scoped state |
36
+
37
+ Your code uses standards. Shovel makes them work everywhere.
38
+
39
+ ## True Portability
40
+
41
+ Shovel is a complete meta-framework. Same code, any runtime, any rendering strategy:
42
+
43
+ - **Server runtimes**: Node.js, Bun, Cloudflare Workers for development and production
44
+ - **Browser ServiceWorkers**: The same app can run as a PWA service worker
45
+ - **Universal rendering**: Dynamic, static, or client-side - link and deploy assets automatically
46
+
47
+ ## Quick Start
48
+
49
+ ```javascript
50
+ // app.js
51
+ import {Router} from "@b9g/router";
52
+
53
+ const router = new Router();
54
+
55
+ router.route("/").get(() => new Response("Hello World"));
56
+
57
+ router.route("/users/:id").get((request, {params}) => {
58
+ return Response.json({id: params.id});
59
+ });
60
+
61
+ self.addEventListener("fetch", (event) => {
62
+ event.respondWith(router.handler(event.request));
63
+ });
64
+ ```
65
+
66
+ ```bash
67
+ # Create a new project
68
+ npm create @b9g/shovel my-app
69
+
70
+ # Development with hot reload
71
+ npx @b9g/shovel develop app.js
72
+
73
+ # Build for production
74
+ npx @b9g/shovel build app.js --platform=node
75
+ npx @b9g/shovel build app.js --platform=bun
76
+ npx @b9g/shovel build app.js --platform=cloudflare
77
+ ```
78
+
79
+ ## Platform APIs
80
+
81
+ ```javascript
82
+ // Cache API - response caching
83
+ const cache = await self.caches.open("my-cache");
84
+ await cache.put(request, response.clone());
85
+ const cached = await cache.match(request);
86
+
87
+ // File System Access - storage buckets (local, S3, R2)
88
+ const bucket = await self.buckets.open("uploads");
89
+ const file = await bucket.getFileHandle("image.png");
90
+ const contents = await (await file.getFile()).arrayBuffer();
91
+
92
+ // Cookie Store - cookie management
93
+ const session = await self.cookieStore.get("session");
94
+ await self.cookieStore.set("theme", "dark");
95
+
96
+ // AsyncContext - request-scoped state without prop drilling
97
+ const requestId = new AsyncContext.Variable();
98
+ requestId.run(crypto.randomUUID(), async () => {
99
+ console.log(requestId.get()); // Works anywhere in the call stack
100
+ });
101
+ ```
102
+
103
+ ## Asset Pipeline
104
+
105
+ Import any file and get its production URL with content hashing:
106
+
107
+ ```javascript
108
+ import styles from "./styles.css" with { assetBase: "/assets" };
109
+ import logo from "./logo.png" with { assetBase: "/assets" };
110
+
111
+ // styles = "/assets/styles-a1b2c3d4.css"
112
+ // logo = "/assets/logo-e5f6g7h8.png"
113
+ ```
114
+
115
+ At build time, Shovel:
116
+ - Copies assets to the output directory with content hashes
117
+ - Generates a manifest mapping original paths to hashed URLs
118
+ - Transforms imports to return the final URLs
119
+
120
+ Assets are served via the platform's best option:
121
+ - **Cloudflare**: Workers Assets (edge-cached, zero config)
122
+ - **Node/Bun**: Static file middleware or bucket storage
123
+
124
+ ## Packages
125
+
126
+ | Package | Description |
127
+ |---------|-------------|
128
+ | `@b9g/shovel` | CLI for development and deployment |
129
+ | `@b9g/platform` | Core runtime and platform APIs |
130
+ | `@b9g/platform-node` | Node.js adapter |
131
+ | `@b9g/platform-bun` | Bun adapter |
132
+ | `@b9g/platform-cloudflare` | Cloudflare Workers adapter |
133
+ | `@b9g/router` | URLPattern-based routing with middleware |
134
+ | `@b9g/cache` | Cache API implementation |
135
+ | `@b9g/filesystem` | File System Access implementation |
136
+ | `@b9g/match-pattern` | URLPattern with extensions (100% WPT) |
137
+ | `@b9g/async-context` | AsyncContext.Variable implementation |
138
+ | `@b9g/http-errors` | Standard HTTP error classes |
139
+ | `@b9g/auth` | OAuth2/PKCE and CORS middleware |
140
+ | `@b9g/assets` | Static asset handling |
141
+
142
+ ## License
143
+
144
+ MIT
package/bin/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env sh
2
+ export {};