Code Monkey home page Code Monkey logo

sveltekit-search-params's Issues

Initial store value is undefined for param with defaultValue set

Describe the bug

creating a store and immediately accessing it in the root layout while defining a parameter with a default value causes the initial value to be undefined.

In the reproduction, there is a parameter "foo" with default "bar". accessing /, the url is updated to include ?foo=bar but the initial value in +layout.svelte is undefined.

This is unexpected and causes an error if you want to access $params.foo.

Possible solutions:

  • Do not render default values in the url, but reflect them in the store if the url does not set a different value
  • Fall back to default value if url does not supply it

Reproduction

https://www.sveltelab.dev/49is8k7v2xv3ap3

Logs

No response

Optimistic store updates, update store before navigation happens.

Describe the problem

When writing to a query param the store only updates once the navigation has finished, this can cause a non-instant change when using user input like a select. This feels janky and isn't good UX. This is especially noticable when load functions are doing work since navigation only resolves once the load function finishes.

Describe the proposed solution

I don't know if this is technically feasable within the library but my proposal is to optimistically update the store. So instead of just mutating the URL and letting the subscribe handle the updates you can optimistically set the store before the navigation even happens so the store is updated immediately.
Downside would be that the update would cause subscribers to get notified 2 times. (Unless you can detect the value was updated optimistically and only update if the optimistic value doesn't match the actual URL value).

Allow encoding as undefined to remove param

Describe the problem

If there is a default version of a parameter it can be nice to not have it show up in the URL.

Describe the proposed solution

If encode returns undefined delete the parameter from the url.

Array helper default value not typed correctly

Describe the bug

Thanks for this awesome library!

Simple issue - the default value of an array param when using the ssp.array() helper is not typed correctly.

Currently we have

    array: <T = any>(defaultValue?: T) => ({
        encode: (value: T[]) => JSON.stringify(value),
        decode: (value: string | null): T[] | null => {
            if (value === null) return null;
            try {
                return JSON.parse(value);
            } catch (e) {
                return null;
            }
        },
        defaultValue,
    }),

The default value should be typed as T[] and not T.

Reproduction

Logs

No response

Setting a default if enumerated parameter is invalid

Describe the problem

Provide an api to check validity of query keys and provide defaults if invalid.

For whatever reason some users try to modify our search params manually. We assume this mostly happens when a url not fully copied to the clipboard. Nonetheless you'll end up with a query that looks like ?sort=highes for example; where the "t" is cutoff.

At the moment we are the default parameter but that only adds a default value if the key is not present instead of checking if the value is valid it seems.

We are currently checking this in our onMount like so; but it gets verbose when there are 15 keys to check for (search heavy data app).

	onMount(() => {
		if ($store.sort !== 'highest' ?? $store.sort !== 'recent') {
			$store.sort = 'highest';
		}
	});

Describe the proposed solution

An api similar to the default feature that would not only check for a missing key, but check for its validity and set a default value if invalid.

Updating to SvelteKit 2 leads to warning

Describe the bug

We just updated from "@sveltejs/kit": "^1.24.1" to "@sveltejs/kit": "^2.5.0" and started getting the warning:

Avoid using history.pushState(...) and history.replaceState(...) as these will conflict with SvelteKit's router. Use the pushState and replaceState imports from $app/navigation instead.

Reproduction

This just happens every time we write to the query-params.

Logs

No response

Value is nullable if default value is provided

Describe the bug

image

type of page should be Writable<number>

Reproduction

<script>
  import { queryParam, ssp } from "sveltekit-search-params";

  $: page = queryParam("p", ssp.number());
</script>

Logs

No response

sort params in url to improve browser cache hit rate

Describe the problem

With optional parameters it is currently possible to add them at different times, and their insertion order determines their position in the query string of the url.

http caching uses the full url , so https://example.com?a=1&b=2 is a different entry than https://example.com?b=2&a=1
In order to have a more stable url representation and improve cache hit rate, it would be great if the params can be sorted.

Describe the proposed solution

use native sort() by default, add an option for custom sort function (or false to disable)

Unable to navigate to other pages

Describe the bug

After I open a page with this library configured I cannot navigate to any other page.
The URL does change but my app still shows the same page which is using sveltekit-search-params

Reproduction

Will setup a reproduction and add here.

Logs

No response

Reset search param A when search param B changes - Unexpected behaviour

Describe the bug

Hi,

I have 2 search parameters:

  1. Page: This is used for pagination.
  2. Ingredients: This is used for filtering shakes by ingredients.

Imagine a user is on page 2 and then selects an ingredient. At this moment, I want to reset the page to "1" to start from the beginning. In fact, this reset may occur each time the filter is updated.

Here's how I achieve this:

const currentPage = queryParam('page', ssp.number(1))
const selectedIngredients = queryParam('ingredients', ssp.array([]), { showDefaults: false })

selectedIngredients.subscribe((value) => {
  if (!value) {
    return;   
  }
  currentPage.set(1)
})

Unfortunately, the filters stop working with this logic. It becomes impossible to check/uncheck ingredients.

Reproduction

https://codesandbox.io/p/devbox/multiple-filters-srqnmf?file=%2Fsrc%2Flib%2Fcomponents%2FIngredientsFilter.svelte%3A13%2C1-18%2C6

Logs

No response

hiding default value with arrays and objects

Describe the bug

Not sure if this is a bug, but let me explain.

When I create a new query param store with an empty array as the default value and showDefaults set to false, everything is fine on the first load. The query param is not added to the URL.

Adding an element to the array and the URL updates accordingly.

But now when I remove the object again or assign [] to the store, the query param is added to the URL with an empty array value.

@paoloricciuti Would love to hear you opinion on what the expected behavior should be. IMO the query param should disappear again after it has been reset to its default value.

Already have an idea that the issue comes from comparison by reference instead of comparison by value, but want to wait for your feedback first, before jumping into any code.

Cheers!

Reproduction

// creating the store, no query param in the URL
const params = queryParam('params', ssp.array([]), { showDefaults: false });

// adding element to store array, URL updates to ?params=["foo"]
$params = ['foo']

// resetting store to empty array, URL updates to ?params=[]
$params = []

Logs

No response

Type error with exactOptionalPropertyTypes on

Describe the bug

Given this code:

const booleanFilters = queryParam('bf', ssp.array<string>([]));

I get this typescript error when exactOptionalPropertyTypes is true in my tsconfig

Argument of type '{ encode: (value: string[]) => string; decode: (value: string | null) => string[] | null; defaultValue: string[] | undefined; }' is not assignable to parameter of type 'EncodeAndDecodeOptions<string[]>' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.
  Types of property 'defaultValue' are incompatible.
    Type 'string[] | undefined' is not assignable to type 'string[]'.
      Type 'undefined' is not assignable to type 'string[]'.ts(2379)

Reproduction

import { ssp, queryParam } from 'sveltekit-search-params';

const booleanFilters = queryParam('bf', ssp.array<string>([]));

Logs

No response

Debouncing updates

it can be nasty to the browser history when we type and the url bar is updated on every keystroke.

could we offer an easy way (probably not default, but recommended) to debounce the updates?

defaultValue not applyed in a second client side navigation

Describe the bug

I have this setting:

const store_qp = queryParameters({
  withOne: ssp.boolean(true),
  withTwo: ssp.boolean(false),
  
  pushHistory: false,
})

First time I see the page, I see my queryParams getting updated, it's all good.
Then, I navigate (client side), and when at some point I go back to this page, defaults don't get applied.

When, I leave the page, my +page.svelte get destoyed well. So I'm not sure what's happening.

Thanks for your help

Reproduction

https://www.sveltelab.dev/?provider=github&owner=jycouet&repo=veltekit-search-params-default-value

  1. Navigate to Page A
    ✅ query param are displayed and applied
  2. Navigate to Page B
    ✅ Nothing special, it's going there
  3. Navigate to Page A
    ❌ Default query params are not applied.

Logs

No response

Remove empty query string.

Describe the bug

How do I get an empty query string off the URL?

Reproduction

Add with data then try to remove.

Logs

No response

Cannot find package '$app'

Describe the bug

Whenever I do a hard refresh, I get this error. Not sure what I am missing!

Reproduction

https://stackblitz.com/edit/sveltejs-kit-template-default-c78wrs?file=src%2Froutes%2F%2Bpage.svelte

Logs

00:48:40 [vite] Error when evaluating SSR module /src/routes/+page.svelte: failed to import "sveltekit-search-params"
|- Error [ERR_MODULE_NOT_FOUND]: Cannot find package '$app' imported from /home/projects/sveltejs-kit-template-default-c78wrs/node_modules/sveltekit-search-params/package/sveltekit-search-params.js
    at  (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:36:4170)
    at packageResolve (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:114:9613)
    at  (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:114:11319)
    at  (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:114:12167)
    at defaultResolve (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:114:12837)
    at  (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:248:2121)
    at  (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:248:2213)
    at  (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:248:7557)
    at resolve (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:248:7997)
    at  (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:248:4394)
    at getModuleJob (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:248:4673)
    at  (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:181:944)
    at  (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:181:989)
    at  (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:352:382940)
    at  (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:181:897)

Error [ERR_MODULE_NOT_FOUND]: Cannot find package '$app' imported from /home/projects/sveltejs-kit-template-default-c78wrs/node_modules/sveltekit-search-params/package/sveltekit-search-params.js
    at  (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:36:4170)
    at packageResolve (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:114:9613)
    at  (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:114:11319)
    at  (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:114:12167)
    at defaultResolve (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:114:12837)
    at  (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:248:2121)
    at  (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:248:2213)
    at  (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:248:7557)
    at resolve (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:248:7997)
    at  (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:248:4394)
    at getModuleJob (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:248:4673)
    at  (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:181:944)
    at  (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:181:989)
    at  (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:352:382940)
    at  (https://sveltejskittemplatedefaultc78w-xkpr.w-corp.staticblitz.com/blitz.95086023.js:181:897) {
  code: 'ERR_MODULE_NOT_FOUND'
}

Error exporting compressToEncodedURIComponent

client-manifest.js:28 SyntaxError: The requested module '/node_modules/.pnpm/[email protected]/node_modules/lz-string/libs/lz-string.js?v=2285ece9' does not provide an export named 'compressToEncodedURIComponent' (at sveltekit-search-params.js?v=2285ece9:7:10)
handleError @ client-manifest.js:28

using:

"@sveltejs/adapter-auto": "next",
"@sveltejs/kit": "1.0.0-next.561",

Usage in derived storage

Describe the problem

I would like to do some computations in a derived store based on values returned from queryParameters but can't figure out how. I guess that it may currently not be possible based on how queryParameters is exported? Currently it's exported as a function but the derived store expects a writable store as an argument.

Describe the proposed solution

It would be great to have an exported writable store that could be used as such:

export const derivedStore = derived([queryParameters, anotherStore], ([$queryParameters, $anotherStore]) => {
   const { param1, param2, ... } = $queryParameters;
   // ... 
});

Possible bug: Inconsistent behavior with Node 20

Describe the bug

First off, I'll say that I haven't verified if this happens without the use of your plugin.

const search = queryParam('q', ssp.string(), {pushHistory: false})
...
<input type="search" name="search" placeholder="Search" bind:value={$search} />

Running this on Node 18, no calls to __data.json happen when typing in the input. But when I upgrade to Node 20, I see a request to __data.json on every keystroke.

It took me a looong time to figure out what the culprit was. I created a whole Stackblitz for you, only to find that the issue wasn't there because apparently it runs Node 16.

Reproduction

https://stackblitz.com/edit/sveltejs-kit-template-default-d1rzdh?file=README.md

Logs

No response

Svelte 5 support

Svelte 5 is right around the corner and while stores are still supported i want to upgrade this library to take advantage of runes.

This however require some changes that are not back compatible so my plan is to continue supporting stores in sveltekit-search-params@^2 and upgrade to runes in sveltekit-search-params@^3.

The new version however will likely face some api changes because of how runes behave.

queryParameters

The function queryParameters will benefit a lot from runes: today this function return an unique store object with each query parameter as the key.

<script>
    import { ssp, queryParameters } from "sveltekit-search-params";
    const params = queryParameters({
        search: ssp.string(),
    });
</script>

<input bind:value={$params.search} />

with runes the syntax will not change that much but the updates should be much more fine grained which is good

<script>
    import { ssp, queryParameters } from "sveltekit-search-params";
    const params = queryParameters({
        search: ssp.string(),
    });
</script>

<input bind:value={params.search} />

queryParam

Here's where the change will be much more intensive so first thing first sorry if you are using this intensively...i'll try to see if i can create a migration CLI to help you with your upgrade.

Today queryParam accept the key of the query parameter as input and returns a store with that param by itself. If the query parameter is a string the store will contain the string itself.

<script>
    import { ssp, queryParam } from "sveltekit-search-params";
    const search = queryParam("search");
</script>

<input bind:value={$search} />

This is not possible with runes so we have three options:

The boxed value

The simplest option would to return a ref or a boxed instead of the actual value. The downside is that you need to access it with .value everywhere.

<script>
    import { ssp, queryParam } from "sveltekit-search-params";
    const search = queryParam("search");
</script>

<input bind:value={search.value} />

This is simple to refactor but once you need to access it with .value everywhere is it really worth it over using queryParameters with a short name and just access it like qp.search everywhere?

The function

Another option could be have the returned value be a function...you could access it by calling it and set it by calling it with a typesafe parameter.

<script>
    import { ssp, queryParam } from "sveltekit-search-params";
    const search = queryParam("search");
</script>

<input value={search()} oninput={(e)=>{search(e.target.value)}} />

this is nice to see but it can get complex with Typescript type narrowing and it get's pretty hairy with objects and arrays.

The derived

A somewhat nice option would be to make use of $derived.by to destructure the return value of queryParam. This would give us a simple value to use everywhere and we could even return an input object to spread into your inputs that automatically set the oninput property to mimic the bind behaviour.

<script>
    import { ssp, queryParam } from "sveltekit-search-params";
    const [search, inputsearch, setsearch] = $derived.by(queryParam("search"));
</script>

<input {...inputsearch} />
The search is {search}

but this again become very hairy with object and arrays (especially if you want to bind a property of that object instead of the whole object).

Conclusion

I'm not really satisfied with any of the options for queryParam and i wonder if we should just drop that api but i would love to have YOUR opinion and ideas on this.

Using update function from queryParam store doesn't update the url

i notice this when i building my pagination component, i use this code
const current_page = queryParam("page", ssp.number(1));\
and using this button to go to previous page
<button class="grid place-items-center bg-white border-gray-600 shadow-md" on:click={() => current_page.update((e) => { const new_val = Math.max((e ?? 1) - 1, 1); return new_val; })} > &lt; </button>
the current_page state gets updated but the brower url doesn't.

URL #hash being removed on update

Describe the bug

Hi, I am excited to use your plugin as it does everything I need to maintain state using query params, thank you for developing it!

I noticed that when I update a queryParam, it seems to remove the #hash portion of the URL. I assume this is not intentional?

As you can see in my reproduction steps below, I am using maplibre-gl which maintains its map state in the URL hash automatically, so I'd like to leave it untouched.

Reproduction

// Current URL: http://localhost/#10/29.42/-98.47
const search = queryParam('q', ssp.string());
$search = 'foo';
// New URL: http://localhost/?q=foo

Logs

No response

Potential uncaught error message?

Describe the bug

Hello,

We've chatted before. Thanks again for creating this super helpful package. I'd donate to you if there was an option for it (is there?)

I wanted to report something I have been getting in my logs on any page that uses this package. I checked the stack trace and it appears that goto is being called a total of 4 times in the main sveltekit-search-params.js file. It's possible I have things setup in an unusual way where SvelteKit tries to execute this code on the server - I have a lot of logic about how navigation happens in my app. This happens on a page where I use debounceHistory and a page where I don't.

I'm not sure I will be able to repro it, but I will try later today. But I think adding a if(browser) guard before the goto calls would maybe fix the issue? Even if it's not something that only occurs in edge cases.

Screenshot 2023-04-20 at 8 53 49 AM

Reproduction

N/A

Logs

No response

Crashes with enabled prerendering

Describe the bug

When queryParam is used on a page that has enabled sveltekit prerendering, the build crashes. This in theory is understandable because obviously there are no query parameters during build. However, I would expect the behavior to be the same as in during SSR: I get null and wait for hydration.

Reproduction

Minimal reproduction repo: https://github.com/shilangyu/sveltekit-search-params-prerender

Run npm run build to see the problem.

Logs

Error: Cannot access url.searchParams on a page with prerendering enabled
    at URL.get (file:///Users/marcinwojnarowski/coding/temp/svelte-kit-prerender-query/.svelte-kit/output/server/chunks/exports.js:92:15)
    at file:///Users/marcinwojnarowski/coding/temp/svelte-kit-prerender-query/.svelte-kit/output/server/entries/pages/_page.svelte.js:22:35
    at sync (file:///Users/marcinwojnarowski/coding/temp/svelte-kit-prerender-query/.svelte-kit/output/server/chunks/index.js:66:22)
    at file:///Users/marcinwojnarowski/coding/temp/svelte-kit-prerender-query/.svelte-kit/output/server/chunks/index.js:89:5
    at Object.subscribe2 [as subscribe] (file:///Users/marcinwojnarowski/coding/temp/svelte-kit-prerender-query/.svelte-kit/output/server/chunks/index.js:36:14)
    at subscribe (file:///Users/marcinwojnarowski/coding/temp/svelte-kit-prerender-query/.svelte-kit/output/server/chunks/ssr.js:25:23)
    at file:///Users/marcinwojnarowski/coding/temp/svelte-kit-prerender-query/.svelte-kit/output/server/entries/pages/_page.svelte.js:49:25
    at Object.$$render (file:///Users/marcinwojnarowski/coding/temp/svelte-kit-prerender-query/.svelte-kit/output/server/chunks/ssr.js:87:18)
    at Object.default (file:///Users/marcinwojnarowski/coding/temp/svelte-kit-prerender-query/.svelte-kit/output/server/chunks/internal.js:80:98)
    at file:///Users/marcinwojnarowski/coding/temp/svelte-kit-prerender-query/.svelte-kit/output/server/entries/fallbacks/layout.svelte.js:3:42

node:internal/event_target:1096
  process.nextTick(() => { throw err; });
                           ^
Error: 500 /
To suppress or handle this error, implement `handleHttpError` in https://kit.svelte.dev/docs/configuration#prerender
    at file:///Users/marcinwojnarowski/coding/temp/svelte-kit-prerender-query/node_modules/@sveltejs/kit/src/core/config/options.js:202:13
    at file:///Users/marcinwojnarowski/coding/temp/svelte-kit-prerender-query/node_modules/@sveltejs/kit/src/core/postbuild/prerender.js:65:25
    at save (file:///Users/marcinwojnarowski/coding/temp/svelte-kit-prerender-query/node_modules/@sveltejs/kit/src/core/postbuild/prerender.js:403:4)
    at visit (file:///Users/marcinwojnarowski/coding/temp/svelte-kit-prerender-query/node_modules/@sveltejs/kit/src/core/postbuild/prerender.js:236:3)

Node.js v21.6.1

Remove the query string from the URL when a parameter isn't set

Describe the problem

I have a search query string parameter bound to a search input field. Ideally, when the search input field is empty, I'd like to see the search query string disappear from the URL. Currently, it shows ?search=.

Describe the proposed solution

The current solution is this:

function nullableQueryParam<T>({
  encode,
  ...codec
}: EncodeAndDecodeOptions<T>) {
  return {
    ...codec,
    encode(value) {
      if (value === "") return undefined;
      if (Array.isArray(value) && value.length === 0) return undefined;

      return encode(value);
    },
  } as EncodeAndDecodeOptions<T>;
}

Then use it as follows:

export function getUrlSearchParamsFiltersStore() {
  return queryParam<string[]>("filters", nullableQueryParam(ssp.array()));
}

Unsubscribing

I noticed when I go to different page routes my search params are persisting, and I think it's because I need to unsubscribe() during an onDestroy() lifecycle hook. Would you consider returning the subscription that you have here?

Support for bind:group directive

Describe the problem

In Svelte, you can use the bind:group feature like so:

<script lang="ts">
    let selected = []
</script>

<input type="checkbox" bind:group={selected} value="2022" />
<input type="checkbox" bind:group={selected} value="2023" />
<input type="checkbox" bind:group={selected} value="2024" />

However, when attempting to apply the same technique with the (awesome! 😎) sveltekit-search-params package, as shown:

<script lang="ts">
    import { ssp, queryParam } from 'sveltekit-search-params';

    const selected = queryParam('years', ssp.array());
</script>

<input type="checkbox" bind:group={$selected} value="2022" />
<input type="checkbox" bind:group={$selected} value="2023" />
<input type="checkbox" bind:group={$selected} value="2024" />

An error occurs:

TypeError: Cannot read properties of null (reading 'indexOf')

Describe the proposed solution

It's possible that there's an error in my implementation, or perhaps this feature isn't supported yet. Regardless, having this functionality would be fantastic.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.