@wire-dsl/web 0.0.7 → 0.1.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/.turbo/turbo-build.log +103 -7
- package/CHANGELOG.md +30 -3
- package/dist/assets/abap-DLDM7-KI.js +1 -0
- package/dist/assets/apex-DNDY2TF8.js +1 -0
- package/dist/assets/azcli-Y6nb8tq_.js +1 -0
- package/dist/assets/bat-BwHxbl9M.js +1 -0
- package/dist/assets/bicep-CFznDFnq.js +2 -0
- package/dist/assets/cameligo-Bf6VGUru.js +1 -0
- package/dist/assets/clojure-Dnu-v4kV.js +1 -0
- package/dist/assets/codicon-ngg6Pgfi.ttf +0 -0
- package/dist/assets/coffee-Bd8akH9Z.js +1 -0
- package/dist/assets/cpp-BbWJElDN.js +1 -0
- package/dist/assets/csharp-Co3qMtFm.js +1 -0
- package/dist/assets/csp-D-4FJmMZ.js +1 -0
- package/dist/assets/css-DdJfP1eB.js +3 -0
- package/dist/assets/css.worker-DBVD8oXr.js +93 -0
- package/dist/assets/cssMode-BgkzAyoH.js +1 -0
- package/dist/assets/cypher-cTPe9QuQ.js +1 -0
- package/dist/assets/dart-BOtBlQCF.js +1 -0
- package/dist/assets/dockerfile-BG73LgW2.js +1 -0
- package/dist/assets/ecl-BEgZUVRK.js +1 -0
- package/dist/assets/elixir-BkW5O-1t.js +1 -0
- package/dist/assets/flow9-BeJ5waoc.js +1 -0
- package/dist/assets/freemarker2-D05KrEgD.js +3 -0
- package/dist/assets/fsharp-PahG7c26.js +1 -0
- package/dist/assets/go-acbASCJo.js +1 -0
- package/dist/assets/graphql-BxJiqAUM.js +1 -0
- package/dist/assets/handlebars-CmNF6dIr.js +1 -0
- package/dist/assets/hcl-DtV1sZF8.js +1 -0
- package/dist/assets/html-DdFfMtqo.js +1 -0
- package/dist/assets/html.worker-CwpTb9lJ.js +470 -0
- package/dist/assets/htmlMode-BzENSv3x.js +1 -0
- package/dist/assets/index-C6yQ9VSx.js +1595 -0
- package/dist/assets/index-CmAJnnOw.css +1 -0
- package/dist/assets/ini-Kd9XrMLS.js +1 -0
- package/dist/assets/java-CXBNlu9o.js +1 -0
- package/dist/assets/javascript-BDq34vkg.js +1 -0
- package/dist/assets/json.worker-BoL8UZqY.js +58 -0
- package/dist/assets/jsonMode-xsVJWt4Q.js +7 -0
- package/dist/assets/julia-cl7-CwDS.js +1 -0
- package/dist/assets/kotlin-s7OhZKlX.js +1 -0
- package/dist/assets/less-9HpZscsL.js +2 -0
- package/dist/assets/lexon-OrD6JF1K.js +1 -0
- package/dist/assets/liquid-BKLduW-j.js +1 -0
- package/dist/assets/lspLanguageFeatures-DENz5XIL.js +4 -0
- package/dist/assets/lua-Cyyb5UIc.js +1 -0
- package/dist/assets/m3-B8OfTtLu.js +1 -0
- package/dist/assets/markdown-BFxVWTOG.js +1 -0
- package/dist/assets/mdx-Cpg3g8iv.js +1 -0
- package/dist/assets/mips-CiqrrVzr.js +1 -0
- package/dist/assets/msdax-DmeGPVcC.js +1 -0
- package/dist/assets/mysql-C_tMU-Nz.js +1 -0
- package/dist/assets/objective-c-BDtDVThU.js +1 -0
- package/dist/assets/pascal-vHIfCaH5.js +1 -0
- package/dist/assets/pascaligo-DtZ0uQbO.js +1 -0
- package/dist/assets/perl-Ub6l9XKa.js +1 -0
- package/dist/assets/pgsql-BlNEE0v7.js +1 -0
- package/dist/assets/php-BBUBE1dy.js +1 -0
- package/dist/assets/pla-DSh2-awV.js +1 -0
- package/dist/assets/postiats-CocnycG-.js +1 -0
- package/dist/assets/powerquery-tScXyioY.js +1 -0
- package/dist/assets/powershell-COWaemsV.js +1 -0
- package/dist/assets/protobuf-Brw8urJB.js +2 -0
- package/dist/assets/pug-8SOpv6rk.js +1 -0
- package/dist/assets/python-Ca2JvAvf.js +1 -0
- package/dist/assets/qsharp-Bw9ernYp.js +1 -0
- package/dist/assets/r-j7ic8hl3.js +1 -0
- package/dist/assets/razor-B_xld0Yq.js +1 -0
- package/dist/assets/redis-Bu5POkcn.js +1 -0
- package/dist/assets/redshift-Bs9aos_-.js +1 -0
- package/dist/assets/restructuredtext-CqXO7rUv.js +1 -0
- package/dist/assets/ruby-zBfavPgS.js +1 -0
- package/dist/assets/rust-BzKRNQWT.js +1 -0
- package/dist/assets/sb-BBc9UKZt.js +1 -0
- package/dist/assets/scala-D9hQfWCl.js +1 -0
- package/dist/assets/scheme-BPhDTwHR.js +1 -0
- package/dist/assets/scss-CBJaRo0y.js +3 -0
- package/dist/assets/shell-DiJ1NA_G.js +1 -0
- package/dist/assets/solidity-Db0IVjzk.js +1 -0
- package/dist/assets/sophia-CnS9iZB_.js +1 -0
- package/dist/assets/sparql-CJmd_6j2.js +1 -0
- package/dist/assets/sql-ClhHkBeG.js +1 -0
- package/dist/assets/st-CHwy0fLd.js +1 -0
- package/dist/assets/swift-CnmFD0ga.js +1 -0
- package/dist/assets/systemverilog-Bs9z6M-B.js +1 -0
- package/dist/assets/tcl-Dm6ycUr_.js +1 -0
- package/dist/assets/ts.worker-BH9nVgjN.js +67718 -0
- package/dist/assets/tsMode-BinQkqy9.js +11 -0
- package/dist/assets/twig-Csy3S7wG.js +1 -0
- package/dist/assets/typescript-DQO38ZbJ.js +1 -0
- package/dist/assets/typespec-Btyra-wh.js +1 -0
- package/dist/assets/vb-Db0cS2oM.js +1 -0
- package/dist/assets/wgsl-BTesnYfV.js +298 -0
- package/dist/assets/xml-DF1bgZg2.js +1 -0
- package/dist/assets/yaml-BiNWh9S_.js +1 -0
- package/dist/examples/admin-dashboard.wire +95 -0
- package/dist/examples/analytics-dashboard.wire +65 -0
- package/dist/examples/form-example.wire +50 -0
- package/dist/examples/simple-dashboard.wire +40 -0
- package/dist/examples/simple-multi-screen.wire +30 -0
- package/dist/index.html +2 -2
- package/package.json +5 -3
- package/postcss.config.mjs +3 -1
- package/public/examples/admin-dashboard.wire +95 -0
- package/public/examples/analytics-dashboard.wire +65 -0
- package/public/examples/form-example.wire +50 -0
- package/public/examples/simple-dashboard.wire +40 -0
- package/public/examples/simple-multi-screen.wire +30 -0
- package/src/App.tsx +3 -13
- package/src/components/MonacoEditorComponent.tsx +112 -0
- package/src/components/WireLiveEditor.tsx +729 -0
- package/src/components/WireLiveHeader.tsx +469 -0
- package/src/components/index.ts +5 -0
- package/src/hooks/useCanvasZoom.ts +137 -0
- package/src/hooks/useFileSystemAccess.ts +123 -0
- package/src/hooks/useWireParser.ts +222 -0
- package/src/index.css +1 -3
- package/src/main.tsx +7 -5
- package/src/monaco/wireLanguage.ts +370 -0
- package/src/store/editorStore.ts +196 -0
- package/src/store/index.ts +2 -0
- package/tailwind.config.js +2 -1
- package/vite.config.ts +17 -0
- package/dist/assets/index-CHiOjnNN.js +0 -9
- package/dist/assets/index-CUIy2zPc.css +0 -1
- package/src/App.js +0 -4
- package/src/main.js +0 -6
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { useCallback, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
declare global {
|
|
4
|
+
interface Window {
|
|
5
|
+
showOpenFilePicker?: (options?: any) => Promise<FileSystemFileHandle[]>;
|
|
6
|
+
showSaveFilePicker?: (options?: any) => Promise<FileSystemFileHandle>;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface FileSystemFileHandle {
|
|
11
|
+
name: string;
|
|
12
|
+
getFile(): Promise<File>;
|
|
13
|
+
createWritable(): Promise<FileSystemWritableFileStream>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface FileSystemWritableFileStream {
|
|
17
|
+
write(data: string | ArrayBuffer | Blob): Promise<void>;
|
|
18
|
+
close(): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface FileHandle {
|
|
22
|
+
name: string;
|
|
23
|
+
handle: FileSystemFileHandle;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface UseFileSystemAccessReturn {
|
|
27
|
+
fileHandle: FileHandle | null;
|
|
28
|
+
setFileHandle: (handle: FileHandle | null) => void;
|
|
29
|
+
openFile: () => Promise<{ name: string; content: string; handle: FileSystemFileHandle } | null>;
|
|
30
|
+
saveFile: (content: string) => Promise<boolean>;
|
|
31
|
+
saveFileAs: (content: string, suggestedName?: string) => Promise<{ name: string; handle: FileSystemFileHandle } | false | null>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const useFileSystemAccess = (): UseFileSystemAccessReturn => {
|
|
35
|
+
const [fileHandle, setFileHandle] = useState<FileHandle | null>(null);
|
|
36
|
+
|
|
37
|
+
const openFile = useCallback(async (): Promise<{ name: string; content: string; handle: FileSystemFileHandle } | null> => {
|
|
38
|
+
try {
|
|
39
|
+
const handles = await (window.showOpenFilePicker as any)({
|
|
40
|
+
types: [
|
|
41
|
+
{
|
|
42
|
+
description: 'Wire Files',
|
|
43
|
+
accept: { 'text/plain': ['.wire'] },
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
multiple: false,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
if (handles.length === 0) return null;
|
|
50
|
+
|
|
51
|
+
const handle = handles[0];
|
|
52
|
+
const file = await handle.getFile();
|
|
53
|
+
const content = await file.text();
|
|
54
|
+
|
|
55
|
+
setFileHandle({ name: file.name, handle });
|
|
56
|
+
return { name: file.name, content, handle };
|
|
57
|
+
} catch (error) {
|
|
58
|
+
if (error instanceof DOMException && error.name !== 'AbortError') {
|
|
59
|
+
console.error('Error opening file:', error);
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}, []);
|
|
64
|
+
|
|
65
|
+
const saveFile = useCallback(
|
|
66
|
+
async (content: string): Promise<boolean> => {
|
|
67
|
+
if (!fileHandle) return false;
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
const writable = await fileHandle.handle.createWritable();
|
|
71
|
+
await writable.write(content);
|
|
72
|
+
await writable.close();
|
|
73
|
+
return true;
|
|
74
|
+
} catch (error) {
|
|
75
|
+
console.error('Error saving file:', error);
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
[fileHandle]
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
const saveFileAs = useCallback(
|
|
83
|
+
async (content: string, suggestedName?: string): Promise<{ name: string; handle: FileSystemFileHandle } | false | null> => {
|
|
84
|
+
try {
|
|
85
|
+
const handle = await (window.showSaveFilePicker as any)({
|
|
86
|
+
types: [
|
|
87
|
+
{
|
|
88
|
+
description: 'Wire Files',
|
|
89
|
+
accept: { 'text/plain': ['.wire'] },
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
suggestedName: suggestedName || 'untitled.wire',
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
const writable = await handle.createWritable();
|
|
96
|
+
await writable.write(content);
|
|
97
|
+
await writable.close();
|
|
98
|
+
|
|
99
|
+
setFileHandle({ name: handle.name, handle });
|
|
100
|
+
return { name: handle.name, handle };
|
|
101
|
+
} catch (error) {
|
|
102
|
+
// Usuario canceló el diálogo
|
|
103
|
+
if (error instanceof DOMException && error.name === 'AbortError') {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
// Error real
|
|
107
|
+
if (error instanceof DOMException && error.name !== 'AbortError') {
|
|
108
|
+
console.error('Error saving file:', error);
|
|
109
|
+
}
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
[]
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
fileHandle,
|
|
118
|
+
setFileHandle,
|
|
119
|
+
openFile,
|
|
120
|
+
saveFile,
|
|
121
|
+
saveFileAs,
|
|
122
|
+
};
|
|
123
|
+
};
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
parseWireDSL,
|
|
4
|
+
generateIR,
|
|
5
|
+
calculateLayout,
|
|
6
|
+
renderToSVG,
|
|
7
|
+
} from '@wire-dsl/engine';
|
|
8
|
+
import type { IRContract } from '@wire-dsl/engine';
|
|
9
|
+
|
|
10
|
+
export interface WireRenderResult {
|
|
11
|
+
svg: string;
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
projectName: string;
|
|
15
|
+
screenCount: number;
|
|
16
|
+
componentCount: number;
|
|
17
|
+
screens: Array<{ name: string; id: string }>;
|
|
18
|
+
selectedScreenName: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface WireDiagnostic {
|
|
22
|
+
line: number;
|
|
23
|
+
column: number;
|
|
24
|
+
message: string;
|
|
25
|
+
severity: 'error' | 'warning';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Hook to parse Wire DSL code and render to SVG
|
|
30
|
+
*
|
|
31
|
+
* Uses @wire-dsl/engine for parsing, IR generation, layout calculation, and rendering.
|
|
32
|
+
* All operations run in the browser (engine is pure JS/TS with no Node.js dependencies).
|
|
33
|
+
*
|
|
34
|
+
* Pipeline:
|
|
35
|
+
* 1. Parse DSL code to AST using Chevrotain parser
|
|
36
|
+
* 2. Generate IR (Intermediate Representation) with validation
|
|
37
|
+
* 3. Calculate layout positions and dimensions
|
|
38
|
+
* 4. Render to SVG with all visual properties
|
|
39
|
+
*/
|
|
40
|
+
export function useWireParser(code: string, selectedScreenName?: string | null) {
|
|
41
|
+
const [renderResult, setRenderResult] = useState<WireRenderResult | null>(null);
|
|
42
|
+
const [diagnostics, setDiagnostics] = useState<WireDiagnostic[]>([]);
|
|
43
|
+
const [renderState, setRenderState] = useState<'idle' | 'parsing' | 'rendering'>('idle');
|
|
44
|
+
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
if (!code || code.trim().length === 0) {
|
|
47
|
+
setRenderResult(null);
|
|
48
|
+
setDiagnostics([]);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const processWireCode = async () => {
|
|
53
|
+
try {
|
|
54
|
+
setRenderState('parsing');
|
|
55
|
+
const errors: WireDiagnostic[] = [];
|
|
56
|
+
|
|
57
|
+
// 1. Parse DSL to AST
|
|
58
|
+
let ast;
|
|
59
|
+
try {
|
|
60
|
+
ast = parseWireDSL(code);
|
|
61
|
+
} catch (parseError) {
|
|
62
|
+
const message =
|
|
63
|
+
parseError instanceof Error
|
|
64
|
+
? parseError.message
|
|
65
|
+
: 'Failed to parse Wire DSL';
|
|
66
|
+
errors.push({
|
|
67
|
+
line: 1,
|
|
68
|
+
column: 1,
|
|
69
|
+
message,
|
|
70
|
+
severity: 'error',
|
|
71
|
+
});
|
|
72
|
+
setDiagnostics(errors);
|
|
73
|
+
setRenderResult(null);
|
|
74
|
+
setRenderState('idle');
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// 2. Generate IR
|
|
79
|
+
let ir: IRContract;
|
|
80
|
+
try {
|
|
81
|
+
ir = generateIR(ast);
|
|
82
|
+
} catch (irError) {
|
|
83
|
+
const message =
|
|
84
|
+
irError instanceof Error
|
|
85
|
+
? irError.message
|
|
86
|
+
: 'Failed to generate IR';
|
|
87
|
+
errors.push({
|
|
88
|
+
line: 1,
|
|
89
|
+
column: 1,
|
|
90
|
+
message,
|
|
91
|
+
severity: 'error',
|
|
92
|
+
});
|
|
93
|
+
setDiagnostics(errors);
|
|
94
|
+
setRenderResult(null);
|
|
95
|
+
setRenderState('idle');
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// 3. Calculate layout
|
|
100
|
+
setRenderState('rendering');
|
|
101
|
+
let layout;
|
|
102
|
+
try {
|
|
103
|
+
layout = calculateLayout(ir);
|
|
104
|
+
} catch (layoutError) {
|
|
105
|
+
const message =
|
|
106
|
+
layoutError instanceof Error
|
|
107
|
+
? layoutError.message
|
|
108
|
+
: 'Failed to calculate layout';
|
|
109
|
+
errors.push({
|
|
110
|
+
line: 1,
|
|
111
|
+
column: 1,
|
|
112
|
+
message,
|
|
113
|
+
severity: 'error',
|
|
114
|
+
});
|
|
115
|
+
setDiagnostics(errors);
|
|
116
|
+
setRenderResult(null);
|
|
117
|
+
setRenderState('idle');
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// 4. Render to SVG
|
|
122
|
+
let svgOutput: string;
|
|
123
|
+
const screenToRender = selectedScreenName
|
|
124
|
+
? ir.project.screens.find((s) => s.name === selectedScreenName)
|
|
125
|
+
: null;
|
|
126
|
+
|
|
127
|
+
const screenName = screenToRender?.name || ir.project.screens[0]?.name;
|
|
128
|
+
|
|
129
|
+
try {
|
|
130
|
+
svgOutput = renderToSVG(ir, layout, { screenName });
|
|
131
|
+
} catch (renderError) {
|
|
132
|
+
const message =
|
|
133
|
+
renderError instanceof Error
|
|
134
|
+
? renderError.message
|
|
135
|
+
: 'Failed to render SVG';
|
|
136
|
+
errors.push({
|
|
137
|
+
line: 1,
|
|
138
|
+
column: 1,
|
|
139
|
+
message,
|
|
140
|
+
severity: 'error',
|
|
141
|
+
});
|
|
142
|
+
setDiagnostics(errors);
|
|
143
|
+
setRenderResult(null);
|
|
144
|
+
setRenderState('idle');
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Success: extract metadata and set result
|
|
149
|
+
const screenCount = ir.project.screens.length;
|
|
150
|
+
const componentCount = ir.project.screens.reduce(
|
|
151
|
+
(total: number, screen: any) => total + countComponents(screen),
|
|
152
|
+
0
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
// Get dimensions for the rendered screen
|
|
156
|
+
const renderedScreen = ir.project.screens.find((s) => s.name === screenName);
|
|
157
|
+
const width = renderedScreen?.viewport.width || 800;
|
|
158
|
+
const height = renderedScreen?.viewport.height || 600;
|
|
159
|
+
|
|
160
|
+
// Build screens list with name and id
|
|
161
|
+
const screens = ir.project.screens.map((screen) => ({
|
|
162
|
+
name: screen.name,
|
|
163
|
+
id: screen.id,
|
|
164
|
+
}));
|
|
165
|
+
|
|
166
|
+
setRenderResult({
|
|
167
|
+
svg: svgOutput,
|
|
168
|
+
width,
|
|
169
|
+
height,
|
|
170
|
+
projectName: ir.project.name,
|
|
171
|
+
screenCount,
|
|
172
|
+
componentCount,
|
|
173
|
+
screens,
|
|
174
|
+
selectedScreenName: screenName,
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
setDiagnostics([]);
|
|
178
|
+
} catch (error) {
|
|
179
|
+
const message =
|
|
180
|
+
error instanceof Error ? error.message : 'Unknown error';
|
|
181
|
+
setDiagnostics([
|
|
182
|
+
{
|
|
183
|
+
line: 1,
|
|
184
|
+
column: 1,
|
|
185
|
+
message,
|
|
186
|
+
severity: 'error',
|
|
187
|
+
},
|
|
188
|
+
]);
|
|
189
|
+
setRenderResult(null);
|
|
190
|
+
} finally {
|
|
191
|
+
setRenderState('idle');
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
processWireCode();
|
|
196
|
+
}, [code, selectedScreenName]);
|
|
197
|
+
|
|
198
|
+
return {
|
|
199
|
+
renderResult,
|
|
200
|
+
diagnostics,
|
|
201
|
+
renderState,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Helper to count components in a screen
|
|
207
|
+
*/
|
|
208
|
+
function countComponents(screen: any): number {
|
|
209
|
+
if (!screen.layout) return 0;
|
|
210
|
+
|
|
211
|
+
let count = 0;
|
|
212
|
+
const countInNode = (node: any) => {
|
|
213
|
+
if (node.type === 'component') {
|
|
214
|
+
count++;
|
|
215
|
+
} else if (node.children) {
|
|
216
|
+
node.children.forEach(countInNode);
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
countInNode(screen.layout);
|
|
221
|
+
return count;
|
|
222
|
+
}
|
package/src/index.css
CHANGED
package/src/main.tsx
CHANGED
|
@@ -2,9 +2,11 @@ import React from 'react';
|
|
|
2
2
|
import ReactDOM from 'react-dom/client';
|
|
3
3
|
import App from './App';
|
|
4
4
|
import './index.css';
|
|
5
|
+
import { registerWireLanguage } from './monaco/wireLanguage';
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
);
|
|
7
|
+
// Registrar lenguaje Wire en Monaco
|
|
8
|
+
registerWireLanguage();
|
|
9
|
+
|
|
10
|
+
// Render app
|
|
11
|
+
const root = ReactDOM.createRoot(document.getElementById('root')!);
|
|
12
|
+
root.render(<App />);
|