@rejot-dev/thalo 0.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 (237) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +396 -0
  3. package/dist/ast/ast-types.d.ts +469 -0
  4. package/dist/ast/ast-types.d.ts.map +1 -0
  5. package/dist/ast/ast-types.js +11 -0
  6. package/dist/ast/ast-types.js.map +1 -0
  7. package/dist/ast/builder.js +158 -0
  8. package/dist/ast/builder.js.map +1 -0
  9. package/dist/ast/extract.js +748 -0
  10. package/dist/ast/extract.js.map +1 -0
  11. package/dist/ast/node-at-position.d.ts +147 -0
  12. package/dist/ast/node-at-position.d.ts.map +1 -0
  13. package/dist/ast/node-at-position.js +382 -0
  14. package/dist/ast/node-at-position.js.map +1 -0
  15. package/dist/ast/visitor.js +232 -0
  16. package/dist/ast/visitor.js.map +1 -0
  17. package/dist/checker/check.d.ts +53 -0
  18. package/dist/checker/check.d.ts.map +1 -0
  19. package/dist/checker/check.js +105 -0
  20. package/dist/checker/check.js.map +1 -0
  21. package/dist/checker/rules/actualize-missing-updated.js +34 -0
  22. package/dist/checker/rules/actualize-missing-updated.js.map +1 -0
  23. package/dist/checker/rules/actualize-unresolved-target.js +42 -0
  24. package/dist/checker/rules/actualize-unresolved-target.js.map +1 -0
  25. package/dist/checker/rules/alter-before-define.js +53 -0
  26. package/dist/checker/rules/alter-before-define.js.map +1 -0
  27. package/dist/checker/rules/alter-undefined-entity.js +32 -0
  28. package/dist/checker/rules/alter-undefined-entity.js.map +1 -0
  29. package/dist/checker/rules/create-requires-section.js +34 -0
  30. package/dist/checker/rules/create-requires-section.js.map +1 -0
  31. package/dist/checker/rules/define-entity-requires-section.js +31 -0
  32. package/dist/checker/rules/define-entity-requires-section.js.map +1 -0
  33. package/dist/checker/rules/duplicate-entity-definition.js +37 -0
  34. package/dist/checker/rules/duplicate-entity-definition.js.map +1 -0
  35. package/dist/checker/rules/duplicate-field-in-schema.js +38 -0
  36. package/dist/checker/rules/duplicate-field-in-schema.js.map +1 -0
  37. package/dist/checker/rules/duplicate-link-id.js +52 -0
  38. package/dist/checker/rules/duplicate-link-id.js.map +1 -0
  39. package/dist/checker/rules/duplicate-metadata-key.js +21 -0
  40. package/dist/checker/rules/duplicate-metadata-key.js.map +1 -0
  41. package/dist/checker/rules/duplicate-section-heading.js +41 -0
  42. package/dist/checker/rules/duplicate-section-heading.js.map +1 -0
  43. package/dist/checker/rules/duplicate-section-in-schema.js +38 -0
  44. package/dist/checker/rules/duplicate-section-in-schema.js.map +1 -0
  45. package/dist/checker/rules/duplicate-timestamp.js +104 -0
  46. package/dist/checker/rules/duplicate-timestamp.js.map +1 -0
  47. package/dist/checker/rules/empty-required-value.js +45 -0
  48. package/dist/checker/rules/empty-required-value.js.map +1 -0
  49. package/dist/checker/rules/empty-section.js +21 -0
  50. package/dist/checker/rules/empty-section.js.map +1 -0
  51. package/dist/checker/rules/invalid-date-range-value.js +56 -0
  52. package/dist/checker/rules/invalid-date-range-value.js.map +1 -0
  53. package/dist/checker/rules/invalid-default-value.js +86 -0
  54. package/dist/checker/rules/invalid-default-value.js.map +1 -0
  55. package/dist/checker/rules/invalid-field-type.js +45 -0
  56. package/dist/checker/rules/invalid-field-type.js.map +1 -0
  57. package/dist/checker/rules/missing-required-field.js +48 -0
  58. package/dist/checker/rules/missing-required-field.js.map +1 -0
  59. package/dist/checker/rules/missing-required-section.js +51 -0
  60. package/dist/checker/rules/missing-required-section.js.map +1 -0
  61. package/dist/checker/rules/missing-title.js +56 -0
  62. package/dist/checker/rules/missing-title.js.map +1 -0
  63. package/dist/checker/rules/remove-undefined-field.js +42 -0
  64. package/dist/checker/rules/remove-undefined-field.js.map +1 -0
  65. package/dist/checker/rules/remove-undefined-section.js +42 -0
  66. package/dist/checker/rules/remove-undefined-section.js.map +1 -0
  67. package/dist/checker/rules/rules.d.ts +71 -0
  68. package/dist/checker/rules/rules.d.ts.map +1 -0
  69. package/dist/checker/rules/rules.js +102 -0
  70. package/dist/checker/rules/rules.js.map +1 -0
  71. package/dist/checker/rules/synthesis-empty-query.js +35 -0
  72. package/dist/checker/rules/synthesis-empty-query.js.map +1 -0
  73. package/dist/checker/rules/synthesis-missing-prompt.js +42 -0
  74. package/dist/checker/rules/synthesis-missing-prompt.js.map +1 -0
  75. package/dist/checker/rules/synthesis-missing-sources.js +32 -0
  76. package/dist/checker/rules/synthesis-missing-sources.js.map +1 -0
  77. package/dist/checker/rules/synthesis-unknown-query-entity.js +39 -0
  78. package/dist/checker/rules/synthesis-unknown-query-entity.js.map +1 -0
  79. package/dist/checker/rules/timestamp-out-of-order.js +55 -0
  80. package/dist/checker/rules/timestamp-out-of-order.js.map +1 -0
  81. package/dist/checker/rules/unknown-entity.js +32 -0
  82. package/dist/checker/rules/unknown-entity.js.map +1 -0
  83. package/dist/checker/rules/unknown-field.js +40 -0
  84. package/dist/checker/rules/unknown-field.js.map +1 -0
  85. package/dist/checker/rules/unknown-section.js +47 -0
  86. package/dist/checker/rules/unknown-section.js.map +1 -0
  87. package/dist/checker/rules/unresolved-link.js +34 -0
  88. package/dist/checker/rules/unresolved-link.js.map +1 -0
  89. package/dist/checker/rules/update-without-create.js +65 -0
  90. package/dist/checker/rules/update-without-create.js.map +1 -0
  91. package/dist/checker/visitor.d.ts +69 -0
  92. package/dist/checker/visitor.d.ts.map +1 -0
  93. package/dist/checker/visitor.js +67 -0
  94. package/dist/checker/visitor.js.map +1 -0
  95. package/dist/checker/workspace-index.d.ts +50 -0
  96. package/dist/checker/workspace-index.d.ts.map +1 -0
  97. package/dist/checker/workspace-index.js +108 -0
  98. package/dist/checker/workspace-index.js.map +1 -0
  99. package/dist/commands/actualize.d.ts +113 -0
  100. package/dist/commands/actualize.d.ts.map +1 -0
  101. package/dist/commands/actualize.js +111 -0
  102. package/dist/commands/actualize.js.map +1 -0
  103. package/dist/commands/check.d.ts +65 -0
  104. package/dist/commands/check.d.ts.map +1 -0
  105. package/dist/commands/check.js +61 -0
  106. package/dist/commands/check.js.map +1 -0
  107. package/dist/commands/format.d.ts +90 -0
  108. package/dist/commands/format.d.ts.map +1 -0
  109. package/dist/commands/format.js +80 -0
  110. package/dist/commands/format.js.map +1 -0
  111. package/dist/commands/query.d.ts +152 -0
  112. package/dist/commands/query.d.ts.map +1 -0
  113. package/dist/commands/query.js +151 -0
  114. package/dist/commands/query.js.map +1 -0
  115. package/dist/constants.d.ts +31 -0
  116. package/dist/constants.d.ts.map +1 -0
  117. package/dist/constants.js +51 -0
  118. package/dist/constants.js.map +1 -0
  119. package/dist/files.d.ts +58 -0
  120. package/dist/files.d.ts.map +1 -0
  121. package/dist/files.js +103 -0
  122. package/dist/files.js.map +1 -0
  123. package/dist/formatters.d.ts +39 -0
  124. package/dist/formatters.d.ts.map +1 -0
  125. package/dist/formatters.js +200 -0
  126. package/dist/formatters.js.map +1 -0
  127. package/dist/fragment.d.ts +22 -0
  128. package/dist/fragment.d.ts.map +1 -0
  129. package/dist/git/git.js +240 -0
  130. package/dist/git/git.js.map +1 -0
  131. package/dist/merge/conflict-detector.d.ts +89 -0
  132. package/dist/merge/conflict-detector.d.ts.map +1 -0
  133. package/dist/merge/conflict-detector.js +352 -0
  134. package/dist/merge/conflict-detector.js.map +1 -0
  135. package/dist/merge/conflict-formatter.js +143 -0
  136. package/dist/merge/conflict-formatter.js.map +1 -0
  137. package/dist/merge/driver.d.ts +54 -0
  138. package/dist/merge/driver.d.ts.map +1 -0
  139. package/dist/merge/driver.js +112 -0
  140. package/dist/merge/driver.js.map +1 -0
  141. package/dist/merge/entry-matcher.d.ts +50 -0
  142. package/dist/merge/entry-matcher.d.ts.map +1 -0
  143. package/dist/merge/entry-matcher.js +141 -0
  144. package/dist/merge/entry-matcher.js.map +1 -0
  145. package/dist/merge/entry-merger.js +194 -0
  146. package/dist/merge/entry-merger.js.map +1 -0
  147. package/dist/merge/merge-result-builder.d.ts +62 -0
  148. package/dist/merge/merge-result-builder.d.ts.map +1 -0
  149. package/dist/merge/merge-result-builder.js +89 -0
  150. package/dist/merge/merge-result-builder.js.map +1 -0
  151. package/dist/mod.d.ts +31 -0
  152. package/dist/mod.js +23 -0
  153. package/dist/model/document.d.ts +134 -0
  154. package/dist/model/document.d.ts.map +1 -0
  155. package/dist/model/document.js +275 -0
  156. package/dist/model/document.js.map +1 -0
  157. package/dist/model/line-index.d.ts +85 -0
  158. package/dist/model/line-index.d.ts.map +1 -0
  159. package/dist/model/line-index.js +159 -0
  160. package/dist/model/line-index.js.map +1 -0
  161. package/dist/model/workspace.d.ts +296 -0
  162. package/dist/model/workspace.d.ts.map +1 -0
  163. package/dist/model/workspace.js +562 -0
  164. package/dist/model/workspace.js.map +1 -0
  165. package/dist/parser.js +27 -0
  166. package/dist/parser.js.map +1 -0
  167. package/dist/parser.native.d.ts +51 -0
  168. package/dist/parser.native.d.ts.map +1 -0
  169. package/dist/parser.native.js +62 -0
  170. package/dist/parser.native.js.map +1 -0
  171. package/dist/parser.shared.d.ts +99 -0
  172. package/dist/parser.shared.d.ts.map +1 -0
  173. package/dist/parser.shared.js +124 -0
  174. package/dist/parser.shared.js.map +1 -0
  175. package/dist/parser.web.d.ts +67 -0
  176. package/dist/parser.web.d.ts.map +1 -0
  177. package/dist/parser.web.js +49 -0
  178. package/dist/parser.web.js.map +1 -0
  179. package/dist/schema/registry.d.ts +108 -0
  180. package/dist/schema/registry.d.ts.map +1 -0
  181. package/dist/schema/registry.js +281 -0
  182. package/dist/schema/registry.js.map +1 -0
  183. package/dist/semantic/analyzer.d.ts +107 -0
  184. package/dist/semantic/analyzer.d.ts.map +1 -0
  185. package/dist/semantic/analyzer.js +261 -0
  186. package/dist/semantic/analyzer.js.map +1 -0
  187. package/dist/services/change-tracker/change-tracker.d.ts +111 -0
  188. package/dist/services/change-tracker/change-tracker.d.ts.map +1 -0
  189. package/dist/services/change-tracker/change-tracker.js +62 -0
  190. package/dist/services/change-tracker/change-tracker.js.map +1 -0
  191. package/dist/services/change-tracker/create-tracker.d.ts +42 -0
  192. package/dist/services/change-tracker/create-tracker.d.ts.map +1 -0
  193. package/dist/services/change-tracker/create-tracker.js +53 -0
  194. package/dist/services/change-tracker/create-tracker.js.map +1 -0
  195. package/dist/services/change-tracker/git-tracker.d.ts +59 -0
  196. package/dist/services/change-tracker/git-tracker.d.ts.map +1 -0
  197. package/dist/services/change-tracker/git-tracker.js +218 -0
  198. package/dist/services/change-tracker/git-tracker.js.map +1 -0
  199. package/dist/services/change-tracker/timestamp-tracker.d.ts +22 -0
  200. package/dist/services/change-tracker/timestamp-tracker.d.ts.map +1 -0
  201. package/dist/services/change-tracker/timestamp-tracker.js +74 -0
  202. package/dist/services/change-tracker/timestamp-tracker.js.map +1 -0
  203. package/dist/services/definition.d.ts +37 -0
  204. package/dist/services/definition.d.ts.map +1 -0
  205. package/dist/services/definition.js +43 -0
  206. package/dist/services/definition.js.map +1 -0
  207. package/dist/services/entity-navigation.d.ts +200 -0
  208. package/dist/services/entity-navigation.d.ts.map +1 -0
  209. package/dist/services/entity-navigation.js +211 -0
  210. package/dist/services/entity-navigation.js.map +1 -0
  211. package/dist/services/hover.d.ts +81 -0
  212. package/dist/services/hover.d.ts.map +1 -0
  213. package/dist/services/hover.js +669 -0
  214. package/dist/services/hover.js.map +1 -0
  215. package/dist/services/query.d.ts +116 -0
  216. package/dist/services/query.d.ts.map +1 -0
  217. package/dist/services/query.js +225 -0
  218. package/dist/services/query.js.map +1 -0
  219. package/dist/services/references.d.ts +52 -0
  220. package/dist/services/references.d.ts.map +1 -0
  221. package/dist/services/references.js +66 -0
  222. package/dist/services/references.js.map +1 -0
  223. package/dist/services/semantic-tokens.d.ts +54 -0
  224. package/dist/services/semantic-tokens.d.ts.map +1 -0
  225. package/dist/services/semantic-tokens.js +213 -0
  226. package/dist/services/semantic-tokens.js.map +1 -0
  227. package/dist/services/synthesis.d.ts +90 -0
  228. package/dist/services/synthesis.d.ts.map +1 -0
  229. package/dist/services/synthesis.js +113 -0
  230. package/dist/services/synthesis.js.map +1 -0
  231. package/dist/source-map.d.ts +42 -0
  232. package/dist/source-map.d.ts.map +1 -0
  233. package/dist/source-map.js +170 -0
  234. package/dist/source-map.js.map +1 -0
  235. package/package.json +128 -0
  236. package/tree-sitter-thalo.wasm +0 -0
  237. package/web-tree-sitter.wasm +0 -0
@@ -0,0 +1,51 @@
1
+ import { FileType, ParseOptions, ParsedBlock as ParsedBlock$1, ParsedDocument as ParsedDocument$1, ThaloParser } from "./parser.shared.js";
2
+ import { Workspace } from "./model/workspace.js";
3
+ import { Tree } from "tree-sitter";
4
+
5
+ //#region src/parser.native.d.ts
6
+
7
+ type ParsedBlock = ParsedBlock$1<Tree>;
8
+ type ParsedDocument = ParsedDocument$1<Tree>;
9
+ /**
10
+ * Create a native ThaloParser instance.
11
+ *
12
+ * This creates a new tree-sitter Parser with the thalo language loaded.
13
+ * Each call creates a new parser instance.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * import { createParser } from "@rejot-dev/thalo/native";
18
+ *
19
+ * const parser = createParser();
20
+ * const tree = parser.parse(source);
21
+ * const doc = parser.parseDocument(source, { fileType: "thalo" });
22
+ * ```
23
+ */
24
+ declare function createParser(): ThaloParser<Tree>;
25
+ /**
26
+ * Create a Workspace with the native (Node.js) parser.
27
+ *
28
+ * This is a convenience function for Node.js environments that don't need
29
+ * to customize the parser. For browser environments, use the Workspace
30
+ * constructor directly with a web parser.
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * import { createWorkspace } from "@rejot-dev/thalo/native";
35
+ *
36
+ * const workspace = createWorkspace();
37
+ * workspace.addDocument(source, { filename: "test.thalo" });
38
+ * ```
39
+ */
40
+ declare function createWorkspace(): Workspace;
41
+ /**
42
+ * Get the singleton parser (creating it if needed) and parse a document.
43
+ *
44
+ * @param source - The source code to parse
45
+ * @param options - Parse options
46
+ * @returns A parsed document
47
+ */
48
+ declare function parseDocument(source: string, options?: ParseOptions): ParsedDocument$1<Tree>;
49
+ //#endregion
50
+ export { type FileType, type ParseOptions, ParsedBlock, ParsedDocument, type ThaloParser, Workspace, createParser, createWorkspace, parseDocument };
51
+ //# sourceMappingURL=parser.native.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.native.d.ts","names":[],"sources":["../src/parser.native.ts"],"sourcesContent":[],"mappings":";;;;;;AAkBY,KADA,WAAA,GAAc,aACG,CADgB,IAChB,CAAA;AAwBb,KAxBJ,cAAA,GAAiB,gBAwBc,CAxBQ,IAwBR,CAAA;;;;;;;;;;;;;;;;iBAA3B,YAAA,CAAA,GAAgB,YAAY;;;;;;;;;;;;;;;;iBAyB5B,eAAA,CAAA,GAAmB;;;;;;;;iBAcnB,aAAA,2BAAwC,eAAe,iBAAsB"}
@@ -0,0 +1,62 @@
1
+ import { createThaloParser } from "./parser.shared.js";
2
+ import { Workspace } from "./model/workspace.js";
3
+ import Parser from "tree-sitter";
4
+ import thalo from "@rejot-dev/tree-sitter-thalo";
5
+
6
+ //#region src/parser.native.ts
7
+ let cachedParser = null;
8
+ /**
9
+ * Create a native ThaloParser instance.
10
+ *
11
+ * This creates a new tree-sitter Parser with the thalo language loaded.
12
+ * Each call creates a new parser instance.
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * import { createParser } from "@rejot-dev/thalo/native";
17
+ *
18
+ * const parser = createParser();
19
+ * const tree = parser.parse(source);
20
+ * const doc = parser.parseDocument(source, { fileType: "thalo" });
21
+ * ```
22
+ */
23
+ function createParser() {
24
+ thalo.nodeTypeInfo ??= [];
25
+ const tsParser = new Parser();
26
+ tsParser.setLanguage(thalo);
27
+ return createThaloParser(tsParser);
28
+ }
29
+ /**
30
+ * Create a Workspace with the native (Node.js) parser.
31
+ *
32
+ * This is a convenience function for Node.js environments that don't need
33
+ * to customize the parser. For browser environments, use the Workspace
34
+ * constructor directly with a web parser.
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * import { createWorkspace } from "@rejot-dev/thalo/native";
39
+ *
40
+ * const workspace = createWorkspace();
41
+ * workspace.addDocument(source, { filename: "test.thalo" });
42
+ * ```
43
+ */
44
+ function createWorkspace() {
45
+ if (!cachedParser) cachedParser = createParser();
46
+ return new Workspace(cachedParser);
47
+ }
48
+ /**
49
+ * Get the singleton parser (creating it if needed) and parse a document.
50
+ *
51
+ * @param source - The source code to parse
52
+ * @param options - Parse options
53
+ * @returns A parsed document
54
+ */
55
+ function parseDocument(source, options) {
56
+ if (!cachedParser) cachedParser = createParser();
57
+ return cachedParser.parseDocument(source, options);
58
+ }
59
+
60
+ //#endregion
61
+ export { Workspace, createParser, createWorkspace, parseDocument };
62
+ //# sourceMappingURL=parser.native.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.native.js","names":["cachedParser: ThaloParser<Tree> | null"],"sources":["../src/parser.native.ts"],"sourcesContent":["/**\n * Native (Node.js) parser implementation using tree-sitter native bindings.\n */\n\nimport Parser, { type Language, type Tree } from \"tree-sitter\";\nimport thalo from \"@rejot-dev/tree-sitter-thalo\";\nimport {\n createThaloParser,\n type ThaloParser,\n type ParsedBlock as GenericParsedBlock,\n type ParsedDocument as GenericParsedDocument,\n type FileType,\n type ParseOptions,\n} from \"./parser.shared.js\";\nimport { Workspace } from \"./model/workspace.js\";\n\n// Re-export shared types specialized to native Tree type\nexport type ParsedBlock = GenericParsedBlock<Tree>;\nexport type ParsedDocument = GenericParsedDocument<Tree>;\nexport type { FileType, ParseOptions, ThaloParser };\n\n// Re-export Workspace for convenience\nexport { Workspace } from \"./model/workspace.js\";\n\n// Cached parser instance for createWorkspace\nlet cachedParser: ThaloParser<Tree> | null = null;\n\n/**\n * Create a native ThaloParser instance.\n *\n * This creates a new tree-sitter Parser with the thalo language loaded.\n * Each call creates a new parser instance.\n *\n * @example\n * ```typescript\n * import { createParser } from \"@rejot-dev/thalo/native\";\n *\n * const parser = createParser();\n * const tree = parser.parse(source);\n * const doc = parser.parseDocument(source, { fileType: \"thalo\" });\n * ```\n */\nexport function createParser(): ThaloParser<Tree> {\n // Ensure nodeTypeInfo is an array (may be undefined if JSON import fails in some environments)\n thalo.nodeTypeInfo ??= [];\n\n const tsParser = new Parser();\n tsParser.setLanguage(thalo as unknown as Language);\n\n return createThaloParser(tsParser);\n}\n\n/**\n * Create a Workspace with the native (Node.js) parser.\n *\n * This is a convenience function for Node.js environments that don't need\n * to customize the parser. For browser environments, use the Workspace\n * constructor directly with a web parser.\n *\n * @example\n * ```typescript\n * import { createWorkspace } from \"@rejot-dev/thalo/native\";\n *\n * const workspace = createWorkspace();\n * workspace.addDocument(source, { filename: \"test.thalo\" });\n * ```\n */\nexport function createWorkspace(): Workspace {\n if (!cachedParser) {\n cachedParser = createParser();\n }\n return new Workspace(cachedParser);\n}\n\n/**\n * Get the singleton parser (creating it if needed) and parse a document.\n *\n * @param source - The source code to parse\n * @param options - Parse options\n * @returns A parsed document\n */\nexport function parseDocument(source: string, options?: ParseOptions): GenericParsedDocument<Tree> {\n if (!cachedParser) {\n cachedParser = createParser();\n }\n return cachedParser.parseDocument(source, options);\n}\n"],"mappings":";;;;;;AAyBA,IAAIA,eAAyC;;;;;;;;;;;;;;;;AAiB7C,SAAgB,eAAkC;AAEhD,OAAM,iBAAiB,EAAE;CAEzB,MAAM,WAAW,IAAI,QAAQ;AAC7B,UAAS,YAAY,MAA6B;AAElD,QAAO,kBAAkB,SAAS;;;;;;;;;;;;;;;;;AAkBpC,SAAgB,kBAA6B;AAC3C,KAAI,CAAC,aACH,gBAAe,cAAc;AAE/B,QAAO,IAAI,UAAU,aAAa;;;;;;;;;AAUpC,SAAgB,cAAc,QAAgB,SAAqD;AACjG,KAAI,CAAC,aACH,gBAAe,cAAc;AAE/B,QAAO,aAAa,cAAc,QAAQ,QAAQ"}
@@ -0,0 +1,99 @@
1
+ import { SyntaxNode } from "./ast/ast-types.js";
2
+ import { SourceMap } from "./source-map.js";
3
+
4
+ //#region src/parser.shared.d.ts
5
+
6
+ /**
7
+ * Edit parameters for incremental parsing.
8
+ */
9
+ interface TreeEdit {
10
+ startIndex: number;
11
+ oldEndIndex: number;
12
+ newEndIndex: number;
13
+ startPosition: {
14
+ row: number;
15
+ column: number;
16
+ };
17
+ oldEndPosition: {
18
+ row: number;
19
+ column: number;
20
+ };
21
+ newEndPosition: {
22
+ row: number;
23
+ column: number;
24
+ };
25
+ }
26
+ /**
27
+ * A generic tree interface that both tree-sitter and web-tree-sitter satisfy.
28
+ *
29
+ * Note: Both `Tree` (from tree-sitter) and `Tree` (from web-tree-sitter) have this shape.
30
+ * The main difference is that web-tree-sitter's SyntaxNode is called "Node", but the
31
+ * interface is compatible.
32
+ *
33
+ * This is a minimal interface that only specifies the properties we actually use.
34
+ * The actual Tree types have many more properties (language, copy, delete, etc.)
35
+ * but we don't constrain those to keep the interface flexible.
36
+ */
37
+ interface GenericTree {
38
+ readonly rootNode: SyntaxNode;
39
+ /** Edit the tree for incremental parsing */
40
+ edit(edit: TreeEdit): void;
41
+ }
42
+ /**
43
+ * A parsed thalo block with its source, source map for position translation, and parse tree.
44
+ */
45
+ interface ParsedBlock<T extends GenericTree = GenericTree> {
46
+ /** The thalo source code */
47
+ source: string;
48
+ /** Source map for translating block-relative positions to file-absolute positions */
49
+ sourceMap: SourceMap;
50
+ /** The parsed tree-sitter tree */
51
+ tree: T;
52
+ }
53
+ /**
54
+ * A parsed document containing one or more thalo blocks.
55
+ */
56
+ interface ParsedDocument<T extends GenericTree = GenericTree> {
57
+ /** The parsed thalo blocks */
58
+ blocks: ParsedBlock<T>[];
59
+ }
60
+ /**
61
+ * File type for parsing
62
+ */
63
+ type FileType = "thalo" | "markdown";
64
+ /**
65
+ * Options for parseDocument
66
+ */
67
+ interface ParseOptions {
68
+ /** The file type. If not provided, uses heuristics based on filename or content. */
69
+ fileType?: FileType;
70
+ /** Optional filename (used for heuristics if fileType is not provided) */
71
+ filename?: string;
72
+ }
73
+ /**
74
+ * The ThaloParser interface - a configured parser instance that can parse thalo source.
75
+ */
76
+ interface ThaloParser<T extends GenericTree = GenericTree> {
77
+ /**
78
+ * Parse a thalo source string into a tree-sitter Tree.
79
+ */
80
+ parse(source: string): T;
81
+ /**
82
+ * Parse a thalo source string with optional incremental parsing.
83
+ *
84
+ * When an oldTree is provided, tree-sitter can reuse unchanged parts of the
85
+ * parse tree, making parsing much faster for small edits.
86
+ *
87
+ * Note: Before calling this with an oldTree, you must call oldTree.edit()
88
+ * to inform tree-sitter about the changes made to the source.
89
+ */
90
+ parseIncremental(source: string, oldTree?: T): T;
91
+ /**
92
+ * Parse a document, automatically detecting if it's a .thalo file or markdown
93
+ * with embedded thalo blocks.
94
+ */
95
+ parseDocument(source: string, options?: ParseOptions): ParsedDocument<T>;
96
+ }
97
+ //#endregion
98
+ export { FileType, GenericTree, ParseOptions, ParsedBlock, ParsedDocument, ThaloParser };
99
+ //# sourceMappingURL=parser.shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.shared.d.ts","names":[],"sources":["../src/parser.shared.ts"],"sourcesContent":[],"mappings":";;;;;AA+CA;;;AAIa,UAxCI,QAAA,CAwCJ;EAEL,UAAA,EAAA,MAAA;EAAC,WAAA,EAAA,MAAA;EAMQ,WAAA,EAAA,MAAc;EAAW,aAAA,EAAA;IAAc,GAAA,EAAA,MAAA;IAElC,MAAA,EAAA,MAAA;EAAZ,CAAA;EAAW,cAAA,EAAA;IAMT,GAAA,EAAA,MAAQ;IAKH,MAAA,EAAA,MAAY;EAgCZ,CAAA;EAAsB,cAAA,EAAA;IAAc,GAAA,EAAA,MAAA;IAI5B,MAAA,EAAA,MAAA;EAWoB,CAAA;;;;;;;;;;;;;UAxF5B,WAAA;qBACI;;aAER;;;;;UAaI,sBAAsB,cAAc;;;;aAIxC;;QAEL;;;;;UAMS,yBAAyB,cAAc;;UAE9C,YAAY;;;;;KAMV,QAAA;;;;UAKK,YAAA;;aAEJ;;;;;;;UA8BI,sBAAsB,cAAc;;;;yBAI5B;;;;;;;;;;6CAWoB,IAAI;;;;;0CAMP,eAAe,eAAe"}
@@ -0,0 +1,124 @@
1
+ import { createSourceMap, identitySourceMap } from "./source-map.js";
2
+
3
+ //#region src/parser.shared.ts
4
+ /**
5
+ * Regex to match fenced thalo code blocks in markdown.
6
+ * Captures the content between ```thalo and ```
7
+ */
8
+ const THALO_FENCE_REGEX = /^```thalo\s*\n([\s\S]*?)^```/gm;
9
+ /**
10
+ * Detect file type from filename extension.
11
+ *
12
+ * @param filename - The filename to check
13
+ * @returns The detected file type ("thalo" or "markdown"), or undefined if unknown
14
+ */
15
+ function detectFileType(filename) {
16
+ if (filename.endsWith(".thalo")) return "thalo";
17
+ if (filename.endsWith(".md")) return "markdown";
18
+ }
19
+ /**
20
+ * Create a ThaloParser from a generic tree-sitter parser instance.
21
+ *
22
+ * @param tsParser - A tree-sitter or web-tree-sitter Parser instance with the thalo language loaded
23
+ * @returns A ThaloParser instance
24
+ */
25
+ function createThaloParser(tsParser) {
26
+ /**
27
+ * Parse a thalo source string into a tree-sitter Tree.
28
+ *
29
+ * @param source - The thalo source code to parse
30
+ * @returns The parsed tree-sitter Tree
31
+ * @throws Error if parsing fails
32
+ */
33
+ function parse(source) {
34
+ const tree = tsParser.parse(source);
35
+ if (!tree) throw new Error("Failed to parse source");
36
+ return tree;
37
+ }
38
+ /**
39
+ * Parse a thalo source string with optional incremental parsing.
40
+ *
41
+ * @param source - The thalo source code to parse
42
+ * @param oldTree - Optional previous tree for incremental parsing
43
+ * @returns The parsed tree-sitter Tree
44
+ * @throws Error if parsing fails
45
+ */
46
+ function parseIncremental(source, oldTree) {
47
+ const tree = tsParser.parse(source, oldTree);
48
+ if (!tree) throw new Error("Failed to parse source");
49
+ return tree;
50
+ }
51
+ /**
52
+ * Extract thalo code blocks from markdown source.
53
+ *
54
+ * Searches for fenced code blocks marked with ```thalo and extracts
55
+ * their content, creating a ParsedDocument with one ParsedBlock per
56
+ * code block found.
57
+ *
58
+ * @param source - The markdown source containing thalo code blocks
59
+ * @returns A ParsedDocument containing the extracted thalo blocks
60
+ */
61
+ function extractThaloBlocks(source) {
62
+ const blocks = [];
63
+ let match;
64
+ while ((match = THALO_FENCE_REGEX.exec(source)) !== null) {
65
+ const content = match[1];
66
+ const sourceMap = createSourceMap(source, match.index + match[0].indexOf(content), content);
67
+ blocks.push({
68
+ source: content,
69
+ sourceMap,
70
+ tree: parse(content)
71
+ });
72
+ }
73
+ THALO_FENCE_REGEX.lastIndex = 0;
74
+ return { blocks };
75
+ }
76
+ /**
77
+ * Parse a pure thalo document (not markdown).
78
+ *
79
+ * Creates a ParsedDocument with a single block containing the entire
80
+ * source as a thalo file.
81
+ *
82
+ * @param source - The thalo source code
83
+ * @returns A ParsedDocument with a single block
84
+ */
85
+ function parseThaloDocument(source) {
86
+ return { blocks: [{
87
+ source,
88
+ sourceMap: identitySourceMap(),
89
+ tree: parse(source)
90
+ }] };
91
+ }
92
+ /**
93
+ * Parse a document, automatically detecting if it's a .thalo file or markdown
94
+ * with embedded thalo blocks.
95
+ *
96
+ * Uses fileType option, filename-based heuristics, or content-based heuristics
97
+ * to determine how to parse the source.
98
+ *
99
+ * @param source - The source code to parse
100
+ * @param options - Parse options including fileType and filename
101
+ * @returns A ParsedDocument containing one or more parsed blocks
102
+ */
103
+ function parseDocument(source, options = {}) {
104
+ const { fileType, filename } = options;
105
+ if (fileType === "thalo") return parseThaloDocument(source);
106
+ if (fileType === "markdown") return extractThaloBlocks(source);
107
+ if (filename) {
108
+ const detected = detectFileType(filename);
109
+ if (detected === "thalo") return parseThaloDocument(source);
110
+ if (detected === "markdown") return extractThaloBlocks(source);
111
+ }
112
+ if (source.includes("```thalo")) return extractThaloBlocks(source);
113
+ return parseThaloDocument(source);
114
+ }
115
+ return {
116
+ parse,
117
+ parseIncremental,
118
+ parseDocument
119
+ };
120
+ }
121
+
122
+ //#endregion
123
+ export { createThaloParser };
124
+ //# sourceMappingURL=parser.shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.shared.js","names":["blocks: ParsedBlock<T>[]","match: RegExpExecArray | null"],"sources":["../src/parser.shared.ts"],"sourcesContent":["/**\n * Shared parser logic used by both native (Node.js) and web (WASM) implementations.\n * This module is platform-agnostic and works with any tree-sitter-like parser.\n */\n\nimport { createSourceMap, identitySourceMap, type SourceMap } from \"./source-map.js\";\nimport type { SyntaxNode } from \"./ast/ast-types.js\";\n\n/**\n * Edit parameters for incremental parsing.\n */\nexport interface TreeEdit {\n startIndex: number;\n oldEndIndex: number;\n newEndIndex: number;\n startPosition: { row: number; column: number };\n oldEndPosition: { row: number; column: number };\n newEndPosition: { row: number; column: number };\n}\n\n/**\n * A generic tree interface that both tree-sitter and web-tree-sitter satisfy.\n *\n * Note: Both `Tree` (from tree-sitter) and `Tree` (from web-tree-sitter) have this shape.\n * The main difference is that web-tree-sitter's SyntaxNode is called \"Node\", but the\n * interface is compatible.\n *\n * This is a minimal interface that only specifies the properties we actually use.\n * The actual Tree types have many more properties (language, copy, delete, etc.)\n * but we don't constrain those to keep the interface flexible.\n */\nexport interface GenericTree {\n readonly rootNode: SyntaxNode;\n /** Edit the tree for incremental parsing */\n edit(edit: TreeEdit): void;\n}\n\n/**\n * A generic parser interface that both tree-sitter and web-tree-sitter satisfy.\n */\nexport interface GenericParser<T extends GenericTree> {\n parse(source: string, oldTree?: T | null): T | null;\n}\n\n/**\n * A parsed thalo block with its source, source map for position translation, and parse tree.\n */\nexport interface ParsedBlock<T extends GenericTree = GenericTree> {\n /** The thalo source code */\n source: string;\n /** Source map for translating block-relative positions to file-absolute positions */\n sourceMap: SourceMap;\n /** The parsed tree-sitter tree */\n tree: T;\n}\n\n/**\n * A parsed document containing one or more thalo blocks.\n */\nexport interface ParsedDocument<T extends GenericTree = GenericTree> {\n /** The parsed thalo blocks */\n blocks: ParsedBlock<T>[];\n}\n\n/**\n * File type for parsing\n */\nexport type FileType = \"thalo\" | \"markdown\";\n\n/**\n * Options for parseDocument\n */\nexport interface ParseOptions {\n /** The file type. If not provided, uses heuristics based on filename or content. */\n fileType?: FileType;\n /** Optional filename (used for heuristics if fileType is not provided) */\n filename?: string;\n}\n\n/**\n * Regex to match fenced thalo code blocks in markdown.\n * Captures the content between ```thalo and ```\n */\nconst THALO_FENCE_REGEX = /^```thalo\\s*\\n([\\s\\S]*?)^```/gm;\n\n/**\n * Detect file type from filename extension.\n *\n * @param filename - The filename to check\n * @returns The detected file type (\"thalo\" or \"markdown\"), or undefined if unknown\n */\nexport function detectFileType(filename: string): FileType | undefined {\n if (filename.endsWith(\".thalo\")) {\n return \"thalo\";\n }\n if (filename.endsWith(\".md\")) {\n return \"markdown\";\n }\n return undefined;\n}\n\n/**\n * The ThaloParser interface - a configured parser instance that can parse thalo source.\n */\nexport interface ThaloParser<T extends GenericTree = GenericTree> {\n /**\n * Parse a thalo source string into a tree-sitter Tree.\n */\n parse(source: string): T;\n\n /**\n * Parse a thalo source string with optional incremental parsing.\n *\n * When an oldTree is provided, tree-sitter can reuse unchanged parts of the\n * parse tree, making parsing much faster for small edits.\n *\n * Note: Before calling this with an oldTree, you must call oldTree.edit()\n * to inform tree-sitter about the changes made to the source.\n */\n parseIncremental(source: string, oldTree?: T): T;\n\n /**\n * Parse a document, automatically detecting if it's a .thalo file or markdown\n * with embedded thalo blocks.\n */\n parseDocument(source: string, options?: ParseOptions): ParsedDocument<T>;\n}\n\n/**\n * Create a ThaloParser from a generic tree-sitter parser instance.\n *\n * @param tsParser - A tree-sitter or web-tree-sitter Parser instance with the thalo language loaded\n * @returns A ThaloParser instance\n */\nexport function createThaloParser<T extends GenericTree>(\n tsParser: GenericParser<T>,\n): ThaloParser<T> {\n /**\n * Parse a thalo source string into a tree-sitter Tree.\n *\n * @param source - The thalo source code to parse\n * @returns The parsed tree-sitter Tree\n * @throws Error if parsing fails\n */\n function parse(source: string): T {\n const tree = tsParser.parse(source);\n if (!tree) {\n throw new Error(\"Failed to parse source\");\n }\n return tree;\n }\n\n /**\n * Parse a thalo source string with optional incremental parsing.\n *\n * @param source - The thalo source code to parse\n * @param oldTree - Optional previous tree for incremental parsing\n * @returns The parsed tree-sitter Tree\n * @throws Error if parsing fails\n */\n function parseIncremental(source: string, oldTree?: T): T {\n const tree = tsParser.parse(source, oldTree);\n if (!tree) {\n throw new Error(\"Failed to parse source\");\n }\n return tree;\n }\n\n /**\n * Extract thalo code blocks from markdown source.\n *\n * Searches for fenced code blocks marked with ```thalo and extracts\n * their content, creating a ParsedDocument with one ParsedBlock per\n * code block found.\n *\n * @param source - The markdown source containing thalo code blocks\n * @returns A ParsedDocument containing the extracted thalo blocks\n */\n function extractThaloBlocks(source: string): ParsedDocument<T> {\n const blocks: ParsedBlock<T>[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = THALO_FENCE_REGEX.exec(source)) !== null) {\n const content = match[1];\n const charOffset = match.index + match[0].indexOf(content);\n const sourceMap = createSourceMap(source, charOffset, content);\n blocks.push({\n source: content,\n sourceMap,\n tree: parse(content),\n });\n }\n\n THALO_FENCE_REGEX.lastIndex = 0;\n return { blocks };\n }\n\n /**\n * Parse a pure thalo document (not markdown).\n *\n * Creates a ParsedDocument with a single block containing the entire\n * source as a thalo file.\n *\n * @param source - The thalo source code\n * @returns A ParsedDocument with a single block\n */\n function parseThaloDocument(source: string): ParsedDocument<T> {\n return {\n blocks: [{ source, sourceMap: identitySourceMap(), tree: parse(source) }],\n };\n }\n\n /**\n * Parse a document, automatically detecting if it's a .thalo file or markdown\n * with embedded thalo blocks.\n *\n * Uses fileType option, filename-based heuristics, or content-based heuristics\n * to determine how to parse the source.\n *\n * @param source - The source code to parse\n * @param options - Parse options including fileType and filename\n * @returns A ParsedDocument containing one or more parsed blocks\n */\n function parseDocument(source: string, options: ParseOptions = {}): ParsedDocument<T> {\n const { fileType, filename } = options;\n\n if (fileType === \"thalo\") {\n return parseThaloDocument(source);\n }\n if (fileType === \"markdown\") {\n return extractThaloBlocks(source);\n }\n\n if (filename) {\n const detected = detectFileType(filename);\n if (detected === \"thalo\") {\n return parseThaloDocument(source);\n }\n if (detected === \"markdown\") {\n return extractThaloBlocks(source);\n }\n }\n\n if (source.includes(\"```thalo\")) {\n return extractThaloBlocks(source);\n }\n\n return parseThaloDocument(source);\n }\n\n return {\n parse,\n parseIncremental,\n parseDocument,\n };\n}\n"],"mappings":";;;;;;;AAmFA,MAAM,oBAAoB;;;;;;;AAQ1B,SAAgB,eAAe,UAAwC;AACrE,KAAI,SAAS,SAAS,SAAS,CAC7B,QAAO;AAET,KAAI,SAAS,SAAS,MAAM,CAC1B,QAAO;;;;;;;;AAsCX,SAAgB,kBACd,UACgB;;;;;;;;CAQhB,SAAS,MAAM,QAAmB;EAChC,MAAM,OAAO,SAAS,MAAM,OAAO;AACnC,MAAI,CAAC,KACH,OAAM,IAAI,MAAM,yBAAyB;AAE3C,SAAO;;;;;;;;;;CAWT,SAAS,iBAAiB,QAAgB,SAAgB;EACxD,MAAM,OAAO,SAAS,MAAM,QAAQ,QAAQ;AAC5C,MAAI,CAAC,KACH,OAAM,IAAI,MAAM,yBAAyB;AAE3C,SAAO;;;;;;;;;;;;CAaT,SAAS,mBAAmB,QAAmC;EAC7D,MAAMA,SAA2B,EAAE;EACnC,IAAIC;AAEJ,UAAQ,QAAQ,kBAAkB,KAAK,OAAO,MAAM,MAAM;GACxD,MAAM,UAAU,MAAM;GAEtB,MAAM,YAAY,gBAAgB,QADf,MAAM,QAAQ,MAAM,GAAG,QAAQ,QAAQ,EACJ,QAAQ;AAC9D,UAAO,KAAK;IACV,QAAQ;IACR;IACA,MAAM,MAAM,QAAQ;IACrB,CAAC;;AAGJ,oBAAkB,YAAY;AAC9B,SAAO,EAAE,QAAQ;;;;;;;;;;;CAYnB,SAAS,mBAAmB,QAAmC;AAC7D,SAAO,EACL,QAAQ,CAAC;GAAE;GAAQ,WAAW,mBAAmB;GAAE,MAAM,MAAM,OAAO;GAAE,CAAC,EAC1E;;;;;;;;;;;;;CAcH,SAAS,cAAc,QAAgB,UAAwB,EAAE,EAAqB;EACpF,MAAM,EAAE,UAAU,aAAa;AAE/B,MAAI,aAAa,QACf,QAAO,mBAAmB,OAAO;AAEnC,MAAI,aAAa,WACf,QAAO,mBAAmB,OAAO;AAGnC,MAAI,UAAU;GACZ,MAAM,WAAW,eAAe,SAAS;AACzC,OAAI,aAAa,QACf,QAAO,mBAAmB,OAAO;AAEnC,OAAI,aAAa,WACf,QAAO,mBAAmB,OAAO;;AAIrC,MAAI,OAAO,SAAS,WAAW,CAC7B,QAAO,mBAAmB,OAAO;AAGnC,SAAO,mBAAmB,OAAO;;AAGnC,QAAO;EACL;EACA;EACA;EACD"}
@@ -0,0 +1,67 @@
1
+ import { FileType, ParseOptions, ParsedBlock as ParsedBlock$1, ParsedDocument as ParsedDocument$1, ThaloParser } from "./parser.shared.js";
2
+ import { Node, Tree, Tree as Tree$1 } from "web-tree-sitter";
3
+
4
+ //#region src/parser.web.d.ts
5
+
6
+ type ParsedBlock = ParsedBlock$1<Tree$1>;
7
+ type ParsedDocument = ParsedDocument$1<Tree$1>;
8
+ /**
9
+ * WASM input type - either raw bytes or a pre-compiled WebAssembly.Module.
10
+ *
11
+ * Use `WebAssembly.Module` in environments that support it (like Cloudflare Workers)
12
+ * or when you want to pre-compile the WASM for better performance.
13
+ */
14
+ type WasmInput = Uint8Array | WebAssembly.Module;
15
+ /**
16
+ * Options for creating a web parser.
17
+ */
18
+ interface CreateParserOptions {
19
+ /**
20
+ * The web-tree-sitter runtime WASM.
21
+ * This is the `tree-sitter.wasm` file from the `web-tree-sitter` package.
22
+ *
23
+ * Can be provided as:
24
+ * - `Uint8Array`: Raw WASM bytes
25
+ * - `WebAssembly.Module`: Pre-compiled WASM module (useful for Cloudflare Workers, etc.)
26
+ */
27
+ treeSitterWasm: WasmInput;
28
+ /**
29
+ * The thalo language WASM.
30
+ * This is the `tree-sitter-thalo.wasm` file from `@rejot-dev/tree-sitter-thalo`.
31
+ *
32
+ * Can be provided as:
33
+ * - `Uint8Array`: Raw WASM bytes
34
+ * - `WebAssembly.Module`: Pre-compiled WASM module (useful for Cloudflare Workers, etc.)
35
+ */
36
+ languageWasm: WasmInput;
37
+ }
38
+ /**
39
+ * Create a web ThaloParser instance using WASM.
40
+ *
41
+ * This initializes web-tree-sitter and loads the thalo language WASM.
42
+ * Must be awaited before parsing.
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * import { createParser } from "@rejot-dev/thalo/web";
47
+ *
48
+ * // Option 1: Fetch both WASM files as bytes
49
+ * const [treeSitterWasm, languageWasm] = await Promise.all([
50
+ * fetch("/wasm/tree-sitter.wasm").then(r => r.arrayBuffer()).then(b => new Uint8Array(b)),
51
+ * fetch("/wasm/tree-sitter-thalo.wasm").then(r => r.arrayBuffer()).then(b => new Uint8Array(b)),
52
+ * ]);
53
+ *
54
+ * // Option 2: Use pre-compiled WebAssembly.Module (e.g., in Cloudflare Workers)
55
+ * // import treeSitterWasm from "./tree-sitter.wasm";
56
+ * // import languageWasm from "./tree-sitter-thalo.wasm";
57
+ *
58
+ * const parser = await createParser({ treeSitterWasm, languageWasm });
59
+ *
60
+ * const tree = parser.parse(source);
61
+ * const doc = parser.parseDocument(source, { fileType: "thalo" });
62
+ * ```
63
+ */
64
+ declare function createParser(options: CreateParserOptions): Promise<ThaloParser<Tree$1>>;
65
+ //#endregion
66
+ export { CreateParserOptions, type FileType, type Node, type ParseOptions, ParsedBlock, ParsedDocument, type ThaloParser, type Tree, WasmInput, createParser };
67
+ //# sourceMappingURL=parser.web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.web.d.ts","names":[],"sources":["../src/parser.web.ts"],"sourcesContent":[],"mappings":";;;;;AA4BY,KAVA,WAAA,GAAc,aAUW,CAVQ,MAUR,CAAA;AAKpB,KAdL,cAAA,GAAiB,gBAiCb,CAjCmC,MAiCnC,CAAA;;;;;;;KAxBJ,SAAA,GAAY,aAAa,WAAA,CAAY;;;;UAKhC,mBAAA;;;;;;;;;kBASC;;;;;;;;;gBAUF;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6BM,YAAA,UAAsB,sBAAsB,QAAQ,YAAY"}
@@ -0,0 +1,49 @@
1
+ import { createThaloParser } from "./parser.shared.js";
2
+ import { Language, Parser } from "web-tree-sitter";
3
+
4
+ //#region src/parser.web.ts
5
+ /**
6
+ * Create a web ThaloParser instance using WASM.
7
+ *
8
+ * This initializes web-tree-sitter and loads the thalo language WASM.
9
+ * Must be awaited before parsing.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * import { createParser } from "@rejot-dev/thalo/web";
14
+ *
15
+ * // Option 1: Fetch both WASM files as bytes
16
+ * const [treeSitterWasm, languageWasm] = await Promise.all([
17
+ * fetch("/wasm/tree-sitter.wasm").then(r => r.arrayBuffer()).then(b => new Uint8Array(b)),
18
+ * fetch("/wasm/tree-sitter-thalo.wasm").then(r => r.arrayBuffer()).then(b => new Uint8Array(b)),
19
+ * ]);
20
+ *
21
+ * // Option 2: Use pre-compiled WebAssembly.Module (e.g., in Cloudflare Workers)
22
+ * // import treeSitterWasm from "./tree-sitter.wasm";
23
+ * // import languageWasm from "./tree-sitter-thalo.wasm";
24
+ *
25
+ * const parser = await createParser({ treeSitterWasm, languageWasm });
26
+ *
27
+ * const tree = parser.parse(source);
28
+ * const doc = parser.parseDocument(source, { fileType: "thalo" });
29
+ * ```
30
+ */
31
+ async function createParser(options) {
32
+ const { treeSitterWasm, languageWasm } = options;
33
+ if (treeSitterWasm instanceof WebAssembly.Module) await Parser.init({ instantiateWasm: async (imports, successCallback) => {
34
+ const instance = await WebAssembly.instantiate(treeSitterWasm, imports);
35
+ successCallback(instance, treeSitterWasm);
36
+ return instance.exports;
37
+ } });
38
+ else await Parser.init({ wasmBinary: treeSitterWasm });
39
+ const tsParser = new Parser();
40
+ let language;
41
+ if (languageWasm instanceof WebAssembly.Module) language = Language.loadModuleSync(languageWasm);
42
+ else language = await Language.load(languageWasm);
43
+ tsParser.setLanguage(language);
44
+ return createThaloParser(tsParser);
45
+ }
46
+
47
+ //#endregion
48
+ export { createParser };
49
+ //# sourceMappingURL=parser.web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.web.js","names":["language: Language"],"sources":["../src/parser.web.ts"],"sourcesContent":["/**\n * Web (WASM) parser implementation using web-tree-sitter.\n */\n\nimport { Parser, Language, type Tree, type Node } from \"web-tree-sitter\";\nimport {\n createThaloParser,\n type ThaloParser,\n type ParsedBlock as GenericParsedBlock,\n type ParsedDocument as GenericParsedDocument,\n type FileType,\n type ParseOptions,\n} from \"./parser.shared.js\";\n\n// Re-export web-tree-sitter types for consumers\nexport type { Tree, Node } from \"web-tree-sitter\";\n\n// Re-export shared types specialized to web-tree-sitter Tree type\nexport type ParsedBlock = GenericParsedBlock<Tree>;\nexport type ParsedDocument = GenericParsedDocument<Tree>;\nexport type { FileType, ParseOptions, ThaloParser };\n\n/**\n * WASM input type - either raw bytes or a pre-compiled WebAssembly.Module.\n *\n * Use `WebAssembly.Module` in environments that support it (like Cloudflare Workers)\n * or when you want to pre-compile the WASM for better performance.\n */\nexport type WasmInput = Uint8Array | WebAssembly.Module;\n\n/**\n * Options for creating a web parser.\n */\nexport interface CreateParserOptions {\n /**\n * The web-tree-sitter runtime WASM.\n * This is the `tree-sitter.wasm` file from the `web-tree-sitter` package.\n *\n * Can be provided as:\n * - `Uint8Array`: Raw WASM bytes\n * - `WebAssembly.Module`: Pre-compiled WASM module (useful for Cloudflare Workers, etc.)\n */\n treeSitterWasm: WasmInput;\n\n /**\n * The thalo language WASM.\n * This is the `tree-sitter-thalo.wasm` file from `@rejot-dev/tree-sitter-thalo`.\n *\n * Can be provided as:\n * - `Uint8Array`: Raw WASM bytes\n * - `WebAssembly.Module`: Pre-compiled WASM module (useful for Cloudflare Workers, etc.)\n */\n languageWasm: WasmInput;\n}\n\n/**\n * Create a web ThaloParser instance using WASM.\n *\n * This initializes web-tree-sitter and loads the thalo language WASM.\n * Must be awaited before parsing.\n *\n * @example\n * ```typescript\n * import { createParser } from \"@rejot-dev/thalo/web\";\n *\n * // Option 1: Fetch both WASM files as bytes\n * const [treeSitterWasm, languageWasm] = await Promise.all([\n * fetch(\"/wasm/tree-sitter.wasm\").then(r => r.arrayBuffer()).then(b => new Uint8Array(b)),\n * fetch(\"/wasm/tree-sitter-thalo.wasm\").then(r => r.arrayBuffer()).then(b => new Uint8Array(b)),\n * ]);\n *\n * // Option 2: Use pre-compiled WebAssembly.Module (e.g., in Cloudflare Workers)\n * // import treeSitterWasm from \"./tree-sitter.wasm\";\n * // import languageWasm from \"./tree-sitter-thalo.wasm\";\n *\n * const parser = await createParser({ treeSitterWasm, languageWasm });\n *\n * const tree = parser.parse(source);\n * const doc = parser.parseDocument(source, { fileType: \"thalo\" });\n * ```\n */\nexport async function createParser(options: CreateParserOptions): Promise<ThaloParser<Tree>> {\n const { treeSitterWasm, languageWasm } = options;\n\n // Initialize the tree-sitter runtime\n if (treeSitterWasm instanceof WebAssembly.Module) {\n // Pre-compiled module: use instantiateWasm to provide it\n // The callback expects (instance, module) - both the Instance and the Module\n await Parser.init({\n instantiateWasm: async (\n imports: WebAssembly.Imports,\n successCallback: (instance: WebAssembly.Instance, module: WebAssembly.Module) => void,\n ) => {\n const instance = await WebAssembly.instantiate(treeSitterWasm, imports);\n // Pass both the instance AND the original module to the callback\n successCallback(instance, treeSitterWasm);\n return instance.exports;\n },\n });\n } else {\n // Raw bytes: use wasmBinary\n await Parser.init({\n wasmBinary: treeSitterWasm,\n });\n }\n\n const tsParser = new Parser();\n\n // Load the language - supports both Uint8Array and WebAssembly.Module\n let language: Language;\n if (languageWasm instanceof WebAssembly.Module) {\n // Use our patched loadModuleSync method for pre-compiled modules (synchronous)\n language = Language.loadModuleSync(languageWasm);\n } else {\n // Use standard load for bytes (async)\n language = await Language.load(languageWasm);\n }\n tsParser.setLanguage(language);\n\n return createThaloParser(tsParser);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiFA,eAAsB,aAAa,SAA0D;CAC3F,MAAM,EAAE,gBAAgB,iBAAiB;AAGzC,KAAI,0BAA0B,YAAY,OAGxC,OAAM,OAAO,KAAK,EAChB,iBAAiB,OACf,SACA,oBACG;EACH,MAAM,WAAW,MAAM,YAAY,YAAY,gBAAgB,QAAQ;AAEvE,kBAAgB,UAAU,eAAe;AACzC,SAAO,SAAS;IAEnB,CAAC;KAGF,OAAM,OAAO,KAAK,EAChB,YAAY,gBACb,CAAC;CAGJ,MAAM,WAAW,IAAI,QAAQ;CAG7B,IAAIA;AACJ,KAAI,wBAAwB,YAAY,OAEtC,YAAW,SAAS,eAAe,aAAa;KAGhD,YAAW,MAAM,SAAS,KAAK,aAAa;AAE9C,UAAS,YAAY,SAAS;AAE9B,QAAO,kBAAkB,SAAS"}
@@ -0,0 +1,108 @@
1
+ import { ValueContent } from "../ast/ast-types.js";
2
+ import { ModelDefaultValue, ModelSchemaEntry, ModelTypeExpression } from "../model/workspace.js";
3
+
4
+ //#region src/schema/registry.d.ts
5
+
6
+ /**
7
+ * A resolved entity schema (after applying all define-entity and alter-entity entries)
8
+ */
9
+ interface EntitySchema {
10
+ /** The entity name */
11
+ name: string;
12
+ /** Description from the define-entity entry */
13
+ description: string;
14
+ /** Field definitions */
15
+ fields: Map<string, FieldSchema>;
16
+ /** Section definitions */
17
+ sections: Map<string, SectionSchema>;
18
+ /** Timestamp of the define-entity that created this schema */
19
+ definedAt: string;
20
+ /** File where this schema was defined */
21
+ definedIn: string;
22
+ }
23
+ /**
24
+ * A field schema in an entity definition
25
+ */
26
+ interface FieldSchema {
27
+ /** Field name */
28
+ name: string;
29
+ /** Whether the field is optional */
30
+ optional: boolean;
31
+ /** The type expression */
32
+ type: ModelTypeExpression;
33
+ /** Default value (if any) */
34
+ defaultValue: ModelDefaultValue | null;
35
+ /** Description (if any) */
36
+ description: string | null;
37
+ }
38
+ /**
39
+ * A section schema in an entity definition
40
+ */
41
+ interface SectionSchema {
42
+ /** Section name (PascalCase) */
43
+ name: string;
44
+ /** Whether the section is optional */
45
+ optional: boolean;
46
+ /** Description (if any) */
47
+ description: string | null;
48
+ }
49
+ /**
50
+ * Registry for entity schemas.
51
+ * Collects define-entity and alter-entity entries and resolves them into EntitySchemas.
52
+ */
53
+ declare class SchemaRegistry {
54
+ private schemas;
55
+ private defineEntries;
56
+ private alterEntries;
57
+ /**
58
+ * Add a schema entry (define-entity or alter-entity)
59
+ */
60
+ add(entry: ModelSchemaEntry): void;
61
+ /**
62
+ * Get a resolved entity schema by name
63
+ */
64
+ get(name: string): EntitySchema | undefined;
65
+ /**
66
+ * Check if an entity is defined
67
+ */
68
+ has(name: string): boolean;
69
+ /**
70
+ * Get all defined entity names
71
+ */
72
+ entityNames(): string[];
73
+ /**
74
+ * Clear all schemas
75
+ */
76
+ clear(): void;
77
+ /**
78
+ * Resolve an entity schema from its define and alter entries
79
+ */
80
+ private resolve;
81
+ /**
82
+ * Apply an alter-entity entry to a schema
83
+ */
84
+ private applyAlter;
85
+ }
86
+ /**
87
+ * Type checking utilities for type expressions.
88
+ * Uses the grammar-parsed ValueContent for type validation.
89
+ */
90
+ declare const TypeExpr: {
91
+ /**
92
+ * Check if a value content matches a type expression.
93
+ * This uses the grammar-parsed structure for reliable type checking.
94
+ */
95
+ matchesContent(content: ValueContent, type: ModelTypeExpression): boolean;
96
+ /**
97
+ * Check if a default value matches a type expression.
98
+ * Default values can only be quoted strings, links, or datetimes.
99
+ */
100
+ matchesDefaultValue(defaultValue: ModelDefaultValue, type: ModelTypeExpression): boolean;
101
+ /**
102
+ * Get a human-readable string for a type expression
103
+ */
104
+ toString(type: ModelTypeExpression): string;
105
+ };
106
+ //#endregion
107
+ export { EntitySchema, FieldSchema, SchemaRegistry, SectionSchema, TypeExpr };
108
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","names":[],"sources":["../../src/schema/registry.ts"],"sourcesContent":[],"mappings":";;;;;;;AAsBA;AAMsB,UANL,YAAA,CAMK;EAAZ;EAEc,IAAA,EAAA,MAAA;EAAZ;EAAG,WAAA,EAAA,MAAA;EAUE;EAgBA,MAAA,EA5BP,GA4BO,CAAA,MAAa,EA5BR,WA4BQ,CAAA;EAajB;EAyLA,QAAA,EAhOD,GAkSX,CAAA,MAAA,EAlSuB,aAkSvB,CAAA;EA7DyB;EAAoB,SAAA,EAAA,MAAA;EAqBV;EAAyB,SAAA,EAAA,MAAA;;;;;UAhP5C,WAAA;;;;;;QAMT;;gBAEQ;;;;;;;UAQC,aAAA;;;;;;;;;;;;cAaJ,cAAA;;;;;;;aAQA;;;;qBAgBQ;;;;;;;;;;;;;;;;;;;;;;;;;;cAiKR;;;;;0BAKa,oBAAoB;;;;;oCAqBV,yBAAyB;;;;iBAsB5C"}