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

@segment/fql-ts

v1.10.1

Published

<p align="center"> <h2 align="center">FQL (TypeScript)</h2> </p> <p align="center"> Language for filtering json streams <br><br> </p>

Downloads

12,501

Maintainers

harksinghharksinghfhalim-segmentfhalim-segmentcfreecfreeldelossantosldelossantoshjoonpmhjoonpmceline-segmentceline-segmentpmcanseco-segmentpmcanseco-segmentmasiramasiraamillet89amillet89cholt002cholt002av-segmentav-segmentaghotikaraghotikarvikrant-segmentvikrant-segmentlarryatsegmentlarryatsegmentscruwys1scruwys1kyliepedersenkyliepedersenjinaparkjinaparkcdignam-segmentcdignam-segmentsegmentiosegmentiojrupasinghejrupasingheshayan-golafshanishayan-golafshanilateefatlateefatrajulvaderarajulvaderayash-twilioyash-twiliosowjanyasegmentsowjanyasegmentebru.odokebru.odokryanligonryanligonlpediredlalpediredlabrookstaylorjrbrookstaylorjrnithan-twilionithan-twiliodean-huynhdean-huynhwdbettswdbettsn2parkon2parkojayakrishnannairjayakrishnannairrhall-twiliorhall-twiliokarimkeshwanikarimkeshwanityson_segmenttyson_segmentjgabe13jgabe13bgamwellbgamwellpoojasegmentpoojasegmentmaryam.sharifmaryam.sharifwally.tgwally.tgsalolivaressalolivareserikdwerikdwchenxiangzhangchenxiangzhangjusteenjusteenmericssonmericssonprayansh-segmenttprayansh-segmenttjeremylarkinjeremylarkinbsneedbsneeddanieljackinsdanieljackinssegment-sethsegment-sethsayan-das-insayan-das-injames9446james9446priscilla.giattipriscilla.giattinlsunnlsundrew-thompsondrew-thompsonsegment-jsinghsegment-jsinghmcoulibalimcoulibaliandrius-segmentandrius-segmentvalerieernstvalerieernstnithin-bennynithin-bennyainatancincoainatancincoskondamuriskondamuriclintz.segclintz.segreplateroreplateroslenin-twilioslenin-twilioakashyap91akashyap91csayusocsayusoseanhan-segmentseanhan-segmentnevermore2022nevermore2022gilomergilomermarcelopvmarcelopveric.rognereric.rognerkdharaiyakdharaiyajon.anderson-at-segment.comjon.anderson-at-segment.comstacy.songstacy.songrexatsegmentrexatsegmentnickaguilarnickaguilarbradenbeckerbradenbeckerreneewangreneewangdan.laskydan.laskysam.tapiasam.tapialnambalnambavikramkumar19vikramkumar19mpriyad25mpriyad25jeremy.parkerjeremy.parkersmidgessmidgesnageshgolemnageshgolemsudojatinsudojatinpmaidpmaidsethsegmentsethsegmentjair.avilesjair.avilesmanali-bhosalemanali-bhosaleelmoselyeeelmoselyeechtoombschtoombspeterdemartinipeterdemartinivincen7tranvincen7tranmayur-pitalemayur-pitalelfdelossantoslfdelossantosemmy.byrneemmy.byrnefelttripfelttripsa-jsootersa-jsooterlluque-twiliolluque-twiliokevinburkesegmentkevinburkesegmentafsha-nazim-segafsha-nazim-segsong4yousong4youdavid.anusontarangkul.segmentdavid.anusontarangkul.segmentjyim008jyim008michaelghsegmichaelghsegacharles14acharles14aishikawakiaishikawakitwjosiahtwjosiahtanya.gupta.segmenttanya.gupta.segmentsindhusegmentsindhusegmentprabhnoor1997prabhnoor1997chihchun-twiliochihchun-twiliopmiller-twiliopmiller-twiliovbatanovvbatanovsimpixelatedsimpixelatedmcullenmeyermcullenmeyerneeharikakondipatineeharikakondipatieric-hydeeric-hydearunlalam-segmentarunlalam-segmentmschaszbergermschaszbergershuvrajit9904shuvrajit9904abhinavsurekaabhinavsurekavaradarajan-twvaradarajan-twimmanojimmanojblangtwilioblangtwiliojsh-wujsh-wujahood-twiliojahood-twiliosethnutetwiliosethnutetwiliorrivera-segmentrrivera-segmentsegment-adminsegment-adminbgillanbgillantcgilberttcgilbertmckern_segmentmckern_segmentmaneesh.dharma29maneesh.dharma29joetessyjoetessygkochar123gkochar123dominicbarnesdominicbarnesmugelstadmugelstadjalexy12jalexy12lerahulramlerahulrampmuninpmuninwhaider_twiliowhaider_twilioariel.silvestriariel.silvestris3gm3nts3gm3ntama0223ama0223shraddha-twilioshraddha-twiliomichelrmichelrbrandon.scott-segmentbrandon.scott-segmentjfehrman.segmentjfehrman.segmentprayansh-twilioprayansh-twiliodangmai-segmentdangmai-segmentaaronklishaaronklishbrianhumphreystwiliobrianhumphreystwiliormukundanrmukundanashwitha.bgashwitha.bgryanrouleau-segmentryanrouleau-segmentfunlufunlutdibaccotdibaccofauzy.yyfauzy.yynlubchenconlubchencoricardo.rossiricardo.rossisahilsharma0709sahilsharma0709arubiochavezarubiochavezphillip.thomasphillip.thomasjkusa_segmentjkusa_segmentrollcoderollcodemeg1000meg1000nainy.agrawalnainy.agrawalseg-rustybaileyseg-rustybaileyjbandi-twiliojbandi-twiliosaisagarkappaganthulasaisagarkappaganthulaforgetfulfellowforgetfulfellowdbaik-twilio-segmentdbaik-twilio-segmentpooja.patilpooja.patiljoe.ayoub.segmentjoe.ayoub.segmenthmohanram_seghmohanram_segbrian.aguirrebrian.aguirreenyi.asonyeenyi.asonyefarhan0581farhan0581tbrennanjtbrennanjparag.pandaparag.pandacherylj-segmentcherylj-segmentharsh.vardhanharsh.vardhansshaikh_segmentsshaikh_segmentxinghao.huangxinghao.huangshupadhyayshupadhyayjohn.lee1100john.lee1100kx-segmentkx-segmentsegment_fansegment_fandazu70dazu70sbhodiwalsbhodiwalsai-patanjalisai-patanjaliemilyjiaemilyjiay.yuy.yuea_segmentea_segmentyli119yli119pooyajpooyajsungju.jinsungju.jinconniechenconniechenbharath.boregowdabharath.boregowdaigracheva-twilioigracheva-twiliobenattwiliobenattwiliomarinheromarinheroankit.gupta.unthinkableankit.gupta.unthinkabledobrin.ganevdobrin.ganevalfrimpongalfrimpongbrandonheyer-segmentbrandonheyer-segmentalecjacobs-segmentalecjacobs-segmentcjo2cjo2yashnit-segmentyashnit-segmentdltnbrks-segmentdltnbrks-segmentachandrashekaranachandrashekaranhimanshuphhimanshuphpraguptapraguptatw-dgarciatw-dgarciaalayvoraalayvoraaparna.singhalaparna.singhalynguyenynguyentimmyzsearcytimmyzsearcylweimersegmentlweimersegmentanton-vylushchakanton-vylushchakazhaotwilioazhaotwiliorokatyalrokatyalkjoerreskjoerresmsarafmsarafvikakumarvikakumaraditi.raveeshaditi.raveeshchenchensegmentcomchenchensegmentcomsanket.mishrasanket.mishraodoren_segmentodoren_segmentjxin_twiliojxin_twiliorcheedhallarcheedhallajbasiglio-segmentjbasiglio-segmentviveksainaneesegmentviveksainaneesegmentpriyanshispriyanshispreetyppreetypakash.gautam07akash.gautam07nanotimmnanotimmyshkpryshkprsrivig21srivig21ssunejassunejabala.singareddybala.singareddymoyara2moyara2arjunbhandagearjunbhandageakodankiryakodankiryrodhilton_twiliorodhilton_twiliocdelaomartinezcdelaomartinezgbatragbatraspencerattickspenceratticksegmentseansegmentseansundareswar.jayakumarsundareswar.jayakumarvaibhavnandavaibhavnandabannapplebannapplesrishti-nemasrishti-nemaar7devar7devgsolis_segmentgsolis_segmentitsarijitrayitsarijitraybhavanki-segmentbhavanki-segmentnitinpm432nitinpm432nikumarsegmentnikumarsegmentnanette.ranesnanette.ranesamigandhiamigandhiguthriesegmentguthriesegmentmiguelpdiaz8miguelpdiaz8mansarimansarisandhya16sandhya16hema-bahirwani-segmenthema-bahirwani-segmentbnakkinabnakkinapraveenugiripraveenugiriighorelaighorelanemery-segmentnemery-segmentwlumsegmentwlumsegmentnat-gridnat-gridneedcaffeineneedcaffeinekbhargavaram-sgkbhargavaram-sgirfan.ali.segmentirfan.ali.segmentharsh-joshi99harsh-joshi99ed-twilion-npmed-twilion-npmaubreysineaubreysinelight-bringer-blrlight-bringer-blrsethgrid_segmentsethgrid_segmentjibrangjibrangseg-leonelsanchesseg-leonelsanchessmccoy-twiliosmccoy-twiliodevthaledevthaleandwivediandwivedipoojapatilsegpoojapatilseggaprabhugaprabhuapackerapackermonusegmentmonusegmentehydesegmentehydesegment

Keywords

Readme

fql-ts is a Typescript lexer for Segment's Filter Query Language (FQL).

The goal is to allow us to use FQL on the browser and generate React components on top of FQL. It could also be used to give our FQL in-browser REPLs and integrate into existing tooling.

Usage

Install it with:

yarn add @segment/fql-ts

Lexing

To convert some code into some strings, you can use lex:

import { lex } from '@segment/fql-ts'

const { tokens } = lex('message.event > 30')

If some thing goes wrong lexing you'll get an error that you could surface to the user.

const { error } = lex('message.event > 30.30.30')

error.cursor.line // 0
error.cursor.column // 22
error.message // 'multiple decimal points in one number'

Tokens

In fql-ts, a token is an object with a value and an enum type.

For example, a string like "Order Completed" has a token that looks like this:

import { types } from '@segment/fql-ts'

{
    type: types.String,
    value: "Order Completed"
}

Some tokens don't have a unique value, so theirs is set to the name of the token. This is helpful for when we want to "unlex" or convert tokens back to strings.

{
    type: types.Comma,
    value: ","
}

But fql-ts also comes with helper functions to create tokens. We can create that same String token with:

import { t } from '@segment/fql-ts'

t.String('"Order Completed"')

Likewise, tokens that don't need values don't need string inputs in their helper functions:

t.Comma()

Below is the full list of token types. There's a corresponding helper for each of them as well.

// types
enum TokenType {
  Err = 'err',
  Ident = 'ident',
  Dot = 'dot',
  Operator = 'operator',
  Conditional = 'conditional',
  String = 'string',
  Number = 'number',
  Null = 'null',
  BrackLeft = 'brackleft',
  BrackRight = 'brackright',
  ParenLeft = 'parenleft',
  ParenRight = 'parenright',
  Comma = 'comma',
  EOS = 'eos' // End of statement (the final token)
}

// example helpers
t.Err()
t.Ident('someIdentifier')
t.Dot()
t.Operator('=')
t.Conditional('or')
t.String('"Something Something Something"') // note the extra "" quotes here
t.Number('23') // Still needs to be a string
t.Null()
t.BrackLeft()
t.BrackRight()
t.ParenLeft()
t.ParenRight()
t.Comma()
t.EOS()

Unlexing

If you can lex, can you un-lex? Why of course! fql-ts comes with full support for turning tokens back into code.

This is pretty helpful for generating FQL code, either through UI pieces or programatically.

import { lex, unlex } from '@segment/fql-ts'

const { tokens } = lex('some.code >= 30')
const { code } = unlex(tokens)

code // 'some.code >= 30' (give or take some whitespace)

If we have errors during the unlexing, we'll return an error object, just like the lexer.

const { error } = unlex(dangerousErrorTokens)

AST

We can create a typed AST from an array of tokens.

import { ast, lex } from '@segment/fql-ts'

const { tokens } = lex(`message = "foo"`)
const { node } = ast(tokens)

The AST returns the root node of the tree which will always have the node.type of ROOT.

The Tree structure type looks like this:

{
  children: [],
  type: "expr"
}

Leaves are arrays of tokens, nodes are other nodes. The type is an enum defined with AbstractSyntaxType. If you're using typescript, they're defined as:

export enum AbstractSyntaxType {
  ROOT = 'root',
  EXPR = 'expr',
  PATH = 'path',
  FUNC = 'func',
  ERR = 'err',
  CONDITIONAL = 'conditional',
  OPERATOR = 'operator'
}

interface ASTNode {
  children: Array<Token | ASTNode>
  type: AbstractSyntaxType
}

interface Token {
  type: TokenType
  value: string
}

Errors

If something went wrong in the parsing, the AST will return an error and the last node will be of type ERR:

import { ast, lex } from '@segment/fql-ts'

const { tokens } = lex(`message = `)
const { node, error } = ast(tokens)

console.error(error) // "ParserError: ..."

All Tokens are wrapped by a Node

For consistency and parsing reasons, there are no heterogenous children on nodes. In other words, a node NEVER has BOTH a token and another node as a children.

This is impossible in FQL-TS:

// BAD
node
 - token 
 - node
   - token

Instead, tokens are wrapped in their own node:

// GOOD
node 
 - node
   - token
 - node
   - token

This is incredibly important to note in conditional (like "and" and "or") and operator nodes, as it's often easy to assume that FQL like message.event = "foo" might look like this:

// BAD
node(expr)
  - node(path)
    - ...
  - token('=')
  - node(string)
    - ...

Instead, we'd see something like this:

// GOOD
node(expr)
  - node(path)
    - ...
  - node(operator)
    - token('=')
  - node(string)
    - ...

There and Back Again

You can go from an AST to tokens pretty easily with astToTokens:

import { astToTokens, lex, ast } from '@segment/fql-ts'

const { tokens } = lex(`message = "foo"`)
const { node } = ast(tokens)

astToTokens(node) // same thing as tokens

Contributing

Install the dependencies!

yarn

Run the tests!

yarn test --coverage

Create a build!

yarn build

License

MIT License

Copyright (c) 2021 Segment

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Contributing

All third party contributors acknowledge that any contributions they provide will be made under the same open source license that the open source project is provided under.