@b9g/shovel 0.2.0-beta.0 → 0.2.0-beta.10

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/README.md CHANGED
@@ -29,7 +29,7 @@ Shovel implements web platform APIs that server-side JavaScript is missing:
29
29
  |-----|----------|--------------|
30
30
  | `fetch` event | [Service Workers](https://w3c.github.io/ServiceWorker/) | Request handling |
31
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) |
32
+ | `self.directories` | [FileSystem API](https://fs.spec.whatwg.org/) | Storage (local, S3, R2) |
33
33
  | `self.cookieStore` | [Cookie Store API](https://wicg.github.io/cookie-store/) | Cookie management |
34
34
  | `URLPattern` | [URLPattern](https://urlpattern.spec.whatwg.org/) | Route matching (100% WPT) |
35
35
  | `AsyncContext.Variable` | [TC39 Stage 2](https://github.com/tc39/proposal-async-context) | Request-scoped state |
@@ -84,9 +84,9 @@ const cache = await self.caches.open("my-cache");
84
84
  await cache.put(request, response.clone());
85
85
  const cached = await cache.match(request);
86
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");
87
+ // File System Access - storage directories (local, S3, R2)
88
+ const directory = await self.directories.open("uploads");
89
+ const file = await directory.getFileHandle("image.png");
90
90
  const contents = await (await file.getFile()).arrayBuffer();
91
91
 
92
92
  // Cookie Store - cookie management
@@ -119,7 +119,7 @@ At build time, Shovel:
119
119
 
120
120
  Assets are served via the platform's best option:
121
121
  - **Cloudflare**: Workers Assets (edge-cached, zero config)
122
- - **Node/Bun**: Static file middleware or bucket storage
122
+ - **Node/Bun**: Static file middleware or directory storage
123
123
 
124
124
  ## Packages
125
125
 
@@ -0,0 +1,96 @@
1
+ import {
2
+ applyJSXOptions,
3
+ importMetaPlugin,
4
+ loadJSXConfig
5
+ } from "./chunk-ILQUUH2L.js";
6
+ import {
7
+ DEFAULTS,
8
+ findProjectRoot,
9
+ getNodeModulesPath
10
+ } from "./chunk-CSH7M4MK.js";
11
+
12
+ // src/commands/activate.ts
13
+ import { getLogger } from "@logtape/logtape";
14
+ import * as Platform from "@b9g/platform";
15
+ import * as ESBuild from "esbuild";
16
+ import { resolve, join } from "path";
17
+ import { mkdir } from "fs/promises";
18
+ import { assetsPlugin } from "@b9g/assets/plugin";
19
+ var logger = getLogger(["cli"]);
20
+ async function activateCommand(entrypoint, options, config) {
21
+ try {
22
+ const platformName = Platform.resolvePlatform({ ...options, config });
23
+ const workerCount = getWorkerCount(options, config);
24
+ logger.debug("Platform: {platform}", { platform: platformName });
25
+ logger.debug("Worker count: {workerCount}", { workerCount });
26
+ logger.info("Building ServiceWorker for activation");
27
+ const builtEntrypoint = await buildForActivate(entrypoint);
28
+ const platformInstance = await Platform.createPlatform(platformName);
29
+ logger.info("Activating ServiceWorker", {});
30
+ const serviceWorker = await platformInstance.loadServiceWorker(
31
+ builtEntrypoint,
32
+ {
33
+ hotReload: false,
34
+ workerCount
35
+ }
36
+ );
37
+ logger.info(
38
+ "ServiceWorker activated - check dist/ for generated content",
39
+ {}
40
+ );
41
+ await serviceWorker.dispose();
42
+ await platformInstance.dispose();
43
+ } catch (error) {
44
+ logger.error("ServiceWorker activation failed: {error}", { error });
45
+ process.exit(1);
46
+ }
47
+ }
48
+ async function buildForActivate(entrypoint) {
49
+ const entryPath = resolve(entrypoint);
50
+ const outputDir = resolve("dist");
51
+ const serverDir = join(outputDir, "server");
52
+ await mkdir(serverDir, { recursive: true });
53
+ await mkdir(join(outputDir, "static"), { recursive: true });
54
+ const projectRoot = findProjectRoot();
55
+ const jsxOptions = await loadJSXConfig(projectRoot);
56
+ const outfile = join(serverDir, "server.js");
57
+ const buildConfig = {
58
+ entryPoints: [entryPath],
59
+ bundle: true,
60
+ format: "esm",
61
+ target: "es2022",
62
+ platform: "node",
63
+ outfile,
64
+ absWorkingDir: projectRoot,
65
+ mainFields: ["module", "main"],
66
+ conditions: ["import", "module"],
67
+ nodePaths: [getNodeModulesPath()],
68
+ plugins: [
69
+ importMetaPlugin(),
70
+ assetsPlugin({
71
+ outDir: outputDir,
72
+ clientBuild: {
73
+ jsx: jsxOptions.jsx,
74
+ jsxFactory: jsxOptions.jsxFactory,
75
+ jsxFragment: jsxOptions.jsxFragment,
76
+ jsxImportSource: jsxOptions.jsxImportSource
77
+ }
78
+ })
79
+ ],
80
+ external: ["node:*"]
81
+ };
82
+ applyJSXOptions(buildConfig, jsxOptions);
83
+ logger.debug("Building entrypoint: {entryPath}", { entryPath, outfile });
84
+ await ESBuild.build(buildConfig);
85
+ logger.debug("Build complete: {outfile}", { outfile });
86
+ return outfile;
87
+ }
88
+ function getWorkerCount(options, config) {
89
+ if (options.workers) {
90
+ return parseInt(options.workers, 10);
91
+ }
92
+ return config?.workers ?? DEFAULTS.WORKERS;
93
+ }
94
+ export {
95
+ activateCommand
96
+ };