fusee-framework 2.7.0 → 2.7.2

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 (61) hide show
  1. package/README.md +98 -26
  2. package/bin/create-fusee-linux +0 -0
  3. package/bin/create-fusee-mac-arm64 +0 -0
  4. package/bin/create-fusee-mac-intel +0 -0
  5. package/bin/create-fusee-win.exe +0 -0
  6. package/framework/auto-import-preset.js +20 -12
  7. package/framework/auto-imports.d.ts +68 -39
  8. package/framework/core/compiler.js +310 -310
  9. package/framework/core/component-core.js +445 -0
  10. package/framework/core/component.js +11 -440
  11. package/framework/core/composable.js +29 -29
  12. package/framework/core/h.js +119 -44
  13. package/framework/core/jsx-helpers.js +11 -2
  14. package/framework/core/jsx-runtime.js +73 -73
  15. package/framework/core/rust-compiler/pkg/fusee_compiler_bg.wasm +0 -0
  16. package/framework/core/store.js +333 -333
  17. package/framework/globals.js +42 -0
  18. package/framework/index.js +22 -55
  19. package/framework/router/file-router.js +184 -184
  20. package/framework/server/actions.js +183 -183
  21. package/framework/server/generate-manifest.js +3 -3
  22. package/framework/types/component.d.ts +97 -86
  23. package/framework/types/index.d.ts +118 -117
  24. package/package.json +83 -80
  25. package/framework/core/rust-compiler/Cargo.toml +0 -31
  26. package/framework/core/rust-compiler/README.md +0 -69
  27. package/framework/core/rust-compiler/pkg/README.md +0 -69
  28. package/framework/core/rust-compiler/pkg/fusee_compiler.d.ts +0 -6
  29. package/framework/core/rust-compiler/pkg/fusee_compiler.js +0 -9
  30. package/framework/core/rust-compiler/pkg/fusee_compiler_bg.js +0 -137
  31. package/framework/core/rust-compiler/pkg/fusee_compiler_bg.wasm.d.ts +0 -11
  32. package/framework/core/rust-compiler/pkg/package.json +0 -18
  33. package/framework/core/rust-compiler/src/ast.rs +0 -274
  34. package/framework/core/rust-compiler/src/errors.rs +0 -204
  35. package/framework/core/rust-compiler/src/generator.rs +0 -583
  36. package/framework/core/rust-compiler/src/lexer.rs +0 -414
  37. package/framework/core/rust-compiler/src/lib.rs +0 -87
  38. package/framework/core/rust-compiler/src/main_compiler.rs +0 -165
  39. package/framework/core/rust-compiler/src/parser.rs +0 -516
  40. package/framework/core/rust-compiler/src/ssr_generator.rs +0 -688
  41. package/framework/core/rust-compiler/src/transformer.rs +0 -562
  42. package/framework/core/rust-compiler/src/utils.rs +0 -10
  43. package/framework/engine-go/actions.go +0 -112
  44. package/framework/engine-go/cmd/server/main.go +0 -233
  45. package/framework/engine-go/comet/comet.go +0 -41
  46. package/framework/engine-go/comet/fragment.go +0 -51
  47. package/framework/engine-go/dispatcher.go +0 -120
  48. package/framework/engine-go/elements.go +0 -248
  49. package/framework/engine-go/evalexpr/evalexpr.go +0 -733
  50. package/framework/engine-go/go.mod +0 -3
  51. package/framework/engine-go/hydration.go +0 -43
  52. package/framework/engine-go/load-helpers.go +0 -29
  53. package/framework/engine-go/manifest.go +0 -41
  54. package/framework/engine-go/reactive.go +0 -123
  55. package/framework/engine-go/render.go +0 -635
  56. package/framework/engine-go/reqcontext.go +0 -48
  57. package/framework/engine-go/router.go +0 -85
  58. package/framework/engine-go/rustast/rustast.go +0 -317
  59. package/framework/engine-go/ssr.go +0 -103
  60. package/framework/engine-go/static-assets.go +0 -139
  61. package/framework/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
@@ -0,0 +1,42 @@
1
+ // ─── Opt-in Globals ───────────────────────────────────────────────────────────
2
+ // `import 'fusee-framework/globals'` copies every fusée export onto globalThis, for code
3
+ // that calls the API without imports (plain <script> tags, quick demos). Apps built with
4
+ // Vite get auto-imports instead and should not load this: it keeps the whole framework
5
+ // in the bundle, since bundlers can no longer drop unused modules.
6
+ import * as signalModule from './core/signal.js'
7
+ import * as resourceModule from './core/resource.js'
8
+ import * as componentModule from './core/component.js'
9
+ import * as elementModule from './core/element.js'
10
+ import * as diModule from './core/di.js'
11
+ import * as routerModule from './router/router.js'
12
+ import * as fileRouterModule from './router/file-router.js'
13
+ import * as compilerModule from './core/compiler.js'
14
+ import * as composableModule from './core/composable.js'
15
+ import * as storeModule from './core/store.js'
16
+ import * as directivesModule from './core/directives.js'
17
+ import * as reconcileModule from './core/reconcile.js'
18
+ import * as actionsModule from './server/actions.js'
19
+ import * as appRegistryModule from './core/app-registry.js'
20
+ import * as pluginsModule from './core/plugins.js'
21
+ import { emit } from './index.js'
22
+
23
+ if (typeof globalThis !== 'undefined') {
24
+ Object.assign(globalThis, {
25
+ ...signalModule,
26
+ ...resourceModule,
27
+ ...componentModule,
28
+ ...elementModule,
29
+ ...diModule,
30
+ ...routerModule,
31
+ ...fileRouterModule,
32
+ ...compilerModule,
33
+ ...composableModule,
34
+ ...storeModule,
35
+ ...directivesModule,
36
+ ...reconcileModule,
37
+ ...actionsModule,
38
+ ...appRegistryModule,
39
+ ...pluginsModule,
40
+ emit
41
+ })
42
+ }
@@ -1,55 +1,22 @@
1
- // ─── Framework Public API ─────────────────────────────────────────────────────
2
- import * as signalModule from './core/signal.js'
3
- import * as resourceModule from './core/resource.js'
4
- import * as componentModule from './core/component.js'
5
- import * as elementModule from './core/element.js'
6
- import * as diModule from './core/di.js'
7
- import * as routerModule from './router/router.js'
8
- import * as fileRouterModule from './router/file-router.js'
9
- import * as compilerModule from './core/compiler.js'
10
- import * as composableModule from './core/composable.js'
11
- import * as storeModule from './core/store.js'
12
- import * as directivesModule from './core/directives.js'
13
- import * as reconcileModule from './core/reconcile.js'
14
- import * as actionsModule from './server/actions.js'
15
- import * as appRegistryModule from './core/app-registry.js'
16
- import * as pluginsModule from './core/plugins.js'
17
-
18
- export const emit = () => console.warn('[framework] emit() can only be used inside component setup()')
19
-
20
- export { signal, computed, effect, batch, untrack, inspect, watch, onCleanup, resource, createSuspense, scheduleAsyncJob } from './core/signal.js'
21
- export { defineResource } from './core/resource.js'
22
- export { defineComponent, defineAsyncComponent, onMount, onUnmount, parseSlots, provide, inject, getCurrentInstance } from './core/component.js'
23
- export { defineElement, toCustomElement, css, unsafeCSS } from './core/element.js'
24
- export { InjectionToken, provideGlobal } from './core/di.js'
25
- export { createRouter, navigate, mountOutlet, currentRoute, routeParams, routeQuery, matchedRoutes } from './router/router.js'
26
- export { generateRoutes } from './router/file-router.js'
27
- export { mountTemplate } from './core/compiler.js'
28
- export { defineComposable, assertSetupContext } from './core/composable.js'
29
- export { defineStore, resetStore, clearStores, registerStorePlugin, storeToRefs, storeToState, storeToGetters, useNestedStore, MutationType } from './core/store.js'
30
- export { directive } from './core/directives.js'
31
- export { reconcile } from './core/reconcile.js'
32
- export { defineAction, createActionProxy, useAction } from './server/actions.js'
33
- export { createApp } from './core/app-registry.js'
34
- export { defineCompilerPlugin, defineServerPlugin, defineDevToolsPlugin, defineRuntimeAdapter, defineFuseePlugin } from './core/plugins.js'
35
-
36
- if (typeof globalThis !== 'undefined') {
37
- Object.assign(globalThis, {
38
- ...signalModule,
39
- ...resourceModule,
40
- ...componentModule,
41
- ...elementModule,
42
- ...diModule,
43
- ...routerModule,
44
- ...fileRouterModule,
45
- ...compilerModule,
46
- ...composableModule,
47
- ...storeModule,
48
- ...directivesModule,
49
- ...reconcileModule,
50
- ...actionsModule,
51
- ...appRegistryModule,
52
- ...pluginsModule,
53
- emit
54
- })
55
- }
1
+ // ─── Framework Public API ─────────────────────────────────────────────────────
2
+ // Exports only, with no side effects, so bundlers keep just what an app uses.
3
+ // To expose the API on globalThis instead, import 'fusee-framework/globals'.
4
+
5
+ export const emit = () => console.warn('[framework] emit() can only be used inside component setup()')
6
+
7
+ export { signal, computed, effect, batch, untrack, inspect, watch, onCleanup, resource, createSuspense, scheduleAsyncJob } from './core/signal.js'
8
+ export { defineResource } from './core/resource.js'
9
+ export { defineComponent } from './core/component.js'
10
+ export { defineCompiledComponent, defineAsyncComponent, onMount, onUnmount, parseSlots, provide, inject, getCurrentInstance } from './core/component-core.js'
11
+ export { defineElement, toCustomElement, css, unsafeCSS } from './core/element.js'
12
+ export { InjectionToken, provideGlobal } from './core/di.js'
13
+ export { createRouter, navigate, mountOutlet, currentRoute, routeParams, routeQuery, matchedRoutes } from './router/router.js'
14
+ export { generateRoutes } from './router/file-router.js'
15
+ export { mountTemplate } from './core/compiler.js'
16
+ export { defineComposable, assertSetupContext } from './core/composable.js'
17
+ export { defineStore, resetStore, clearStores, registerStorePlugin, storeToRefs, storeToState, storeToGetters, useNestedStore, MutationType } from './core/store.js'
18
+ export { directive } from './core/directives.js'
19
+ export { reconcile } from './core/reconcile.js'
20
+ export { defineAction, createActionProxy, useAction } from './server/actions.js'
21
+ export { createApp } from './core/app-registry.js'
22
+ export { defineCompilerPlugin, defineServerPlugin, defineDevToolsPlugin, defineRuntimeAdapter, defineFuseePlugin } from './core/plugins.js'
@@ -1,184 +1,184 @@
1
- import { defineAsyncComponent } from '../core/component.js';
2
-
3
- /** Builds a nested route tree from Vite-style page module glob results. */
4
- export function generateRoutes(globResults, options = {}) {
5
- const entries = _parseGlobEntries(globResults, options);
6
- const tree = _buildRouteTree(entries, false);
7
- _sortRoutesRecursive(tree);
8
- return tree;
9
- }
10
-
11
- /** Converts page module paths into normalized route entries and async components. */
12
- function _parseGlobEntries(globResults, options) {
13
- const entries = [];
14
-
15
- for (const filePath of Object.keys(globResults)) {
16
- const loader = globResults[filePath];
17
-
18
- let cleanPath = filePath
19
- .replace(/^\.?\/?app\/pages\//, '')
20
- .replace(/^\.?\/?pages\//, '')
21
- .replace(/\.[jt]sx?$/, '');
22
-
23
- const parts = cleanPath.split('/');
24
- const rawFileName = parts.pop();
25
- const rawDirSegments = parts;
26
-
27
- const dirSegments = rawDirSegments.map(_transformSegment);
28
- const fileName = _transformSegment(rawFileName);
29
-
30
- const isIndex = rawFileName === 'index';
31
- const isCatchAll = /^\[\.\.\./.test(rawFileName);
32
-
33
- entries.push({
34
- filePath,
35
- loader,
36
- dirSegments,
37
- fileName,
38
- isIndex,
39
- isCatchAll,
40
- component: defineAsyncComponent({
41
- loader,
42
- loadingComponent: options.loadingComponent
43
- })
44
- });
45
- }
46
-
47
- return entries;
48
- }
49
-
50
- /** Converts bracket-style page segments into router parameter or wildcard syntax. */
51
- function _transformSegment(seg) {
52
- return seg
53
- .replace(/\[\.\.\.([^\]]+)\]/g, '*')
54
- .replace(/\[([^\]]+)\]/g, ':$1');
55
- }
56
-
57
- /** Groups route entries by directory and promotes matching files to layouts. */
58
- function _buildRouteTree(entries, isChild) {
59
- const filesHere = new Map();
60
- const grouped = new Map();
61
-
62
- for (const entry of entries) {
63
- if (entry.dirSegments.length === 0) {
64
- filesHere.set(entry.fileName, entry);
65
- } else {
66
- const firstDir = entry.dirSegments[0];
67
- if (!grouped.has(firstDir)) grouped.set(firstDir, []);
68
- grouped.get(firstDir).push(entry);
69
- }
70
- }
71
-
72
- let rootLayoutEntry = null;
73
- if (filesHere.has('_layout')) {
74
- rootLayoutEntry = filesHere.get('_layout');
75
- filesHere.delete('_layout');
76
- }
77
-
78
- const routes = [];
79
- const usedAsLayout = new Set();
80
-
81
- for (const [dirName, dirEntries] of grouped) {
82
- const layoutEntry = filesHere.get(dirName);
83
-
84
- if (layoutEntry) {
85
- usedAsLayout.add(dirName);
86
-
87
- const childEntries = dirEntries.map(e => ({
88
- ...e,
89
- dirSegments: e.dirSegments.slice(1)
90
- }));
91
-
92
- const children = _buildRouteTree(childEntries, true);
93
-
94
- routes.push({
95
- path: isChild ? dirName : '/' + dirName,
96
- component: layoutEntry.component,
97
- children
98
- });
99
- } else {
100
- for (const entry of dirEntries) {
101
- const segments = [...entry.dirSegments];
102
- if (!entry.isIndex) segments.push(entry.fileName);
103
-
104
- const routePath = isChild
105
- ? segments.join('/')
106
- : '/' + segments.join('/');
107
-
108
- routes.push({
109
- path: routePath,
110
- component: entry.component
111
- });
112
- }
113
- }
114
- }
115
-
116
- for (const [name, entry] of filesHere) {
117
- if (usedAsLayout.has(name)) continue;
118
-
119
- if (entry.isIndex) {
120
- routes.push({ path: isChild ? '' : '/', component: entry.component });
121
- } else if (entry.isCatchAll || name === '*') {
122
- routes.push({ path: '*', component: entry.component });
123
- } else {
124
- routes.push({
125
- path: isChild ? name : '/' + name,
126
- component: entry.component
127
- });
128
- }
129
- }
130
-
131
- if (rootLayoutEntry) {
132
- return [{
133
- path: '',
134
- component: rootLayoutEntry.component,
135
- children: routes
136
- }];
137
- }
138
-
139
- return routes;
140
- }
141
-
142
- /** Sorts every route level from most specific to least specific. */
143
- function _sortRoutesRecursive(routes) {
144
- routes.sort(_compareRoutes);
145
- for (const route of routes) {
146
- if (route.children) _sortRoutesRecursive(route.children);
147
- }
148
- }
149
-
150
- /** Normalizes a route path into an array for comparison. */
151
- function _getPathArray(path) {
152
- return Array.isArray(path) ? path : [path];
153
- }
154
-
155
- /** Orders static, layout, dynamic, and wildcard routes deterministically. */
156
- function _compareRoutes(a, b) {
157
- const aPaths = _getPathArray(a.path);
158
- const bPaths = _getPathArray(b.path);
159
-
160
- const aPath = aPaths[0];
161
- const bPath = bPaths[0];
162
-
163
- if (aPath === '*' && bPath !== '*') return 1;
164
- if (aPath !== '*' && bPath === '*') return -1;
165
-
166
- const aWild = aPath.endsWith('/*');
167
- const bWild = bPath.endsWith('/*');
168
- if (aWild && !bWild) return 1;
169
- if (!aWild && bWild) return -1;
170
-
171
- const aDynamic = aPath.includes(':');
172
- const bDynamic = bPath.includes(':');
173
- if (aDynamic && !bDynamic) return 1;
174
- if (!aDynamic && bDynamic) return -1;
175
-
176
- if (a.children && !b.children) return -1;
177
- if (!a.children && b.children) return 1;
178
-
179
- const aSegs = aPath.split('/').filter(Boolean).length;
180
- const bSegs = bPath.split('/').filter(Boolean).length;
181
- if (aSegs !== bSegs) return bSegs - aSegs;
182
-
183
- return aPath.localeCompare(bPath);
184
- }
1
+ import { defineAsyncComponent } from '../core/component-core.js';
2
+
3
+ /** Builds a nested route tree from Vite-style page module glob results. */
4
+ export function generateRoutes(globResults, options = {}) {
5
+ const entries = _parseGlobEntries(globResults, options);
6
+ const tree = _buildRouteTree(entries, false);
7
+ _sortRoutesRecursive(tree);
8
+ return tree;
9
+ }
10
+
11
+ /** Converts page module paths into normalized route entries and async components. */
12
+ function _parseGlobEntries(globResults, options) {
13
+ const entries = [];
14
+
15
+ for (const filePath of Object.keys(globResults)) {
16
+ const loader = globResults[filePath];
17
+
18
+ let cleanPath = filePath
19
+ .replace(/^\.?\/?app\/pages\//, '')
20
+ .replace(/^\.?\/?pages\//, '')
21
+ .replace(/\.[jt]sx?$/, '');
22
+
23
+ const parts = cleanPath.split('/');
24
+ const rawFileName = parts.pop();
25
+ const rawDirSegments = parts;
26
+
27
+ const dirSegments = rawDirSegments.map(_transformSegment);
28
+ const fileName = _transformSegment(rawFileName);
29
+
30
+ const isIndex = rawFileName === 'index';
31
+ const isCatchAll = /^\[\.\.\./.test(rawFileName);
32
+
33
+ entries.push({
34
+ filePath,
35
+ loader,
36
+ dirSegments,
37
+ fileName,
38
+ isIndex,
39
+ isCatchAll,
40
+ component: defineAsyncComponent({
41
+ loader,
42
+ loadingComponent: options.loadingComponent
43
+ })
44
+ });
45
+ }
46
+
47
+ return entries;
48
+ }
49
+
50
+ /** Converts bracket-style page segments into router parameter or wildcard syntax. */
51
+ function _transformSegment(seg) {
52
+ return seg
53
+ .replace(/\[\.\.\.([^\]]+)\]/g, '*')
54
+ .replace(/\[([^\]]+)\]/g, ':$1');
55
+ }
56
+
57
+ /** Groups route entries by directory and promotes matching files to layouts. */
58
+ function _buildRouteTree(entries, isChild) {
59
+ const filesHere = new Map();
60
+ const grouped = new Map();
61
+
62
+ for (const entry of entries) {
63
+ if (entry.dirSegments.length === 0) {
64
+ filesHere.set(entry.fileName, entry);
65
+ } else {
66
+ const firstDir = entry.dirSegments[0];
67
+ if (!grouped.has(firstDir)) grouped.set(firstDir, []);
68
+ grouped.get(firstDir).push(entry);
69
+ }
70
+ }
71
+
72
+ let rootLayoutEntry = null;
73
+ if (filesHere.has('_layout')) {
74
+ rootLayoutEntry = filesHere.get('_layout');
75
+ filesHere.delete('_layout');
76
+ }
77
+
78
+ const routes = [];
79
+ const usedAsLayout = new Set();
80
+
81
+ for (const [dirName, dirEntries] of grouped) {
82
+ const layoutEntry = filesHere.get(dirName);
83
+
84
+ if (layoutEntry) {
85
+ usedAsLayout.add(dirName);
86
+
87
+ const childEntries = dirEntries.map(e => ({
88
+ ...e,
89
+ dirSegments: e.dirSegments.slice(1)
90
+ }));
91
+
92
+ const children = _buildRouteTree(childEntries, true);
93
+
94
+ routes.push({
95
+ path: isChild ? dirName : '/' + dirName,
96
+ component: layoutEntry.component,
97
+ children
98
+ });
99
+ } else {
100
+ for (const entry of dirEntries) {
101
+ const segments = [...entry.dirSegments];
102
+ if (!entry.isIndex) segments.push(entry.fileName);
103
+
104
+ const routePath = isChild
105
+ ? segments.join('/')
106
+ : '/' + segments.join('/');
107
+
108
+ routes.push({
109
+ path: routePath,
110
+ component: entry.component
111
+ });
112
+ }
113
+ }
114
+ }
115
+
116
+ for (const [name, entry] of filesHere) {
117
+ if (usedAsLayout.has(name)) continue;
118
+
119
+ if (entry.isIndex) {
120
+ routes.push({ path: isChild ? '' : '/', component: entry.component });
121
+ } else if (entry.isCatchAll || name === '*') {
122
+ routes.push({ path: '*', component: entry.component });
123
+ } else {
124
+ routes.push({
125
+ path: isChild ? name : '/' + name,
126
+ component: entry.component
127
+ });
128
+ }
129
+ }
130
+
131
+ if (rootLayoutEntry) {
132
+ return [{
133
+ path: '',
134
+ component: rootLayoutEntry.component,
135
+ children: routes
136
+ }];
137
+ }
138
+
139
+ return routes;
140
+ }
141
+
142
+ /** Sorts every route level from most specific to least specific. */
143
+ function _sortRoutesRecursive(routes) {
144
+ routes.sort(_compareRoutes);
145
+ for (const route of routes) {
146
+ if (route.children) _sortRoutesRecursive(route.children);
147
+ }
148
+ }
149
+
150
+ /** Normalizes a route path into an array for comparison. */
151
+ function _getPathArray(path) {
152
+ return Array.isArray(path) ? path : [path];
153
+ }
154
+
155
+ /** Orders static, layout, dynamic, and wildcard routes deterministically. */
156
+ function _compareRoutes(a, b) {
157
+ const aPaths = _getPathArray(a.path);
158
+ const bPaths = _getPathArray(b.path);
159
+
160
+ const aPath = aPaths[0];
161
+ const bPath = bPaths[0];
162
+
163
+ if (aPath === '*' && bPath !== '*') return 1;
164
+ if (aPath !== '*' && bPath === '*') return -1;
165
+
166
+ const aWild = aPath.endsWith('/*');
167
+ const bWild = bPath.endsWith('/*');
168
+ if (aWild && !bWild) return 1;
169
+ if (!aWild && bWild) return -1;
170
+
171
+ const aDynamic = aPath.includes(':');
172
+ const bDynamic = bPath.includes(':');
173
+ if (aDynamic && !bDynamic) return 1;
174
+ if (!aDynamic && bDynamic) return -1;
175
+
176
+ if (a.children && !b.children) return -1;
177
+ if (!a.children && b.children) return 1;
178
+
179
+ const aSegs = aPath.split('/').filter(Boolean).length;
180
+ const bSegs = bPath.split('/').filter(Boolean).length;
181
+ if (aSegs !== bSegs) return bSegs - aSegs;
182
+
183
+ return aPath.localeCompare(bPath);
184
+ }