fusee-framework 1.6.0 → 1.8.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 (129) hide show
  1. package/README.md +145 -123
  2. package/app/benchmark/benchmark.js +633 -0
  3. package/app/benchmark/index.html +102 -0
  4. package/app/benchmark/styles.css +249 -0
  5. package/app/components/Counter.js +17 -7
  6. package/app/components/CounterSection.js +3 -4
  7. package/app/main.js +50 -62
  8. package/app/main.ts +78 -63
  9. package/app/pages/404.js +16 -0
  10. package/app/pages/[...all].js +35 -0
  11. package/app/pages/[...all].ts +35 -0
  12. package/app/pages/_layout.js +53 -0
  13. package/app/pages/_layout.ts +26 -0
  14. package/app/pages/about.js +23 -0
  15. package/app/pages/about.ts +29 -0
  16. package/app/pages/async-work.js +65 -0
  17. package/app/pages/composables.js +158 -0
  18. package/app/pages/composables.ts +158 -0
  19. package/app/pages/dynamic.js +40 -0
  20. package/app/pages/dynamic.ts +40 -0
  21. package/app/pages/index.js +137 -0
  22. package/app/pages/index.ts +87 -0
  23. package/app/pages/login.ts +21 -0
  24. package/app/pages/objects/[id].js +56 -0
  25. package/app/pages/objects/[id].ts +56 -0
  26. package/app/pages/posts/[category]/[slug].js +56 -0
  27. package/app/pages/posts/[category]/[slug].ts +56 -0
  28. package/app/pages/router-example.js +79 -0
  29. package/app/pages/router-example.ts +56 -0
  30. package/app/pages/scroll-demo.ts +102 -0
  31. package/app/pages/test-for.js +65 -0
  32. package/app/pages/test-for.ts +80 -0
  33. package/app/pages/users/[id].js +24 -0
  34. package/app/pages/users/[id].ts +46 -0
  35. package/app/pages/users/index.js +22 -0
  36. package/app/pages/users/index.ts +29 -0
  37. package/app/pages/users.js +43 -0
  38. package/app/pages/users.ts +78 -0
  39. package/app/providers/ChildComponent.js +8 -2
  40. package/app/providers/ChildComponent.ts +47 -47
  41. package/app/providers/GrandchildComponent.js +19 -0
  42. package/app/providers/ParentComponent.js +5 -1
  43. package/app/routes/About.js +1 -1
  44. package/app/routes/About.ts +1 -1
  45. package/app/routes/AuthRoutes.ts +41 -0
  46. package/app/routes/Home.js +9 -0
  47. package/app/routes/NotFound.js +16 -0
  48. package/app/routes/NotFound.ts +16 -0
  49. package/app/routes/RouterExample.js +78 -0
  50. package/app/routes/RouterExample.ts +56 -0
  51. package/app/routes/TestResource.js +47 -0
  52. package/app/routes/WildcardDemo.js +35 -0
  53. package/app/routes/WildcardDemo.ts +35 -0
  54. package/app/services.js +15 -0
  55. package/auto-imports.d.ts +9 -0
  56. package/bin/create-fusee-linux +0 -0
  57. package/bin/create-fusee-mac-arm64 +0 -0
  58. package/bin/create-fusee-mac-intel +0 -0
  59. package/bin/create-fusee-win.exe +0 -0
  60. package/bin/create-fusee.exe +0 -0
  61. package/bin/index.js +38 -0
  62. package/create-fusee-go/cmd/generate.go +72 -0
  63. package/create-fusee-go/cmd/init.go +38 -0
  64. package/create-fusee-go/cmd/root.go +121 -0
  65. package/create-fusee-go/go.mod +10 -0
  66. package/create-fusee-go/go.sum +10 -0
  67. package/create-fusee-go/internal/assets/assets.go +78 -0
  68. package/create-fusee-go/internal/assets/embed/framework/auto-import-preset.js +9 -0
  69. package/create-fusee-go/internal/assets/embed/framework/core/compiler.js +253 -0
  70. package/create-fusee-go/internal/assets/embed/framework/core/component.js +266 -0
  71. package/create-fusee-go/internal/assets/embed/framework/core/composable.js +27 -0
  72. package/create-fusee-go/internal/assets/embed/framework/core/directives.js +875 -0
  73. package/create-fusee-go/internal/assets/embed/framework/core/evaluator.js +153 -0
  74. package/create-fusee-go/internal/assets/embed/framework/core/event-delegation.js +191 -0
  75. package/create-fusee-go/internal/assets/embed/framework/core/signal.js +412 -0
  76. package/create-fusee-go/internal/assets/embed/framework/core/store.js +81 -0
  77. package/create-fusee-go/internal/assets/embed/framework/index.d.ts +3 -0
  78. package/create-fusee-go/internal/assets/embed/framework/index.js +10 -0
  79. package/create-fusee-go/internal/assets/embed/framework/router/file-router.js +177 -0
  80. package/create-fusee-go/internal/assets/embed/framework/router/router.js +462 -0
  81. package/create-fusee-go/internal/assets/embed/framework/types/compiler.d.ts +15 -0
  82. package/create-fusee-go/internal/assets/embed/framework/types/component.d.ts +88 -0
  83. package/create-fusee-go/internal/assets/embed/framework/types/composable.d.ts +14 -0
  84. package/create-fusee-go/internal/assets/embed/framework/types/directives.d.ts +55 -0
  85. package/create-fusee-go/internal/assets/embed/framework/types/evaluator.d.ts +13 -0
  86. package/create-fusee-go/internal/assets/embed/framework/types/event-delegation.d.ts +32 -0
  87. package/create-fusee-go/internal/assets/embed/framework/types/index.d.ts +22 -0
  88. package/create-fusee-go/internal/assets/embed/framework/types/router.d.ts +32 -0
  89. package/create-fusee-go/internal/assets/embed/framework/types/signal.d.ts +79 -0
  90. package/create-fusee-go/internal/assets/embed/framework/types/store.d.ts +8 -0
  91. package/create-fusee-go/internal/assets/templates/Counter.tmpl +26 -0
  92. package/create-fusee-go/internal/assets/templates/component.tmpl +11 -0
  93. package/create-fusee-go/internal/assets/templates/components/Loading.tmpl +24 -0
  94. package/create-fusee-go/internal/assets/templates/index.html.tmpl +15 -0
  95. package/create-fusee-go/internal/assets/templates/main.tmpl +14 -0
  96. package/create-fusee-go/internal/assets/templates/package.json.tmpl +14 -0
  97. package/create-fusee-go/internal/assets/templates/page.tmpl +12 -0
  98. package/create-fusee-go/internal/assets/templates/pages/about.tmpl +20 -0
  99. package/create-fusee-go/internal/assets/templates/pages/index.tmpl +22 -0
  100. package/create-fusee-go/internal/assets/templates/pages/layout.tmpl +18 -0
  101. package/create-fusee-go/internal/assets/templates/tsconfig.json.tmpl +14 -0
  102. package/create-fusee-go/internal/assets/templates/vite.config.js.tmpl +18 -0
  103. package/create-fusee-go/main.go +7 -0
  104. package/framework/auto-import-preset.js +13 -9
  105. package/framework/core/compiler.js +252 -249
  106. package/framework/core/component.js +279 -260
  107. package/framework/core/di.js +187 -0
  108. package/framework/core/directives.js +819 -786
  109. package/framework/core/evaluator.js +153 -70
  110. package/framework/core/event-delegation.js +33 -14
  111. package/framework/core/reconcile.js +151 -0
  112. package/framework/core/signal.js +679 -403
  113. package/framework/core/store.js +322 -81
  114. package/framework/index.js +12 -11
  115. package/framework/router/file-router.js +177 -0
  116. package/framework/router/router.js +554 -80
  117. package/framework/types/component.d.ts +89 -88
  118. package/framework/types/di.d.ts +43 -0
  119. package/framework/types/event-delegation.d.ts +0 -58
  120. package/framework/types/index.d.ts +32 -22
  121. package/framework/types/reconcile.d.ts +7 -0
  122. package/framework/types/router.d.ts +42 -15
  123. package/framework/types/signal.d.ts +147 -78
  124. package/framework/types/store.d.ts +66 -8
  125. package/index.html +638 -626
  126. package/package.json +5 -3
  127. package/tsconfig.json +1 -0
  128. package/vite.config.js +7 -1
  129. /package/{framework → create-fusee-go/internal/assets/embed/framework}/bin/create-fusee.js +0 -0
@@ -0,0 +1,32 @@
1
+ import type { ComponentApi, ComponentFactory } from './component'
2
+ import type { Signal } from './signal'
3
+
4
+ export type Route = {
5
+ path: string | string[]
6
+ component: ComponentFactory<any>
7
+ children?: Route[]
8
+ }
9
+
10
+ export type Router = {
11
+ navigate: (path: string) => void
12
+ destroy: () => void
13
+ }
14
+
15
+ export type RouteParams = Record<string, string>
16
+
17
+ export declare const currentRoute: Signal<string>
18
+ export declare const routeParams: Signal<RouteParams>
19
+ export declare const matchedRoutes: Signal<Route[]>
20
+
21
+ export declare function createRouter(routes: Route[], options?: { cacheSize?: number; routerViewTimeout?: number }): Router
22
+ export declare function navigate(path: string): void
23
+ export declare function mountOutlet(el: HTMLElement): void
24
+
25
+ export type FileRouterOptions = {
26
+ loadingComponent?: ComponentFactory<any>
27
+ }
28
+
29
+ export declare function generateRoutes(
30
+ globResults: Record<string, () => Promise<any>>,
31
+ options?: FileRouterOptions
32
+ ): Route[]
@@ -0,0 +1,79 @@
1
+ export type SignalAccessor<T> = {
2
+ (): T;
3
+ (newValue: T): void;
4
+ isSignal: boolean;
5
+ }
6
+
7
+ export interface ReactiveArrayMethods<T> {
8
+ map<U>(callbackfn: (value: T, index: number, array: T[]) => U): Computed<U[]>;
9
+ filter(predicate: (value: T, index: number, array: T[]) => boolean): Computed<T[]>;
10
+ slice(start?: number, end?: number): Computed<T[]>;
11
+ reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): Computed<U>;
12
+ reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): Computed<T>;
13
+ find(predicate: (value: T, index: number, obj: T[]) => boolean): Computed<T | undefined>;
14
+ findLast(predicate: (value: T, index: number, obj: T[]) => boolean): Computed<T | undefined>;
15
+ findIndex(predicate: (value: T, index: number, obj: T[]) => boolean): Computed<number>;
16
+ findLastIndex(predicate: (value: T, index: number, obj: T[]) => boolean): Computed<number>;
17
+ every(predicate: (value: T, index: number, array: T[]) => boolean): Computed<boolean>;
18
+ some(predicate: (value: T, index: number, array: T[]) => boolean): Computed<boolean>;
19
+ includes(searchElement: T, fromIndex?: number): Computed<boolean>;
20
+ indexOf(searchElement: T, fromIndex?: number): Computed<number>;
21
+ lastIndexOf(searchElement: T, fromIndex?: number): Computed<number>;
22
+ at(index: number): Computed<T | undefined>;
23
+ concat(...items: (T | T[])[]): Computed<T[]>;
24
+ flat<depth extends number = 1>(depth?: depth): Computed<any[]>;
25
+ flatMap<U>(callback: (value: T, index: number, array: T[]) => U | U[]): Computed<U[]>;
26
+ join(separator?: string): Computed<string>;
27
+ }
28
+
29
+ export type ArraySignalAccessor<T extends any[]> = SignalAccessor<T> & ReactiveArrayMethods<T[number]> & {
30
+ push(...items: T[number][]): number;
31
+ pop(): T[number] | undefined;
32
+ shift(): T[number] | undefined;
33
+ unshift(...items: T[number][]): number;
34
+ splice(start: number, deleteCount: number, ...items: T[number][]): T[number][];
35
+ remove(predicate: (item: T[number], index: number) => boolean): void;
36
+ clear(): void;
37
+ sort(compareFn?: (a: T[number], b: T[number]) => number): ArraySignalAccessor<T>;
38
+ reverse(): ArraySignalAccessor<T>;
39
+ }
40
+
41
+ export type ComputedAccessor<T> = {
42
+ (): T;
43
+ isSignal: boolean;
44
+ readonly: true;
45
+ } & (T extends any[] ? ReactiveArrayMethods<T[number]> : {})
46
+
47
+ export type Signal<T = any> = SignalAccessor<T> & (T extends any[] ? ReactiveArrayMethods<T[number]> : {})
48
+ export type Computed<T = any> = ComputedAccessor<T> & (T extends any[] ? ReactiveArrayMethods<T[number]> : {})
49
+
50
+ type EffectRunner = {
51
+ (): void;
52
+ deps: Set<Set<EffectRunner>>;
53
+ }
54
+
55
+ export type WatchSource<T = any> = (() => T) | Signal<T> | Computed<T>
56
+ export type WatchCallback<T = any> = (newValue: T, oldValue: T | undefined, onCleanup: (fn: () => void) => void) => void
57
+
58
+ export interface WatchOptions {
59
+ immediate?: boolean;
60
+ equals?: (a: any, b: any) => boolean;
61
+ }
62
+
63
+ export declare function signal<T extends any[]>(initialValue: T): ArraySignalAccessor<T>
64
+ export declare function signal<T>(initialValue: T): SignalAccessor<T>
65
+ export declare function effect(fn: () => void): () => void
66
+ export declare function computed<T>(fn: () => T): Computed<T>
67
+ export declare function batch<T>(fn: () => T): T
68
+ export declare function untrack<T>(fn: () => T): T
69
+ export declare function watch<T>(source: WatchSource<T>, callback: WatchCallback<T>, options?: WatchOptions): () => void
70
+ export declare function watch<T extends any[]>(
71
+ sources: [...{ [K in keyof T]: WatchSource<T[K]> }],
72
+ callback: (newValue: T, oldValue: T | undefined, onCleanup: (fn: () => void) => void) => void,
73
+ options?: WatchOptions
74
+ ): () => void
75
+ export declare function inspect(...args: any[]): (() => void) | void
76
+ export declare function onCleanup(fn: () => void): void
77
+
78
+ declare function setEffectHook(fn: (eff: any) => void): void
79
+
@@ -0,0 +1,8 @@
1
+ export function defineStore<T>(id: string, setup: () => T): () => T;
2
+ export function resetStore(id: string): void;
3
+ export function clearStores(): void;
4
+ export function registerStorePlugin(plugin: (store: any, id: string) => void): void;
5
+
6
+ declare global {
7
+ function defineStore<T>(id: string, setup: () => T): () => T;
8
+ }
@@ -0,0 +1,26 @@
1
+ {{if .IsTS}}interface CounterResult {
2
+ count: Signal<number>
3
+ inc: () => void
4
+ dec: () => void
5
+ template: string
6
+ }
7
+
8
+ export const Counter = defineComponent({
9
+ setup(): CounterResult {
10
+ {{else}}export const Counter = defineComponent({
11
+ setup() {
12
+ {{end}} const count = signal{{if .IsTS}}<number>{{end}}(0);
13
+ return {
14
+ count,
15
+ inc: () => count(count() + 1),
16
+ dec: () => count(count() - 1),
17
+ template: `
18
+ <div style="display:flex; align-items:center; gap:2rem; background:#111; padding:2rem; border-radius:20px; border:1px solid #222;">
19
+ <button @click="dec" style="{{.BtnStyle}}">-</button>
20
+ <span style="font-size:3rem; font-weight:bold; min-width:60px; text-align:center;">{{`{{`}} count {{`}}` }}</span>
21
+ <button @click="inc" style="{{.BtnStyle}}">+</button>
22
+ </div>
23
+ `
24
+ };
25
+ }
26
+ });
@@ -0,0 +1,11 @@
1
+ export const {{.ProjectName}} = defineComponent({
2
+ setup() {
3
+ return {
4
+ template: `
5
+ <div class="component-{{.ProjectName}}">
6
+ <h3>{{.ProjectName}} Component</h3>
7
+ </div>
8
+ `
9
+ };
10
+ }
11
+ });
@@ -0,0 +1,24 @@
1
+ export const Loading = defineComponent({
2
+ setup() {
3
+ return {
4
+ template: `
5
+ <div style="display: flex; justify-content: center; align-items: center; padding: 5rem;">
6
+ <div style="
7
+ width: 50px;
8
+ height: 50px;
9
+ border: 5px solid #222;
10
+ border-top: 5px solid #ff3333;
11
+ border-radius: 50%;
12
+ animation: spin 1s linear infinite;
13
+ "></div>
14
+ <style>
15
+ @keyframes spin {
16
+ 0% { transform: rotate(0deg); }
17
+ 100% { transform: rotate(360deg); }
18
+ }
19
+ </style>
20
+ </div>
21
+ `
22
+ }
23
+ }
24
+ })
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Fusée App</title>
6
+ <style>
7
+ body { background: #050505; color: white; font-family: system-ui, margin: 0; }
8
+ #app { min-height: 100vh; }
9
+ </style>
10
+ </head>
11
+ <body>
12
+ <div id="app"></div>
13
+ <script type="module" src="/app/main.{{.Ext}}"></script>
14
+ </body>
15
+ </html>
@@ -0,0 +1,14 @@
1
+ import { createRouter, mountOutlet, generateRoutes } from 'fusee-framework';
2
+ import { Loading } from './components/Loading';
3
+
4
+ const pages = import.meta.glob('./pages/**/*.{js,ts}');
5
+ const routes = generateRoutes(pages, {
6
+ loadingComponent: Loading
7
+ });
8
+
9
+ createRouter(routes);
10
+
11
+ const root = document.getElementById('app');
12
+ if (root) {
13
+ mountOutlet(root);
14
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "{{.ProjectName}}",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "scripts": {
6
+ "dev": "vite",
7
+ "build": "vite build"
8
+ },
9
+ "devDependencies": {
10
+ "vite": "^5.0.0",
11
+ "unplugin-auto-import": "^0.17.0"{{if .IsTS}},
12
+ "typescript": "^5.0.0"{{end}}
13
+ }
14
+ }
@@ -0,0 +1,12 @@
1
+ export const {{.ProjectName}} = defineComponent({
2
+ setup() {
3
+ return {
4
+ template: `
5
+ <div class="page-{{.ProjectName}}">
6
+ <h1>{{.ProjectName}} Page</h1>
7
+ <p>Generated by Fusée CLI</p>
8
+ </div>
9
+ `
10
+ };
11
+ }
12
+ });
@@ -0,0 +1,20 @@
1
+ export const About = defineComponent({
2
+ setup() {
3
+ return {
4
+ template: `
5
+ <div style="max-width: 800px; margin: 0 auto; padding-top: 4rem;">
6
+ <h1 style="color: #ff3333; margin-bottom: 2rem;">About Fusée</h1>
7
+ <p style="line-height: 1.6; font-size: 1.2rem; opacity: 0.9;">
8
+ Fusée is a high-performance, reactive framework inspired by SolidJS and Nuxt.
9
+ It features a unique template engine that works directly with the DOM,
10
+ providing a seamless development experience with minimal overhead.
11
+ </p>
12
+ <div style="margin-top: 3rem; padding: 2rem; background: #111; border-radius: 15px; border-left: 4px solid #ff3333;">
13
+ <h3 style="margin-top: 0;">File-Based Routing</h3>
14
+ <p>This page was automatically registered based on its filename in the <code>app/pages</code> directory.</p>
15
+ </div>
16
+ </div>
17
+ `
18
+ };
19
+ }
20
+ });
@@ -0,0 +1,22 @@
1
+ export const Index = defineComponent({
2
+ setup() {
3
+ const count = signal(0);
4
+ return {
5
+ count,
6
+ inc: () => count(count() + 1),
7
+ template: `
8
+ <div style="text-align: center; padding-top: 4rem;">
9
+ <h1 style="font-size: 4rem; color: #ff3333; margin-bottom: 1rem;">Welcome Home</h1>
10
+ <p style="opacity: 0.7; margin-bottom: 3rem;">File-based routing and layouts are now active!</p>
11
+
12
+ <div style="display: inline-flex; align-items: center; gap: 2rem; background: #111; padding: 2rem; border-radius: 20px; border: 1px solid #222;">
13
+ <span style="font-size: 3rem; font-weight: bold;">{{`{{`}} count {{`}}` }}</span>
14
+ <button @click="inc" style="background: #ff3333; color: white; border: none; padding: 1rem 2rem; border-radius: 10px; cursor: pointer; font-weight: bold;">
15
+ Increment
16
+ </button>
17
+ </div>
18
+ </div>
19
+ `
20
+ };
21
+ }
22
+ });
@@ -0,0 +1,18 @@
1
+ export const Layout = defineComponent({
2
+ setup() {
3
+ return {
4
+ template: `
5
+ <div style="min-height: 100vh; display: flex; flex-direction: column;">
6
+ <nav style="background: #111; padding: 1rem 2rem; display: flex; gap: 2rem; border-bottom: 1px solid #222;">
7
+ <a href="/" style="color: #ff3333; text-decoration: none; font-weight: bold;">Fusée 🚀</a>
8
+ <a href="/about" style="color: #eee; text-decoration: none; opacity: 0.8;">About</a>
9
+ </nav>
10
+ <main style="flex: 1; padding: 2rem;" data-router-view></main>
11
+ <footer style="padding: 2rem; border-top: 1px solid #222; text-align: center; opacity: 0.5; font-size: 0.8rem;">
12
+ Built with Fusée Framework
13
+ </footer>
14
+ </div>
15
+ `
16
+ };
17
+ }
18
+ });
@@ -0,0 +1,14 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "strict": true,
7
+ "esModuleInterop": true,
8
+ "skipLibCheck": true,
9
+ "paths": {
10
+ "fusee-framework": ["./framework/types/index.d.ts"]
11
+ }
12
+ },
13
+ "include": ["app/**/*", "framework/**/*", "auto-imports.d.ts"]
14
+ }
@@ -0,0 +1,18 @@
1
+ import { defineConfig } from 'vite';
2
+ import path from 'path';
3
+ import AutoImport from 'unplugin-auto-import/vite';
4
+ import { FuseePreset } from './framework/auto-import-preset.js';
5
+
6
+ export default defineConfig({
7
+ resolve: {
8
+ alias: {
9
+ 'fusee-framework': path.resolve(__dirname, './framework')
10
+ }
11
+ },
12
+ plugins: [
13
+ AutoImport({
14
+ imports: [FuseePreset],
15
+ dts: true // Generates auto-imports.d.ts
16
+ })
17
+ ]
18
+ });
@@ -0,0 +1,7 @@
1
+ package main
2
+
3
+ import "create-fusee/cmd"
4
+
5
+ func main() {
6
+ cmd.Execute()
7
+ }
@@ -1,9 +1,13 @@
1
- export const FuseePreset = {
2
- 'fusee-framework': [
3
- 'signal', 'computed', 'effect', 'watch',
4
- 'batch', 'untrack', 'inspect',
5
- 'defineComponent', 'onMount', 'onUnmount',
6
- 'directive',
7
- 'mountOutlet', 'mountTemplate', 'emit'
8
- ]
9
- }
1
+ export const FuseePreset = {
2
+ 'fusee-framework': [
3
+ 'signal', 'computed', 'effect', 'watch',
4
+ 'batch', 'untrack', 'inspect', 'onCleanup',
5
+ 'defineComponent', 'onMount', 'onUnmount',
6
+ 'directive',
7
+ 'mountOutlet', 'mountTemplate', 'emit',
8
+ 'defineStore', 'resetStore', 'clearStores',
9
+ 'registerStorePlugin', 'useNestedStore',
10
+ 'storeToRefs', 'storeToState', 'storeToGetters',
11
+ 'MutationType'
12
+ ]
13
+ }