fusee-framework 1.9.0 → 1.9.1

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 (62) hide show
  1. package/README.md +1 -1
  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/bin/create-fusee.exe +0 -0
  7. package/create-fusee-go/internal/assets/embed/framework/auto-import-preset.js +15 -9
  8. package/create-fusee-go/internal/assets/embed/framework/core/async-context.js +27 -0
  9. package/create-fusee-go/internal/assets/embed/framework/core/compiler/ast.js +167 -0
  10. package/create-fusee-go/internal/assets/embed/framework/core/compiler/errors-list.js +47 -0
  11. package/create-fusee-go/internal/assets/embed/framework/core/compiler/errors.js +107 -0
  12. package/create-fusee-go/internal/assets/embed/framework/core/compiler/generator.js +363 -0
  13. package/create-fusee-go/internal/assets/embed/framework/core/compiler/lexer.js +347 -0
  14. package/create-fusee-go/internal/assets/embed/framework/core/compiler/main-compiler.js +115 -0
  15. package/create-fusee-go/internal/assets/embed/framework/core/compiler/parser.js +414 -0
  16. package/create-fusee-go/internal/assets/embed/framework/core/compiler/plugins/actions-plugin.js +263 -0
  17. package/create-fusee-go/internal/assets/embed/framework/core/compiler/plugins/compiler-plugin.d.ts +5 -0
  18. package/create-fusee-go/internal/assets/embed/framework/core/compiler/plugins/compiler-plugin.js +45 -0
  19. package/create-fusee-go/internal/assets/embed/framework/core/compiler/plugins/file-router-plugin.js +301 -0
  20. package/create-fusee-go/internal/assets/embed/framework/core/compiler/plugins/router-plugin.js +196 -0
  21. package/create-fusee-go/internal/assets/embed/framework/core/compiler/transformer.js +398 -0
  22. package/create-fusee-go/internal/assets/embed/framework/core/component.js +61 -23
  23. package/create-fusee-go/internal/assets/embed/framework/core/di.js +187 -0
  24. package/create-fusee-go/internal/assets/embed/framework/core/directives.js +40 -96
  25. package/create-fusee-go/internal/assets/embed/framework/core/evaluator.js +1 -1
  26. package/create-fusee-go/internal/assets/embed/framework/core/h.js +430 -0
  27. package/create-fusee-go/internal/assets/embed/framework/core/hydration.js +83 -0
  28. package/create-fusee-go/internal/assets/embed/framework/core/reconcile.js +151 -0
  29. package/create-fusee-go/internal/assets/embed/framework/core/signal.js +269 -0
  30. package/create-fusee-go/internal/assets/embed/framework/core/store.js +322 -81
  31. package/create-fusee-go/internal/assets/embed/framework/index.js +5 -3
  32. package/create-fusee-go/internal/assets/embed/framework/router/file-router.js +1 -1
  33. package/create-fusee-go/internal/assets/embed/framework/router/router.js +113 -21
  34. package/create-fusee-go/internal/assets/embed/framework/server/actions.js +173 -0
  35. package/create-fusee-go/internal/assets/embed/framework/server/actions.server.js +88 -0
  36. package/create-fusee-go/internal/assets/embed/framework/server/index.js +18 -0
  37. package/create-fusee-go/internal/assets/embed/framework/types/actions.d.ts +50 -0
  38. package/create-fusee-go/internal/assets/embed/framework/types/actions.server.d.ts +36 -0
  39. package/create-fusee-go/internal/assets/embed/framework/types/compiler/ast.d.ts +166 -0
  40. package/create-fusee-go/internal/assets/embed/framework/types/compiler/errors-codes.d.ts +23 -0
  41. package/create-fusee-go/internal/assets/embed/framework/types/compiler/errors.d.ts +43 -0
  42. package/create-fusee-go/internal/assets/embed/framework/types/compiler/generator.d.ts +8 -0
  43. package/create-fusee-go/internal/assets/embed/framework/types/compiler/h.d.ts +46 -0
  44. package/create-fusee-go/internal/assets/embed/framework/types/compiler/lexer.d.ts +27 -0
  45. package/create-fusee-go/internal/assets/embed/framework/types/compiler/main-compiler.d.ts +60 -0
  46. package/create-fusee-go/internal/assets/embed/framework/types/compiler/parser.d.ts +4 -0
  47. package/create-fusee-go/internal/assets/embed/framework/types/compiler/plugins/actions.d.ts +30 -0
  48. package/create-fusee-go/internal/assets/embed/framework/types/compiler/plugins/compiler-plugin.d.ts +5 -0
  49. package/create-fusee-go/internal/assets/embed/framework/types/compiler/plugins/file-router-plugins.d.ts +32 -0
  50. package/create-fusee-go/internal/assets/embed/framework/types/compiler/plugins/router-plugin.d.ts +24 -0
  51. package/create-fusee-go/internal/assets/embed/framework/types/compiler/transformer.d.ts +28 -0
  52. package/create-fusee-go/internal/assets/embed/framework/types/component.d.ts +89 -88
  53. package/create-fusee-go/internal/assets/embed/framework/types/di.d.ts +43 -0
  54. package/create-fusee-go/internal/assets/embed/framework/types/hydration.d.ts +30 -0
  55. package/create-fusee-go/internal/assets/embed/framework/types/index.d.ts +38 -22
  56. package/create-fusee-go/internal/assets/embed/framework/types/reconcile.d.ts +7 -0
  57. package/create-fusee-go/internal/assets/embed/framework/types/router.d.ts +11 -1
  58. package/create-fusee-go/internal/assets/embed/framework/types/server.d.ts +11 -0
  59. package/create-fusee-go/internal/assets/embed/framework/types/signal.d.ts +142 -79
  60. package/create-fusee-go/internal/assets/embed/framework/types/store.d.ts +66 -8
  61. package/package.json +1 -1
  62. package/create-fusee-go/internal/assets/embed/framework/bin/create-fusee.js +0 -199
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Fusée Framework
2
2
 
3
- **v1.9.0 — Signals-First JS Framework | Atomic Reactivity | Peak Performance**
3
+ **v1.9.1 — Signals-First JS Framework | Atomic Reactivity | Peak Performance**
4
4
 
5
5
  Fusée is a custom, high-performance fine-grained reactive JavaScript framework built for speed and simplicity. It features a recursive, non-greedy compiler, a signals-based reactivity engine, Dependency Injection for components and a comprehensive CLI for instant application scaffolding.
6
6
 
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -1,9 +1,15 @@
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
- ]
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
+ 'provide', 'inject', 'provideGlobal', 'InjectionToken',
13
+ 'defineComposable', 'assertSetupContext'
14
+ ]
15
+ }
@@ -0,0 +1,27 @@
1
+ let _als = null
2
+
3
+ export function _registerALS(als) {
4
+ _als = als
5
+ }
6
+
7
+ export function _getALS() {
8
+ return _als
9
+ }
10
+
11
+ export const _globalInFlightMaps = {
12
+ byKey: new Map(),
13
+ byFetcher: new WeakMap()
14
+ }
15
+
16
+ export function getInFlightStore() {
17
+ if (_als) {
18
+ const ctx = _als.getStore()
19
+ if (ctx) return ctx.inFlightMaps
20
+ }
21
+ return _globalInFlightMaps
22
+ }
23
+
24
+ export function isSSRContext() {
25
+ if (!_als) return false
26
+ return _als.getStore() !== undefined
27
+ }
@@ -0,0 +1,167 @@
1
+ export const NodeType = {
2
+ ROOT: 'Root',
3
+ ELEMENT: 'Element',
4
+ COMPONENT: 'Component',
5
+ TEXT: 'Text',
6
+ INTERPOLATION: 'Interpolation',
7
+ EXPRESSION: 'Expression',
8
+ ATTRIBUTE: 'Attribute',
9
+ BINDING: 'Binding',
10
+ EVENT: 'Event',
11
+ DIRECTIVE: 'Directive',
12
+ SLOT_OUTLET: 'SlotOutlet',
13
+ SLOT_CONTENT: 'SlotContent'
14
+ }
15
+
16
+ export function createLoc(start, end, source) {
17
+ return { start, end, source }
18
+ }
19
+
20
+ export function createPos(line, col, offset) {
21
+ return { line, col, offset }
22
+ }
23
+
24
+ export function createRoot(children = [], loc = null) {
25
+ return { type: NodeType.ROOT, children, loc }
26
+ }
27
+
28
+ export function createElement(tag, props = [], children = [], selfClosing = false, loc = null) {
29
+ return {
30
+ type: NodeType.ELEMENT,
31
+ tag,
32
+ props,
33
+ children,
34
+ selfClosing,
35
+ isStatic: false,
36
+ hoisted: false,
37
+ loc
38
+ }
39
+ }
40
+
41
+ export function createComponent(name, props = [], slots = {}, loc = null) {
42
+ return {
43
+ type: NodeType.COMPONENT,
44
+ name,
45
+ props,
46
+ slots,
47
+ loc
48
+ }
49
+ }
50
+
51
+ export function createText(content, loc = null) {
52
+ return { type: NodeType.TEXT, content, loc }
53
+ }
54
+
55
+ export function createInterpolation(expression, loc = null) {
56
+ return {
57
+ type: NodeType.INTERPOLATION,
58
+ expression,
59
+ loc
60
+ }
61
+ }
62
+
63
+ export function createExpression(content, isStatic = false, loc = null) {
64
+ return {
65
+ type: NodeType.EXPRESSION,
66
+ content,
67
+ isStatic,
68
+ loc
69
+ }
70
+ }
71
+
72
+ export function createAttribute(name, value, loc = null) {
73
+ return {
74
+ type: NodeType.ATTRIBUTE,
75
+ name,
76
+ value,
77
+ loc
78
+ }
79
+ }
80
+
81
+ export function createBinding(name, expression, isProp = false, loc = null) {
82
+ return {
83
+ type: NodeType.BINDING,
84
+ name,
85
+ expression,
86
+ isProp,
87
+ loc
88
+ }
89
+ }
90
+
91
+ export function createEvent(name, expression, modifiers = [], loc = null) {
92
+ return {
93
+ type: NodeType.EVENT,
94
+ name,
95
+ expression,
96
+ modifiers,
97
+ loc
98
+ }
99
+ }
100
+
101
+ export function createDirective(name, expression = null, arg = null, loc = null) {
102
+ return {
103
+ type: NodeType.DIRECTIVE,
104
+ name,
105
+ expression,
106
+ arg,
107
+ loc
108
+ }
109
+ }
110
+
111
+ export function createSlotOutlet(slotName = 'default', fallback = [], loc = null) {
112
+ return {
113
+ type: NodeType.SLOT_OUTLET,
114
+ slotName,
115
+ fallback,
116
+ loc
117
+ }
118
+ }
119
+
120
+ export function createSlotContent(slotName = 'default', children = [], loc = null) {
121
+ return {
122
+ type: NodeType.SLOT_CONTENT,
123
+ slotName,
124
+ children,
125
+ loc
126
+ }
127
+ }
128
+
129
+ export function createForArg(item, source, index = null, loc = null) {
130
+ return { item, source, index, loc }
131
+ }
132
+
133
+ export function isElement(node) {
134
+ return node?.type === NodeType.ELEMENT
135
+ }
136
+
137
+ export function isComponent(node) {
138
+ return node?.type === NodeType.COMPONENT
139
+ }
140
+
141
+ export function isText(node) {
142
+ return node?.type === NodeType.TEXT
143
+ }
144
+
145
+ export function isInterpolation(node) {
146
+ return node?.type === NodeType.INTERPOLATION
147
+ }
148
+
149
+ export function isDirective(node, name) {
150
+ return node?.type === NodeType.DIRECTIVE && (name == null || node.name === name)
151
+ }
152
+
153
+ export function isStaticText(node) {
154
+ return node?.type === NodeType.TEXT || (node?.type === NodeType.INTERPOLATION && node.expression?.isStatic)
155
+ }
156
+
157
+ export function findDirective(element, name) {
158
+ return element.props.find(p => isDirective(p, name)) ?? null
159
+ }
160
+
161
+ export function getEvents(element) {
162
+ return element.props.filter(p => p.type === NodeType.EVENT)
163
+ }
164
+
165
+ export function cloneNode(node) {
166
+ return { ...node, props: node.props ? [...node.props] : undefined, children: node.children ? [...node.children] : undefined }
167
+ }
@@ -0,0 +1,47 @@
1
+ export const ErrorCode = {
2
+ UNEXPECTED_CHAR: 'E001',
3
+ UNTERMINATED_STRING: 'E002',
4
+ UNTERMINATED_MUSTACHE: 'E003',
5
+ UNTERMINATED_TAG: 'E004',
6
+ MALFORMED_COMMENT: 'E005',
7
+ UNEXPECTED_TOKEN: 'P001',
8
+ MISSING_CLOSING_TAG: 'P002',
9
+ UNEXPECTED_CLOSING_TAG: 'P003',
10
+ INVALID_DIRECTIVE_SYNTAX: 'P004',
11
+ INVALID_FOR_SYNTAX: 'P005',
12
+ DUPLICATE_KEY: 'P006',
13
+ V_ELSE_NO_IF: 'P007',
14
+ EMPTY_EXPRESSION: 'P008',
15
+ INVALID_SLOT_NAME: 'P009',
16
+ DUPLICATE_DIRECTIVE: 'T001',
17
+ FOR_MISSING_KEY: 'T002',
18
+ MODEL_ON_NON_INPUT: 'T003',
19
+ COMPONENT_NOT_REGISTERED: 'T004',
20
+ UNKNOWN_IDENTIFIER: 'S001',
21
+ STATIC_FOR_KEY: 'S002',
22
+ UNKNOWN_NODE_TYPE: 'G001',
23
+ }
24
+
25
+ export const ERROR_MESSAGES = {
26
+ [ErrorCode.UNEXPECTED_CHAR]: 'Unexpected character "{0}"',
27
+ [ErrorCode.UNTERMINATED_STRING]: 'Unterminated string literal',
28
+ [ErrorCode.UNTERMINATED_MUSTACHE]: 'Unterminated mustache expression "{0}"',
29
+ [ErrorCode.UNTERMINATED_TAG]: 'Unterminated tag "<{0}"',
30
+ [ErrorCode.MALFORMED_COMMENT]: 'Malformed HTML comment',
31
+ [ErrorCode.UNEXPECTED_TOKEN]: 'Unexpected token "{0}", expected "{1}"',
32
+ [ErrorCode.MISSING_CLOSING_TAG]: 'Missing closing tag for <{0}>',
33
+ [ErrorCode.UNEXPECTED_CLOSING_TAG]: 'Unexpected closing tag </{0}>',
34
+ [ErrorCode.INVALID_DIRECTIVE_SYNTAX]: 'Invalid directive syntax: "{0}"',
35
+ [ErrorCode.INVALID_FOR_SYNTAX]: 'Invalid f-for syntax: "{0}". Expected "(item, index) in source" or "item in source"',
36
+ [ErrorCode.DUPLICATE_KEY]: 'Duplicate attribute "{0}" on element <{1}>',
37
+ [ErrorCode.V_ELSE_NO_IF]: 'f-else / f-else-if has no matching f-if',
38
+ [ErrorCode.EMPTY_EXPRESSION]: 'Expression in "{0}" must not be empty',
39
+ [ErrorCode.INVALID_SLOT_NAME]: 'Invalid slot name "{0}"',
40
+ [ErrorCode.DUPLICATE_DIRECTIVE]: 'Duplicate directive "f-{0}" on element <{1}>',
41
+ [ErrorCode.FOR_MISSING_KEY]: 'f-for on <{0}> is missing a :key binding — add :key="<unique expr>"',
42
+ [ErrorCode.MODEL_ON_NON_INPUT]: 'f-model can only be used on <input>, <textarea> or <select>, got <{0}>',
43
+ [ErrorCode.COMPONENT_NOT_REGISTERED]: 'Component "{0}" is used in the template but not registered',
44
+ [ErrorCode.UNKNOWN_NODE_TYPE]: 'Unknown AST node type "{0}" encountered in generator',
45
+ [ErrorCode.UNKNOWN_IDENTIFIER]: 'Unknown identifier "{0}" in expression "{1}" — not found in component scope',
46
+ [ErrorCode.STATIC_FOR_KEY]: ':key="{0}" is a static literal — keys must be unique per item (use a dynamic expression like :key="item.id")',
47
+ }
@@ -0,0 +1,107 @@
1
+ import { ErrorCode, ERROR_MESSAGES } from './errors-list.js'
2
+
3
+ export class CompileError extends Error {
4
+ constructor(code, loc, source, ...args) {
5
+ const template = ERROR_MESSAGES[code] ?? `Unknown compiler error (${code})`
6
+ const message = _interpolate(template, args)
7
+ super(message)
8
+ this.name = 'CompileError'
9
+ this.code = code
10
+ this.loc = loc
11
+ this.source = source
12
+ this._snippet = null
13
+ }
14
+
15
+ format(filePath = '<template>') {
16
+ const { line, col } = this.loc?.start ?? { line: '?', col: '?' }
17
+ const header = `[fusée] ${this.name} ${this.code} at ${filePath}:${line}:${col}`
18
+ const snippet = this._buildSnippet()
19
+ return snippet ? `${header}\n${this.message}\n\n${snippet}` : `${header}\n${this.message}`
20
+ }
21
+
22
+ _buildSnippet() {
23
+ if (this._snippet !== null) return this._snippet
24
+ if (!this.source || !this.loc?.start) {
25
+ this._snippet = ''
26
+ return ''
27
+ }
28
+
29
+ const lines = this.source.split('\n')
30
+ const lineIdx = this.loc.start.line - 1
31
+ const col = this.loc.start.col
32
+ const CONTEXT = 2
33
+ const firstLine = Math.max(0, lineIdx - CONTEXT)
34
+ const lastLine = Math.min(lines.length - 1, lineIdx + CONTEXT)
35
+ const width = String(lastLine + 1).length
36
+ const parts = []
37
+
38
+ for (let i = firstLine; i <= lastLine; i++) {
39
+ const lineNo = String(i + 1).padStart(width, ' ')
40
+ const prefix = i === lineIdx ? '> ' : ' '
41
+ parts.push(`${prefix}${lineNo} | ${lines[i]}`)
42
+ if (i === lineIdx) {
43
+ const caretPad = ' '.repeat(width + 4 + (col - 1))
44
+ const caretLen = Math.max(1, (this.loc.end?.col ?? col) - col)
45
+ parts.push(`${caretPad}${'~'.repeat(caretLen)}`)
46
+ }
47
+ }
48
+
49
+ this._snippet = parts.join('\n')
50
+ return this._snippet
51
+ }
52
+ }
53
+
54
+ export class CompileWarning {
55
+ constructor(code, loc, source, ...args) {
56
+ const template = ERROR_MESSAGES[code] ?? `Unknown compiler warning (${code})`
57
+ this.message = _interpolate(template, args)
58
+ this.code = code
59
+ this.loc = loc
60
+ this.source = source
61
+ }
62
+
63
+ format(filePath = '<template>') {
64
+ const { line, col } = this.loc?.start ?? { line: '?', col: '?' }
65
+ return `[fusée] Warning ${this.code} at ${filePath}:${line}:${col}\n${this.message}`
66
+ }
67
+ }
68
+
69
+ export class ErrorCollector {
70
+ constructor(source) {
71
+ this.source = source
72
+ this.errors = []
73
+ this.warnings = []
74
+ }
75
+
76
+ error(code, loc, ...args) {
77
+ const err = new CompileError(code, loc, this.source, ...args)
78
+ this.errors.push(err)
79
+ return err
80
+ }
81
+
82
+ warn(code, loc, ...args) {
83
+ const w = new CompileWarning(code, loc, this.source, ...args)
84
+ this.warnings.push(w)
85
+ return w
86
+ }
87
+
88
+ throwIfAny() {
89
+ if (this.errors.length > 0) throw this.errors[0]
90
+ }
91
+
92
+ get hasErrors() {
93
+ return this.errors.length > 0
94
+ }
95
+
96
+ get hasWarnings() {
97
+ return this.warnings.length > 0
98
+ }
99
+ }
100
+
101
+ function _interpolate(template, args) {
102
+ return template.replace(/\{(\d+)\}/g, (_, i) => args[i] ?? '')
103
+ }
104
+
105
+ export function throwError(code, loc, source, ...args) {
106
+ throw new CompileError(code, loc, source, ...args)
107
+ }