@webstir-io/webstir 0.1.1 → 0.1.3

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.
Files changed (78) hide show
  1. package/README.md +13 -0
  2. package/assets/deployment/docker/.dockerignore +7 -0
  3. package/assets/deployment/docker/Dockerfile +17 -0
  4. package/assets/deployment/docker/README.md +44 -0
  5. package/assets/deployment/docker/example.env +3 -0
  6. package/assets/features/client_nav/client_nav.ts +369 -264
  7. package/assets/features/client_nav/document_navigation.ts +344 -0
  8. package/assets/features/client_nav/form_enhancement.ts +275 -0
  9. package/assets/templates/api/src/backend/index.ts +71 -10
  10. package/assets/templates/api/src/backend/tsconfig.json +6 -1
  11. package/assets/templates/full/src/backend/index.ts +71 -10
  12. package/assets/templates/full/src/backend/module.ts +515 -0
  13. package/assets/templates/full/src/backend/tests/progressive-enhancement.test.ts +180 -0
  14. package/assets/templates/full/src/backend/tsconfig.json +6 -1
  15. package/assets/templates/full/src/frontend/app/scripts/features/client-nav.ts +574 -0
  16. package/assets/templates/full/src/frontend/app/scripts/features/document-navigation.ts +344 -0
  17. package/assets/templates/full/src/frontend/app/scripts/features/form-enhancement.ts +275 -0
  18. package/assets/templates/full/src/frontend/pages/home/index.css +8 -0
  19. package/assets/templates/full/src/frontend/pages/home/index.html +6 -1
  20. package/assets/templates/full/src/frontend/pages/home/tests/home.test.ts +12 -2
  21. package/assets/templates/spa/src/frontend/pages/home/tests/home.test.ts +10 -2
  22. package/package.json +31 -13
  23. package/scripts/check-feature-projections.mjs +87 -0
  24. package/scripts/check-full-demo-sync.mjs +89 -0
  25. package/scripts/check-package-install.mjs +537 -0
  26. package/scripts/check-standalone-install.mjs +221 -0
  27. package/scripts/pack-standalone.mjs +52 -28
  28. package/scripts/publish.sh +9 -0
  29. package/scripts/run-tests.mjs +103 -0
  30. package/scripts/sync-assets.mjs +175 -17
  31. package/src/add-backend-compat.ts +628 -0
  32. package/src/add-backend.ts +155 -27
  33. package/src/add.ts +111 -4
  34. package/src/agent.ts +393 -0
  35. package/src/api-watch.ts +7 -4
  36. package/src/backend-inspect.ts +70 -2
  37. package/src/backend-runtime.ts +22 -14
  38. package/src/build.ts +1 -3
  39. package/src/bun-generated-frontend-watch.ts +209 -0
  40. package/src/bun-globals.d.ts +23 -0
  41. package/src/bun-spa-document.ts +310 -0
  42. package/src/bun-spa-routes.ts +159 -0
  43. package/src/bun-spa-watch.ts +29 -0
  44. package/src/bun-ssg-watch.ts +304 -0
  45. package/src/cli.ts +381 -50
  46. package/src/compile-tests.ts +37 -29
  47. package/src/dev-server.ts +215 -144
  48. package/src/doctor.ts +164 -0
  49. package/src/enable-assets.ts +18 -1
  50. package/src/enable.ts +133 -41
  51. package/src/execute.ts +30 -4
  52. package/src/external-workspace.ts +178 -0
  53. package/src/format.ts +296 -17
  54. package/src/frontend-inspect.ts +32 -0
  55. package/src/frontend-watch.ts +27 -102
  56. package/src/full-watch.ts +13 -18
  57. package/src/index.ts +7 -0
  58. package/src/init-assets.ts +41 -11
  59. package/src/init.ts +85 -71
  60. package/src/inspect.ts +112 -0
  61. package/src/mcp/run-cli-json.ts +46 -0
  62. package/src/mcp/server.ts +307 -0
  63. package/src/operations.ts +176 -0
  64. package/src/providers.ts +20 -18
  65. package/src/refresh.ts +29 -3
  66. package/src/repair.ts +110 -43
  67. package/src/runtime-filter.ts +41 -0
  68. package/src/runtime.ts +1 -1
  69. package/src/smoke.ts +48 -16
  70. package/src/test.ts +54 -16
  71. package/src/testing-runtime.ts +273 -0
  72. package/src/types.ts +1 -4
  73. package/src/watch-events.ts +46 -17
  74. package/src/watch.ts +25 -14
  75. package/src/workspace-lock.ts +207 -0
  76. package/src/workspace-watcher.ts +10 -6
  77. package/src/workspace.ts +4 -2
  78. package/src/watch-daemon-client.ts +0 -171
package/package.json CHANGED
@@ -1,18 +1,33 @@
1
1
  {
2
2
  "name": "@webstir-io/webstir",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "webstir": "src/cli.ts"
7
7
  },
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/webstir-io/webstir.git",
11
+ "directory": "orchestrators/bun"
12
+ },
8
13
  "scripts": {
9
- "build": "node scripts/sync-assets.mjs && bun run build:deps && tsc -p tsconfig.json",
14
+ "check:assets": "bun scripts/sync-assets.mjs --check",
15
+ "check:feature-projections": "bun scripts/check-feature-projections.mjs",
16
+ "check:full-demo-sync": "bun scripts/check-full-demo-sync.mjs",
17
+ "build": "bun scripts/sync-assets.mjs && bun run build:deps && tsc -p tsconfig.json",
10
18
  "build:deps": "bun run --filter @webstir-io/module-contract build && bun run --filter @webstir-io/testing-contract build && bun run --filter @webstir-io/webstir-frontend build && bun run --filter @webstir-io/webstir-backend build && bun run --filter @webstir-io/webstir-testing build",
11
- "test": "bun run build && bun test ./tests/*.ts ./tests/**/*.ts",
19
+ "test": "bun run test:required",
20
+ "test:required": "bun run build && bun scripts/run-tests.mjs required",
21
+ "test:with-watch-browser": "bun run build && bun scripts/run-tests.mjs with-watch-browser",
22
+ "test:browser:publish": "bun run build && bun scripts/run-tests.mjs publish-browser",
23
+ "test:browser:watch": "bun run build && bun scripts/run-tests.mjs watch-browser",
24
+ "test:install:package": "bun scripts/check-package-install.mjs",
25
+ "test:install:standalone": "bun scripts/check-standalone-install.mjs",
12
26
  "clean": "rm -rf dist",
13
- "prepack": "node scripts/sync-assets.mjs",
27
+ "prepack": "bun scripts/sync-assets.mjs",
14
28
  "pack:local": "bun pm pack",
15
- "pack:standalone": "node scripts/pack-standalone.mjs"
29
+ "pack:standalone": "bun scripts/pack-standalone.mjs",
30
+ "release": "bash scripts/publish.sh"
16
31
  },
17
32
  "files": [
18
33
  "assets",
@@ -21,21 +36,24 @@
21
36
  "README.md"
22
37
  ],
23
38
  "engines": {
24
- "bun": ">=1.3.5"
39
+ "bun": ">=1.3.11"
25
40
  },
26
41
  "publishConfig": {
27
42
  "registry": "https://registry.npmjs.org",
28
43
  "access": "public"
29
44
  },
30
45
  "dependencies": {
31
- "@webstir-io/module-contract": "^0.1.15",
32
- "@webstir-io/testing-contract": "^0.1.7",
33
- "@webstir-io/webstir-backend": "^0.1.15",
34
- "@webstir-io/webstir-frontend": "^0.1.40",
35
- "@webstir-io/webstir-testing": "^0.1.5",
36
- "typescript": "^5.7.2"
46
+ "@modelcontextprotocol/sdk": "1.28.0",
47
+ "@webstir-io/module-contract": "^0.1.16",
48
+ "@webstir-io/testing-contract": "^0.1.8",
49
+ "@webstir-io/webstir-backend": "^0.1.16",
50
+ "@webstir-io/webstir-frontend": "^0.1.41",
51
+ "@webstir-io/webstir-testing": "^0.1.6",
52
+ "typescript": "^5.7.2",
53
+ "zod": "^3.23.8"
37
54
  },
38
55
  "devDependencies": {
39
- "@types/node": "^20.19.21"
56
+ "@types/node": "^20.19.21",
57
+ "playwright": "^1.58.2"
40
58
  }
41
59
  }
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { readFile } from 'node:fs/promises';
4
+ import path from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+
7
+ const here = path.dirname(fileURLToPath(import.meta.url));
8
+ const packageRoot = path.resolve(here, '..');
9
+
10
+ const exactProjectionChecks = [
11
+ {
12
+ source: path.join(packageRoot, 'resources', 'features', 'client_nav', 'client_nav.ts'),
13
+ target: path.join(
14
+ packageRoot,
15
+ 'resources',
16
+ 'templates',
17
+ 'full',
18
+ 'src',
19
+ 'frontend',
20
+ 'app',
21
+ 'scripts',
22
+ 'features',
23
+ 'client-nav.ts',
24
+ ),
25
+ },
26
+ {
27
+ source: path.join(packageRoot, 'resources', 'features', 'client_nav', 'document_navigation.ts'),
28
+ target: path.join(
29
+ packageRoot,
30
+ 'resources',
31
+ 'templates',
32
+ 'full',
33
+ 'src',
34
+ 'frontend',
35
+ 'app',
36
+ 'scripts',
37
+ 'features',
38
+ 'document-navigation.ts',
39
+ ),
40
+ },
41
+ {
42
+ source: path.join(packageRoot, 'resources', 'features', 'client_nav', 'form_enhancement.ts'),
43
+ target: path.join(
44
+ packageRoot,
45
+ 'resources',
46
+ 'templates',
47
+ 'full',
48
+ 'src',
49
+ 'frontend',
50
+ 'app',
51
+ 'scripts',
52
+ 'features',
53
+ 'form-enhancement.ts',
54
+ ),
55
+ },
56
+ ];
57
+
58
+ async function main() {
59
+ const differences = [];
60
+
61
+ for (const check of exactProjectionChecks) {
62
+ const [source, target] = await Promise.all([readFile(check.source), readFile(check.target)]);
63
+
64
+ if (!source.equals(target)) {
65
+ differences.push({
66
+ source: path.relative(packageRoot, check.source),
67
+ target: path.relative(packageRoot, check.target),
68
+ });
69
+ }
70
+ }
71
+
72
+ if (differences.length > 0) {
73
+ throw new Error(
74
+ [
75
+ 'Built-in Bun feature projections are out of sync.',
76
+ 'Update the projected template copies or change this check if the relationship is intentionally changing.',
77
+ ...differences.map((difference) => ` - ${difference.source} != ${difference.target}`),
78
+ ].join('\n'),
79
+ );
80
+ }
81
+
82
+ console.log(
83
+ `[webstir] feature projections OK (${exactProjectionChecks.length} exact mirrors checked)`,
84
+ );
85
+ }
86
+
87
+ await main();
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { readdir, readFile } from 'node:fs/promises';
4
+ import path from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+
7
+ const here = path.dirname(fileURLToPath(import.meta.url));
8
+ const packageRoot = path.resolve(here, '..');
9
+ const repoRoot = path.resolve(packageRoot, '..', '..');
10
+ const templateRoot = path.join(packageRoot, 'resources', 'templates', 'full', 'src');
11
+ const demoRoot = path.join(repoRoot, 'examples', 'demos', 'full', 'src');
12
+
13
+ const allowedDifferences = new Set(['frontend/app/app.ts', 'frontend/pages/home/index.ts']);
14
+
15
+ async function main() {
16
+ const [templateEntries, demoEntries] = await Promise.all([
17
+ collectFiles(templateRoot),
18
+ collectFiles(demoRoot),
19
+ ]);
20
+
21
+ const differences = [];
22
+ const relativePaths = [...new Set([...templateEntries.keys(), ...demoEntries.keys()])].sort();
23
+
24
+ for (const relativePath of relativePaths) {
25
+ const templateFile = templateEntries.get(relativePath);
26
+ const demoFile = demoEntries.get(relativePath);
27
+
28
+ if (!templateFile) {
29
+ differences.push(`unexpected demo file: src/${relativePath}`);
30
+ continue;
31
+ }
32
+
33
+ if (!demoFile) {
34
+ differences.push(`missing demo file: src/${relativePath}`);
35
+ continue;
36
+ }
37
+
38
+ if (templateFile.equals(demoFile)) {
39
+ if (allowedDifferences.has(relativePath)) {
40
+ differences.push(`expected proof-only delta missing: src/${relativePath}`);
41
+ }
42
+ continue;
43
+ }
44
+
45
+ if (allowedDifferences.has(relativePath)) {
46
+ continue;
47
+ }
48
+
49
+ differences.push(`unexpected content drift: src/${relativePath}`);
50
+ }
51
+
52
+ if (differences.length > 0) {
53
+ throw new Error(
54
+ [
55
+ 'examples/demos/full no longer matches the Bun full template outside the approved proof-only deltas.',
56
+ 'If this drift is intentional, update orchestrators/bun/scripts/check-full-demo-sync.mjs and the docs that describe the relationship.',
57
+ ...differences.map((difference) => ` - ${difference}`),
58
+ ].join('\n'),
59
+ );
60
+ }
61
+
62
+ console.log(
63
+ `[webstir] full demo sync OK (${templateEntries.size} files checked, ${allowedDifferences.size} approved deltas)`,
64
+ );
65
+ }
66
+
67
+ async function collectFiles(root, currentPath = root, files = new Map()) {
68
+ const children = await readdir(currentPath, { withFileTypes: true });
69
+
70
+ for (const child of children) {
71
+ const childPath = path.join(currentPath, child.name);
72
+
73
+ if (child.isDirectory()) {
74
+ await collectFiles(root, childPath, files);
75
+ continue;
76
+ }
77
+
78
+ if (!child.isFile()) {
79
+ continue;
80
+ }
81
+
82
+ const relativePath = path.relative(root, childPath);
83
+ files.set(relativePath, await readFile(childPath));
84
+ }
85
+
86
+ return files;
87
+ }
88
+
89
+ await main();