fuzor 0.0.1 → 0.2.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.
Files changed (98) hide show
  1. package/README.md +112 -0
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +97 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/compiler/index.d.ts +28 -0
  7. package/dist/compiler/index.d.ts.map +1 -0
  8. package/dist/compiler/index.js +160 -0
  9. package/dist/compiler/index.js.map +1 -0
  10. package/dist/compiler/islands.d.ts +17 -0
  11. package/dist/compiler/islands.d.ts.map +1 -0
  12. package/dist/compiler/islands.js +78 -0
  13. package/dist/compiler/islands.js.map +1 -0
  14. package/dist/create.d.ts +21 -0
  15. package/dist/create.d.ts.map +1 -0
  16. package/dist/create.js +111 -0
  17. package/dist/create.js.map +1 -0
  18. package/dist/index.d.ts +8 -8
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +6 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/islands/react.d.ts +8 -0
  23. package/dist/islands/react.d.ts.map +1 -0
  24. package/dist/islands/react.js +19 -0
  25. package/dist/islands/react.js.map +1 -0
  26. package/dist/islands/solid.d.ts +8 -0
  27. package/dist/islands/solid.d.ts.map +1 -0
  28. package/dist/islands/solid.js +15 -0
  29. package/dist/islands/solid.js.map +1 -0
  30. package/dist/islands/vue.d.ts +5 -0
  31. package/dist/islands/vue.d.ts.map +1 -0
  32. package/dist/islands/vue.js +13 -0
  33. package/dist/islands/vue.js.map +1 -0
  34. package/dist/runtime/atom.d.ts +10 -0
  35. package/dist/runtime/atom.d.ts.map +1 -0
  36. package/dist/runtime/atom.js +38 -0
  37. package/dist/runtime/atom.js.map +1 -0
  38. package/dist/runtime/index.d.ts +31 -0
  39. package/dist/runtime/index.d.ts.map +1 -0
  40. package/dist/runtime/index.js +121 -0
  41. package/dist/runtime/index.js.map +1 -0
  42. package/dist/runtime/islands.d.ts +6 -0
  43. package/dist/runtime/islands.d.ts.map +1 -0
  44. package/dist/runtime/islands.js +43 -0
  45. package/dist/runtime/islands.js.map +1 -0
  46. package/dist/ssr/node.d.ts +7 -0
  47. package/dist/ssr/node.d.ts.map +1 -0
  48. package/dist/ssr/node.js +46 -0
  49. package/dist/ssr/node.js.map +1 -0
  50. package/dist/ssr.d.ts +10 -0
  51. package/dist/ssr.d.ts.map +1 -0
  52. package/dist/ssr.js +19 -0
  53. package/dist/ssr.js.map +1 -0
  54. package/dist/vite.d.ts +8 -0
  55. package/dist/vite.d.ts.map +1 -0
  56. package/dist/vite.js +310 -0
  57. package/dist/vite.js.map +1 -0
  58. package/package.json +69 -56
  59. package/templates/basic/README.md +16 -0
  60. package/templates/basic/_gitignore +3 -0
  61. package/templates/basic/components/app-badge.html +1 -0
  62. package/templates/basic/index.html +12 -0
  63. package/templates/basic/islands/counter.ts +13 -0
  64. package/templates/basic/package.json +20 -0
  65. package/templates/basic/pages/about/index.html +5 -0
  66. package/templates/basic/pages/docs/index.md +9 -0
  67. package/templates/basic/pages/index.html +9 -0
  68. package/templates/basic/pages/layout.html +8 -0
  69. package/templates/basic/pnpm-workspace.yaml +5 -0
  70. package/templates/basic/server.mjs +10 -0
  71. package/templates/basic/style.css +1 -0
  72. package/templates/basic/tsconfig.json +13 -0
  73. package/templates/basic/vite.config.ts +4 -0
  74. package/bin/index.js +0 -13
  75. package/dist/core/init.d.ts +0 -7
  76. package/dist/core/router.d.ts +0 -4
  77. package/dist/core/vite-config.d.ts +0 -5
  78. package/dist/init.cjs +0 -237
  79. package/dist/init.js +0 -468
  80. package/dist/lib.cjs +0 -222
  81. package/dist/lib.js +0 -19247
  82. package/dist/render/lit.d.ts +0 -1
  83. package/dist/render/preact.d.ts +0 -1
  84. package/dist/render/react.d.ts +0 -7
  85. package/dist/render/solid.d.ts +0 -1
  86. package/dist/render/svelte.d.ts +0 -6
  87. package/dist/render/vue.d.ts +0 -1
  88. package/dist/utils/create-file-if-not-exists.d.ts +0 -1
  89. package/dist/utils/create-folder-if-not-exist.d.ts +0 -2
  90. package/dist/utils/default-theme-files.d.ts +0 -7
  91. package/dist/utils/file-path-helpers.d.ts +0 -3
  92. package/dist/utils/is-valid-wordpress-slug.d.ts +0 -17
  93. package/dist/utils/read-write-file.d.ts +0 -1
  94. package/dist/utils/remove-file-exists.d.ts +0 -2
  95. package/dist/utils/remove-trailing-slash-url.d.ts +0 -1
  96. package/dist/utils/router-helpers.d.ts +0 -19
  97. package/dist/utils/zip-wp-theme.d.ts +0 -2
  98. package/types/index.d.ts +0 -6
@@ -0,0 +1,9 @@
1
+ <section class="hero">
2
+ <p class="eyebrow">HTML first · SPA · MPA · SSR</p>
3
+ <app-badge></app-badge>
4
+ <h1>Build once. Choose how to ship.</h1>
5
+ <p>Edit <code>pages/index.html</code> and run the same app as an SPA, MPA, or server-served build.</p>
6
+ <fuzor-island src="counter" client:load></fuzor-island>
7
+ <p class="hint">This button is in the initial HTML. Its behavior loads as an island.</p>
8
+ <fuzor-link href="/docs/" class="link">Explore the Markdown page →</fuzor-link>
9
+ </section>
@@ -0,0 +1,8 @@
1
+ <div class="shell">
2
+ <header class="header">
3
+ <a href="/" class="brand">◉ Fuzor</a>
4
+ <nav><fuzor-link href="/">Home</fuzor-link><fuzor-link href="/about/">About</fuzor-link><fuzor-link href="/docs/">Docs</fuzor-link></nav>
5
+ </header>
6
+ <main><slot></slot></main>
7
+ <footer>One app. Three ways to ship.</footer>
8
+ </div>
@@ -0,0 +1,5 @@
1
+ packages:
2
+ - .
3
+
4
+ onlyBuiltDependencies:
5
+ - esbuild
@@ -0,0 +1,10 @@
1
+ import path from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+ import { createNodeSsrServer } from "fuzor/ssr/node";
4
+ import { handler } from "./dist-ssr/server/entry.mjs";
5
+
6
+ const here = path.dirname(fileURLToPath(import.meta.url));
7
+ const host = process.env.HOST ?? "127.0.0.1";
8
+ const port = Number(process.env.PORT ?? 4173);
9
+ createNodeSsrServer({ handler, assetsDir: path.join(here, "dist-ssr/client") })
10
+ .listen(port, host, () => console.log(`Fuzor listening on http://${host}:${port}`));
@@ -0,0 +1 @@
1
+ :root{font-family:Inter,ui-sans-serif,system-ui,sans-serif;color:#e9efff;background:#0d1220;font-synthesis:none}*{box-sizing:border-box}body{margin:0}.shell{min-height:100vh;display:flex;flex-direction:column}.header{display:flex;align-items:center;justify-content:space-between;padding:1.5rem max(5vw,1.5rem);border-bottom:1px solid #263044}.brand{color:#8bd8c7;font-weight:800;text-decoration:none;letter-spacing:-.04em}nav{display:flex;gap:1.25rem}nav a,.link{color:#b7c5e1;text-decoration:none}nav a:hover,.link:hover{color:#8bd8c7}main{width:min(880px,90vw);margin:0 auto;flex:1;padding:7vw 0}.hero{max-width:680px}.eyebrow{text-transform:uppercase;letter-spacing:.18em;color:#8bd8c7;font-size:.72rem;font-weight:700}.badge{display:inline-block;padding:.35rem .65rem;border:1px solid #316456;border-radius:999px;color:#8bd8c7;font-size:.78rem}h1{font-size:clamp(2.6rem,7vw,5rem);line-height:1.05;letter-spacing:-.065em;margin:.5rem 0 1.5rem}p,li{line-height:1.7;color:#bac6dc}code{color:#8bd8c7}.counter{background:#8bd8c7;color:#10221f;border:0;border-radius:999px;padding:.85rem 1.25rem;font:inherit;font-weight:700;cursor:pointer}.hint{font-size:.86rem}.link{display:inline-block;margin-top:1.5rem}footer{padding:1.5rem max(5vw,1.5rem);border-top:1px solid #263044;color:#71819e;font-size:.8rem}
@@ -0,0 +1,13 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "Bundler",
6
+ "lib": ["ES2022", "DOM"],
7
+ "types": ["vite/client"],
8
+ "strict": true,
9
+ "skipLibCheck": true,
10
+ "noEmit": true
11
+ },
12
+ "include": ["vite.config.ts", "islands/**/*.ts"]
13
+ }
@@ -0,0 +1,4 @@
1
+ import { defineConfig } from "vite";
2
+ import { fuzorPlugin } from "fuzor/vite";
3
+
4
+ export default defineConfig({ plugins: [fuzorPlugin()] });
package/bin/index.js DELETED
@@ -1,13 +0,0 @@
1
- #!/usr/bin/env node
2
- import { Command } from "commander";
3
- import { init } from "../dist/init.js";
4
-
5
- const program = new Command();
6
-
7
- // command to start wordpress dev server
8
- program
9
- .command("dev") // Define your custom command, "start"
10
- .description("Start the wp-start process with a custom path")
11
- .action(init);
12
-
13
- await program.parseAsync(process.argv);
@@ -1,7 +0,0 @@
1
- export declare const devDirPath: string;
2
- export declare const pagesDir: string;
3
- export declare const srcDir: string;
4
- export declare const themeDir: string;
5
- export declare const pagesJSON: string;
6
- export declare const snapshotTXTPath: string;
7
- export declare function init(): Promise<void>;
@@ -1,4 +0,0 @@
1
- /**
2
- * @description route/layout builder
3
- */
4
- export declare function router(): Promise<void>;
@@ -1,5 +0,0 @@
1
- type Config = {
2
- targets: Array<any>;
3
- };
4
- export declare function createApphead(mafubaConfig: Config): import('vinxi').App;
5
- export {};
package/dist/init.cjs DELETED
@@ -1,237 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const $=require("@wp-now/wp-now"),s=require("node:path"),r=require("node:fs/promises"),f=require("@parcel/watcher"),S=require("fast-glob");async function E(t){try{try{await r.access(t)}catch{await r.mkdir(t,{recursive:!0})}}catch(e){console.error(e)}}async function j(t,e=""){try{await r.access(t)}catch(a){if(a instanceof Error&&a.code==="ENOENT")await r.writeFile(t,e,{flag:"wx"});else throw console.error(`Error checking or creating file: ${a instanceof Error?a.message:a}`),a}}async function w(t,e){try{const a=await r.readFile(t,"utf8");await r.writeFile(e,a)}catch(a){console.error("Error:",a)}}const m=[".html",".jsx",".tsx",".svelte",".vue",".css"];async function y(t,e){try{const a=`${t}/**/*.{${m.map(l=>l.slice(1)).join(",")}}`,i={pages:(await S(a,{dot:!0})).map(l=>({path:s.basename(l,s.extname(l)),type:"create"}))};await r.writeFile(e,JSON.stringify(i,null,2)),console.log(`JSON saved to ${e}`)}catch(a){console.error("Error creating JSON:",a)}}async function T(t,e){try{const a=await r.readFile(e,"utf-8"),n=JSON.parse(a),_=s.basename(t,s.extname(t));n.pages=n.pages.filter(i=>i.path!==_),await r.writeFile(e,JSON.stringify(n,null,2)),console.log(`Entry with path "${_}" has been removed from ${e}`)}catch(a){console.error("Error deleting entry from JSON:",a)}}const v=(t,e)=>t.includes(s.join(s.sep,e,s.sep)),b=async t=>{const e=s.basename(t.path);v(t.path,"pages")&&await w(s.resolve(t.path),s.resolve(c,"theme","templates",e)),v(t.path,"components")&&await w(s.resolve(t.path),s.resolve(c,"theme","parts",e))},N=async(t,e)=>{switch(t.type){case"create":console.log("create"),await b(t),await y(h,p);break;case"update":console.log("update"),e&&(await b(t),await y(h,p));break;case"delete":console.log("delete"),await T(t.path,p);break}};async function x(){(await f.getEventsSince(g,u)).filter(a=>m.some(n=>a.path.endsWith(n))).forEach(a=>{console.log("since"),N(a,!1)}),await f.subscribe(g,(a,n)=>{if(a){console.error("Error watching files:",a);return}n.filter(i=>m.some(l=>i.path.endsWith(l))).forEach(i=>{N(i,!0)})},{ignore:["node_modules"]}),await f.writeSnapshot(g,u)}const O=()=>`== theme ==
2
-
3
- Contributors: fuzia
4
- Requires at least: 6.7
5
- Tested up to: 6.7
6
- Requires PHP: 5.7
7
- License: GPLv2 or later
8
- License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
-
10
-
11
- == Description ==
12
-
13
- blank theme
14
-
15
-
16
- == Changelog ==
17
-
18
- = 1.0.0 =
19
- * Initial release
20
-
21
-
22
- == Copyright ==
23
-
24
- theme WordPress Theme, (C) 2025 fuzia
25
- theme is distributed under the terms of the GNU GPL.
26
-
27
- This program is free software: you can redistribute it and/or modify
28
- it under the terms of the GNU General Public License as published by
29
- the Free Software Foundation, either version 2 of the License, or
30
- (at your option) any later version.
31
-
32
- This program is distributed in the hope that it will be useful,
33
- but WITHOUT ANY WARRANTY; without even the implied warranty of
34
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35
- GNU General Public License for more details.`,P=()=>`/*
36
- Theme Name: theme
37
- Theme URI:
38
- Author: fuzia
39
- Author URI:
40
- Description: blank theme
41
- Requires at least: 6.7
42
- Tested up to: 6.7
43
- Requires PHP: 5.7
44
- Version:
45
- License: GNU General Public License v2 or later
46
- License URI: http://www.gnu.org/licenses/gpl-2.0.html
47
- Text Domain: theme
48
- Tags:
49
- */`,k=`{
50
- "settings": {
51
- "appearanceTools": true,
52
- "layout": {
53
- "contentSize": "620px",
54
- "wideSize": "1000px"
55
- },
56
- "spacing": {
57
- "units": [
58
- "%",
59
- "px",
60
- "em",
61
- "rem",
62
- "vh",
63
- "vw"
64
- ]
65
- },
66
- "typography": {
67
- "fontFamilies": [
68
- {
69
- "fontFamily": "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif",
70
- "name": "System Font",
71
- "slug": "system-font"
72
- }
73
- ]
74
- },
75
- "useRootPaddingAwareAlignments": true
76
- },
77
- "templateParts": [
78
- {
79
- "area": "header",
80
- "name": "header"
81
- },
82
- {
83
- "area": "footer",
84
- "name": "footer"
85
- }
86
- ],
87
- "version": 3,
88
- "$schema": "https://schemas.wp.org/wp/6.7/theme.json"
89
- }`,I=`<?php
90
- // Flag to prevent recursive execution
91
- $prevent_recursive_execution = false;
92
-
93
- function create_or_update_or_delete_pages_from_json() {
94
- global $prevent_recursive_execution;
95
-
96
- // Prevent recursive execution
97
- if ($prevent_recursive_execution) {
98
- return;
99
- }
100
-
101
- // Path to the JSON file
102
- $json_file = get_template_directory() . '/pages.json';
103
-
104
- // Check if the file exists
105
- if (file_exists($json_file)) {
106
- // Read the JSON file
107
- $json_data = file_get_contents($json_file);
108
- $pages = json_decode($json_data, true)['pages'];
109
-
110
- // Initialize an array to store pages that are not deleted
111
- $updated_pages = [];
112
-
113
- // Get all pages from the database
114
- $all_pages = get_pages(array(
115
- 'post_status' => 'any'
116
- ));
117
-
118
- // Check if $all_pages is an array
119
- if (is_array($all_pages)) {
120
- // Create an array of slugs for all pages in the database
121
- $db_page_slugs = array_map(function($page) {
122
- return $page->post_name;
123
- }, $all_pages);
124
- } else {
125
- $db_page_slugs = [];
126
- }
127
-
128
- // Loop through the pages array
129
- foreach ($pages as $page) {
130
- $page_slug = $page['path'];
131
- $page_type = $page['type'];
132
-
133
- // Use WP_Query to find the page by slug
134
- $query = new WP_Query(array(
135
- 'post_type' => 'page',
136
- 'name' => $page_slug,
137
- 'post_status' => 'any',
138
- 'posts_per_page' => 1,
139
- 'no_found_rows' => true,
140
- 'ignore_sticky_posts' => true,
141
- 'update_post_term_cache' => false,
142
- 'update_post_meta_cache' => false,
143
- ));
144
-
145
- $page_check = !empty($query->posts) ? $query->posts[0] : null;
146
-
147
- if ($page_type === 'create') {
148
- // If the page exists, update it
149
- if ($page_check) {
150
- $page_id = $page_check->ID;
151
- $my_post = array(
152
- 'ID' => $page_id,
153
- 'post_title' => ucfirst(str_replace('-', ' ', $page_slug)),
154
- 'post_name' => $page_slug,
155
- 'post_status' => 'publish',
156
- 'post_author' => 1,
157
- 'post_type' => 'page',
158
- 'page_template' => $page_slug
159
- );
160
-
161
- // Update the post in the database
162
- wp_update_post($my_post);
163
- } else {
164
- // If the page doesn't exist, create it
165
- $my_post = array(
166
- 'post_title' => ucfirst(str_replace('-', ' ', $page_slug)),
167
- 'post_name' => $page_slug,
168
- 'post_status' => 'publish',
169
- 'post_author' => 1,
170
- 'post_type' => 'page',
171
- 'page_template' => $page_slug
172
- );
173
-
174
- // Insert the post into the database
175
- wp_insert_post($my_post);
176
- }
177
-
178
- // Add the page to the updated pages array
179
- $updated_pages[] = $page;
180
- } elseif ($page_type === 'delete' && $page_check) {
181
- // If the page exists and the type is 'delete', delete it
182
- wp_delete_post($page_check->ID, true);
183
-
184
- // Remove the "create" entry of the deleted page
185
- $updated_pages = array_filter($updated_pages, function($p) use ($page_slug) {
186
- return $p['path'] !== $page_slug;
187
- });
188
- }
189
- }
190
-
191
- // Update the JSON file with the remaining pages
192
- $new_json_data = json_encode(['pages' => $updated_pages], JSON_PRETTY_PRINT);
193
- file_put_contents($json_file, $new_json_data);
194
- }
195
- }
196
-
197
- // Hook the function to the 'init' action
198
- add_action('init', 'create_or_update_or_delete_pages_from_json');
199
-
200
- // Function to remove page from JSON before deletion
201
- function remove_page_from_json_before_delete($post_id) {
202
- global $prevent_recursive_execution;
203
-
204
- // Check if the post type is 'page'
205
- if (get_post_type($post_id) !== 'page') {
206
- return;
207
- }
208
-
209
- // Path to the JSON file
210
- $json_file = get_template_directory() . '/pages.json';
211
-
212
- // Check if the file exists
213
- if (file_exists($json_file)) {
214
- // Read the JSON file
215
- $json_data = file_get_contents($json_file);
216
- $pages = json_decode($json_data, true)['pages'];
217
-
218
- // Get the slug of the page being deleted
219
- $page_slug = get_post_field('post_name', $post_id);
220
-
221
- // Remove the page entry from the JSON data
222
- $updated_pages = array_filter($pages, function($page) use ($page_slug) {
223
- return $page['path'] !== $page_slug;
224
- });
225
-
226
- // Update the JSON file with the remaining pages
227
- $new_json_data = json_encode(['pages' => array_values($updated_pages)], JSON_PRETTY_PRINT);
228
- file_put_contents($json_file, $new_json_data);
229
-
230
- // Set the flag to prevent recursive execution
231
- $prevent_recursive_execution = true;
232
- }
233
- }
234
-
235
- // Hook the function to the 'wp_trash_post' and 'wp_delete_post' actions
236
- add_action('wp_trash_post', 'remove_page_from_json_before_delete', 10, 1);
237
- add_action('wp_delete_post', 'remove_page_from_json_before_delete', 10, 1);`;async function R(t){try{await r.access(t),await r.unlink(t)}catch(e){e instanceof Error&&e.code==="ENOENT"||console.error(`Error checking or removing file "${t}":`,e)}}const d=process.cwd(),c=s.resolve(d,"__dev"),h=s.resolve(d,"src","pages"),g=s.resolve(d,"src"),o=s.resolve(c,"theme"),p=s.resolve(o,"pages.json"),u=s.resolve(c,"cache","snapshot.txt"),J=[{type:"del",path:p},{type:"dir",path:c},{type:"dir",path:o},{type:"file",path:p,content:JSON.stringify({})},{type:"dir",path:s.resolve(o,"parts")},{type:"dir",path:s.resolve(o,"templates")},{type:"dir",path:s.resolve(c,"cache")},{type:"file",path:u,content:""},{type:"file",path:s.resolve(d,"src","theme.json"),content:k},{type:"file",path:s.resolve(o,"readme.txt"),content:O()},{type:"file",path:s.resolve(o,"style.css"),content:P()},{type:"file",path:s.resolve(o,"functions.php"),content:I}];async function F(){for await(const e of J)switch(e.type){case"dir":await E(e.path);break;case"file":await j(e.path,e.content);break;case"del":await R(e.path);break}await y(h,p);const t=await $.getWpNowConfig({path:o});await $.startServer(t);try{await x()}catch(e){if(e instanceof Error&&e.message==="ENOENT")console.error("Error executing wp-start:",e.message);else throw console.error(`Error checking or creating file: ${e instanceof Error?e.message:e}`),e}}exports.devDirPath=c;exports.init=F;exports.pagesDir=h;exports.pagesJSON=p;exports.snapshotTXTPath=u;exports.srcDir=g;exports.themeDir=o;