@fazelstudio/floe 1.0.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 (154) hide show
  1. package/LICENSE +21 -0
  2. package/dist/src/cli/check.d.ts +14 -0
  3. package/dist/src/cli/check.d.ts.map +1 -0
  4. package/dist/src/cli/check.js +88 -0
  5. package/dist/src/cli/check.js.map +1 -0
  6. package/dist/src/cli/format.d.ts +9 -0
  7. package/dist/src/cli/format.d.ts.map +1 -0
  8. package/dist/src/cli/format.js +114 -0
  9. package/dist/src/cli/format.js.map +1 -0
  10. package/dist/src/cli/main.d.ts +19 -0
  11. package/dist/src/cli/main.d.ts.map +1 -0
  12. package/dist/src/cli/main.js +207 -0
  13. package/dist/src/cli/main.js.map +1 -0
  14. package/dist/src/cli/render.d.ts +7 -0
  15. package/dist/src/cli/render.d.ts.map +1 -0
  16. package/dist/src/cli/render.js +90 -0
  17. package/dist/src/cli/render.js.map +1 -0
  18. package/dist/src/diagnostics.d.ts +32 -0
  19. package/dist/src/diagnostics.d.ts.map +1 -0
  20. package/dist/src/diagnostics.js +4 -0
  21. package/dist/src/diagnostics.js.map +1 -0
  22. package/dist/src/index.d.ts +40 -0
  23. package/dist/src/index.d.ts.map +1 -0
  24. package/dist/src/index.js +64 -0
  25. package/dist/src/index.js.map +1 -0
  26. package/dist/src/language/completion.d.ts +6 -0
  27. package/dist/src/language/completion.d.ts.map +1 -0
  28. package/dist/src/language/completion.js +363 -0
  29. package/dist/src/language/completion.js.map +1 -0
  30. package/dist/src/language/definitions.d.ts +9 -0
  31. package/dist/src/language/definitions.d.ts.map +1 -0
  32. package/dist/src/language/definitions.js +70 -0
  33. package/dist/src/language/definitions.js.map +1 -0
  34. package/dist/src/language/diagnosticsService.d.ts +14 -0
  35. package/dist/src/language/diagnosticsService.d.ts.map +1 -0
  36. package/dist/src/language/diagnosticsService.js +37 -0
  37. package/dist/src/language/diagnosticsService.js.map +1 -0
  38. package/dist/src/language/folding.d.ts +8 -0
  39. package/dist/src/language/folding.d.ts.map +1 -0
  40. package/dist/src/language/folding.js +58 -0
  41. package/dist/src/language/folding.js.map +1 -0
  42. package/dist/src/language/formatting.d.ts +5 -0
  43. package/dist/src/language/formatting.d.ts.map +1 -0
  44. package/dist/src/language/formatting.js +274 -0
  45. package/dist/src/language/formatting.js.map +1 -0
  46. package/dist/src/language/highlighting.d.ts +9 -0
  47. package/dist/src/language/highlighting.d.ts.map +1 -0
  48. package/dist/src/language/highlighting.js +74 -0
  49. package/dist/src/language/highlighting.js.map +1 -0
  50. package/dist/src/language/hover.d.ts +6 -0
  51. package/dist/src/language/hover.d.ts.map +1 -0
  52. package/dist/src/language/hover.js +197 -0
  53. package/dist/src/language/hover.js.map +1 -0
  54. package/dist/src/language/indentation.d.ts +15 -0
  55. package/dist/src/language/indentation.d.ts.map +1 -0
  56. package/dist/src/language/indentation.js +97 -0
  57. package/dist/src/language/indentation.js.map +1 -0
  58. package/dist/src/language/index.d.ts +54 -0
  59. package/dist/src/language/index.d.ts.map +1 -0
  60. package/dist/src/language/index.js +85 -0
  61. package/dist/src/language/index.js.map +1 -0
  62. package/dist/src/language/references.d.ts +12 -0
  63. package/dist/src/language/references.d.ts.map +1 -0
  64. package/dist/src/language/references.js +35 -0
  65. package/dist/src/language/references.js.map +1 -0
  66. package/dist/src/language/rename.d.ts +18 -0
  67. package/dist/src/language/rename.d.ts.map +1 -0
  68. package/dist/src/language/rename.js +53 -0
  69. package/dist/src/language/rename.js.map +1 -0
  70. package/dist/src/language/semanticModel.d.ts +21 -0
  71. package/dist/src/language/semanticModel.d.ts.map +1 -0
  72. package/dist/src/language/semanticModel.js +43 -0
  73. package/dist/src/language/semanticModel.js.map +1 -0
  74. package/dist/src/language/symbols.d.ts +9 -0
  75. package/dist/src/language/symbols.d.ts.map +1 -0
  76. package/dist/src/language/symbols.js +160 -0
  77. package/dist/src/language/symbols.js.map +1 -0
  78. package/dist/src/language/types.d.ts +49 -0
  79. package/dist/src/language/types.d.ts.map +1 -0
  80. package/dist/src/language/types.js +2 -0
  81. package/dist/src/language/types.js.map +1 -0
  82. package/dist/src/language/utils.d.ts +24 -0
  83. package/dist/src/language/utils.d.ts.map +1 -0
  84. package/dist/src/language/utils.js +154 -0
  85. package/dist/src/language/utils.js.map +1 -0
  86. package/dist/src/layout/dagre.d.ts +13 -0
  87. package/dist/src/layout/dagre.d.ts.map +1 -0
  88. package/dist/src/layout/dagre.js +229 -0
  89. package/dist/src/layout/dagre.js.map +1 -0
  90. package/dist/src/layout/index.d.ts +15 -0
  91. package/dist/src/layout/index.d.ts.map +1 -0
  92. package/dist/src/layout/index.js +22 -0
  93. package/dist/src/layout/index.js.map +1 -0
  94. package/dist/src/layout/simple.d.ts +20 -0
  95. package/dist/src/layout/simple.d.ts.map +1 -0
  96. package/dist/src/layout/simple.js +674 -0
  97. package/dist/src/layout/simple.js.map +1 -0
  98. package/dist/src/layout/types.d.ts +65 -0
  99. package/dist/src/layout/types.d.ts.map +1 -0
  100. package/dist/src/layout/types.js +2 -0
  101. package/dist/src/layout/types.js.map +1 -0
  102. package/dist/src/lexer.d.ts +25 -0
  103. package/dist/src/lexer.d.ts.map +1 -0
  104. package/dist/src/lexer.js +280 -0
  105. package/dist/src/lexer.js.map +1 -0
  106. package/dist/src/lsp/documents.d.ts +24 -0
  107. package/dist/src/lsp/documents.d.ts.map +1 -0
  108. package/dist/src/lsp/documents.js +97 -0
  109. package/dist/src/lsp/documents.js.map +1 -0
  110. package/dist/src/lsp/server.d.ts +70 -0
  111. package/dist/src/lsp/server.d.ts.map +1 -0
  112. package/dist/src/lsp/server.js +623 -0
  113. package/dist/src/lsp/server.js.map +1 -0
  114. package/dist/src/lsp/utils.d.ts +47 -0
  115. package/dist/src/lsp/utils.d.ts.map +1 -0
  116. package/dist/src/lsp/utils.js +142 -0
  117. package/dist/src/lsp/utils.js.map +1 -0
  118. package/dist/src/parser.d.ts +106 -0
  119. package/dist/src/parser.d.ts.map +1 -0
  120. package/dist/src/parser.js +1018 -0
  121. package/dist/src/parser.js.map +1 -0
  122. package/dist/src/pipeline.d.ts +51 -0
  123. package/dist/src/pipeline.d.ts.map +1 -0
  124. package/dist/src/pipeline.js +65 -0
  125. package/dist/src/pipeline.js.map +1 -0
  126. package/dist/src/range.d.ts +24 -0
  127. package/dist/src/range.d.ts.map +1 -0
  128. package/dist/src/range.js +20 -0
  129. package/dist/src/range.js.map +1 -0
  130. package/dist/src/render/index.d.ts +3 -0
  131. package/dist/src/render/index.d.ts.map +1 -0
  132. package/dist/src/render/index.js +3 -0
  133. package/dist/src/render/index.js.map +1 -0
  134. package/dist/src/render/shapes.d.ts +20 -0
  135. package/dist/src/render/shapes.d.ts.map +1 -0
  136. package/dist/src/render/shapes.js +110 -0
  137. package/dist/src/render/shapes.js.map +1 -0
  138. package/dist/src/render/svg.d.ts +19 -0
  139. package/dist/src/render/svg.d.ts.map +1 -0
  140. package/dist/src/render/svg.js +227 -0
  141. package/dist/src/render/svg.js.map +1 -0
  142. package/dist/src/security/url.d.ts +7 -0
  143. package/dist/src/security/url.d.ts.map +1 -0
  144. package/dist/src/security/url.js +27 -0
  145. package/dist/src/security/url.js.map +1 -0
  146. package/dist/src/types.d.ts +111 -0
  147. package/dist/src/types.d.ts.map +1 -0
  148. package/dist/src/types.js +16 -0
  149. package/dist/src/types.js.map +1 -0
  150. package/dist/src/validator.d.ts +47 -0
  151. package/dist/src/validator.d.ts.map +1 -0
  152. package/dist/src/validator.js +235 -0
  153. package/dist/src/validator.js.map +1 -0
  154. package/package.json +90 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../src/diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAEpD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,CAAC;AAEX,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,KAAK,CAAC;CACd;AAED,wBAAgB,IAAI,CAClB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,KAAK,GACX,UAAU,CAEZ"}
@@ -0,0 +1,4 @@
1
+ export function diag(severity, code, message, range) {
2
+ return { severity, code, message, range };
3
+ }
4
+ //# sourceMappingURL=diagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../../src/diagnostics.ts"],"names":[],"mappings":"AAgDA,MAAM,UAAU,IAAI,CAClB,QAAkB,EAClB,IAAoB,EACpB,OAAe,EACf,KAAY;IAEZ,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Floe — Diagram DSL public API (v1.0 stable)
3
+ *
4
+ * Core language does not depend on CodeMirror, React, Vue, DOM, SVG, Canvas, Dagre, ELK, or LSP.
5
+ * This entry point re-exports pure language primitives.
6
+ * Language services are editor-independent (see src/language/).
7
+ *
8
+ * Stability: exports listed under "Stable Public API" in docs/api.md are semver-stable.
9
+ * Exports marked @internal are deprecated and may be hidden in 2.0 — prefer stable wrappers.
10
+ */
11
+ export type { Position, Range } from "./range.js";
12
+ export { rangeToString } from "./range.js";
13
+ export type { Diagnostic, DiagnosticCode, Severity } from "./diagnostics.js";
14
+ export type { Direction, FloeDiagram, FloeNode, FloeEdge, FloeGroup, FloeAnnotation, FloeLink, EdgeKind, ParseResult, } from "./types.js";
15
+ export { DEFAULT_DIRECTION, DIRECTIONS, IDENTIFIER_RE, isValidIdentifier, } from "./types.js";
16
+ export { Lexer, tokenize, type Token, type TokenType } from "./lexer.js";
17
+ export { Parser, parse as parseRaw, parseRaw as parseRawFloe } from "./parser.js";
18
+ export { validate, type ValidationInput, type ValidationResult } from "./validator.js";
19
+ import type { ParseResult } from "./types.js";
20
+ /**
21
+ * @stable
22
+ * Parse Floe source with full pipeline:
23
+ * 1. lexical analysis
24
+ * 2. grammar-based parsing (with source ranges, error recovery)
25
+ * 3. semantic validation (separate phase)
26
+ *
27
+ * Never throws on malformed input — returns diagnostics instead.
28
+ * This is the recommended entry point (stable).
29
+ */
30
+ export declare function parseFloe(source: string): ParseResult;
31
+ /**
32
+ * Alias: `parse` is the validated entry as well for ergonomics.
33
+ * For raw (without validation) use `parseRaw` / `parseRawFloe`.
34
+ */
35
+ export declare const parse: typeof parseFloe;
36
+ export declare function isValid(source: string): boolean;
37
+ export { getHighlightTokens, getHighlightingInfo, getCompletions, getDiagnostics, getDiagnosticsWithSource, lint, getHover, getSymbols, getFlatSymbols, getDefinition, getDefinitionForWord, getReferences, getReferencesForWord, rename, renameWord, applyEdits, format, isFormatted, getIndentForLine, getIndentationInfo, getIndentationColumn, DEFAULT_INDENT, getFoldingRanges, getFoldingInfo, buildSemanticModel, getSemanticModel, } from "./language/index.js";
38
+ export type { CompletionItem, HoverInfo, SymbolKind, SymbolInformation, Location, TextEdit, FoldingRange, HighlightToken, FormattingOptions, SemanticModel, } from "./language/index.js";
39
+ export { FloeLanguageService, floeLanguageService } from "./language/index.js";
40
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG7E,YAAY,EACV,SAAS,EACT,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,cAAc,EACd,QAAQ,EACR,QAAQ,EACR,WAAW,GACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAKpB,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,KAAK,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAEzE,OAAO,EAAE,MAAM,EAAE,KAAK,IAAI,QAAQ,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,aAAa,CAAC;AAElF,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAIvF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,CAgBrD;AAED;;;GAGG;AACH,eAAO,MAAM,KAAK,kBAAY,CAAC;AAG/B,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAG/C;AAMD,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,wBAAwB,EACxB,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,aAAa,EACb,oBAAoB,EACpB,MAAM,EACN,UAAU,EACV,UAAU,EACV,MAAM,EACN,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,cAAc,EACd,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,aAAa,GACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Floe — Diagram DSL public API (v1.0 stable)
3
+ *
4
+ * Core language does not depend on CodeMirror, React, Vue, DOM, SVG, Canvas, Dagre, ELK, or LSP.
5
+ * This entry point re-exports pure language primitives.
6
+ * Language services are editor-independent (see src/language/).
7
+ *
8
+ * Stability: exports listed under "Stable Public API" in docs/api.md are semver-stable.
9
+ * Exports marked @internal are deprecated and may be hidden in 2.0 — prefer stable wrappers.
10
+ */
11
+ export { rangeToString } from "./range.js"; // utility, stable
12
+ export { DEFAULT_DIRECTION, DIRECTIONS, IDENTIFIER_RE, isValidIdentifier, } from "./types.js";
13
+ // ── Stable: high-level parse API ──
14
+ // parseFloe is the recommended entry; parse is alias; parseRaw is raw without validation (stable).
15
+ // Parser class and Lexer are low-level and considered @internal/low-level (still exported for tooling compat).
16
+ export { Lexer, tokenize } from "./lexer.js"; // @internal low-level
17
+ export { Parser, parse as parseRaw, parseRaw as parseRawFloe } from "./parser.js"; // @internal low-level: prefer parseRaw() function
18
+ export { validate } from "./validator.js"; // @internal: validation is internal phase, use parseFloe()
19
+ import { Parser } from "./parser.js";
20
+ import { validate } from "./validator.js";
21
+ /**
22
+ * @stable
23
+ * Parse Floe source with full pipeline:
24
+ * 1. lexical analysis
25
+ * 2. grammar-based parsing (with source ranges, error recovery)
26
+ * 3. semantic validation (separate phase)
27
+ *
28
+ * Never throws on malformed input — returns diagnostics instead.
29
+ * This is the recommended entry point (stable).
30
+ */
31
+ export function parseFloe(source) {
32
+ const raw = new Parser(source).parse();
33
+ const validated = validate({
34
+ diagram: raw.diagram,
35
+ diagnostics: raw.diagnostics,
36
+ explicitNodes: raw.explicitNodes,
37
+ edges: raw.edges,
38
+ directionDeclarations: raw.directionDeclarations,
39
+ groups: raw.groups,
40
+ annotations: raw.annotations,
41
+ links: raw.links,
42
+ });
43
+ return {
44
+ diagram: validated.diagram,
45
+ diagnostics: validated.diagnostics,
46
+ };
47
+ }
48
+ /**
49
+ * Alias: `parse` is the validated entry as well for ergonomics.
50
+ * For raw (without validation) use `parseRaw` / `parseRawFloe`.
51
+ */
52
+ export const parse = parseFloe;
53
+ // Convenience: check if source is valid (no error diagnostics)
54
+ export function isValid(source) {
55
+ const { diagnostics } = parseFloe(source);
56
+ return diagnostics.every((d) => d.severity !== "error");
57
+ }
58
+ // ---------------------------------------------------------------------------
59
+ // Language Tooling — editor-independent language services (stable)
60
+ // Re-export explicit stable surface instead of wildcard to avoid leaking internals.
61
+ // ---------------------------------------------------------------------------
62
+ export { getHighlightTokens, getHighlightingInfo, getCompletions, getDiagnostics, getDiagnosticsWithSource, lint, getHover, getSymbols, getFlatSymbols, getDefinition, getDefinitionForWord, getReferences, getReferencesForWord, rename, renameWord, applyEdits, format, isFormatted, getIndentForLine, getIndentationInfo, getIndentationColumn, DEFAULT_INDENT, getFoldingRanges, getFoldingInfo, buildSemanticModel, getSemanticModel, } from "./language/index.js";
63
+ export { FloeLanguageService, floeLanguageService } from "./language/index.js";
64
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC,CAAC,kBAAkB;AAgB9D,OAAO,EACL,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAEpB,qCAAqC;AACrC,mGAAmG;AACnG,+GAA+G;AAC/G,OAAO,EAAE,KAAK,EAAE,QAAQ,EAA8B,MAAM,YAAY,CAAC,CAAC,sBAAsB;AAEhG,OAAO,EAAE,MAAM,EAAE,KAAK,IAAI,QAAQ,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,aAAa,CAAC,CAAC,kDAAkD;AAErI,OAAO,EAAE,QAAQ,EAA+C,MAAM,gBAAgB,CAAC,CAAC,2DAA2D;AAEnJ,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG1C;;;;;;;;;GASG;AACH,MAAM,UAAU,SAAS,CAAC,MAAc;IACtC,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC;IACvC,MAAM,SAAS,GAAG,QAAQ,CAAC;QACzB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,aAAa,EAAE,GAAG,CAAC,aAAa;QAChC,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,qBAAqB,EAAE,GAAG,CAAC,qBAAqB;QAChD,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,KAAK,EAAE,GAAG,CAAC,KAAK;KACjB,CAAC,CAAC;IACH,OAAO;QACL,OAAO,EAAE,SAAS,CAAC,OAAO;QAC1B,WAAW,EAAE,SAAS,CAAC,WAAW;KACnC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,SAAS,CAAC;AAE/B,+DAA+D;AAC/D,MAAM,UAAU,OAAO,CAAC,MAAc;IACpC,MAAM,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAC1C,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;AAC1D,CAAC;AAED,8EAA8E;AAC9E,mEAAmE;AACnE,oFAAoF;AACpF,8EAA8E;AAC9E,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,wBAAwB,EACxB,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,aAAa,EACb,oBAAoB,EACpB,MAAM,EACN,UAAU,EACV,UAAU,EACV,MAAM,EACN,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAa7B,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { CompletionItem } from "./types.js";
2
+ /**
3
+ * Context-aware completion — operates on semantic model, not random.
4
+ */
5
+ export declare function getCompletions(source: string, offset: number): CompletionItem[];
6
+ //# sourceMappingURL=completion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../../../src/language/completion.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAkDjD;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,cAAc,EAAE,CAwS/E"}
@@ -0,0 +1,363 @@
1
+ import { tokenize } from "../lexer.js";
2
+ import { getTokenBeforeOffset, getTokenAtOffset, positionAt } from "./utils.js";
3
+ import { Parser } from "../parser.js";
4
+ import { validate } from "../validator.js";
5
+ function parseFloe(source) {
6
+ const raw = new Parser(source).parse();
7
+ const validated = validate({
8
+ diagram: raw.diagram,
9
+ diagnostics: raw.diagnostics,
10
+ explicitNodes: raw.explicitNodes,
11
+ edges: raw.edges,
12
+ directionDeclarations: raw.directionDeclarations,
13
+ groups: raw.groups,
14
+ annotations: raw.annotations,
15
+ links: raw.links,
16
+ });
17
+ return { diagram: validated.diagram, diagnostics: validated.diagnostics };
18
+ }
19
+ const DIRECTIONS = ["TB", "BT", "LR", "RL"];
20
+ const KNOWN_TYPES = [
21
+ "person",
22
+ "service",
23
+ "database",
24
+ "client",
25
+ "subsystem",
26
+ "external",
27
+ "system",
28
+ "container",
29
+ "component",
30
+ "queue",
31
+ "store",
32
+ "gateway",
33
+ ];
34
+ const TOP_LEVEL_KEYWORDS = ["direction", "group", "meta", "note", "link"];
35
+ function prefixFilter(items, prefix) {
36
+ if (!prefix)
37
+ return items;
38
+ const lower = prefix.toLowerCase();
39
+ return items.filter((i) => i.label.toLowerCase().startsWith(lower));
40
+ }
41
+ function getPrefixAtOffset(source, offset) {
42
+ let start = offset;
43
+ while (start > 0 && /[A-Za-z0-9_-]/.test(source[start - 1]))
44
+ start--;
45
+ return source.slice(start, offset);
46
+ }
47
+ /**
48
+ * Context-aware completion — operates on semantic model, not random.
49
+ */
50
+ export function getCompletions(source, offset) {
51
+ const tokens = tokenize(source);
52
+ const before = getTokenBeforeOffset(tokens, offset);
53
+ const at = getTokenAtOffset(tokens, offset);
54
+ const pos = positionAt(source, offset);
55
+ const textBefore = source.slice(0, offset);
56
+ const prefix = getPrefixAtOffset(source, offset);
57
+ // If inside string or comment, no completions (avoid invalid syntax)
58
+ if (at && (at.type === "STRING" || at.type === "COMMENT")) {
59
+ return [];
60
+ }
61
+ // Helper to detect context requiring completion
62
+ const trimmedBefore = textBefore.trimEnd();
63
+ const lines = source.slice(0, offset).split(/\r?\n/);
64
+ const currentLinePrefix = lines[lines.length - 1] ?? "";
65
+ const trimmedLine = currentLinePrefix.trimStart();
66
+ // 1) After "direction" keyword => suggest directions
67
+ // Detect if last keyword before offset is "direction" and no direction value yet consumed
68
+ // Check tokens: look backward for nearest DIRECTION_KW not followed by IDENT before offset
69
+ {
70
+ // Find last DIRECTION_KW before offset
71
+ let lastDirIdx = -1;
72
+ for (let i = 0; i < tokens.length; i++) {
73
+ const t = tokens[i];
74
+ if (t.type === "DIRECTION_KW" && t.range.end.offset <= offset)
75
+ lastDirIdx = i;
76
+ }
77
+ if (lastDirIdx !== -1) {
78
+ const dirTok = tokens[lastDirIdx];
79
+ // Check tokens after direction until offset: if there is no IDENT after it (direction value) then suggest
80
+ let hasValue = false;
81
+ let valueToken;
82
+ for (let i = lastDirIdx + 1; i < tokens.length; i++) {
83
+ const t = tokens[i];
84
+ if (t.range.start.offset >= offset)
85
+ break;
86
+ if (t.type === "NEWLINE" || t.type === "COMMENT")
87
+ break;
88
+ if (t.type === "IDENT" || t.type === "UNKNOWN") {
89
+ hasValue = true;
90
+ valueToken = t;
91
+ break;
92
+ }
93
+ }
94
+ if (!hasValue) {
95
+ const items = DIRECTIONS.map((d) => ({
96
+ label: d,
97
+ kind: "value",
98
+ detail: "direction",
99
+ }));
100
+ // When cursor is directly after keyword (offset at token end), prefix is empty for value completion
101
+ // Don't use keyword prefix; check if we are inside a partial value token at cursor
102
+ let valuePrefix = "";
103
+ if (at && at.type === "IDENT" && at.range.start.offset > dirTok.range.end.offset) {
104
+ valuePrefix = source.slice(at.range.start.offset, offset);
105
+ }
106
+ else if (at && at.type === "UNKNOWN" && at.range.start.offset > dirTok.range.end.offset) {
107
+ valuePrefix = source.slice(at.range.start.offset, offset);
108
+ }
109
+ return prefixFilter(items, valuePrefix);
110
+ }
111
+ else {
112
+ // hasValue true: user may be editing the existing direction value token (partial)
113
+ // Handle cursor inside or right after valueToken (at may be undefined when at token end)
114
+ if (valueToken) {
115
+ const idx = tokens.indexOf(valueToken);
116
+ const prevIsDir = idx > 0 && tokens[idx - 1]?.type === "DIRECTION_KW";
117
+ if (prevIsDir && offset >= valueToken.range.start.offset && offset <= valueToken.range.end.offset + 1) {
118
+ const valuePrefix = source.slice(valueToken.range.start.offset, offset);
119
+ const items = DIRECTIONS.map((d) => ({
120
+ label: d,
121
+ kind: "value",
122
+ detail: "direction",
123
+ }));
124
+ return prefixFilter(items, valuePrefix);
125
+ }
126
+ }
127
+ // Fallback for at being IDENT (when offset inside token)
128
+ if (at && at.type === "IDENT") {
129
+ // check previous token is DIRECTION_KW or this token is the value token
130
+ const isValueToken = valueToken && at.range.start.offset === valueToken.range.start.offset;
131
+ const prevIsDir = (() => {
132
+ const idx = tokens.indexOf(at);
133
+ return idx > 0 && tokens[idx - 1]?.type === "DIRECTION_KW";
134
+ })();
135
+ if (isValueToken || prevIsDir) {
136
+ const items = DIRECTIONS.map((d) => ({
137
+ label: d,
138
+ kind: "value",
139
+ detail: "direction",
140
+ }));
141
+ // Use value token prefix, not keyword prefix
142
+ const valuePrefix = source.slice(at.range.start.offset, offset);
143
+ return prefixFilter(items, valuePrefix);
144
+ }
145
+ }
146
+ if (at && at.type === "UNKNOWN" && valueToken && at.range.start.offset === valueToken.range.start.offset) {
147
+ const items = DIRECTIONS.map((d) => ({
148
+ label: d,
149
+ kind: "value",
150
+ detail: "direction",
151
+ }));
152
+ const valuePrefix = source.slice(at.range.start.offset, offset);
153
+ return prefixFilter(items, valuePrefix);
154
+ }
155
+ }
156
+ }
157
+ // Also if currentLinePrefix trimmed is exactly "direction" or "direction " etc, or prefix is part of "direction" keyword? handle typo? but not needed
158
+ // Direct textual check: if trimmedBefore endsWith "direction" (keyword not yet completed + space)
159
+ if (trimmedBefore.endsWith("direction") && !trimmedBefore.endsWith("direction ")) {
160
+ // cursor right after keyword without space — also suggest directions after space? but we suggest directions
161
+ // Provide directions anyway
162
+ // Actually spec example: After "direction\n" suggest TB etc — means after keyword on next line? Wait example:
163
+ // After:
164
+ // direction
165
+ // suggest TB etc -> means line is "direction" with no value, next line maybe? Or same line start?
166
+ // Interpret as after typing "direction" and awaiting value
167
+ }
168
+ }
169
+ // 2) Inside brackets [ _ ] — suggest known node types
170
+ // Detect if previous non-whitespace char before offset is "[" or inside bracket context
171
+ {
172
+ // Find last LBRACKET before offset not closed before offset
173
+ // Simple: look backward for LBRACKET, check if not followed by RBRACKET before offset
174
+ let lastLbIdx = -1;
175
+ let lastRbIdx = -1;
176
+ for (let i = 0; i < tokens.length; i++) {
177
+ const t = tokens[i];
178
+ if (t.range.end.offset > offset)
179
+ break;
180
+ if (t.type === "LBRACKET")
181
+ lastLbIdx = i;
182
+ if (t.type === "RBRACKET")
183
+ lastRbIdx = i;
184
+ }
185
+ if (lastLbIdx !== -1 && lastLbIdx > lastRbIdx) {
186
+ // Inside brackets
187
+ const items = KNOWN_TYPES.map((t) => ({
188
+ label: t,
189
+ kind: "type",
190
+ detail: "node type",
191
+ }));
192
+ return prefixFilter(items, prefix);
193
+ }
194
+ }
195
+ // 3) After edge operator -> or -- => suggest node ids (existing nodes)
196
+ {
197
+ // Find last ARROW/DASHDASH before offset that is on same line and no target yet
198
+ let lastOpIdx = -1;
199
+ for (let i = tokens.length - 1; i >= 0; i--) {
200
+ const t = tokens[i];
201
+ if (t.range.end.offset <= offset && (t.type === "ARROW" || t.type === "DASHDASH")) {
202
+ lastOpIdx = i;
203
+ break;
204
+ }
205
+ if (t.type === "NEWLINE" && t.range.start.offset < offset) {
206
+ // crossed line, but maybe edge is multiline? Floe is single line per statement, so break
207
+ break;
208
+ }
209
+ }
210
+ if (lastOpIdx !== -1) {
211
+ const opTok = tokens[lastOpIdx];
212
+ // Check if there is already a target IDENT after op before offset and before newline
213
+ let hasTarget = false;
214
+ for (let i = lastOpIdx + 1; i < tokens.length; i++) {
215
+ const t = tokens[i];
216
+ if (t.range.start.offset >= offset)
217
+ break;
218
+ if (t.type === "NEWLINE" || t.type === "COMMENT" || t.type === "RBRACE")
219
+ break;
220
+ if (t.type === "IDENT") {
221
+ // Could be target but if prefix exists we still want to suggest? If at is IDENT (partial target) we should suggest filtered node ids
222
+ hasTarget = true;
223
+ // But if we are currently typing target (at is IDENT), we should still suggest
224
+ if (at && at.type === "IDENT" && at.range.start.offset > opTok.range.end.offset) {
225
+ hasTarget = false; // still completing target
226
+ }
227
+ break;
228
+ }
229
+ }
230
+ if (!hasTarget) {
231
+ // Suggest existing node ids + group ids
232
+ try {
233
+ const { diagram } = parseFloe(source);
234
+ const ids = diagram.nodes.map((n) => n.id);
235
+ // also groups
236
+ const collectGroups = (gs) => {
237
+ const out = [];
238
+ for (const g of gs) {
239
+ out.push(g.id);
240
+ out.push(...collectGroups(g.groups));
241
+ }
242
+ return out;
243
+ };
244
+ const groupIds = collectGroups(diagram.groups);
245
+ const allIds = Array.from(new Set([...ids, ...groupIds]));
246
+ const items = allIds.map((id) => ({
247
+ label: id,
248
+ kind: "variable",
249
+ detail: "node",
250
+ }));
251
+ if (items.length === 0) {
252
+ // Fallback suggest placeholder?
253
+ return [];
254
+ }
255
+ return prefixFilter(items, prefix);
256
+ }
257
+ catch {
258
+ return [];
259
+ }
260
+ }
261
+ }
262
+ }
263
+ // 4) At line start or after newline => suggest top-level keywords + existing ids for edge sources?
264
+ // Check if current line prefix after trimStart is empty or is partial keyword
265
+ {
266
+ const lineTrim = trimmedLine;
267
+ // If line is empty or starts with partial identifier that could be keyword
268
+ if (lineTrim === "" || /^[A-Za-z]*$/.test(prefix) && lineTrim.length <= prefix.length + 10) {
269
+ // Determine if we are at start of statement (beginning of line)
270
+ // Suggest keywords
271
+ const keywordItems = TOP_LEVEL_KEYWORDS.map((k) => ({
272
+ label: k,
273
+ kind: "keyword",
274
+ detail: "keyword",
275
+ }));
276
+ // Also suggest existing node ids as potential edge sources? Might be useful
277
+ // But to avoid random, we only suggest keywords at line start; user can type edge from existing node by typing its id
278
+ // For now, suggest keywords filtered by prefix, plus maybe direction values if after direction? already handled
279
+ // Include node types? No
280
+ // For broader completions, include existing ids as well when prefix matches?
281
+ // Let's include node ids when prefix is not empty and not a keyword prefix?
282
+ // Better: if prefix empty, suggest keywords; if prefix matches keyword start, filter keywords; else also suggest node ids
283
+ const filteredKeywords = prefixFilter(keywordItems, prefix);
284
+ if (filteredKeywords.length > 0) {
285
+ // Also consider suggesting node ids if requested? But keep deterministic
286
+ // Include node ids as secondary if keyword filter yields many? Keep just keywords for top-level start
287
+ return filteredKeywords;
288
+ }
289
+ // If no keyword matches, fallback to suggest node ids (useful for edge source completion at line start)
290
+ if (prefix.length > 0) {
291
+ try {
292
+ const { diagram } = parseFloe(source);
293
+ const ids = Array.from(new Set(diagram.nodes.map((n) => n.id)));
294
+ const idItems = ids.map((id) => ({
295
+ label: id,
296
+ kind: "variable",
297
+ detail: "node id",
298
+ }));
299
+ const filteredIds = prefixFilter(idItems, prefix);
300
+ if (filteredIds.length > 0)
301
+ return filteredIds;
302
+ }
303
+ catch { }
304
+ }
305
+ return filteredKeywords;
306
+ }
307
+ }
308
+ // 5) After "group" keyword — expecting group id? Could suggest?
309
+ {
310
+ if (before && before.type === "GROUP_KW") {
311
+ return []; // expecting new identifier, no suggestion
312
+ }
313
+ if (trimmedBefore.endsWith("group") || trimmedBefore.match(/\bgroup\s+$/)) {
314
+ return [];
315
+ }
316
+ }
317
+ // 6) After "meta", "note", "link" etc — suggest identifiers
318
+ {
319
+ if (before && before.type === "META_KW") {
320
+ // meta key — suggest? no
321
+ return [];
322
+ }
323
+ if (before && before.type === "NOTE_KW") {
324
+ // note [target] — suggest existing ids
325
+ try {
326
+ const { diagram } = parseFloe(source);
327
+ const ids = Array.from(new Set([...diagram.nodes.map((n) => n.id), ...collectGroupIds(diagram.groups)]));
328
+ const items = ids.map((id) => ({
329
+ label: id,
330
+ kind: "variable",
331
+ detail: "note target",
332
+ }));
333
+ // Also suggest string? But not needed
334
+ if (items.length > 0)
335
+ return prefixFilter(items, prefix);
336
+ }
337
+ catch { }
338
+ }
339
+ if (before && before.type === "LINK_KW") {
340
+ try {
341
+ const { diagram } = parseFloe(source);
342
+ const ids = Array.from(new Set([...diagram.nodes.map((n) => n.id), ...collectGroupIds(diagram.groups)]));
343
+ const items = ids.map((id) => ({
344
+ label: id,
345
+ kind: "variable",
346
+ detail: "link target",
347
+ }));
348
+ return prefixFilter(items, prefix);
349
+ }
350
+ catch { }
351
+ }
352
+ }
353
+ return [];
354
+ }
355
+ function collectGroupIds(groups) {
356
+ const out = [];
357
+ for (const g of groups) {
358
+ out.push(g.id);
359
+ out.push(...collectGroupIds(g.groups));
360
+ }
361
+ return out;
362
+ }
363
+ //# sourceMappingURL=completion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completion.js","sourceRoot":"","sources":["../../../src/language/completion.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { Location } from "./types.js";
2
+ /**
3
+ * Definitions — a node declaration should be identifiable.
4
+ * Given offset, find definition location of symbol at that offset.
5
+ */
6
+ export declare function getDefinition(source: string, offset: number): Location | null;
7
+ /** For testing: get definition for a given word directly */
8
+ export declare function getDefinitionForWord(source: string, word: string): Location | null;
9
+ //# sourceMappingURL=definitions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../../src/language/definitions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAmB3C;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CA4B7E;AAED,4DAA4D;AAC5D,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAOlF"}
@@ -0,0 +1,70 @@
1
+ import { tokenize } from "../lexer.js";
2
+ import { getTokenAtOffset } from "./utils.js";
3
+ import { Parser } from "../parser.js";
4
+ import { validate } from "../validator.js";
5
+ function parseFloe(source) {
6
+ const raw = new Parser(source).parse();
7
+ const validated = validate({
8
+ diagram: raw.diagram,
9
+ diagnostics: raw.diagnostics,
10
+ explicitNodes: raw.explicitNodes,
11
+ edges: raw.edges,
12
+ directionDeclarations: raw.directionDeclarations,
13
+ groups: raw.groups,
14
+ annotations: raw.annotations,
15
+ links: raw.links,
16
+ });
17
+ return { diagram: validated.diagram, diagnostics: validated.diagnostics };
18
+ }
19
+ /**
20
+ * Definitions — a node declaration should be identifiable.
21
+ * Given offset, find definition location of symbol at that offset.
22
+ */
23
+ export function getDefinition(source, offset) {
24
+ const tokens = tokenize(source);
25
+ const tok = getTokenAtOffset(tokens, offset);
26
+ if (!tok || tok.type !== "IDENT")
27
+ return null;
28
+ const id = tok.lexeme;
29
+ const { diagram } = parseFloe(source);
30
+ // Search explicit nodes first
31
+ const node = diagram.nodes.find((n) => n.id === id);
32
+ if (node) {
33
+ return { range: node.range };
34
+ }
35
+ // Search groups
36
+ const grp = findGroup(diagram.groups, id);
37
+ if (grp) {
38
+ return { range: grp.range };
39
+ }
40
+ // If not found as node/group but appears as edge source/target implicit, definition could be first occurrence?
41
+ // Fallback: find first token with same lexeme
42
+ for (const t of tokens) {
43
+ if (t.type === "IDENT" && t.lexeme === id) {
44
+ return { range: t.range };
45
+ }
46
+ }
47
+ return null;
48
+ }
49
+ /** For testing: get definition for a given word directly */
50
+ export function getDefinitionForWord(source, word) {
51
+ const { diagram } = parseFloe(source);
52
+ const node = diagram.nodes.find((n) => n.id === word);
53
+ if (node)
54
+ return { range: node.range };
55
+ const grp = findGroup(diagram.groups, word);
56
+ if (grp)
57
+ return { range: grp.range };
58
+ return null;
59
+ }
60
+ function findGroup(groups, id) {
61
+ for (const g of groups) {
62
+ if (g.id === id)
63
+ return g;
64
+ const child = findGroup(g.groups, id);
65
+ if (child)
66
+ return child;
67
+ }
68
+ return undefined;
69
+ }
70
+ //# sourceMappingURL=definitions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../../src/language/definitions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { Diagnostic } from "../diagnostics.js";
2
+ /**
3
+ * Diagnostics API — useful while document is incomplete.
4
+ * Should produce recoverable diagnostic rather than crashing.
5
+ * Example: "User ->" should produce E009/E006 not throw.
6
+ */
7
+ export declare function getDiagnostics(source: string): Diagnostic[];
8
+ export declare function getDiagnosticsWithSource(source: string): {
9
+ diagnostics: Diagnostic[];
10
+ hasErrors: boolean;
11
+ };
12
+ /** For LSP/CodeMirror lint integration — returns diagnostics sorted */
13
+ export declare function lint(source: string): Diagnostic[];
14
+ //# sourceMappingURL=diagnosticsService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnosticsService.d.ts","sourceRoot":"","sources":["../../../src/language/diagnosticsService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAmBpD;;;;GAIG;AAEH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE,CAG3D;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,WAAW,EAAE,UAAU,EAAE,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAM1G;AAED,uEAAuE;AACvE,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE,CAEjD"}