mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-25 12:38:35 +00:00
move haskell-tree-sitter-playground
This commit is contained in:
parent
2aac085bb8
commit
09e455e17e
2
packages/haskell/.gitignore
vendored
2
packages/haskell/.gitignore
vendored
@ -25,5 +25,3 @@ dist-ssr
|
|||||||
|
|
||||||
public/tree-sitter.wasm
|
public/tree-sitter.wasm
|
||||||
public/tree-sitter-haskell.wasm
|
public/tree-sitter-haskell.wasm
|
||||||
public/tree-sitter-haskell_mine.wasm
|
|
||||||
public/tree-sitter-haskell_theirs.wasm
|
|
||||||
@ -1,31 +1,11 @@
|
|||||||
# @strudel/haskell
|
# @strudel/tidal
|
||||||
|
|
||||||
This is an experiment in implementing tree-sitter for parsing haskell.
|
This is an experiment in implementing tree-sitter for parsing haskell.
|
||||||
|
|
||||||
So far, I have just set up a vite project that imports and inits `web-tree-sitter`, which works after
|
|
||||||
|
|
||||||
- <https://github.com/tree-sitter/tree-sitter/issues/2831>
|
|
||||||
- <https://github.com/tree-sitter/tree-sitter/pull/2830>
|
|
||||||
|
|
||||||
Running:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cd haskell && pnpm i
|
pnpm i
|
||||||
|
cd haskell
|
||||||
pnpm dev
|
pnpm dev
|
||||||
```
|
```
|
||||||
|
|
||||||
will start the vite dev server, loading tree sitter on `http://localhost:5174/`.
|
This
|
||||||
|
|
||||||
The next step is be to generate `tree-sitter-haskell.wasm` file following <https://www.npmjs.com/package/web-tree-sitter#generate-wasm-language-files>.
|
|
||||||
|
|
||||||
I've tried to generate it using <https://www.npmjs.com/package/tree-sitter-haskell> but it failed, due to some versioning conflicts involving node / v8 / node-gyp.
|
|
||||||
|
|
||||||
It seems a lot of work has gone into this package in <https://github.com/tree-sitter/tree-sitter-haskell/pull/29>, without a new npm package version being released, which is why I've written this comment: <https://github.com/tree-sitter/tree-sitter-haskell/pull/29#issuecomment-1865951565>.
|
|
||||||
|
|
||||||
So either someone authorized releases a new version of the package or we might need to pull the changes and try to build it from the tree-sitter master branch.
|
|
||||||
|
|
||||||
## Update 1
|
|
||||||
|
|
||||||
I've managed to make it work by using [this tree-sitter-haskell.wasm](https://github.com/tree-sitter/tree-sitter-haskell/blob/master/tree-sitter-haskell.wasm), instead of using the version on npm! Make sure both `tree-sitter.wasm` and `tree-sitter-haskell.wasm` are in the public dir, then run `pnpm dev`. The console should log a tree sitter AST string.
|
|
||||||
|
|
||||||
Next step: understand how the ast works to then transform it into JS function calls!
|
|
||||||
43
packages/haskell/graph.mjs
Normal file
43
packages/haskell/graph.mjs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import { Graphviz } from '@hpcc-js/wasm';
|
||||||
|
import toDot from 'jgf-dot';
|
||||||
|
|
||||||
|
const graphvizLoaded = Graphviz.load();
|
||||||
|
|
||||||
|
function walk(node, branch = [0], parent) {
|
||||||
|
let nodes = [];
|
||||||
|
let edges = [];
|
||||||
|
const color = 'white';
|
||||||
|
const current = {
|
||||||
|
id: branch.join('-'),
|
||||||
|
color,
|
||||||
|
fontcolor: color,
|
||||||
|
label: node.type.replace('\\', 'lambda'), // backslash kills graphviz..
|
||||||
|
};
|
||||||
|
nodes.push(current);
|
||||||
|
parent && edges.push({ source: parent.id, target: current.id, color });
|
||||||
|
if (node.children.length) {
|
||||||
|
node.children.forEach((child, j) => {
|
||||||
|
const { nodes: childNodes, edges: childEdges } = walk(child, branch.concat([j]), current);
|
||||||
|
nodes = nodes.concat(childNodes || []);
|
||||||
|
edges = edges.concat(childEdges || []);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return { nodes, edges };
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function renderGraph(tree, container) {
|
||||||
|
const { nodes, edges } = walk(tree.rootNode);
|
||||||
|
const graphviz = await graphvizLoaded;
|
||||||
|
let dot = toDot({
|
||||||
|
graph: {
|
||||||
|
nodes,
|
||||||
|
edges,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
dot = dot.split('\n');
|
||||||
|
dot.splice(1, 0, 'bgcolor="transparent"');
|
||||||
|
dot.splice(1, 0, 'color="white"');
|
||||||
|
dot = dot.join('\n');
|
||||||
|
const svg = await graphviz.layout(dot, 'svg', 'dot', {});
|
||||||
|
container.innerHTML = svg;
|
||||||
|
}
|
||||||
131
packages/haskell/hs2js.mjs
Normal file
131
packages/haskell/hs2js.mjs
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
function runApply(node, scope, ops) {
|
||||||
|
if (node.children.length !== 2)
|
||||||
|
throw new Error(`expected 2 children for node type apply, got ${node.children.length}`);
|
||||||
|
const [fn, arg] = node.children.map((child) => run(child, scope, ops));
|
||||||
|
if (typeof fn !== 'function') {
|
||||||
|
throw new Error(`${node.children[0].text} is not a function`);
|
||||||
|
}
|
||||||
|
// only works if fn is curried!
|
||||||
|
return fn(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
function runInfix(left, symbol, right, ops) {
|
||||||
|
const customOp = ops[symbol];
|
||||||
|
if (customOp) {
|
||||||
|
return customOp(left, right);
|
||||||
|
}
|
||||||
|
switch (symbol) {
|
||||||
|
case '+':
|
||||||
|
return left + right;
|
||||||
|
case '-':
|
||||||
|
return left - right;
|
||||||
|
case '*':
|
||||||
|
return left * right;
|
||||||
|
case '/':
|
||||||
|
return left / right;
|
||||||
|
case '$':
|
||||||
|
return left(right);
|
||||||
|
case '&':
|
||||||
|
console.log('right', right);
|
||||||
|
return right(left);
|
||||||
|
case '.':
|
||||||
|
return (x) => left(right(x));
|
||||||
|
default:
|
||||||
|
throw new Error('unexpected infix operator ' + symbol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function curry(patterns, body, scope, ops) {
|
||||||
|
const [variable, ...rest] = patterns;
|
||||||
|
return (arg) => {
|
||||||
|
let _scope = { ...scope, [variable.text]: arg };
|
||||||
|
if (patterns.length === 1) {
|
||||||
|
const result = run(body, _scope, ops);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return curry(rest, body, _scope, ops);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function run(node, scope, ops = {}) {
|
||||||
|
let runInScope = (node, scp = scope) => run(node, scp, ops);
|
||||||
|
//console.log("node", node.type, node.text);
|
||||||
|
switch (node.type) {
|
||||||
|
case 'ERROR':
|
||||||
|
throw new Error(`invalid syntax: "${node.text}"`);
|
||||||
|
case 'declarations':
|
||||||
|
let result;
|
||||||
|
node.children.forEach((declaration) => {
|
||||||
|
result = runInScope(declaration);
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
case 'integer':
|
||||||
|
return Number(node.text);
|
||||||
|
case 'float':
|
||||||
|
return Number(node.text);
|
||||||
|
case 'string':
|
||||||
|
const str = node.text.slice(1, -1);
|
||||||
|
return String(str);
|
||||||
|
case 'lambda':
|
||||||
|
const [_, lpatterns, __, lbody] = node.children;
|
||||||
|
return curry(lpatterns.children, lbody, scope, ops);
|
||||||
|
case 'function':
|
||||||
|
const [fvariable, fpatterns, fbody] = node.children;
|
||||||
|
scope[fvariable.text] = curry(fpatterns.children, fbody, scope, ops);
|
||||||
|
return scope[fvariable.text];
|
||||||
|
case 'list': {
|
||||||
|
return node.children
|
||||||
|
.filter((_, i) => i % 2 === 1) // elements are at odd indices
|
||||||
|
.map((node) => runInScope(node));
|
||||||
|
}
|
||||||
|
case 'match':
|
||||||
|
if (node.children[0].text !== '=' || node.children.length !== 2) {
|
||||||
|
throw new Error('match node so far only support simple assignments');
|
||||||
|
}
|
||||||
|
return runInScope(node.children[1]);
|
||||||
|
case 'bind':
|
||||||
|
if (node.children.length !== 2) throw new Error('expected 2 children for node type bind');
|
||||||
|
if (node.children[0].type !== 'variable') throw new Error('expected variable as first child of bind node');
|
||||||
|
if (node.children[1].type !== 'match') throw new Error('expected match as first child of bind node');
|
||||||
|
const [bvariable, bmatch] = node.children;
|
||||||
|
const value = runInScope(bmatch);
|
||||||
|
scope[bvariable.text] = value;
|
||||||
|
return value;
|
||||||
|
case 'variable':
|
||||||
|
return scope[node.text];
|
||||||
|
case 'infix': {
|
||||||
|
const [a, op, b] = node.children;
|
||||||
|
const symbol = op.text;
|
||||||
|
const [left, right] = [runInScope(a), runInScope(b)];
|
||||||
|
return runInfix(left, symbol, right, ops);
|
||||||
|
}
|
||||||
|
case 'apply':
|
||||||
|
return runApply(node, scope, ops);
|
||||||
|
case 'left_section': {
|
||||||
|
const [_, b, op] = node.children;
|
||||||
|
const right = runInScope(b);
|
||||||
|
return (left) => runInfix(left, op.text, right, ops);
|
||||||
|
}
|
||||||
|
case 'right_section': {
|
||||||
|
const [_, op, b] = node.children;
|
||||||
|
const right = runInScope(b);
|
||||||
|
return (left) => runInfix(left, op.text, right, ops);
|
||||||
|
}
|
||||||
|
case 'parens':
|
||||||
|
if (node.children.length !== 3) throw new Error('expected 3 children for node type parens');
|
||||||
|
return runInScope(node.children[1]);
|
||||||
|
default:
|
||||||
|
if (node.children.length === 0) {
|
||||||
|
throw new Error('unhandled leaf type ' + node.type);
|
||||||
|
}
|
||||||
|
if (node.children.length > 1) {
|
||||||
|
throw new Error('unhandled branch type ' + node.type);
|
||||||
|
}
|
||||||
|
return runInScope(node.children[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function evaluate(haskellCode, scope = globalThis, ops) {
|
||||||
|
const ast = await parse(haskellCode);
|
||||||
|
return run(ast.rootNode, scope, ops);
|
||||||
|
}
|
||||||
@ -2,13 +2,28 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Tree sitter test</title>
|
<title>Tree sitter test</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: #121213;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
textarea {
|
||||||
|
padding: 10px;
|
||||||
|
color: white;
|
||||||
|
background-color: transparent;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body style="padding: 0; margin: 0">
|
<body style="margin: 0; padding: 0">
|
||||||
<textarea id="code" style="width: 100%; height: 100px"></textarea>
|
<textarea id="code" style="width: 100%; height: 200px"></textarea>
|
||||||
<div id="graph" style="display: flex; width: 100%"></div>
|
<pre id="result"></pre>
|
||||||
|
<div id="graph" style="display: flex; width: 100%; margin: auto; justify-content: center"></div>
|
||||||
<script type="module" src="/main.js"></script>
|
<script type="module" src="/main.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -1,51 +1,89 @@
|
|||||||
import Parser from 'web-tree-sitter';
|
import { run } from './hs2js.mjs';
|
||||||
import toDot from 'jgf-dot';
|
import { renderGraph } from './graph.mjs';
|
||||||
import { Graphviz } from '@hpcc-js/wasm';
|
import { parse } from './parser.mjs';
|
||||||
|
import { initStrudel, reify, late } from '@strudel/web';
|
||||||
|
initStrudel({
|
||||||
|
prebake: () => samples('github:tidalcycles/dirt-samples'),
|
||||||
|
});
|
||||||
|
|
||||||
const graphvizLoaded = Graphviz.load();
|
|
||||||
const parserLoaded = loadParser();
|
|
||||||
const graphContainer = document.getElementById('graph');
|
const graphContainer = document.getElementById('graph');
|
||||||
|
|
||||||
const textarea = document.getElementById('code');
|
const textarea = document.getElementById('code');
|
||||||
textarea.value = 'd1 $ s "hh(3,8)"';
|
if (window.location.hash) {
|
||||||
textarea.addEventListener('input', (e) => renderGraph(e.target.value, graphContainer));
|
textarea.value = atob(window.location.hash.slice(1));
|
||||||
renderGraph(textarea.value, graphContainer);
|
} else {
|
||||||
|
textarea.value = 'd1 $ s "jvbass(3,8)"';
|
||||||
|
}
|
||||||
|
textarea.addEventListener('input', (e) => {
|
||||||
|
window.location.hash = btoa(e.target.value);
|
||||||
|
update();
|
||||||
|
});
|
||||||
|
update();
|
||||||
|
|
||||||
function walk(node, branch = [0], parent) {
|
function getInfixOperators() {
|
||||||
let nodes = [];
|
let operators = {
|
||||||
let edges = [];
|
'>': 'set',
|
||||||
const current = { id: branch.join('-'), label: node.type };
|
'#': 'set',
|
||||||
nodes.push(current);
|
'+': 'add',
|
||||||
parent && edges.push({ source: parent.id, target: current.id });
|
'-': 'sub',
|
||||||
if (node.children.length) {
|
'*': 'mul',
|
||||||
node.children.forEach((child, j) => {
|
'/': 'div',
|
||||||
const { nodes: childNodes, edges: childEdges } = walk(child, branch.concat([j]), current);
|
};
|
||||||
nodes = nodes.concat(childNodes || []);
|
let alignments = {
|
||||||
edges = edges.concat(childEdges || []);
|
in: (s) => '|' + s,
|
||||||
|
out: (s) => s + '|',
|
||||||
|
mix: (s) => '|' + s + '|',
|
||||||
|
};
|
||||||
|
let ops = {};
|
||||||
|
Object.entries(operators).forEach(([o, name]) => {
|
||||||
|
// operator without alignment
|
||||||
|
ops[o] = (l, r) => reify(l)[name](reify(r));
|
||||||
|
Object.entries(alignments).forEach(([a, getSymbol]) => {
|
||||||
|
// get symbol with alignment
|
||||||
|
let symbol = getSymbol(o);
|
||||||
|
ops[symbol] = (l, r) => reify(l)[name][a](reify(r));
|
||||||
});
|
});
|
||||||
}
|
|
||||||
return { nodes, edges };
|
|
||||||
}
|
|
||||||
|
|
||||||
async function renderGraph(code, container) {
|
|
||||||
const parser = await parserLoaded;
|
|
||||||
const tree = parser.parse(code);
|
|
||||||
const { nodes, edges } = walk(tree.rootNode);
|
|
||||||
const graphviz = await graphvizLoaded;
|
|
||||||
const dot = toDot({
|
|
||||||
graph: {
|
|
||||||
nodes,
|
|
||||||
edges,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
const svg = await graphviz.layout(dot, 'svg', 'dot');
|
ops['~>'] = (l, r) => reify(l).late(reify(r));
|
||||||
container.innerHTML = svg;
|
ops['<~'] = (l, r) => reify(l).early(reify(r));
|
||||||
|
ops['<$>'] = (l, r) => reify(r).fmap(l).outerJoin(); // is this right?
|
||||||
|
return ops;
|
||||||
}
|
}
|
||||||
|
const ops = getInfixOperators();
|
||||||
|
|
||||||
async function loadParser() {
|
async function update() {
|
||||||
await Parser.init();
|
let result, tree;
|
||||||
const parser = new Parser();
|
try {
|
||||||
const Lang = await Parser.Language.load('tree-sitter-haskell.wasm');
|
tree = await parse(textarea.value);
|
||||||
parser.setLanguage(Lang);
|
} catch (err) {
|
||||||
return parser;
|
console.warn('parse error');
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
console.log('parsed tree');
|
||||||
|
console.log(tree.rootNode.toString());
|
||||||
|
try {
|
||||||
|
renderGraph(tree, graphContainer);
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('could not render graph');
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
let patterns = {};
|
||||||
|
window.p = (name, pattern) => {
|
||||||
|
patterns[name] = pattern;
|
||||||
|
};
|
||||||
|
window.d1 = (pat) => window.p(1, pat);
|
||||||
|
window.d2 = (pat) => window.p(2, pat);
|
||||||
|
window.d3 = (pat) => window.p(3, pat);
|
||||||
|
window.rot = late;
|
||||||
|
result = run(tree.rootNode, window, ops);
|
||||||
|
if (Object.values(patterns).length) {
|
||||||
|
stack(...Object.values(patterns)).play();
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('eval error');
|
||||||
|
console.error(err);
|
||||||
|
result = 'ERROR: ' + err.message;
|
||||||
|
}
|
||||||
|
document.getElementById('result').innerHTML = 'Result: ' + result;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,24 +1,42 @@
|
|||||||
{
|
{
|
||||||
"name": "haskell",
|
"name": "@strudel/tidal",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.0",
|
"version": "0.0.1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"postinstall": "cp node_modules/web-tree-sitter/tree-sitter.wasm public",
|
"postinstall": "cp node_modules/web-tree-sitter/tree-sitter.wasm public && npm run build:parser",
|
||||||
"parse": "tree-sitter parse -D ./test.hs"
|
"build:parser": "tree-sitter build-wasm node_modules/tree-sitter-haskell && mv tree-sitter-haskell.wasm public"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"repository": {
|
||||||
"tree-sitter": "^0.20.6",
|
"type": "git",
|
||||||
"tree-sitter-cli": "^0.20.8",
|
"url": "git+https://github.com/tidalcycles/strudel.git"
|
||||||
"tree-sitter-javascript": "^0.20.1",
|
|
||||||
"vite": "^5.0.8"
|
|
||||||
},
|
},
|
||||||
|
"keywords": [
|
||||||
|
"titdalcycles",
|
||||||
|
"strudel",
|
||||||
|
"pattern",
|
||||||
|
"livecoding",
|
||||||
|
"algorave"
|
||||||
|
],
|
||||||
|
"author": "Felix Roos <flix91@gmail.com>",
|
||||||
|
"license": "AGPL-3.0-or-later",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/tidalcycles/strudel/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/tidalcycles/strudel#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hpcc-js/wasm": "^2.15.3",
|
"@hpcc-js/wasm": "^2.15.3",
|
||||||
"jgf-dot": "^1.1.1",
|
"jgf-dot": "^1.1.1",
|
||||||
"web-tree-sitter": "^0.20.8"
|
"web-tree-sitter": "^0.22.6",
|
||||||
|
"tree-sitter-haskell": "^0.21.0",
|
||||||
|
"@strudel/web": "workspace:*"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"tree-sitter": "^0.21.1",
|
||||||
|
"tree-sitter-cli": "^0.20.8",
|
||||||
|
"vite": "^5.0.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
22
packages/haskell/parser.mjs
Normal file
22
packages/haskell/parser.mjs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import Parser from 'web-tree-sitter';
|
||||||
|
|
||||||
|
const base = import.meta.env.BASE_URL;
|
||||||
|
|
||||||
|
async function loadParser() {
|
||||||
|
await Parser.init({
|
||||||
|
locateFile(scriptName, scriptDirectory) {
|
||||||
|
return `${base}${scriptName}`;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const parser = new Parser();
|
||||||
|
const Lang = await Parser.Language.load(`${base}tree-sitter-haskell.wasm`);
|
||||||
|
parser.setLanguage(Lang);
|
||||||
|
return parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
let parserLoaded = loadParser();
|
||||||
|
export async function parse(code) {
|
||||||
|
const parser = await parserLoaded;
|
||||||
|
// for some reason, the parser doesn't like new lines..
|
||||||
|
return parser.parse(code.replaceAll('\n\n', '~~~~').replaceAll('\n', '').replaceAll('~~~~', '\n'));
|
||||||
|
}
|
||||||
58
pnpm-lock.yaml
generated
58
pnpm-lock.yaml
generated
@ -256,22 +256,25 @@ importers:
|
|||||||
'@hpcc-js/wasm':
|
'@hpcc-js/wasm':
|
||||||
specifier: ^2.15.3
|
specifier: ^2.15.3
|
||||||
version: 2.16.2
|
version: 2.16.2
|
||||||
|
'@strudel/web':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../web
|
||||||
jgf-dot:
|
jgf-dot:
|
||||||
specifier: ^1.1.1
|
specifier: ^1.1.1
|
||||||
version: 1.1.1
|
version: 1.1.1
|
||||||
|
tree-sitter-haskell:
|
||||||
|
specifier: ^0.21.0
|
||||||
|
version: 0.21.0(tree-sitter@0.21.1)
|
||||||
web-tree-sitter:
|
web-tree-sitter:
|
||||||
specifier: ^0.20.8
|
specifier: ^0.22.6
|
||||||
version: 0.20.8
|
version: 0.22.6
|
||||||
devDependencies:
|
devDependencies:
|
||||||
tree-sitter:
|
tree-sitter:
|
||||||
specifier: ^0.20.6
|
specifier: ^0.21.1
|
||||||
version: 0.20.6
|
version: 0.21.1
|
||||||
tree-sitter-cli:
|
tree-sitter-cli:
|
||||||
specifier: ^0.20.8
|
specifier: ^0.20.8
|
||||||
version: 0.20.8
|
version: 0.20.8
|
||||||
tree-sitter-javascript:
|
|
||||||
specifier: ^0.20.1
|
|
||||||
version: 0.20.4
|
|
||||||
vite:
|
vite:
|
||||||
specifier: ^5.0.8
|
specifier: ^5.0.8
|
||||||
version: 5.2.2(@types/node@20.10.6)
|
version: 5.2.2(@types/node@20.10.6)
|
||||||
@ -10660,10 +10663,6 @@ packages:
|
|||||||
thenify-all: 1.6.0
|
thenify-all: 1.6.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/nan@2.19.0:
|
|
||||||
resolution: {integrity: sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/nanoid@3.3.7:
|
/nanoid@3.3.7:
|
||||||
resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
|
resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
|
||||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||||
@ -10719,6 +10718,10 @@ packages:
|
|||||||
semver: 7.5.4
|
semver: 7.5.4
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/node-addon-api@8.0.0:
|
||||||
|
resolution: {integrity: sha512-ipO7rsHEBqa9STO5C5T10fj732ml+5kLN1cAG8/jdHd56ldQeGj3Q7+scUS+VHK/qy1zLEwC4wMK5+yM0btPvw==}
|
||||||
|
engines: {node: ^18 || ^20 || >= 21}
|
||||||
|
|
||||||
/node-domexception@1.0.0:
|
/node-domexception@1.0.0:
|
||||||
resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
|
resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
|
||||||
engines: {node: '>=10.5.0'}
|
engines: {node: '>=10.5.0'}
|
||||||
@ -10762,6 +10765,10 @@ packages:
|
|||||||
engines: {node: '>= 0.6.0'}
|
engines: {node: '>= 0.6.0'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/node-gyp-build@4.8.1:
|
||||||
|
resolution: {integrity: sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
/node-gyp@10.0.1:
|
/node-gyp@10.0.1:
|
||||||
resolution: {integrity: sha512-gg3/bHehQfZivQVfqIyy8wTdSymF9yTyP4CJifK73imyNMU8AIGQE2pUa7dNWfmMeG9cDVF2eehiRMv0LC1iAg==}
|
resolution: {integrity: sha512-gg3/bHehQfZivQVfqIyy8wTdSymF9yTyP4CJifK73imyNMU8AIGQE2pUa7dNWfmMeG9cDVF2eehiRMv0LC1iAg==}
|
||||||
engines: {node: ^16.14.0 || >=18.0.0}
|
engines: {node: ^16.14.0 || >=18.0.0}
|
||||||
@ -13497,20 +13504,27 @@ packages:
|
|||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/tree-sitter-javascript@0.20.4:
|
/tree-sitter-haskell@0.21.0(tree-sitter@0.21.1):
|
||||||
resolution: {integrity: sha512-7IUgGkZQROI7MmX2ErKhE3YP4+rM2qwBy5JeukE7fJQMEYP9nHpxvuQpa+eOX+hE1im2pWVc1yDCfVKKCBtxww==}
|
resolution: {integrity: sha512-b2RLegPHuYPh7nJ3YKWgkWnFYxmYlQDE8TDJuNH+iuNuBcCMYyaA9JlJlMHfCvf7DmJNPtqqbO9Kh9NXEmbatQ==}
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
peerDependencies:
|
||||||
|
tree-sitter: ^0.21.0
|
||||||
|
tree_sitter: '*'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
tree_sitter:
|
||||||
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
nan: 2.19.0
|
node-addon-api: 8.0.0
|
||||||
dev: true
|
node-gyp-build: 4.8.1
|
||||||
|
tree-sitter: 0.21.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/tree-sitter@0.20.6:
|
/tree-sitter@0.21.1:
|
||||||
resolution: {integrity: sha512-GxJodajVpfgb3UREzzIbtA1hyRnTxVbWVXrbC6sk4xTMH5ERMBJk9HJNq4c8jOJeUaIOmLcwg+t6mez/PDvGqg==}
|
resolution: {integrity: sha512-7dxoA6kYvtgWw80265MyqJlkRl4yawIjO7S5MigytjELkX43fV2WsAXzsNfO7sBpPPCF5Gp0+XzHk0DwLCq3xQ==}
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
dependencies:
|
dependencies:
|
||||||
nan: 2.19.0
|
node-addon-api: 8.0.0
|
||||||
prebuild-install: 7.1.1
|
node-gyp-build: 4.8.1
|
||||||
dev: true
|
|
||||||
|
|
||||||
/trim-lines@3.0.1:
|
/trim-lines@3.0.1:
|
||||||
resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
|
resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
|
||||||
@ -14306,8 +14320,8 @@ packages:
|
|||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/web-tree-sitter@0.20.8:
|
/web-tree-sitter@0.22.6:
|
||||||
resolution: {integrity: sha512-weOVgZ3aAARgdnb220GqYuh7+rZU0Ka9k9yfKtGAzEYMa6GgiCzW9JjQRJyCJakvibQW+dfjJdihjInKuuCAUQ==}
|
resolution: {integrity: sha512-hS87TH71Zd6mGAmYCvlgxeGDjqd9GTeqXNqTT+u0Gs51uIozNIaaq/kUAbV/Zf56jb2ZOyG8BxZs2GG9wbLi6Q==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/webidl-conversions@3.0.1:
|
/webidl-conversions@3.0.1:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user