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
@@ -1,516 +0,0 @@
1
- use crate::args;
2
- use crate::ast::*;
3
- use crate::errors::{CompileError, ErrorCode};
4
- use crate::lexer::{Token, TokenType};
5
- use once_cell::sync::Lazy;
6
- use regex::Regex;
7
- use std::collections::HashSet;
8
-
9
- static VOID_ELEMENTS: Lazy<HashSet<&'static str>> = Lazy::new(|| {
10
- [
11
- "area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param",
12
- "source", "track", "wbr",
13
- ]
14
- .into_iter()
15
- .collect()
16
- });
17
-
18
- // mirror exact al FOR_RE din parser.js
19
- static FOR_RE: Lazy<Regex> = Lazy::new(|| {
20
- Regex::new(r"^(?:\(\s*([^,)]+?)\s*(?:,\s*([^)]+?)\s*)?\))\s+in\s+(.+)$|^([^\s,]+)\s+in\s+(.+)$")
21
- .unwrap()
22
- });
23
-
24
- pub fn parse(tokens: Vec<Token>, source: &str, components: &HashSet<String>) -> Result<Node, CompileError> {
25
- let mut parser = Parser::new(tokens, source, components);
26
- parser.parse()
27
- }
28
-
29
- struct Parser<'a> {
30
- tokens: Vec<Token>,
31
- source: String,
32
- components: &'a HashSet<String>,
33
- pos: usize,
34
- stack: Vec<String>,
35
- next_id: NodeId,
36
- }
37
-
38
- impl<'a> Parser<'a> {
39
- fn new(tokens: Vec<Token>, source: &str, components: &'a HashSet<String>) -> Self {
40
- Parser {
41
- tokens,
42
- source: source.to_string(),
43
- components,
44
- pos: 0,
45
- stack: Vec::new(),
46
- next_id: 0,
47
- }
48
- }
49
-
50
- fn alloc_id(&mut self) -> NodeId {
51
- let id = self.next_id;
52
- self.next_id += 1;
53
- id
54
- }
55
-
56
- fn parse(&mut self) -> Result<Node, CompileError> {
57
- let start = self.start_loc();
58
- let children = self.parse_children(None)?;
59
- Ok(Node::Root(RootNode {
60
- children,
61
- hoisted: Vec::new(),
62
- loc: Loc::new(start, self.start_loc()),
63
- }))
64
- }
65
-
66
- fn parse_children(&mut self, _parent_tag: Option<&str>) -> Result<Vec<Node>, CompileError> {
67
- let mut children = Vec::new();
68
-
69
- loop {
70
- if self.eof() {
71
- break;
72
- }
73
- let tok = self.peek().unwrap();
74
-
75
- match tok.ttype {
76
- TokenType::Eof => break,
77
- TokenType::TagOpenClose => break,
78
- TokenType::Comment => {
79
- self.advance();
80
- continue;
81
- }
82
- TokenType::Text => {
83
- children.push(self.parse_text()?);
84
- continue;
85
- }
86
- TokenType::MustacheOpen => {
87
- children.push(self.parse_mustache()?);
88
- continue;
89
- }
90
- TokenType::TagOpen => {
91
- if let Some(node) = self.parse_element()? {
92
- children.push(node);
93
- }
94
- continue;
95
- }
96
- _ => {
97
- self.advance();
98
- }
99
- }
100
- }
101
-
102
- Ok(children)
103
- }
104
-
105
- fn parse_text(&mut self) -> Result<Node, CompileError> {
106
- let tok = self.consume(TokenType::Text)?;
107
- Ok(Node::Text(TextNode {
108
- content: tok.value,
109
- is_static: false,
110
- loc: tok.loc,
111
- }))
112
- }
113
-
114
- fn parse_mustache(&mut self) -> Result<Node, CompileError> {
115
- let open = self.consume(TokenType::MustacheOpen)?;
116
- let expr = self.consume(TokenType::MustacheExpr)?;
117
- let close = self.consume(TokenType::MustacheClose)?;
118
-
119
- if expr.value.trim().is_empty() {
120
- return Err(self.err(ErrorCode::EmptyExpression, expr.loc.clone(), args!("{{ }}")));
121
- }
122
-
123
- let loc = Loc::new(open.loc.start, close.loc.end);
124
- Ok(Node::Interpolation(InterpolationNode {
125
- expression: Expression::new(expr.value, false, expr.loc),
126
- is_static: false,
127
- loc,
128
- }))
129
- }
130
-
131
- fn parse_element(&mut self) -> Result<Option<Node>, CompileError> {
132
- let open_tok = self.consume(TokenType::TagOpen)?;
133
- let tag = open_tok.value.clone();
134
- let start_loc = open_tok.loc.start;
135
- let props = self.parse_attrs(&tag)?;
136
-
137
- let mut self_closing = false;
138
- if matches!(self.peek().map(|t| t.ttype), Some(TokenType::TagSelfClose)) {
139
- self.advance();
140
- self_closing = true;
141
- } else {
142
- self.consume(TokenType::TagClose)?;
143
- }
144
-
145
- if tag == "slot" {
146
- return Ok(Some(self.build_slot_outlet(props, start_loc, self_closing)?));
147
- }
148
-
149
- let slot_attr = props
150
- .iter()
151
- .find(|p| matches!(p, Prop::Attribute(a) if a.name == "slot"))
152
- .cloned();
153
-
154
- if tag == "template" {
155
- if let Some(Prop::Attribute(attr)) = slot_attr {
156
- return Ok(Some(
157
- self.build_slot_content(attr, start_loc, self_closing)?,
158
- ));
159
- }
160
- }
161
-
162
- if self_closing || VOID_ELEMENTS.contains(tag.to_lowercase().as_str()) {
163
- return Ok(Some(self.build_node(tag, props, Vec::new(), true, start_loc, None)?));
164
- }
165
-
166
- self.stack.push(tag.clone());
167
- let children = self.parse_children(Some(&tag))?;
168
- self.stack.pop();
169
-
170
- if matches!(self.peek().map(|t| t.ttype), Some(TokenType::TagOpenClose)) {
171
- let close_tok = self.advance().unwrap();
172
- if close_tok.value.to_lowercase() != tag.to_lowercase() {
173
- return Err(self.err(
174
- ErrorCode::UnexpectedClosingTag,
175
- close_tok.loc.clone(),
176
- args!(close_tok.value),
177
- ));
178
- }
179
- if matches!(self.peek().map(|t| t.ttype), Some(TokenType::TagClose)) {
180
- self.advance();
181
- }
182
- } else {
183
- return Err(self.err(
184
- ErrorCode::MissingClosingTag,
185
- Loc::new(start_loc, start_loc),
186
- args!(tag),
187
- ));
188
- }
189
-
190
- let end_loc = self.start_loc();
191
- Ok(Some(self.build_node(
192
- tag,
193
- props,
194
- children,
195
- false,
196
- start_loc,
197
- Some(end_loc),
198
- )?))
199
- }
200
-
201
- fn build_node(&mut self, tag: String, props: Vec<Prop>, children: Vec<Node>, self_closing: bool, start_loc: Pos, end_loc: Option<Pos>) -> Result<Node, CompileError> {
202
- let loc = Loc::new(start_loc, end_loc.unwrap_or(start_loc));
203
- let is_capitalized = tag.chars().next().map(|c| c.is_ascii_uppercase()).unwrap_or(false);
204
-
205
- if self.components.contains(&tag) || is_capitalized {
206
- let slots = self.extract_slots(children);
207
- let id = self.alloc_id();
208
- return Ok(Node::Component(ComponentNode {
209
- id,
210
- name: tag,
211
- props,
212
- slots,
213
- loc,
214
- }));
215
- }
216
-
217
- let id = self.alloc_id();
218
- Ok(Node::Element(ElementNode {
219
- id,
220
- tag,
221
- props,
222
- children,
223
- self_closing,
224
- is_static: false,
225
- hoisted: false,
226
- loc,
227
- }))
228
- }
229
-
230
- fn build_slot_outlet(&mut self, props: Vec<Prop>, start_loc: Pos, self_closing: bool, ) -> Result<Node, CompileError> {
231
- let name_attr = props
232
- .iter()
233
- .find(|p| matches!(p, Prop::Attribute(a) if a.name == "name"));
234
- let slot_name = match name_attr {
235
- Some(Prop::Attribute(a)) => a.value.clone().unwrap_or_else(|| "default".to_string()),
236
- _ => "default".to_string(),
237
- };
238
-
239
- let mut fallback = Vec::new();
240
- if !self_closing {
241
- self.stack.push("slot".to_string());
242
- fallback = self.parse_children(Some("slot"))?;
243
- self.stack.pop();
244
- if matches!(self.peek().map(|t| t.ttype), Some(TokenType::TagOpenClose)) {
245
- self.advance();
246
- if matches!(self.peek().map(|t| t.ttype), Some(TokenType::TagClose)) {
247
- self.advance();
248
- }
249
- }
250
- }
251
-
252
- Ok(Node::SlotOutlet(SlotOutletNode {
253
- slot_name,
254
- fallback,
255
- loc: Loc::new(start_loc, self.start_loc()),
256
- }))
257
- }
258
-
259
- fn build_slot_content(&mut self, slot_attr: AttributeNode, start_loc: Pos, self_closing: bool) -> Result<Node, CompileError> {
260
- let slot_name = slot_attr.value.clone().unwrap_or_else(|| "default".to_string());
261
- let mut children = Vec::new();
262
-
263
- if !self_closing {
264
- self.stack.push("template".to_string());
265
- children = self.parse_children(Some("template"))?;
266
- self.stack.pop();
267
- if matches!(self.peek().map(|t| t.ttype), Some(TokenType::TagOpenClose)) {
268
- self.advance();
269
- if matches!(self.peek().map(|t| t.ttype), Some(TokenType::TagClose)) {
270
- self.advance();
271
- }
272
- }
273
- }
274
-
275
- Ok(Node::SlotContent(SlotContentNode {
276
- slot_name,
277
- children,
278
- loc: Loc::new(start_loc, self.start_loc()),
279
- }))
280
- }
281
-
282
- fn extract_slots(&self, children: Vec<Node>) -> Vec<(String, Vec<Node>)> {
283
- let mut slots: Vec<(String, Vec<Node>)> = vec![("default".to_string(), Vec::new())];
284
-
285
- for child in children {
286
- if let Node::SlotContent(sc) = child {
287
- if let Some(entry) = slots.iter_mut().find(|(n, _)| *n == sc.slot_name) {
288
- entry.1 = sc.children;
289
- } else {
290
- slots.push((sc.slot_name, sc.children));
291
- }
292
- } else {
293
- slots[0].1.push(child);
294
- }
295
- }
296
-
297
- slots
298
- }
299
-
300
- fn parse_attrs(&mut self, tag: &str) -> Result<Vec<Prop>, CompileError> {
301
- let mut props = Vec::new();
302
- let mut seen: HashSet<String> = HashSet::new();
303
-
304
- loop {
305
- if self.eof() {
306
- break;
307
- }
308
- let tok = self.peek().unwrap();
309
- if matches!(
310
- tok.ttype,
311
- TokenType::TagClose | TokenType::TagSelfClose | TokenType::Eof
312
- ) {
313
- break;
314
- }
315
-
316
- if tok.ttype != TokenType::AttrName {
317
- self.advance();
318
- continue;
319
- }
320
-
321
- let name_tok = self.advance().unwrap();
322
- let raw_name = name_tok.value.clone();
323
- if seen.contains(&raw_name) {
324
- return Err(self.err(
325
- ErrorCode::DuplicateKey,
326
- name_tok.loc.clone(),
327
- args!(raw_name, tag.to_string()),
328
- ));
329
- }
330
- seen.insert(raw_name.clone());
331
-
332
- let mut value: Option<String> = None;
333
- if matches!(self.peek().map(|t| t.ttype), Some(TokenType::AttrEquals)) {
334
- self.advance();
335
- let val_tok = self.consume(TokenType::AttrValue)?;
336
- value = Some(val_tok.value);
337
- }
338
-
339
- let loc = name_tok.loc.clone();
340
-
341
- if let Some(rest) = raw_name.strip_prefix('@') {
342
- props.push(self.parse_event_attr(rest, value, loc)?);
343
- } else if let Some(rest) = raw_name.strip_prefix(':') {
344
- props.push(self.parse_binding_attr(&raw_name, rest, value, loc)?);
345
- } else if let Some(rest) = raw_name.strip_prefix("f-") {
346
- props.push(self.parse_directive_attr(&raw_name, rest, value, loc, tag)?);
347
- } else {
348
- props.push(Prop::Attribute(AttributeNode {
349
- name: raw_name,
350
- value,
351
- loc,
352
- }));
353
- }
354
- }
355
-
356
- Ok(props)
357
- }
358
-
359
- fn parse_event_attr(&mut self, rest: &str, value: Option<String>, loc: Loc) -> Result<Prop, CompileError> {
360
- let mut parts = rest.split('.');
361
- let event_name = parts.next().unwrap_or("").to_string();
362
- let modifiers: Vec<String> = parts.map(|s| s.to_string()).collect();
363
-
364
- let val = match &value {
365
- Some(v) if !v.trim().is_empty() => v.clone(),
366
- _ => {
367
- return Err(self.err(
368
- ErrorCode::EmptyExpression,
369
- loc,
370
- args!(format!("@{}", rest)),
371
- ))
372
- }
373
- };
374
-
375
- Ok(Prop::Event(EventNode {
376
- name: event_name,
377
- expression: Expression::new(val.trim().to_string(), false, loc.clone()),
378
- modifiers,
379
- loc,
380
- }))
381
- }
382
-
383
- fn parse_binding_attr(&mut self, raw_name: &str, rest: &str, value: Option<String>, loc: Loc) -> Result<Prop, CompileError> {
384
- let is_prop = rest.starts_with("prop-");
385
- let name = if is_prop { &rest[5..] } else { rest };
386
-
387
- let val = match &value {
388
- Some(v) if !v.trim().is_empty() => v.clone(),
389
- _ => return Err(self.err(ErrorCode::EmptyExpression, loc, args!(raw_name.to_string()))),
390
- };
391
-
392
- Ok(Prop::Binding(BindingNode {
393
- name: name.to_string(),
394
- expression: Expression::new(val.trim().to_string(), false, loc.clone()),
395
- is_prop,
396
- loc,
397
- }))
398
- }
399
-
400
- fn parse_directive_attr(&mut self, raw_name: &str, rest: &str, value: Option<String>, loc: Loc, _tag: &str, ) -> Result<Prop, CompileError> {
401
- let name = rest.to_string();
402
- let needs_expr = name != "else" && name != "once";
403
-
404
- if needs_expr {
405
- match &value {
406
- Some(v) if !v.trim().is_empty() => {}
407
- _ => {
408
- return Err(self.err(
409
- ErrorCode::EmptyExpression,
410
- loc,
411
- args!(raw_name.to_string()),
412
- ))
413
- }
414
- }
415
- }
416
-
417
- let mut expression = None;
418
- let mut arg = None;
419
-
420
- if let Some(v) = &value {
421
- if name == "for" {
422
- arg = Some(self.parse_for_expression(v.trim(), loc.clone())?);
423
- } else {
424
- expression = Some(Expression::new(v.trim().to_string(), false, loc.clone()));
425
- }
426
- }
427
-
428
- Ok(Prop::Directive(DirectiveNode {
429
- name,
430
- expression,
431
- arg,
432
- loc,
433
- }))
434
- }
435
-
436
- fn parse_for_expression(&mut self, raw: &str, loc: Loc) -> Result<ForArg, CompileError> {
437
- let caps = FOR_RE.captures(raw);
438
- let caps = match caps {
439
- Some(c) => c,
440
- None => {
441
- return Err(self.err(
442
- ErrorCode::InvalidForSyntax,
443
- loc,
444
- args!(raw.to_string()),
445
- ))
446
- }
447
- };
448
-
449
- let item = caps
450
- .get(1)
451
- .or_else(|| caps.get(4))
452
- .map(|m| m.as_str().trim().to_string())
453
- .unwrap_or_default();
454
- let index = caps.get(2).map(|m| m.as_str().trim().to_string());
455
- let source = caps
456
- .get(3)
457
- .or_else(|| caps.get(5))
458
- .map(|m| m.as_str().trim().to_string())
459
- .unwrap_or_default();
460
-
461
- Ok(ForArg {
462
- item,
463
- source,
464
- index,
465
- loc,
466
- })
467
- }
468
-
469
- fn eof(&self) -> bool {
470
- self.pos >= self.tokens.len() || matches!(self.peek().map(|t| t.ttype), Some(TokenType::Eof))
471
- }
472
-
473
- fn peek(&self) -> Option<&Token> {
474
- self.tokens.get(self.pos)
475
- }
476
-
477
- fn advance(&mut self) -> Option<Token> {
478
- let tok = self.tokens.get(self.pos).cloned();
479
- if !matches!(tok.as_ref().map(|t| t.ttype), Some(TokenType::Eof)) {
480
- self.pos += 1;
481
- }
482
- tok
483
- }
484
-
485
- fn consume(&mut self, expected: TokenType) -> Result<Token, CompileError> {
486
- let tok = self.peek().cloned();
487
- match &tok {
488
- Some(t) if t.ttype == expected => {
489
- self.advance();
490
- Ok(t.clone())
491
- }
492
- _ => {
493
- let loc = tok
494
- .as_ref()
495
- .map(|t| t.loc.clone())
496
- .unwrap_or_else(|| Loc::new(self.start_loc(), self.start_loc()));
497
- let found = tok
498
- .map(|t| format!("{:?}", t.ttype))
499
- .unwrap_or_else(|| "EOF".to_string());
500
- Err(self.err(
501
- ErrorCode::UnexpectedToken,
502
- loc,
503
- args!(found, format!("{:?}", expected)),
504
- ))
505
- }
506
- }
507
- }
508
-
509
- fn start_loc(&self) -> Pos {
510
- self.peek().map(|t| t.loc.start).unwrap_or_default()
511
- }
512
-
513
- fn err(&self, code: ErrorCode, loc: Loc, args: Vec<String>) -> CompileError {
514
- CompileError::new(code, loc, &self.source, args)
515
- }
516
- }