algraf-editor 0.67.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.
package/dist/index.cjs ADDED
@@ -0,0 +1,1161 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.tsx
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ ALGRAF_DEFAULT_MODEL_URI: () => ALGRAF_DEFAULT_MODEL_URI,
34
+ ALGRAF_LANGUAGE_ID: () => ALGRAF_LANGUAGE_ID,
35
+ ALGRAF_MARKER_OWNER: () => ALGRAF_MARKER_OWNER,
36
+ ALGRAF_SCOPE_NAME: () => ALGRAF_SCOPE_NAME,
37
+ ALGRAF_THEME_NAME: () => ALGRAF_THEME_NAME,
38
+ AlgrafEditor: () => AlgrafEditor,
39
+ defaultAlgrafTheme: () => defaultAlgrafTheme,
40
+ defineAlgrafTheme: () => defineAlgrafTheme,
41
+ diagnosticToAlgrafMarker: () => diagnosticToAlgrafMarker,
42
+ registerAlgrafEditorProviders: () => registerAlgrafEditorProviders,
43
+ registerAlgrafLanguage: () => registerAlgrafLanguage,
44
+ setAlgrafMarkers: () => setAlgrafMarkers,
45
+ setupAlgrafMonaco: () => setupAlgrafMonaco
46
+ });
47
+ module.exports = __toCommonJS(index_exports);
48
+ var import_react = __toESM(require("react"), 1);
49
+ var monaco2 = __toESM(require("monaco-editor/esm/vs/editor/editor.api"), 1);
50
+ var import_editor_main = require("monaco-editor/min/vs/editor/editor.main.css");
51
+ var import_hoverContribution = require("monaco-editor/esm/vs/editor/contrib/hover/browser/hoverContribution");
52
+ var import_editor = __toESM(require("monaco-editor/esm/vs/editor/editor.worker?worker"), 1);
53
+ var import_monaco_editor_textmate = require("monaco-editor-textmate");
54
+ var import_monaco_textmate = require("monaco-textmate");
55
+ var import_onigasm = require("onigasm");
56
+ var import_onigasm2 = __toESM(require("onigasm/lib/onigasm.wasm?url"), 1);
57
+
58
+ // assets/algraf.tmLanguage.json
59
+ var algraf_tmLanguage_default = {
60
+ $schema: "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
61
+ name: "Algraf",
62
+ scopeName: "source.algraf",
63
+ patterns: [
64
+ {
65
+ include: "#comments"
66
+ },
67
+ {
68
+ include: "#strings"
69
+ },
70
+ {
71
+ include: "#quoted-identifiers"
72
+ },
73
+ {
74
+ include: "#numbers"
75
+ },
76
+ {
77
+ include: "#let-bindings"
78
+ },
79
+ {
80
+ include: "#declarations"
81
+ },
82
+ {
83
+ include: "#interactions"
84
+ },
85
+ {
86
+ include: "#geometries"
87
+ },
88
+ {
89
+ include: "#stats"
90
+ },
91
+ {
92
+ include: "#sources"
93
+ },
94
+ {
95
+ include: "#constants"
96
+ },
97
+ {
98
+ include: "#properties"
99
+ },
100
+ {
101
+ include: "#columns"
102
+ },
103
+ {
104
+ include: "#operators"
105
+ },
106
+ {
107
+ include: "#functions"
108
+ }
109
+ ],
110
+ repository: {
111
+ comments: {
112
+ patterns: [
113
+ {
114
+ name: "comment.line.double-slash.algraf",
115
+ match: "//.*$"
116
+ }
117
+ ]
118
+ },
119
+ strings: {
120
+ patterns: [
121
+ {
122
+ name: "string.quoted.double.algraf",
123
+ begin: '"',
124
+ end: '"',
125
+ patterns: [
126
+ {
127
+ name: "constant.character.escape.algraf",
128
+ match: '\\\\[nrt"\\\\]'
129
+ },
130
+ {
131
+ name: "invalid.illegal.escape.algraf",
132
+ match: "\\\\."
133
+ }
134
+ ]
135
+ }
136
+ ]
137
+ },
138
+ "quoted-identifiers": {
139
+ patterns: [
140
+ {
141
+ name: "variable.other.quoted.algraf",
142
+ begin: "`",
143
+ end: "`",
144
+ patterns: [
145
+ {
146
+ name: "constant.character.escape.algraf",
147
+ match: "\\\\[`\\\\]"
148
+ }
149
+ ]
150
+ }
151
+ ]
152
+ },
153
+ numbers: {
154
+ patterns: [
155
+ {
156
+ name: "constant.numeric.algraf",
157
+ match: "\\b-?[0-9]+(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\\b"
158
+ }
159
+ ]
160
+ },
161
+ "let-bindings": {
162
+ patterns: [
163
+ {
164
+ match: "\\b(let)\\s+([A-Za-z_][A-Za-z0-9_]*)",
165
+ captures: {
166
+ "1": {
167
+ name: "keyword.declaration.let.algraf"
168
+ },
169
+ "2": {
170
+ name: "variable.other.declaration.algraf"
171
+ }
172
+ }
173
+ }
174
+ ]
175
+ },
176
+ declarations: {
177
+ patterns: [
178
+ {
179
+ name: "keyword.declaration.algraf",
180
+ match: "\\b(?:Algraf|Chart|Space|Inset|Derive|from|Table|Parse|Scale|Guide|Theme|Layout)\\b"
181
+ },
182
+ {
183
+ name: "keyword.declaration.let.algraf",
184
+ match: "\\blet\\b"
185
+ }
186
+ ]
187
+ },
188
+ geometries: {
189
+ patterns: [
190
+ {
191
+ name: "entity.name.function.geometry.algraf",
192
+ match: "\\b(?:Point|Line|Path|Bar|Rect|Histogram|FreqPoly|Bin2D|HexBin|Smooth|Boxplot|Violin|Density|ErrorBar|LineRange|PointRange|CrossBar|Ribbon|Tile|HLine|VLine|Rug|Area|Text|Label|Image|Segment|Geo|Graticule)\\b(?=\\s*\\()"
193
+ }
194
+ ]
195
+ },
196
+ interactions: {
197
+ patterns: [
198
+ {
199
+ name: "entity.name.function.interaction.algraf",
200
+ match: "\\bOn\\b(?=\\s*\\()"
201
+ }
202
+ ]
203
+ },
204
+ stats: {
205
+ patterns: [
206
+ {
207
+ name: "entity.name.function.stat.algraf",
208
+ match: "\\b(?:Bin|Bin2D|HexBin|Summary2D|SummaryHex|ContourLines|ContourBands|Density2D|Density2DContours|Density2DBands|Distinct|Ecdf|Qq|Summary|SummaryBin|Cut|Count|Smooth|StepVertices|JitterPoints|VectorEndpoints|CurveSample|IntervalSegments|IntervalRects|IntervalMiddles|Boxplot|Density|Centroid|Simplify|SpatialJoin)\\b(?=\\s*\\()"
209
+ }
210
+ ]
211
+ },
212
+ sources: {
213
+ patterns: [
214
+ {
215
+ name: "entity.name.function.source.algraf",
216
+ match: "\\b(?:GeoJson|Shapefile|Sqlite|TopoJson|Style|Stop)\\b(?=\\s*\\()"
217
+ },
218
+ {
219
+ name: "entity.name.function.literal.algraf",
220
+ match: "\\b(?:datetime|date)\\b(?=\\s*\\()"
221
+ }
222
+ ]
223
+ },
224
+ constants: {
225
+ patterns: [
226
+ {
227
+ name: "constant.language.algraf",
228
+ match: "\\b(?:true|false|null|stdin)\\b"
229
+ }
230
+ ]
231
+ },
232
+ properties: {
233
+ patterns: [
234
+ {
235
+ name: "variable.parameter.property.algraf",
236
+ match: "\\b(?:version|features|data|match|width|height|minSize|maxSize|padding|placement|clip|title|subtitle|caption|alt|description|marginTop|marginRight|marginBottom|marginLeft|facetColumns|facetRows|facetCols|facetScales|facetLabel|facetLabels|panelSpacing|axis|legend|grid|timeFormat|tickLabelAngle|tickLabelRows|table|column|format|formats|unit|timezone|onError|coords|zoomX|zoomY|aspect|theta|innerRadius|startAngle|direction|radius|fill|stroke|strokeWidth|dash|alpha|size|shape|src|group|sort|layout|baseline|stat|xmin|xmax|ymin|ymax|bins|binWidth|boundary|closed|interval|bandwidth|n|quantiles|outliers|span|se|taper|curvature|points|lengthScale|type|mode|domain|breaks|expand|expansion|range|reverse|integer|palette|gradient|labels|reducer|by|distribution|reference|output|method|label|at|anchor|dx|dy|nudge|nudgeData|jitter|x|y|xend|yend|sides|tooltip|highlight|projection|name|plotTitle|plotSubtitle|plotCaption|axisTitle|axisText|stripText|legendTitle|legendText|panelBackground|gridMajor|gridMinor|legendPosition|legendSpacing|fontFamily|fontSize|titleSize|pointSize|lineWidth|background|plotBackground|axisColor|gridColor|textColor|axes|style|color|value)\\b(?=\\s*:)"
237
+ },
238
+ {
239
+ name: "variable.parameter.property.unknown.algraf",
240
+ match: "\\b[A-Za-z_][A-Za-z0-9_]*\\b(?=\\s*:)"
241
+ }
242
+ ]
243
+ },
244
+ columns: {
245
+ patterns: [
246
+ {
247
+ name: "variable.other.column.algraf",
248
+ match: "\\b[A-Za-z_][A-Za-z0-9_]*\\b(?!\\s*[:(])"
249
+ }
250
+ ]
251
+ },
252
+ operators: {
253
+ patterns: [
254
+ {
255
+ name: "keyword.operator.algebra.algraf",
256
+ match: "[*/+]"
257
+ },
258
+ {
259
+ name: "keyword.operator.map.algraf",
260
+ match: "=>"
261
+ },
262
+ {
263
+ name: "keyword.operator.assignment.algraf",
264
+ match: "="
265
+ },
266
+ {
267
+ name: "punctuation.separator.comma.algraf",
268
+ match: ","
269
+ },
270
+ {
271
+ name: "punctuation.separator.key-value.algraf",
272
+ match: ":"
273
+ },
274
+ {
275
+ name: "punctuation.section.braces.algraf",
276
+ match: "[{}]"
277
+ },
278
+ {
279
+ name: "punctuation.section.parens.algraf",
280
+ match: "[()]"
281
+ },
282
+ {
283
+ name: "punctuation.section.brackets.algraf",
284
+ match: "[\\[\\]]"
285
+ }
286
+ ]
287
+ },
288
+ functions: {
289
+ patterns: [
290
+ {
291
+ name: "entity.name.function.algraf",
292
+ match: "\\b[A-Za-z_][A-Za-z0-9_]*\\b(?=\\s*\\()"
293
+ }
294
+ ]
295
+ }
296
+ }
297
+ };
298
+
299
+ // assets/language-configuration.json
300
+ var language_configuration_default = {
301
+ comments: {
302
+ lineComment: "//"
303
+ },
304
+ brackets: [
305
+ [
306
+ "{",
307
+ "}"
308
+ ],
309
+ [
310
+ "(",
311
+ ")"
312
+ ],
313
+ [
314
+ "[",
315
+ "]"
316
+ ]
317
+ ],
318
+ autoClosingPairs: [
319
+ {
320
+ open: "{",
321
+ close: "}"
322
+ },
323
+ {
324
+ open: "(",
325
+ close: ")"
326
+ },
327
+ {
328
+ open: "[",
329
+ close: "]"
330
+ },
331
+ {
332
+ open: '"',
333
+ close: '"',
334
+ notIn: [
335
+ "string",
336
+ "comment"
337
+ ]
338
+ },
339
+ {
340
+ open: "`",
341
+ close: "`",
342
+ notIn: [
343
+ "string",
344
+ "comment"
345
+ ]
346
+ }
347
+ ],
348
+ surroundingPairs: [
349
+ {
350
+ open: "{",
351
+ close: "}"
352
+ },
353
+ {
354
+ open: "(",
355
+ close: ")"
356
+ },
357
+ {
358
+ open: "[",
359
+ close: "]"
360
+ },
361
+ {
362
+ open: '"',
363
+ close: '"'
364
+ },
365
+ {
366
+ open: "`",
367
+ close: "`"
368
+ }
369
+ ],
370
+ folding: {
371
+ markers: {
372
+ start: "^\\s*//\\s*#region\\b",
373
+ end: "^\\s*//\\s*#endregion\\b"
374
+ }
375
+ },
376
+ wordPattern: "`[^`]*(?:\\\\.[^`]*)*`|[A-Za-z_][A-Za-z0-9_]*"
377
+ };
378
+
379
+ // src/providers.ts
380
+ var monaco = __toESM(require("monaco-editor/esm/vs/editor/editor.api"), 1);
381
+ var SEMANTIC_TOKEN_TYPES = [
382
+ "keyword",
383
+ "function",
384
+ "property",
385
+ "variable",
386
+ "operator",
387
+ "string",
388
+ "number",
389
+ "comment"
390
+ ];
391
+ function registerAlgrafEditorProviders(languageId, getRuntime, getFiles) {
392
+ const disposables = [
393
+ monaco.languages.registerHoverProvider(languageId, {
394
+ provideHover(model, position) {
395
+ const hover = requestFeature(model, getRuntime, getFiles, {
396
+ kind: "hover",
397
+ position: toLspPosition(position)
398
+ });
399
+ if (!hover) {
400
+ return null;
401
+ }
402
+ return {
403
+ contents: hoverContents(hover.contents),
404
+ range: hover.range ? fromLspRange(hover.range) : void 0
405
+ };
406
+ }
407
+ }),
408
+ monaco.languages.registerCompletionItemProvider(languageId, {
409
+ triggerCharacters: [":", "*", "/", "+", "("],
410
+ provideCompletionItems(model, position) {
411
+ const response = requestFeature(
412
+ model,
413
+ getRuntime,
414
+ getFiles,
415
+ {
416
+ kind: "completion",
417
+ position: toLspPosition(position)
418
+ }
419
+ );
420
+ const items = Array.isArray(response) ? response : response?.items ?? [];
421
+ return {
422
+ suggestions: items.map((item) => completionItem(item, position))
423
+ };
424
+ }
425
+ }),
426
+ monaco.languages.registerSignatureHelpProvider(languageId, {
427
+ signatureHelpTriggerCharacters: ["(", ","],
428
+ signatureHelpRetriggerCharacters: [","],
429
+ provideSignatureHelp(model, position) {
430
+ const help = requestFeature(model, getRuntime, getFiles, {
431
+ kind: "signatureHelp",
432
+ position: toLspPosition(position)
433
+ });
434
+ if (!help) {
435
+ return null;
436
+ }
437
+ return {
438
+ value: {
439
+ activeSignature: help.activeSignature ?? 0,
440
+ activeParameter: help.activeParameter ?? 0,
441
+ signatures: help.signatures.map((signature) => ({
442
+ label: signature.label,
443
+ documentation: markdownString(signature.documentation),
444
+ parameters: (signature.parameters ?? []).map((parameter) => ({
445
+ label: parameter.label,
446
+ documentation: markdownString(parameter.documentation)
447
+ }))
448
+ }))
449
+ },
450
+ dispose: () => void 0
451
+ };
452
+ }
453
+ }),
454
+ monaco.languages.registerDocumentFormattingEditProvider(languageId, {
455
+ provideDocumentFormattingEdits(model) {
456
+ const edits = requestFeature(model, getRuntime, getFiles, {
457
+ kind: "formatting"
458
+ });
459
+ return (edits ?? []).map(textEdit);
460
+ }
461
+ }),
462
+ monaco.languages.registerDocumentRangeFormattingEditProvider(languageId, {
463
+ provideDocumentRangeFormattingEdits(model, range) {
464
+ const edits = requestFeature(model, getRuntime, getFiles, {
465
+ kind: "rangeFormatting",
466
+ range: toLspRange(range)
467
+ });
468
+ return (edits ?? []).map(textEdit);
469
+ }
470
+ }),
471
+ monaco.languages.registerDocumentSemanticTokensProvider(languageId, {
472
+ getLegend() {
473
+ return {
474
+ tokenTypes: SEMANTIC_TOKEN_TYPES,
475
+ tokenModifiers: []
476
+ };
477
+ },
478
+ provideDocumentSemanticTokens(model) {
479
+ const result = requestFeature(
480
+ model,
481
+ getRuntime,
482
+ getFiles,
483
+ {
484
+ kind: "semanticTokens"
485
+ }
486
+ );
487
+ return {
488
+ data: new Uint32Array(flattenSemanticTokens(result?.data ?? [])),
489
+ resultId: void 0
490
+ };
491
+ },
492
+ releaseDocumentSemanticTokens() {
493
+ return void 0;
494
+ }
495
+ }),
496
+ monaco.languages.registerCodeActionProvider(languageId, {
497
+ provideCodeActions(model, range, context) {
498
+ const actions = requestFeature(model, getRuntime, getFiles, {
499
+ kind: "codeActions",
500
+ range: toLspRange(range),
501
+ diagnostics: context.markers.map(markerToDiagnostic)
502
+ });
503
+ return {
504
+ actions: (actions ?? []).map((action) => codeAction(action, model.uri)),
505
+ dispose: () => void 0
506
+ };
507
+ }
508
+ }),
509
+ monaco.languages.registerDefinitionProvider(languageId, {
510
+ provideDefinition(model, position) {
511
+ const result = requestFeature(
512
+ model,
513
+ getRuntime,
514
+ getFiles,
515
+ {
516
+ kind: "definition",
517
+ position: toLspPosition(position)
518
+ }
519
+ );
520
+ return locations(result);
521
+ }
522
+ }),
523
+ monaco.languages.registerReferenceProvider(languageId, {
524
+ provideReferences(model, position, context) {
525
+ const result = requestFeature(model, getRuntime, getFiles, {
526
+ kind: "references",
527
+ position: toLspPosition(position),
528
+ includeDeclaration: context.includeDeclaration
529
+ });
530
+ return locations(result);
531
+ }
532
+ }),
533
+ monaco.languages.registerDocumentHighlightProvider(languageId, {
534
+ provideDocumentHighlights(model, position) {
535
+ const result = requestFeature(model, getRuntime, getFiles, {
536
+ kind: "documentHighlights",
537
+ position: toLspPosition(position)
538
+ });
539
+ return (result ?? []).map((highlight) => ({
540
+ range: fromLspRange(highlight.range),
541
+ kind: documentHighlightKind(highlight.kind)
542
+ }));
543
+ }
544
+ }),
545
+ monaco.languages.registerRenameProvider(languageId, {
546
+ resolveRenameLocation(model, position) {
547
+ const response = requestFeature(model, getRuntime, getFiles, {
548
+ kind: "prepareRename",
549
+ position: toLspPosition(position)
550
+ });
551
+ const range = "range" in (response ?? {}) ? response.range : response;
552
+ if (!range) {
553
+ return {
554
+ range: new monaco.Range(position.lineNumber, position.column, position.lineNumber, position.column),
555
+ text: "",
556
+ rejectReason: "This symbol cannot be renamed."
557
+ };
558
+ }
559
+ return {
560
+ range: fromLspRange(range),
561
+ text: model.getValueInRange(fromLspRange(range))
562
+ };
563
+ },
564
+ provideRenameEdits(model, position, newName) {
565
+ const edit = requestFeature(model, getRuntime, getFiles, {
566
+ kind: "rename",
567
+ position: toLspPosition(position),
568
+ newName
569
+ });
570
+ if (!edit) {
571
+ return { edits: [] };
572
+ }
573
+ return workspaceEdit(edit);
574
+ }
575
+ }),
576
+ monaco.languages.registerDocumentSymbolProvider(languageId, {
577
+ provideDocumentSymbols(model) {
578
+ const result = requestFeature(model, getRuntime, getFiles, {
579
+ kind: "documentSymbols"
580
+ });
581
+ return (result ?? []).map(documentSymbol);
582
+ }
583
+ })
584
+ ];
585
+ return {
586
+ dispose() {
587
+ for (const disposable of disposables) {
588
+ disposable.dispose();
589
+ }
590
+ }
591
+ };
592
+ }
593
+ function requestFeature(model, getRuntime, getFiles, request) {
594
+ const runtime = getRuntime(model);
595
+ if (!runtime) {
596
+ return null;
597
+ }
598
+ const response = runtime.editorService(model.getValue(), getFiles(model), request, model.uri.toString());
599
+ if (response.error) {
600
+ console.warn(`Algraf editor service failed: ${response.error}`);
601
+ return null;
602
+ }
603
+ return response.result;
604
+ }
605
+ function toLspPosition(position) {
606
+ return {
607
+ line: Math.max(0, position.lineNumber - 1),
608
+ character: Math.max(0, position.column - 1)
609
+ };
610
+ }
611
+ function fromLspPosition(position) {
612
+ return {
613
+ lineNumber: position.line + 1,
614
+ column: position.character + 1
615
+ };
616
+ }
617
+ function toLspRange(range) {
618
+ return {
619
+ start: toLspPosition({ lineNumber: range.startLineNumber, column: range.startColumn }),
620
+ end: toLspPosition({ lineNumber: range.endLineNumber, column: range.endColumn })
621
+ };
622
+ }
623
+ function fromLspRange(range) {
624
+ const start = fromLspPosition(range.start);
625
+ const end = fromLspPosition(range.end);
626
+ return new monaco.Range(start.lineNumber, start.column, end.lineNumber, end.column);
627
+ }
628
+ function hoverContents(contents) {
629
+ const values = Array.isArray(contents) ? contents : [contents];
630
+ return values.map((value) => ({
631
+ value: typeof value === "string" ? value : value.value,
632
+ isTrusted: false,
633
+ supportThemeIcons: false,
634
+ supportHtml: false
635
+ }));
636
+ }
637
+ function markdownString(value) {
638
+ if (!value) {
639
+ return void 0;
640
+ }
641
+ if (typeof value === "string") {
642
+ return value;
643
+ }
644
+ return {
645
+ value: value.value,
646
+ isTrusted: false,
647
+ supportHtml: false
648
+ };
649
+ }
650
+ function completionItem(item, position) {
651
+ return {
652
+ label: item.label,
653
+ kind: completionKind(item.kind),
654
+ detail: item.detail,
655
+ documentation: markdownString(item.documentation),
656
+ insertText: item.insertText ?? item.label,
657
+ insertTextRules: item.insertTextFormat === 2 ? monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet : void 0,
658
+ range: new monaco.Range(position.lineNumber, position.column, position.lineNumber, position.column)
659
+ };
660
+ }
661
+ function completionKind(kind) {
662
+ switch (kind) {
663
+ case 3:
664
+ return monaco.languages.CompletionItemKind.Function;
665
+ case 5:
666
+ return monaco.languages.CompletionItemKind.Field;
667
+ case 10:
668
+ return monaco.languages.CompletionItemKind.Property;
669
+ case 12:
670
+ return monaco.languages.CompletionItemKind.Value;
671
+ case 14:
672
+ return monaco.languages.CompletionItemKind.Keyword;
673
+ case 15:
674
+ return monaco.languages.CompletionItemKind.Snippet;
675
+ case 16:
676
+ return monaco.languages.CompletionItemKind.Color;
677
+ case 24:
678
+ return monaco.languages.CompletionItemKind.Operator;
679
+ default:
680
+ return monaco.languages.CompletionItemKind.Text;
681
+ }
682
+ }
683
+ function textEdit(edit) {
684
+ return {
685
+ range: fromLspRange(edit.range),
686
+ text: edit.newText
687
+ };
688
+ }
689
+ function flattenSemanticTokens(data) {
690
+ if (data.length === 0 || typeof data[0] === "number") {
691
+ return data;
692
+ }
693
+ return data.flatMap((token) => [
694
+ token.deltaLine,
695
+ token.deltaStart,
696
+ token.length,
697
+ token.tokenType,
698
+ token.tokenModifiersBitset
699
+ ]);
700
+ }
701
+ function markerToDiagnostic(marker) {
702
+ return {
703
+ range: toLspRange(marker),
704
+ severity: markerSeverity(marker.severity),
705
+ code: markerCode(marker.code),
706
+ source: marker.source,
707
+ message: marker.message
708
+ };
709
+ }
710
+ function markerSeverity(severity) {
711
+ switch (severity) {
712
+ case monaco.MarkerSeverity.Error:
713
+ return 1;
714
+ case monaco.MarkerSeverity.Warning:
715
+ return 2;
716
+ case monaco.MarkerSeverity.Info:
717
+ return 3;
718
+ case monaco.MarkerSeverity.Hint:
719
+ return 4;
720
+ }
721
+ }
722
+ function markerCode(code) {
723
+ if (typeof code === "string" || typeof code === "number") {
724
+ return code;
725
+ }
726
+ return code?.value;
727
+ }
728
+ function codeAction(action, currentUri) {
729
+ return {
730
+ title: action.title,
731
+ kind: action.kind,
732
+ diagnostics: action.diagnostics?.map((diagnostic) => ({
733
+ severity: diagnosticSeverity(diagnostic.severity),
734
+ message: diagnostic.message,
735
+ startLineNumber: diagnostic.range.start.line + 1,
736
+ startColumn: diagnostic.range.start.character + 1,
737
+ endLineNumber: diagnostic.range.end.line + 1,
738
+ endColumn: diagnostic.range.end.character + 1
739
+ })),
740
+ edit: action.edit ? workspaceEdit(action.edit, currentUri) : void 0
741
+ };
742
+ }
743
+ function diagnosticSeverity(severity) {
744
+ switch (severity) {
745
+ case 1:
746
+ return monaco.MarkerSeverity.Error;
747
+ case 2:
748
+ return monaco.MarkerSeverity.Warning;
749
+ case 3:
750
+ return monaco.MarkerSeverity.Info;
751
+ case 4:
752
+ return monaco.MarkerSeverity.Hint;
753
+ default:
754
+ return monaco.MarkerSeverity.Info;
755
+ }
756
+ }
757
+ function workspaceEdit(edit, fallbackUri) {
758
+ const edits = [];
759
+ for (const [uri, textEdits] of Object.entries(edit.changes ?? {})) {
760
+ const resource = uri ? monaco.Uri.parse(uri) : fallbackUri;
761
+ if (!resource) {
762
+ continue;
763
+ }
764
+ for (const text of textEdits) {
765
+ edits.push({
766
+ resource,
767
+ textEdit: {
768
+ range: fromLspRange(text.range),
769
+ text: text.newText
770
+ },
771
+ versionId: void 0
772
+ });
773
+ }
774
+ }
775
+ return { edits };
776
+ }
777
+ function locations(result) {
778
+ const values = Array.isArray(result) ? result : result ? [result] : [];
779
+ return values.map((location) => ({
780
+ uri: monaco.Uri.parse(location.uri),
781
+ range: fromLspRange(location.range)
782
+ }));
783
+ }
784
+ function documentHighlightKind(kind) {
785
+ switch (kind) {
786
+ case 3:
787
+ return monaco.languages.DocumentHighlightKind.Write;
788
+ case 2:
789
+ return monaco.languages.DocumentHighlightKind.Read;
790
+ default:
791
+ return monaco.languages.DocumentHighlightKind.Text;
792
+ }
793
+ }
794
+ function documentSymbol(symbol) {
795
+ return {
796
+ name: symbol.name,
797
+ detail: symbol.detail ?? "",
798
+ kind: symbolKind(symbol.kind),
799
+ range: fromLspRange(symbol.range),
800
+ selectionRange: fromLspRange(symbol.selectionRange),
801
+ tags: [],
802
+ children: symbol.children?.map(documentSymbol)
803
+ };
804
+ }
805
+ function symbolKind(kind) {
806
+ switch (kind) {
807
+ case 7:
808
+ return monaco.languages.SymbolKind.Property;
809
+ case 12:
810
+ return monaco.languages.SymbolKind.Function;
811
+ case 13:
812
+ return monaco.languages.SymbolKind.Variable;
813
+ case 19:
814
+ return monaco.languages.SymbolKind.Object;
815
+ default:
816
+ return monaco.languages.SymbolKind.Object;
817
+ }
818
+ }
819
+
820
+ // src/index.tsx
821
+ var import_jsx_runtime = require("react/jsx-runtime");
822
+ var ALGRAF_LANGUAGE_ID = "algraf";
823
+ var ALGRAF_SCOPE_NAME = "source.algraf";
824
+ var ALGRAF_THEME_NAME = "algraf-playground";
825
+ var ALGRAF_MARKER_OWNER = "algraf-wasm";
826
+ var ALGRAF_DEFAULT_MODEL_URI = "inmemory://algraf/demo.ag";
827
+ var encoder = new TextEncoder();
828
+ var setupPromise = null;
829
+ var onigasmPromise = null;
830
+ var providerDisposable = null;
831
+ var editorContexts = /* @__PURE__ */ new Map();
832
+ function AlgrafEditor({
833
+ value,
834
+ files,
835
+ diagnostics,
836
+ runtime,
837
+ onChange,
838
+ modelUri,
839
+ languageId = ALGRAF_LANGUAGE_ID,
840
+ themeName = ALGRAF_THEME_NAME,
841
+ theme,
842
+ className = "algraf-editor-shell",
843
+ editorClassName = "algraf-editor",
844
+ options,
845
+ setupOptions
846
+ }) {
847
+ const hostRef = import_react.default.useRef(null);
848
+ const editorRef = import_react.default.useRef(null);
849
+ const modelRef = import_react.default.useRef(null);
850
+ const onChangeRef = import_react.default.useRef(onChange);
851
+ const diagnosticsRef = import_react.default.useRef(diagnostics);
852
+ const filesRef = import_react.default.useRef(files);
853
+ const runtimeRef = import_react.default.useRef(runtime);
854
+ const [setupError, setSetupError] = import_react.default.useState(null);
855
+ const resolvedModelUri = import_react.default.useMemo(() => monaco2.Uri.parse(modelUri ?? ALGRAF_DEFAULT_MODEL_URI), [modelUri]);
856
+ import_react.default.useEffect(() => {
857
+ onChangeRef.current = onChange;
858
+ }, [onChange]);
859
+ import_react.default.useEffect(() => {
860
+ filesRef.current = files;
861
+ }, [files]);
862
+ import_react.default.useEffect(() => {
863
+ runtimeRef.current = runtime;
864
+ }, [runtime]);
865
+ import_react.default.useEffect(() => {
866
+ diagnosticsRef.current = diagnostics;
867
+ const model = modelRef.current;
868
+ if (model) {
869
+ setAlgrafMarkers(model, diagnostics);
870
+ }
871
+ }, [diagnostics]);
872
+ import_react.default.useEffect(() => {
873
+ const model = modelRef.current;
874
+ if (model && model.getValue() !== value) {
875
+ const selection = editorRef.current?.getSelection() ?? null;
876
+ model.setValue(value);
877
+ if (selection) {
878
+ editorRef.current?.setSelection(selection);
879
+ }
880
+ setAlgrafMarkers(model, diagnosticsRef.current);
881
+ }
882
+ }, [value]);
883
+ import_react.default.useEffect(() => {
884
+ let cancelled = false;
885
+ let editor2 = null;
886
+ let model = null;
887
+ let contentDisposable = null;
888
+ let contextKey = null;
889
+ setupAlgrafMonaco({ ...setupOptions, languageId, themeName, theme }).then(() => {
890
+ if (cancelled || !hostRef.current) {
891
+ return;
892
+ }
893
+ ensureAlgrafProviders(languageId);
894
+ model = monaco2.editor.createModel(value, languageId, resolvedModelUri);
895
+ contextKey = model.uri.toString();
896
+ editorContexts.set(contextKey, {
897
+ runtime: () => runtimeRef.current,
898
+ files: () => filesRef.current
899
+ });
900
+ editor2 = monaco2.editor.create(hostRef.current, {
901
+ model,
902
+ theme: themeName,
903
+ automaticLayout: true,
904
+ bracketPairColorization: { enabled: true },
905
+ cursorBlinking: "smooth",
906
+ fixedOverflowWidgets: true,
907
+ fontFamily: '"SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace',
908
+ fontSize: 13,
909
+ lineHeight: 20,
910
+ minimap: { enabled: false },
911
+ overviewRulerBorder: false,
912
+ padding: { top: 12, bottom: 12 },
913
+ renderLineHighlight: "line",
914
+ scrollBeyondLastLine: false,
915
+ smoothScrolling: true,
916
+ tabSize: 4,
917
+ wordWrap: "off",
918
+ ...options
919
+ });
920
+ modelRef.current = model;
921
+ editorRef.current = editor2;
922
+ setAlgrafMarkers(model, diagnosticsRef.current);
923
+ contentDisposable = model.onDidChangeContent(() => {
924
+ onChangeRef.current(model?.getValue() ?? "");
925
+ });
926
+ }).catch((err) => {
927
+ if (!cancelled) {
928
+ setSetupError(err instanceof Error ? err.message : String(err));
929
+ }
930
+ });
931
+ return () => {
932
+ cancelled = true;
933
+ contentDisposable?.dispose();
934
+ if (contextKey) {
935
+ editorContexts.delete(contextKey);
936
+ }
937
+ if (model) {
938
+ monaco2.editor.setModelMarkers(model, ALGRAF_MARKER_OWNER, []);
939
+ }
940
+ editor2?.dispose();
941
+ model?.dispose();
942
+ if (editorRef.current === editor2) {
943
+ editorRef.current = null;
944
+ }
945
+ if (modelRef.current === model) {
946
+ modelRef.current = null;
947
+ }
948
+ };
949
+ }, [languageId, options, resolvedModelUri, setupOptions, theme, themeName]);
950
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className, children: [
951
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { "aria-label": "Algraf source", className: editorClassName, ref: hostRef }),
952
+ setupError ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "algraf-editor-error", children: [
953
+ "Editor failed to load: ",
954
+ setupError
955
+ ] }) : null
956
+ ] });
957
+ }
958
+ function ensureAlgrafProviders(languageId) {
959
+ providerDisposable ?? (providerDisposable = registerAlgrafEditorProviders(
960
+ languageId,
961
+ (model) => editorContexts.get(model.uri.toString())?.runtime() ?? null,
962
+ (model) => editorContexts.get(model.uri.toString())?.files() ?? {}
963
+ ));
964
+ }
965
+ function setupAlgrafMonaco(options = {}) {
966
+ setupPromise ?? (setupPromise = setupAlgrafMonacoOnce(options).catch((error) => {
967
+ setupPromise = null;
968
+ throw error;
969
+ }));
970
+ return setupPromise;
971
+ }
972
+ function registerAlgrafLanguage(options = {}) {
973
+ const languageId = options.languageId ?? ALGRAF_LANGUAGE_ID;
974
+ if (monaco2.languages.getLanguages().some((language) => language.id === languageId)) {
975
+ return;
976
+ }
977
+ monaco2.languages.register({
978
+ id: languageId,
979
+ aliases: options.aliases ?? ["Algraf", "algraf"],
980
+ extensions: options.extensions ?? [".ag"]
981
+ });
982
+ monaco2.languages.setLanguageConfiguration(
983
+ languageId,
984
+ options.languageConfiguration ?? language_configuration_default
985
+ );
986
+ }
987
+ async function setupAlgrafMonacoOnce(options) {
988
+ if (options.configureWorker !== false) {
989
+ configureMonacoWorker();
990
+ }
991
+ registerAlgrafLanguage(options);
992
+ defineAlgrafTheme(options.themeName ?? ALGRAF_THEME_NAME, options.theme ?? defaultAlgrafTheme());
993
+ await loadOnigasmOnce(options.onigasmWasmUrl ?? import_onigasm2.default);
994
+ const registry = new import_monaco_textmate.Registry({
995
+ getGrammarDefinition: async () => ({
996
+ format: "json",
997
+ content: options.grammar ?? algraf_tmLanguage_default
998
+ })
999
+ });
1000
+ await (0, import_monaco_editor_textmate.wireTmGrammars)(
1001
+ monaco2,
1002
+ registry,
1003
+ /* @__PURE__ */ new Map([[options.languageId ?? ALGRAF_LANGUAGE_ID, options.scopeName ?? ALGRAF_SCOPE_NAME]])
1004
+ );
1005
+ }
1006
+ function configureMonacoWorker() {
1007
+ const target = globalThis;
1008
+ target.MonacoEnvironment ?? (target.MonacoEnvironment = {
1009
+ getWorker: () => new import_editor.default()
1010
+ });
1011
+ }
1012
+ function loadOnigasmOnce(url) {
1013
+ onigasmPromise ?? (onigasmPromise = (0, import_onigasm.loadWASM)(url).catch((error) => {
1014
+ onigasmPromise = null;
1015
+ throw error;
1016
+ }));
1017
+ return onigasmPromise;
1018
+ }
1019
+ function defineAlgrafTheme(themeName = ALGRAF_THEME_NAME, theme = defaultAlgrafTheme()) {
1020
+ monaco2.editor.defineTheme(themeName, theme);
1021
+ }
1022
+ function defaultAlgrafTheme() {
1023
+ return {
1024
+ base: "vs",
1025
+ inherit: true,
1026
+ rules: [
1027
+ { token: "comment", foreground: "6b7280", fontStyle: "italic" },
1028
+ { token: "string", foreground: "7a4a10" },
1029
+ { token: "number", foreground: "b42318" },
1030
+ { token: "keyword", foreground: "166f5c", fontStyle: "bold" },
1031
+ { token: "function", foreground: "0f5f8f", fontStyle: "bold" },
1032
+ { token: "property", foreground: "9a5512" },
1033
+ { token: "variable", foreground: "355f8c" },
1034
+ { token: "operator", foreground: "4f5b63" },
1035
+ { token: "constant.character.escape", foreground: "9f5b00", fontStyle: "bold" },
1036
+ { token: "constant.numeric", foreground: "b42318" },
1037
+ { token: "constant.language", foreground: "6f42c1" },
1038
+ { token: "invalid.illegal", foreground: "b42318", fontStyle: "underline" },
1039
+ { token: "keyword.control", foreground: "166f5c", fontStyle: "bold" },
1040
+ { token: "keyword.declaration", foreground: "166f5c", fontStyle: "bold" },
1041
+ { token: "keyword.operator.frame", foreground: "7a3f98", fontStyle: "bold" },
1042
+ { token: "keyword.operator", foreground: "4f5b63" },
1043
+ { token: "support.function", foreground: "0f5f8f", fontStyle: "bold" },
1044
+ { token: "support.function.aggregate", foreground: "0f5f8f", fontStyle: "bold" },
1045
+ { token: "support.function.aggregate.pdl", foreground: "0f5f8f", fontStyle: "bold" },
1046
+ { token: "support.function.scalar", foreground: "0f5f8f", fontStyle: "bold" },
1047
+ { token: "support.function.scalar.pdl", foreground: "0f5f8f", fontStyle: "bold" },
1048
+ { token: "support.function.window", foreground: "0f5f8f", fontStyle: "bold" },
1049
+ { token: "support.function.window.pdl", foreground: "0f5f8f", fontStyle: "bold" },
1050
+ { token: "entity.name.function.geometry", foreground: "0f5f8f", fontStyle: "bold" },
1051
+ { token: "entity.name.function.stat", foreground: "7a3f98", fontStyle: "bold" },
1052
+ { token: "entity.name.function.source", foreground: "3c6b22", fontStyle: "bold" },
1053
+ { token: "entity.name.function.literal", foreground: "6f42c1" },
1054
+ { token: "entity.name.function", foreground: "315f7d" },
1055
+ { token: "variable.parameter.property.unknown", foreground: "a33d2d" },
1056
+ { token: "variable.parameter.property", foreground: "9a5512" },
1057
+ { token: "variable.other.declaration", foreground: "145f52", fontStyle: "bold" },
1058
+ { token: "variable.other.quoted", foreground: "385f70" },
1059
+ { token: "variable.other.column", foreground: "355f8c" },
1060
+ { token: "punctuation", foreground: "68757d" }
1061
+ ],
1062
+ colors: {
1063
+ "editor.background": "#ffffff",
1064
+ "editor.foreground": "#171f24",
1065
+ "editor.lineHighlightBackground": "#f4f7f6",
1066
+ "editorLineNumber.foreground": "#9aa6ac",
1067
+ "editorLineNumber.activeForeground": "#21695d",
1068
+ "editorCursor.foreground": "#1f6f62",
1069
+ "editor.selectionBackground": "#cfe8df",
1070
+ "editor.inactiveSelectionBackground": "#e8f2ee",
1071
+ "editorIndentGuide.background1": "#edf1f3",
1072
+ "editorIndentGuide.activeBackground1": "#c9d8d3"
1073
+ }
1074
+ };
1075
+ }
1076
+ function setAlgrafMarkers(model, diagnostics) {
1077
+ monaco2.editor.setModelMarkers(
1078
+ model,
1079
+ ALGRAF_MARKER_OWNER,
1080
+ diagnostics.map((diagnostic) => diagnosticToAlgrafMarker(model, diagnostic))
1081
+ );
1082
+ }
1083
+ function diagnosticToAlgrafMarker(model, diagnostic) {
1084
+ const start = byteOffsetToPosition(model.getValue(), diagnostic.span.start);
1085
+ const end = normalizeEndPosition(model, start, byteOffsetToPosition(model.getValue(), diagnostic.span.end));
1086
+ return {
1087
+ code: diagnostic.code,
1088
+ severity: severityToMarkerSeverity(diagnostic.severity),
1089
+ source: "Algraf",
1090
+ message: diagnostic.help ? `${diagnostic.message}
1091
+
1092
+ ${diagnostic.help}` : diagnostic.message,
1093
+ startLineNumber: start.lineNumber,
1094
+ startColumn: start.column,
1095
+ endLineNumber: end.lineNumber,
1096
+ endColumn: end.column,
1097
+ relatedInformation: diagnostic.related?.map((related) => {
1098
+ const relatedStart = byteOffsetToPosition(model.getValue(), related.span.start);
1099
+ const relatedEnd = normalizeEndPosition(model, relatedStart, byteOffsetToPosition(model.getValue(), related.span.end));
1100
+ return {
1101
+ resource: model.uri,
1102
+ message: related.message,
1103
+ startLineNumber: relatedStart.lineNumber,
1104
+ startColumn: relatedStart.column,
1105
+ endLineNumber: relatedEnd.lineNumber,
1106
+ endColumn: relatedEnd.column
1107
+ };
1108
+ })
1109
+ };
1110
+ }
1111
+ function severityToMarkerSeverity(severity) {
1112
+ switch (severity) {
1113
+ case "error":
1114
+ return monaco2.MarkerSeverity.Error;
1115
+ case "warning":
1116
+ return monaco2.MarkerSeverity.Warning;
1117
+ case "information":
1118
+ return monaco2.MarkerSeverity.Info;
1119
+ case "hint":
1120
+ return monaco2.MarkerSeverity.Hint;
1121
+ }
1122
+ }
1123
+ function byteOffsetToPosition(source, targetByteOffset) {
1124
+ const byteOffset = Math.max(0, targetByteOffset);
1125
+ let bytesSeen = 0;
1126
+ let lineNumber = 1;
1127
+ let column = 1;
1128
+ for (let index = 0; index < source.length && bytesSeen < byteOffset; ) {
1129
+ const codePoint = source.codePointAt(index);
1130
+ if (codePoint === void 0) {
1131
+ break;
1132
+ }
1133
+ const char = String.fromCodePoint(codePoint);
1134
+ const charBytes = encoder.encode(char).length;
1135
+ if (bytesSeen + charBytes > byteOffset) {
1136
+ break;
1137
+ }
1138
+ bytesSeen += charBytes;
1139
+ index += char.length;
1140
+ if (char === "\n") {
1141
+ lineNumber += 1;
1142
+ column = 1;
1143
+ } else {
1144
+ column += char.length;
1145
+ }
1146
+ }
1147
+ return { lineNumber, column };
1148
+ }
1149
+ function normalizeEndPosition(model, start, end) {
1150
+ if (end.lineNumber !== start.lineNumber || end.column !== start.column) {
1151
+ return end;
1152
+ }
1153
+ const maxColumn = model.getLineMaxColumn(start.lineNumber);
1154
+ if (start.column < maxColumn) {
1155
+ return {
1156
+ lineNumber: start.lineNumber,
1157
+ column: start.column + 1
1158
+ };
1159
+ }
1160
+ return end;
1161
+ }