npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@ucod-io/parser

v5.1.7

Published

A parser designed for the UCOD project, capable of ingeniously transforming TypeScript and JSON into a UCOD node structures.

Downloads

737

Readme

UCOD Parser

Description

This parser is designed specifically for UCOD nodes and flows. It efficiently interprets UCOD files, extracting nodes and flows to produce a corresponding JSON representation.

Usage

import { parseNode } from 'mod.ts';
/**
 * For node use
 * import { parseNode } from '@ucod-io/parser'
 */

const parsedNode = parseNode(`
export const $$name = "Addition";
export default (a: number, b: number): number => a + b;
`);
console.log(parsedNode);
{
  "name": "Addition",
  "description": "",
  "state": [],
  "config": [],
  "ports": {
    "flow": { "in": false, "out": [] },
    "data": {
      "in": [
        { "name": "a", "type": "number", "optional": false },
        { "name": "b", "type": "number", "optional": false }
      ],
      "out": [{ "name": "number", "type": "number" }]
    }
  }
}

API

Functions

parseNode

parseNode takes the code of a node as a string and returns a JSON representation of the node.

import { parseNode } from '@ucod-io/parser';
const additionCode = `
export const $$name = "Addition";
export default (a: number, b: number): number => a + b;
`;
const parsedNode = parseNode(additionCode);

parseFlow

parseFlow takes a json representation of the flow and returns a parsed flow JSON.

import { parseFlow } from '@ucod-io/parser';

const flow = {
  name: 'additionFlow',
  version: '1.0.0',
  nodes: [
    {
      id: 'core.math.addition',
      code: addition.code,
    },
    {
      id: 'core.math.randomNumber',
      code: randomNumber.code,
    },
  ],
  connections: [
    ['core.math.randomNumber', 'core.math.addition'],
    ['core.math.randomNumber', 'core.math.addition'],
  ],
};

const parsedFlow = parseFlow(flow);

parseAst

To allow the usage of the parser in the browser, the parser can be used with an AST instead of a string. The AST is generated by @swc/wasm-web.

import { parseAst } from '@ucod-io/parser';
import { useEffect, useState } from 'react';
import initSwc, { parseSync } from '@swc/wasm-web';

export default function App() {
  const [initialized, setInitialized] = useState(false);

  useEffect(() => {
    async function importAndRunSwcOnMount() {
      await initSwc();
      setInitialized(true);
    }
    importAndRunSwcOnMount();
  }, []);

  function parse() {
    if (!initialized) {
      return;
    }
    const additionCode = `
  export const $$name = "Addition";
  export default (a: number, b: number): number => a + b;
  `;
    const result = parseSync(additionCode, {
      syntax: 'typescript',
      target: 'esnext',
      comments: true,
    });
    const ast = result.body;
    const parsedNode = parseAst(ast);
    console.log(parsedNode);
  }

  return (
    <div className='App'>
      <button onClick={parse}>Parse</button>
    </div>
  );
}

parseAst accepts the body of the AST as a parameter. The AST body is the result of the parseSync function of @swc/wasm-web. For more information about the SWC project, please visit the SWC website.

Interfaces

ParsedNode

interface ParsedNode {
  name: string;
  description: string;
  state: ParsedNodeProperty[];
  config: ParsedNodeProperty[];
  ports: {
    flow: {
      in: boolean;
      out: string[];
    };
    data: {
      in: ParsedNodePort[];
      out: ParsedNodePort[];
    };
  };
}

| Field | Type | Description | optional | default value | example | | ----------- | -------------------- | --------------------------------- | -------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------- | | name | string | The name of the node | false | - | 'Addition' | | description | string | The description of the node | true | '' | 'This node adds two numbers' | | state | ParsedNodeProperty[] | The state properties of the node | true | [] | [{name: 'result', type: 'number', optional: false}] | | config | ParsedNodeProperty[] | The config properties of the node | true | [] | [{name: 'result', type: 'number', optional: false}] | | ports | ParsedNodePorts | The ports of the node | false | - | {flow: {in: false, out: []}, data: {in: [{name: 'a', type: 'number', optional: false}], out: [{name: 'result', type: 'number'}]}} |

Examples

Addition

export const $$name = 'Addition';
export const $$description = 'This node adds two numbers';
export default (a: number, b: number): number => a + b;

Http Request

import axios from 'axios';
interface Config {
  method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';
  url: string;
  headers?: Record<string, string>;
}
export const $$name = 'Http Request';
export const $$description = 'Make an HTTP request';
export const $$exec = true;

export const $$config: Config = {
  method: 'GET',
  url: 'https://example.com',
  headers: {
    'Content-Type': 'application/json',
  },
};
export const $$state = {
  data: null,
  error: null,
};
export default async (url?: string, method?: string, [err, suc]: Array<Function>): {
  data: any;
} => {
  const config: Config = {
    method: method || $$config.method,
    url: url || $$config.url,
    headers: $$config.headers,
  };
  try {
    const response = await axios(config);
    $$state.data = response.data;
    suc(response.data);
    return response.data;
  } catch (error) {
    $$state.error = error;
    err(error);
    return error;
  }
};

Importent Notes

Node Name

The Node name is required and must be exported and defined with the $$name variable. And it must be a string.

example

export const $$name = 'Addition';

Node Description

The Node description is optional but if you want to add a description to your node you have to export and define it with the $$description variable. And it must be a string. example:

export const $$description = 'This node adds two numbers';

Node State and Config

The Node state/config is optional but if you want to add a state/config to your node you have to export and define it with the $$state or/and $$config variable(s).

Typing

You can leave the typing of the state/config to the parser. It will automatically detect the type and mark them all as required.

export const $$state = {
  data: null,
  error: null,
};
export const $$config = {
  method: 'GET',
  url: 'https://example.com',
};

Inline Typing

You can also define the type of the state/config using typescript inline typing

export const $$state: {
  data: any;
  error: any;
} = {
  data: null,
  error: null,
};
export const $$config: {
  method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';
  url: string;
} = {
  method: 'GET',
  url: 'https://example.com',
};

Interface Typing

You can also define the type of the state using typescript interfaces.

interface State {
  data: any;
  error: any;
}
interface Config {
  method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';
  url: string;
}
export const $$state: State = {
  data: null,
  error: null,
};
export const $$config: Config = {
  method: 'GET',
  url: 'https://example.com',
};

Output Ports

Function Output

If you want to add an output to your node you have to explicitly define the return type of the default function.

export default (a: number, b: number): number => a + b;

you can also define the output type using typescript interfaces.

interface Output {
  data: any;
  error: any;
}
export default (a: number, b: number): Output => {
  return {
    data: a + b,
    error: null,
  };
};

Or you can define the output type using typescript inline typing.

export default (a: number, b: number): {
  data: any;
  error: any;
} => {
  return {
    data: a + b,
    error: null,
  };
};

Callback functions

Callback functions are functions that are passed as parameters to the default function. The type of the callback functions should be:

  • Array<Function>
  • Array<UCallback>
  • Function[]
  • UCallback[]

The callback functions should be called in the default function as the last parameter.

export default (a: number, b: number, [err, suc]: Array<Function>) => {};
export default (a: number, b: number, [err, suc]: Array<UCallback>) => {};
export default (a: number, b: number, [err, suc]: Function[]) => {};
export default (a: number, b: number, [err, suc]: UCallback[]) => {};

Tests

To run the UCOD-Parser execute this command

make test

Benchmarks

To run the UCOD-Parser benchmarks execute this command

make bench

Results

| Benchmark | Time (avg) | iter/s | (min..max) | p75 | p99 | p995 | | ----------- | -------------- | -------- | ---------------------- | -------- | --------- | --------- | | Addition V1 | 105.44 ms/iter | 9.5 | (98.09 ms … 117.86 ms) | 109 ms | 117.86 ms | 117.86 ms | | Addition V2 | 101.83 µs/iter | 9,820.7 | (85.96 µs … 2.59 ms) | 98.32 µs | 190.21 µs | 208.66 µs | | Addition V5 | 97.24 µs/iter | 10,284.2 | (88.09 µs … 730.42 µs) | 97.43 µs | 161.98 µs | 177.62 µs |

summary Addition V5 1.05x faster than Addition V2 1084.36x faster than Addition V1

| Benchmark | Time (avg) | iter/s | (min..max) | p75 | p99 | p995 | | ---------- | -------------- | ------- | ----------------------- | --------- | --------- | --------- | | Request V1 | 108.84 ms/iter | 9.2 | (101.15 ms … 126.58 ms) | 113.82 ms | 126.58 ms | 126.58 ms | | Request V2 | 163.29 µs/iter | 6,124.0 | (148.55 µs … 2.27 ms) | 162.29 µs | 239.24 µs | 273.15 µs | | Request V5 | 125.18 µs/iter | 7,988.8 | (115.45 µs … 714.9 µs) | 123.63 µs | 195.98 µs | 223.82 µs |

summary Request V5 1.3x faster than Request V2 869.52x faster than Request V1

License

Elastic License 2.0