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

@fighter178/queryjs

v0.0.3

Published

A single JS or TS file, giving (almost) all the features of a framework like Svelte or React.

Downloads

9

Readme

QueryJS

The library that works like a framework, but isn't. One single JS file, giving you all that you need. No fuss with many files, though it does work with Node.

Includes:

  • Components (WIP)
  • Data binding
  • Reactivity (WIP)
  • Flexible Syntax

Excludes:

  • Syntax highting (for now)
  • Good Docs
  • Form Actions
  • Backend framework (eg. Sveltekit)

Install

To install QueryJS, use the CDN:

<script src="https://cdn.jsdelivr.net/gh/Fighter178/QueryJS/qj.min.js" integrity="sha512-SdmGVkl4uiea7nXSFzQ0Eo45QlBiyhDgouJRtsHDbvZW99SmPyS6wEpE7bHf4XkU7ycvGmUiCQ7CqPK7NOUssw==" crossorigin="anonymous"></script>

Or, via NPM:

npm i @fighter178/queryjs

*note that QueryJS uses the document, and so it won't run in Node. Use import syntax instead of "require".

Data attributes

Binding data

To bind data, use the data-bind="[variableName]" syntax. All elements that want to leverage QueryJS, must have an id, though it can be anything that isn't null.

For example,

if I wanted to bind the value of the input below, this would work:

<input type="text" data-bind="myText", id="text-input">

and to get the value I could do

Qj.vars["myText"].value // returns current value of input

or, if I wanted to watch for changes,

Qj.vars["myText"].onChange((v)=>{console.log(`Value of my text: ${v}`)})

However, this would not:

<input type="text" data-bind="myText">

This would throw the error: QueryJS | Element ([element without id]) must have an id. Add id=[id] to fix this. Note, that any variable that is stored by QJ, will and must be in the Qj.varsobject. This is to prevent pollution of the global namespace, and for compatibility. Binding like this watches for all input, user or not. Be aware of this. Using binding works on inputs, textareas, etc.

Showing Data

If you wanted to show the user some data, use the syntax {expression}. Doing this inside of braces allows you to execute JavaScript within HTML. If the user doesn't have JS enabled, then it won't work. If you want to escape braces, use \{}. This escapes it. Renders {} to the screen. To do this, it requires an element to have the data attribute data-template="true" on it, and of course an id.

Example:

*note that unlike most other attributes, templates doesn't require an ID anymore.

<p data-template>{1+2}></p>

Results in this being shown to the user:

3

While this:

<p data-template>\{1+2}</p>

Gives:

{1+2}

on the screen despite data-template being set to true. This works with multiple templates, without limit. Sadly, this is not reactive, though you can use the render function to help.

Executing in the Global Scope (WIP)

By default, a template is executed in its own scope. If you need to execute it in the global scope, then do this: data-template-scope="global". You could also put any scope defined in the global scope here, like a custom scope:

myScope: {
    let i=0;
}

Then use data-template-scope="myScope"

Qj.render Function

As mentioned above, templates aren't reactive, so you'll need to use this function to make them. Use it like this Qj.render(id). This re-renders the templates, so if you changed the text, with elem.innerText, it will re-render.

Example

index.js

let i = 0;
setInterval(()=>{
    const elem = document.querySelector("#my-text-elem").innerText=`{1+${i}}`;
    Qj.render("my-text-elem");
},1000)

index.html

<p id="my-text-elem">{1+0}</p>

Would make the number in the paragraph element count up each second. However, there is a major problem, and that is, this is what normal JS does, except more complicated. So, below is a better version, using Qj.update().

Qj.update function

The update function essentially allows you to render new text to the screen, much more simply. It basically wraps the text updating with the render call. Also with a lot more options. How arguments are ordered: Qj.update(id, text, options). The most interesting part is the options parameter, as it allows you to loop, delay, etc. So, lets implement the example above with the update function. index.js

Qj.update("my-text-elem","{1+i}", {
    loop:{
        count:Infinity, // Loop forever, converts to a setInterval if it is infinite.
        interval:1000, // Wait 1sec between loops,
        callback:()=>{i++} // when loop runs increment i.
    },
    vars:{
        i:0; // set i.
    }
})

This may seem like its more code, and yes, it is. But, it is easier, as there is only one function call, and this is the tip of the iceberg when it comes to the update function. Though, this is the long way to write it, as this also works:

Qj.update("my-text-elem", "{1+i}", {
    loop:[true, 1000," i++"], // true means loop to infinity, 1000 is the interval (default to 0), and i++ is what to run when the loop is done.
    vars:["i"]
});

Variables

Variables in QueryJS are stored in the Qj.vars object. Anything that needs a variable within its local scope uses Qj.vars.local.[functionName] This allows you to access the variables in any Qj function, though truly local ones aren't accessible.

Reactive variables

To create a reactive variable, you need to use Qj.reactive(value, onChange) function. The alias for this is Qj.$. So lets create a reactive variable like this: index.html

<button onclick="myCount.$++">Count up</button>
<p id="counter" data-qj-template="true" data-qj-template-scope="global">{myCount.$}</p>

index.js

const myCount = Qj.$(0, (value)=>{
    Qj("#counter")[1].innerHTML = `{${value}}`;
    Qj.render("counter");
});

This updates the counter.

Writing aliases

Some QueryJS functions have aliases. However, if you want to write your own alias, then you can use the Qj.alias function. You should use this, and not extend the Qj object itself. Qj.alias checks to make sure that an alias isn't already being used, unless safe=false.