Deno

Deno

Deno is a runtime for JavaScript and TypeScript that is based on the V8 JavaScript engine and the Rust programming language. It was created by Ryan Dahl, original creator of Node.js, and is focused on productivity. It was announced by Dahl in 2018 during his talk "10 Things I Regret About Node.js".
Lawrence  Lesch

Lawrence Lesch

1678882982

Arktype: TypeScript's 1:1 Validator, Optimized From Editor to Runtime

ArkType TypeScript's 1:1 validator

arktype.gif typescript@4.9.5 in VS Code— no extensions or plugins required (how?) (try in-browser) 
 

What is it?

ArkType is a runtime validation library that can infer TypeScript definitions 1:1 and reuse them as highly-optimized validators for your data.

With each character you type, you'll get immediate feedback from your editor in the form of either a fully-inferred Type or a specific and helpful ParseError.

This result exactly mirrors what you can expect to happen at runtime down to the punctuation of the error message- no plugins required.

import { type } from "arktype"

// Definitions are statically parsed and inferred as TS.
export const user = type({
    name: "string",
    device: {
        platform: "'android'|'ios'",
        "version?": "number"
    }
})

// Validators return typed data or clear, customizable errors.
export const { data, problems } = user({
    name: "Alan Turing",
    device: {
        // problems.summary: "device/platform must be 'android' or 'ios' (was 'enigma')"
        platform: "enigma"
    }
})

Check out how it works, try it in-browser, or scroll slightly to read about installation.

Install 📦12KB gzipped, 0 dependencies

Npm Icon npm install arktype (or whatever package manager you prefer)

Deno Icon import { type } from "https://deno.land/x/arktype/main.ts"

Our types are tested in strict-mode with TypeScript versions 4.8, 4.9, and 5.0.

Our APIs have mostly stabilized, but details may still change during the alpha/beta stages of our 1.0 release. If you have suggestions that may require a breaking change, now is the time to let us know!

Scopes

Try this example in-browser.

import { scope } from "arktype"

// Scopes are collections of types that can reference each other.
export const types = scope({
    package: {
        name: "string",
        "dependencies?": "package[]",
        "contributors?": "contributor[]"
    },
    contributor: {
        // Subtypes like 'email' are inferred like 'string' but provide additional validation at runtime.
        email: "email",
        "packages?": "package[]"
    }
}).compile()

// Cyclic types are inferred to arbitrary depth...
export type Package = typeof types.package.infer

// And can validate cyclic data.
const packageData: Package = {
    name: "arktype",
    dependencies: [{ name: "typescript" }],
    contributors: [{ email: "david@sharktypeio" }]
}
packageData.dependencies![0].dependencies = [packageData]

export const { data, problems } = types.package(packageData)

API

ArkType supports many of TypeScript's built-in types and operators, as well as some new ones dedicated exclusively to runtime validation. In fact, we got a little ahead of ourselves and built a ton of cool features, but we're still working on getting caught up syntax and API docs. Keep an eye out for more in the next couple weeks ⛵

In the meantime, check out the examples here and use the type hints you get to learn how you can customize your types and scopes. If you want to explore some of the more advanced features, take a look at our unit tests or ask us on Discord if your functionality is supported. If not, create a GitHub issue so we can prioritize it!

How?

ArkType's isomorphic parser has parallel static and dynamic implementations. This means as soon as you type a definition in your editor, you'll know the eventual result at runtime.

If you're curious, below is an example of what that looks like under the hood. If not, close that hood back up, npm install arktype and enjoy top-notch developer experience 🧑‍💻

export const parseOperator = (s: DynamicState): void => {
    const lookahead = s.scanner.shift()
    return lookahead === ""
        ? s.finalize()
        : lookahead === "["
        ? s.scanner.shift() === "]"
            ? s.rootToArray()
            : s.error(incompleteArrayTokenMessage)
        : isKeyOf(lookahead, Scanner.branchTokens)
        ? s.pushRootToBranch(lookahead)
        : lookahead === ")"
        ? s.finalizeGroup()
        : isKeyOf(lookahead, Scanner.comparatorStartChars)
        ? parseBound(s, lookahead)
        : lookahead === "%"
        ? parseDivisor(s)
        : lookahead === " "
        ? parseOperator(s)
        : throwInternalError(writeUnexpectedCharacterMessage(lookahead))
}

export type parseOperator<s extends StaticState> =
    s["unscanned"] extends Scanner.shift<infer lookahead, infer unscanned>
        ? lookahead extends "["
            ? unscanned extends Scanner.shift<"]", infer nextUnscanned>
                ? state.setRoot<s, [s["root"], "[]"], nextUnscanned>
                : error<incompleteArrayTokenMessage>
            : lookahead extends Scanner.BranchToken
            ? state.reduceBranch<s, lookahead, unscanned>
            : lookahead extends ")"
            ? state.finalizeGroup<s, unscanned>
            : lookahead extends Scanner.ComparatorStartChar
            ? parseBound<s, lookahead, unscanned>
            : lookahead extends "%"
            ? parseDivisor<s, unscanned>
            : lookahead extends " "
            ? parseOperator<state.scanTo<s, unscanned>>
            : error<writeUnexpectedCharacterMessage<lookahead>>
        : state.finalize<s>

Contributions

We accept and encourage pull requests from outside ArkType.

Depending on your level of familiarity with type systems and TS generics, some parts of the codebase may be hard to jump into. That said, there's plenty of opportunities for more straightforward contributions.

If you're planning on submitting a non-trivial fix or a new feature, please create an issue first so everyone's on the same page. The last thing we want is for you to spend time on a submission we're unable to merge.

When you're ready, check out our guide to get started!

License

This project is licensed under the terms of the MIT license.

Collaboration

I'd love to hear about what you're working on and how ArkType can help. Please reach out to david@arktype.io.

Code of Conduct

We will not tolerate any form of disrespect toward members of our community. Please refer to our Code of Conduct and reach out to david@arktype.io immediately if you've seen or experienced an interaction that may violate these standards.

Sponsorship

We've been working full-time on this project for over a year and it means a lot to have the community behind us.

If the project has been useful to you and you are in a financial position to do so, please chip in via GitHub Sponsors.

Otherwise, consider sending me an email (david@arktype.io) or message me on Discord to let me know you're a fan of ArkType. Either would make my day!


Download Details:

Author: arktypeio
Source Code: https://github.com/arktypeio/arktype 
License: MIT license

#typescript #javascript #parse #static #deno 

Arktype: TypeScript's 1:1 Validator, Optimized From Editor to Runtime
Monty  Boehm

Monty Boehm

1678779240

Get-pixels: Get The Decoded Pixel Data From A JPG Or PNG Image

🌈 🦕 get_pixels

Load and decode the pixels for a PNG or JPEG image in Deno

This module will take the raw data or URL of a PNG or JPEG image and return the decoded pixels and dimensions of the image.

Usage

import { getPixels } from "https://deno.land/x/get_pixels/mod.ts";

// From a URL
const { width, height, data } = await getPixels(
  "http://placekitten.com/100/100",
);

// From a file

const file = await Deno.readFile("kitten.png");

const { width, height, data } = await getPixels(file);

There is also a getFormat function that will return the format of the image data. This is detected by the first magic bytes at the start of the data.

import { getFormat } from "https://deno.land/x/get_pixels/mod.ts";

const file = await Deno.readFile("kitten.png");
const format = getFormat(file);
// format === "png"

Download Details:

Author: ascorbic
Source Code: https://github.com/ascorbic/get-pixels 
License: MIT licensed

#deno #pixel #typescript #image 

Get-pixels: Get The Decoded Pixel Data From A JPG Or PNG Image
Monty  Boehm

Monty Boehm

1678775344

OG-edge: Generate Open Graph images with Deno & Netlify Edge Functions

Open Graph Image Generation

Generate Open Graph images with Deno and Netlify Edge Functions, no framework needed. This is a fork of the awesome @vercel/og, ported to run on Deno.

Usage

To use on Netlify, create the following Edge Function:

// /netlify/edge-functions/og.tsx

import React from "https://esm.sh/react@18.2.0";
import { ImageResponse } from 'https://deno.land/x/og_edge/mod.ts'

export default async function handler(req: Request) {
    return new ImageResponse(
    (
      <div
        style={{
          width: '100%',
          height: '100%',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
          fontSize: 128,
          background: 'lavender',
        }}
      >
        Hello!
      </div>
    )
  )
}

Then create a netlify.toml file with the following:

[[edge_functions]]
function = "og"
path = "/og"

Make sure you have the latest version of the Netlify CLI installed.Then run netlify dev and load http://localhost:8888/og, the React element will be rendered and returned as a PNG. To deploy to Netlify's edge network, run netlify deploy.

Alternatively, to use with the Deno CLI or Deno Deploy, create a file with the following:

// /og.tsx

import { serve } from "https://deno.land/std@0.140.0/http/server.ts";
import React from "https://esm.sh/react@18.2.0";
import { ImageResponse } from "https://deno.land/x/og_edge/mod.ts";

async function handler(req: Request) {
  return new ImageResponse(
    <div
      style={{
        width: "100%",
        height: "100%",
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        fontSize: 128,
        background: "lavender",
      }}
    >
      Hello!
    </div>,
  );
}

serve(handler);

Then run deno run --allow-net --allow-env og.tsx

Read more about the API, supported features and check out the examples in the following sections.

API Reference

The package exposes an ImageResponse constructor, with the following options available:

import React from "https://esm.sh/react@18.2.0";
import { ImageResponse } from 'https://deno.land/x/og_edge/mod.ts'

// ...
new ImageResponse(
  element: ReactElement,
  options: {
    width?: number = 1200
    height?: number = 630
    emoji?: 'twemoji' | 'blobmoji' | 'noto' | 'openmoji' | 'fluent' | 'fluentFlat' = 'twemoji',
    fonts?: {
      name: string,
      data: ArrayBuffer,
      weight: number,
      style: 'normal' | 'italic'
    }[]
    debug?: boolean = false

    // Options that will be passed to the HTTP response
    status?: number = 200
    statusText?: string
    headers?: Record<string, string>
  },
)

When running in production, these headers will be included by og_edge:

'content-type': 'image/png',
'cache-control': 'public, max-age=31536000, no-transform, immutable',

During development, the cache-control: no-cache, no-store header is used instead.

Supported HTML and CSS Features

Please refer to Satori’s documentation for a list of supported HTML and CSS features.

By default, og_edge only has the Noto Sans font included. If you need to use other fonts, you can pass them in the fonts option. Check the Custom Font example below for more details.

Examples

Development / Contributing

Acknowledgements

Basically all of the credit for this goes to shuding. I just ported it to Deno and added a few tweaks.


Download Details:

Author: ascorbic
Source Code: https://github.com/ascorbic/og-edge 
License: MPL-2.0 license

#deno #netlify #typescript 

OG-edge: Generate Open Graph images with Deno & Netlify Edge Functions
Lawrence  Lesch

Lawrence Lesch

1678524960

Astrodon: Make Desktop apps with Deno

🦕 Astrodon

Desktop App Framework (not there yet!) for Deno, based on Tauri

😎 Features

  • Create webview windows with your own title and URL
  • Bidirectional communication between your frontend and backend
  • Compile your apps as executables and even make installers
  • And most of what you get with Deno, e.g, TypeScript out of the box...

A lot is still missing, but we will get there!

🎁 Demo

Note: Latest public release only supports Windows and Linux, MacOS is not supported. This will be fixed in the next release.

Run the demo:

deno run -A --unstable --reload https://deno.land/x/astrodon@0.1.0-alpha.2/examples/hello_world/demo.ts

📜 To-do

  •  Unit tests
  •  Cross-platform compiling (missing: Apple Silicon)
  •  Typescript checking in the background (astrodon-build's Develop should manage this)
  •  Pass permission and arguments as flags and also put them in the executable metadata
  •  Organize project a little bit better (e.g move dependencies to deps.ts)
  •  A real-world app example
  •  Update the templates (wip)
  •  Match deno_runtime version (and also things like Deno.build) with Deno's releases
  •  Implement Web Workers
  •  Schematize and create plugin system
  •  Organize configs by usage hierarchy (e.g. global.icon -> build.icon)
  •  Ability apps register custom system URI protocols (installer)
  •  Add Cli command astrodon clean to remove cached runtimes
  •  Make Cli's command astrodon run also support HTTPs uris
    •  Add support for common permission flags as CLI arguments

🤔 Plugins ideas

  •  Cross process reactivity module (plugin)
  •  Cross process store module (plugin)
  •  Env variable manager and injection for builds (plugin)

👩‍💻 Development

Requisites:

  • Install the tauri dependencies as indicated in Tauri's Guide.
  • Rust (stable toolchain)
  • Deno

Running both Deno and Rust tests:

deno task test

Download Details:

Author: Astrodon
Source Code: https://github.com/astrodon/astrodon 
License: MIT license

#typescript #javascript #rust #deno

Astrodon: Make Desktop apps with Deno
Lawrence  Lesch

Lawrence Lesch

1677079560

Froebel: A Strictly Typed Utility Library

Froebel - a strictly typed TypeScript utility library.

This is my (WIP) personal collection of TypeScript helper functions and utilities that I use across different projects. Think an opinionated version of lodash, but with first-class types.

If you have an idea for a utility that might make a good addition to this collection, please open an issue and suggest its inclusion.

Runs in Deno, Node.js, and the Browser. Get it from deno.land or npm.

Installation

Using npm

npm install froebel

and — assuming a module-compatible system like webpack — import as:

import { someUtility } from 'froebel';
// you can also import the utility you need directly:
import memoize from 'froebel/memoize';

Using Deno

import { someUtility } from "https://deno.land/x/froebel@v0.23.2/mod.ts";
// or import just the utility you need:
import memoize from "https://deno.land/x/froebel@v0.23.2/memoize.ts"

Available Utilities

Each category also has a file exporting only the utilities in that category, so if you want to only import utilities from one category, you could import them as

import { throttle, debounce } from "froebel/function";

A few utils are exported from multiple categories but will only be listed here once. For example isPromise is exported from both the promise and the predicate category.

Function

ident

(value: T) => T

source | tests

Identity function.

Import

/* Node: */  import ident from "froebel/ident";
/* Deno: */  import ident from "https://deno.land/x/froebel@v0.23.2/ident.ts";

noop

() => void

source | tests

Import

/* Node: */  import noop from "froebel/noop";
/* Deno: */  import noop from "https://deno.land/x/froebel@v0.23.2/noop.ts";

partial

(fun: T, ...argsLeft: PL) => (...argsRight: PR) => ReturnType<T>

source | tests

Partially apply a function.

Import

/* Node: */  import partial from "froebel/partial";
/* Deno: */  import partial from "https://deno.land/x/froebel@v0.23.2/partial.ts";

Example

const divide = (dividend: number, divisor: number) => dividend / divisor

// (divisor: number) => number
const oneOver = partial(divide, 1)

// prints: 0.25
console.log(oneOver(4))

forward

(fun: T, ...argsRight: PR) => (...argsLeft: PL) => ReturnType<T>

source | tests

Given a function and its nth..last arguments, return a function accepting arguments 0..n-1.

Import

/* Node: */  import forward from "froebel/forward";
/* Deno: */  import forward from "https://deno.land/x/froebel@v0.23.2/forward.ts";

Examples

const divide = (dividend: number, divisor: number) => dividend / divisor

// (dividend: number) => number
const divideBy2 = forward(divide, 2)

// prints: 0.5
console.log(divideBy2(1))
const fetchUrl = async (protocol: string, domain: string, path: string) =>
  await fetch(`${protocol}://${domain}/${path}`)

const fetchRepo = forward(fetchUrl, 'github.com', 'MathisBullinger/froebel')

const viaHTTPS = await fetchRepo('https')

unary

(fun: T) => Unary<T>

source | tests

Turns fun into a unary function (a function that only accepts one argument).

Note: fun must accept at least one argument and must not require more than one argument.

Import

/* Node: */  import unary from "froebel/unary";
/* Deno: */  import unary from "https://deno.land/x/froebel@v0.23.2/unary.ts";

Example

['1', '2', '3'].map(unary(parseInt))  // -> [1, 2, 3]

callAll

(funs: F[], ...args: P) => ReturnTypes<F>

source | tests

Take a list of functions that accept the same parameters and call them all with the provided arguments.

Import

/* Node: */  import callAll from "froebel/callAll";
/* Deno: */  import callAll from "https://deno.land/x/froebel@v0.23.2/callAll.ts";

Example

const mult = (a: number, b: number) => a * b
const div  = (a: number, b: number) => a / b

// prints: [8, 2]
console.log( callAll([mult, div], 4, 2) )

pipe

(...funs: T) => PipedFun<T>

source | tests

Given a list of functions returns a function that will execute the given functions one after another, always passing the result of the previous function as an argument to the next function.

If one of the given functions returns a promise, the promise will be resolved before being passed to the next function.

Import

/* Node: */  import pipe from "froebel/pipe";
/* Deno: */  import pipe from "https://deno.land/x/froebel@v0.23.2/pipe.ts";

Example

const join = (...chars: string[]) => chars.join('')
pipe(join, parseInt)('1', '2', '3')  // -> 123

const square = (n: number) => n ** 2

// this is equivalent to: square(square(square(2)))
pipe(square, square, square)(2)  // -> 256

// also works with promises:
fetchNumber :: async () => Promise<number>
pipe(fetchNumber, n => n.toString())  // async () => Promise<string>

applyPipe

(arg: Parameters<T[0]>[0], ...funs: T) => CheckPipe<T, CarryReturn<ReturnTypes<T>, Parameters<T[0]>>, false>

source | tests

Like pipe but takes an argument as its first parameter and invokes the pipe with it.

Note: unlike in pipe, the first function of the pipe must take exactly one argument.

see pipe

Import

/* Node: */  import { applyPipe } from "froebel/pipe";
/* Deno: */  import { applyPipe } from "https://deno.land/x/froebel@v0.23.2/pipe.ts";

Example

applyPipe(2, double, square, half)  // -> 8

bundle

(...funs: λ<T>[]) => (...args: T) => Promise<void>

source | tests

Given a list of functions that accept the same parameters, returns a function that takes these parameters and invokes all of the given functions.

The returned function returns a promise that resolves once all functions returned/resolved and rejects if any of the functions throws/rejects - but only after all returned promises have been settled.

Import

/* Node: */  import bundle from "froebel/bundle";
/* Deno: */  import bundle from "https://deno.land/x/froebel@v0.23.2/bundle.ts";

bundleSync

(...funs: λ<T>[]) => (...args: T) => void

source | tests

Same as bundle, but return synchronously.

If any of the functions throws an error synchronously, none of the functions after it will be invoked and the error will propagate.

Import

/* Node: */  import { bundleSync } from "froebel/bundle";
/* Deno: */  import { bundleSync } from "https://deno.land/x/froebel@v0.23.2/bundle.ts";

nullishChain

(...funs: [] | [FF, ...FR[]]) => (...args: Parameters<FF>) => ReturnType<FF> | ReturnType<FR[number]>

source | tests

Given a list of functions that accept the same parameters, returns a function that given these arguments returns the result of the first function whose result is not nullish.

This is equivalent to chaining together invocations of the passed in functions with the given arguments with nullish coalescing (??) operators.

Import

/* Node: */  import { nullishChain } from "froebel/nullishChain";
/* Deno: */  import { nullishChain } from "https://deno.land/x/froebel@v0.23.2/nullishChain.ts";

Example

const isAdult   = (age: number) => { if (n >= 18) return 'adult' }
const isToddler = (age: number) => { if (n <= 3) return 'toddler' }

const ageGroup = nullishChain(isAdult, isToddler, () => 'child')

// this is functionally equivalent to:
const ageGroup = age => isAdult(age) ?? isToddler(age) ?? 'child'

ageGroup(1)  // prints: 'toddler'
ageGroup(10) // prints: 'child'
ageGroup(50) // prints: 'adult'

asyncNullishChain

(...funs: [] | [FF, ...FR[]]) => (...args: Parameters<FF>) => Promise<PromType<ReturnType<FF>> | PromType<ReturnType<FR[number]>>>

source | tests

Same as nullishChain but accept asynchronous functions too.

Import

/* Node: */  import { asyncNullishChain } from "froebel/nullishChain";
/* Deno: */  import { asyncNullishChain } from "https://deno.land/x/froebel@v0.23.2/nullishChain.ts";

Example

const readFromCache = (id: string): Resource => { if (id in cache) return cache[id] }
const readFromFile  = (id: string): Resource => { if (fileExists(id)) return readFile(id) }
const fetchFromNet  = async (id: string): Promise<Resource> => await fetch(`someURL/${id}`)

// async (id: string) => Promise<Resource>
const getResource = asyncNullishChain(readFromCache, readFromFile, fetchFromNet)

throttle

(fun: T, ms: number, opts?: {leading: boolean, trailing: boolean}) => λ<Parameters<T>, void> & {[cancel]: () => void}

source | tests

Create a throttled function that invokes fun at most every ms milliseconds.

fun is invoked with the last arguments passed to the throttled function.

Calling [throttle.cancel]() on the throttled function will cancel the currently scheduled invocation.

Import

/* Node: */  import throttle from "froebel/throttle";
/* Deno: */  import throttle from "https://deno.land/x/froebel@v0.23.2/throttle.ts";

debounce

(fun: T, ms: number) => λ<Parameters<T>, void> & {[cancel]: () => void}

source | tests

Creates a debounced function that delays invoking fun until ms milliseconds have passed since the last invocation of the debounced function.

fun is invoked with the last arguments passed to the debounced function.

Calling [debounce.cancel]() on the debounced function will cancel the currently scheduled invocation.

Import

/* Node: */  import debounce from "froebel/debounce";
/* Deno: */  import debounce from "https://deno.land/x/froebel@v0.23.2/debounce.ts";

memoize

(fun: T, opt: {limit: number, weak: W, key: (...args: Parameters<T>) => K}) => T & {cache: W extends false ? Map<K, ReturnType<T>> : Cache<K, ReturnType<T>>}

source | tests

Returns a copy of fun that remembers its result for any given arguments and only invokes fun for unknown arguments.

The cache key is computed using the key function. The default key function simply stringifies the arguments.

If limit is specified, only the limit-last entries are kept in cache.

The function's cache is available at memoized.cache.

If opt.weak is true, non-primitive cache keys are stored in a WeakMap. This behavior might for example be useful if you want to memoize some calculation including a DOM Node without holding on to a reference of that node. Using weak keys prohibits setting a limit.

Import

/* Node: */  import memoize from "froebel/memoize";
/* Deno: */  import memoize from "https://deno.land/x/froebel@v0.23.2/memoize.ts";

Examples

const expensiveCalculation = (a: number, b: number) => {
  console.log(`calculate ${a} + ${b}`)
  return a + b
}
const calc = memoize(expensiveCalculation)

console.log( calc(1, 2) )
// calculate 1 + 2
// 3
console.log( calc(20, 5) )
// calculate 20 + 5
// 25
console.log( calc(20, 5) )
// 25
console.log( calc(1, 2) )
// 3

calc.cache.clear()
console.log( calc(1, 2) )
// calculate 1 + 2
// 3
const logIfDifferent = memoize(
  (msg: string) => console.log(msg),
  {
    limit: 1,
    key: msg => msg
  }
)

logIfDifferent('a')
logIfDifferent('a')
logIfDifferent('b')
logIfDifferent('a')

// a
// b
// a

limitInvocations

(fun: T, limit: number, ...funs: ExcS<T>) => T

source | tests

Returns a version of the function fun that can only be invoked limit times. An optional except function will be called with the same parameters on any additional invocations.

If fun returns anything but void (or Promise<void>), supplying an except function is mandatory.

The except function must have the same return type as fun, or — if fun returns a promise — it may return the type that the promise resolves to synchronously.

The except function may also throw instead of returning a value.

Import

/* Node: */  import { limitInvocations } from "froebel/invoke";
/* Deno: */  import { limitInvocations } from "https://deno.land/x/froebel@v0.23.2/invoke.ts";

once

(fun: T, ...funs: ExcS<T>) => T

source | tests

Special case of limitInvocations. fun can only be invoked once.

see limitInvocations

Import

/* Node: */  import { once } from "froebel/invoke";
/* Deno: */  import { once } from "https://deno.land/x/froebel@v0.23.2/invoke.ts";

List

atWrap

(arr: T[], i: number) => T

source | tests

Access list at i % length. Negative indexes start indexing the last element as [-1] and wrap around to the back.

Import

/* Node: */  import atWrap from "froebel/atWrap";
/* Deno: */  import atWrap from "https://deno.land/x/froebel@v0.23.2/atWrap.ts";

zip

(...lists: T) => Zip<T>

source | tests

Takes multiple lists and returns a list of tuples containing the value in each list at the current index. If the lists are of different lengths, the returned list of tuples has the length of the shortest passed in list.

Import

/* Node: */  import zip from "froebel/zip";
/* Deno: */  import zip from "https://deno.land/x/froebel@v0.23.2/zip.ts";

Example

const pairs = zip([1,2,3], ['a','b','c'])
console.log(pairs) // prints: [[1,'a'], [2,'b'], [3,'c']]

zipWith

(zipper: (...args: {[I in string | number | symbol]: U}) => U, ...lists: T) => U[]

source | tests

Same as zip but also takes a zipper function, that is called for each index with the element at current index in each list as arguments. The result of zipper is the element at current index in the list returned from zipWith.

Import

/* Node: */  import { zipWith } from "froebel/zip";
/* Deno: */  import { zipWith } from "https://deno.land/x/froebel@v0.23.2/zip.ts";

Example

const sums = zipWith((a,b) => a+b, [1,2,3], [4,5,6])
console.log(sums) // prints: [5,7,9]

unzip

(...zipped: T[][]) => Unzip<T>

source | tests

Reverse of zip. Takes a list of tuples and deconstructs them into an array (of length of the tuples length) of lists each containing all the elements in all tuples at the lists index.

Import

/* Node: */  import unzip from "froebel/unzip";
/* Deno: */  import unzip from "https://deno.land/x/froebel@v0.23.2/unzip.ts";

Example

const [nums, chars] = unzip([1,'a'], [2,'b'], [3,'c'])
console.log(nums)  // prints: [1, 2, 3]
console.log(chars) // prints: ['a','b','c']

unzipWith

(zipped: T[][], ...unzippers: U) => {[I in string | number | symbol]: ReturnType<U[I]>}

source | tests

Same as unzip but accepts an unzipper function for each tuple index. The unzipper's return value is used as the value in the list at that index returned from unzipWith.

The unzipper takes the current element as its first argument, an accumulator as second argument (initially undefined) and its return value is the accumulator passed into the next invocation.

Import

/* Node: */  import { unzipWith } from "froebel/unzip";
/* Deno: */  import { unzipWith } from "https://deno.land/x/froebel@v0.23.2/unzip.ts";

Example

const [nums, str] = unzipWith(
  [ [1,'a'], [2,'b'], [3,'c'] ],
  (n, acc: number[] = []) => [...acc, n],
  (c, str = '') => str + c
)

console.log(nums) // prints: [1, 2, 3]
console.log(str)  // prints: 'abc'

batch

(list: T[], batchSize: number) => T[][]

source | tests

Takes a list and returns it in multiple smaller lists of the size batchSize. The last batch may be smaller than batchSize depending on if list size is divisible by batchSize.

Import

/* Node: */  import batch from "froebel/batch";
/* Deno: */  import batch from "https://deno.land/x/froebel@v0.23.2/batch.ts";

Example

batch([1,2,3,4,5], 2)  // -> [ [1,2], [3,4], [5] ]

partition

(list: T[], predicate: (el: T) => el is S) => [S[], Exclude<T, S>[]]

source | tests

Takes a list and returns a pair of lists containing: the elements that match the predicate and those that don't, respectively.

Think of it as filter, but the elements that don't pass the filter aren't discarded but returned in a separate list instead.

Import

/* Node: */  import partition from "froebel/partition";
/* Deno: */  import partition from "https://deno.land/x/froebel@v0.23.2/partition.ts";

Example

const [strings, numbers] = partition(
  ['a', 'b', 1, 'c', 2, 3],
  (el): el is string => typeof el === 'string'
)
// strings: ["a", "b", "c"]
// numbers: [1, 2, 3]

shuffle

(list: T[]) => T[]

source | tests

Shuffles list using the Fisher-Yates shuffle algorithm. The original list is not modified and the shuffled list is returned.

Import

/* Node: */  import shuffle from "froebel/shuffle";
/* Deno: */  import shuffle from "https://deno.land/x/froebel@v0.23.2/shuffle.ts";

shuffleInPlace

(list: unknown[]) => void

source | tests

Same as shuffle but shuffles list in place.

Import

/* Node: */  import { shuffleInPlace } from "froebel/shuffle";
/* Deno: */  import { shuffleInPlace } from "https://deno.land/x/froebel@v0.23.2/shuffle.ts";

take

(n: number, list: Iterable<T>) => T[]

source | tests

Takes n elements from the iterable list and returns them as an array.

Import

/* Node: */  import { take } from "froebel/list";
/* Deno: */  import { take } from "https://deno.land/x/froebel@v0.23.2/list.ts";

Example

take(5, repeat(1, 2))  // -> [1, 2, 1, 2, 1]
take(3, [1, 2, 3, 4])  // -> [1, 2, 3]
take(3, [1, 2])        // -> [1, 2]

range

source | tests

Creates a range between two values.

see numberRange and alphaRange

Import

/* Node: */  import range from "froebel/range";
/* Deno: */  import range from "https://deno.land/x/froebel@v0.23.2/range.ts";

numberRange

(start: number, end: number, step: number) => number[]

source | tests

Constructs a numeric between start and end inclusively.

Import

/* Node: */  import { numberRange } from "froebel/range";
/* Deno: */  import { numberRange } from "https://deno.land/x/froebel@v0.23.2/range.ts";

Example

range(2, 6)      // -> [2, 3, 4, 5, 6]
range(8, 9, .3)  // -> [8, 8.3, 8.6, 8.9]
range(3, -2)     // -> [3, 2, 1, 0, -1, -2]

alphaRange

(start: string, end: string) => string[]

source | tests

Constructs a range between characters.

Import

/* Node: */  import { alphaRange } from "froebel/range";
/* Deno: */  import { alphaRange } from "https://deno.land/x/froebel@v0.23.2/range.ts";

Example

range('a', 'd')  // -> ['a', 'b', 'c', 'd']
range('Z', 'W')  // -> ['Z', 'Y', 'X', 'W']

Iterable

repeat

(...sequence: [T, ...T[]]) => Generator<T>

source | tests

Returns a generator that repeats sequence.

Import

/* Node: */  import repeat from "froebel/repeat";
/* Deno: */  import repeat from "https://deno.land/x/froebel@v0.23.2/repeat.ts";

Example

// prints: 1, 2, 3, 1, 2, 3, ...
for (const n of repeat(1, 2, 3))
  console.log(n)

take

(n: number, list: Iterable<T>) => Generator<T>

source | tests

Takes n elements from the iterable list and returns them as a generator.

Import

/* Node: */  import { take } from "froebel/iterable";
/* Deno: */  import { take } from "https://deno.land/x/froebel@v0.23.2/iterable.ts";

Example

[...take(5, repeat(1, 2))]  // -> [1, 2, 1, 2, 1]
[...take(3, [1, 2, 3, 4])]  // -> [1, 2, 3]
[...take(3, [1, 2])]        // -> [1, 2]

Object

pick

(obj: T, ...keys: K[]) => Pick<T, K>

source | tests

From obj, create a new object that only includes keys.

Import

/* Node: */  import pick from "froebel/pick";
/* Deno: */  import pick from "https://deno.land/x/froebel@v0.23.2/pick.ts";

Example

pick({ a: 1, b: 2, c: 3 }, 'a', 'c') // { a: 1, c: 3 }

omit

(obj: T, ...keys: K[]) => Omit<T, K>

source | tests

From obj, create a new object that does not include keys.

Import

/* Node: */  import omit from "froebel/omit";
/* Deno: */  import omit from "https://deno.land/x/froebel@v0.23.2/omit.ts";

Example

omit({ a: 1, b: 2, c: 3 }, 'a', 'c') // { b: 2 }

map

(data: Map<IK, IV>, callback: (key: IK, value: IV) => [OK, OV]) => Map<OK, OV>

source | tests

Map over data. data can be a regular object, a Map, a Set, or an array.

Import

/* Node: */  import map from "froebel/map";
/* Deno: */  import map from "https://deno.land/x/froebel@v0.23.2/map.ts";

Examples

// -> { a: 1, b: 2 }
map({ a: '1', b: '2' }, (key, value) => [key, parseInt(value)])
// -> Map([ [2, 1], [4, 3] ])
map(new Map([ [1, 2], [3, 4] ]), (key, value) => [key + 1, value - 1])

Path

select

(obj: T, ...path: P) => PickPath<T, P>

source | tests

Returns the value in obj at path. If the given path does not exist, the symbol none is returned.

Import

/* Node: */  import select from "froebel/select";
/* Deno: */  import select from "https://deno.land/x/froebel@v0.23.2/select.ts";

Example

// -> 'something'
select(
  { a: { deeply: [{ nested: { object: 'something' } }] } },
  'a', 'deeply', 0, 'nested', 'object'
)

Equality

oneOf

(value: T, ...cmps: TT) => value is TT[number]

source | tests

Checks if v is one of cmps.

Import

/* Node: */  import oneOf from "froebel/oneOf";
/* Deno: */  import oneOf from "https://deno.land/x/froebel@v0.23.2/oneOf.ts";

equal

(a: unknown, b: unknown) => boolean

source | tests

Checks if a and b are structurally equal using the following algorithm:

  • primitives are compared by value
  • functions are compared by reference
  • objects (including arrays) are checked to have the same properties and their values are compared recursively using the same algorithm

Import

/* Node: */  import equal from "froebel/equal";
/* Deno: */  import equal from "https://deno.land/x/froebel@v0.23.2/equal.ts";

clone

(value: T) => T

source | tests

Returns a copied version of value.

If value is primitive, returns value. Otherwise, properties of value are copied recursively. Only value's own enumerable properties are cloned. Arrays are cloned by mapping over their elements.

If a path in value references itself or a parent path, then in the resulting object that path will also reference the path it referenced in the original object (but now in the resuling object instead of the original).

Import

/* Node: */  import clone from "froebel/clone";
/* Deno: */  import clone from "https://deno.land/x/froebel@v0.23.2/clone.ts";

merge

(a: A, b: B) => Merge<A, B>

source | tests

Recursively merges A and B. If a property in A and B is of a different type (i.e. it's not an array, Set, Map, or plain object in both, the value from B will be used in the result).

If there are self-references in the cloned values, array / Set items, or Map keys or values, they will also be self-referencing in the result.

Import

/* Node: */  import merge from "froebel/merge";
/* Deno: */  import merge from "https://deno.land/x/froebel@v0.23.2/merge.ts";

Promise

promisify

(withCallback: T, resultIndex?: N, errorIndex: null | number) => Promisified<T, N>

source | tests

Turns a function accepting a callback into a function returning a promise. You can specify in which parameter (if any) the callback expects to receive a result and in which it expects an error. Pass null to resultIndex or errorIndex if no result or errors are passed to the callback. By default the first argument passed to the callback is interpreted as result and none of the arguments as error (if the function accepting the callback throws or rejects, that will still result in the promisified function rejecting).

The callbackFirst property allows passing additional parameters after the callback and callbackLast will pass additional parameters before the callback.

Import

/* Node: */  import promisify from "froebel/promisify";
/* Deno: */  import promisify from "https://deno.land/x/froebel@v0.23.2/promisify.ts";

Examples

const notify = (cb: (msg: string) => void) => { msg('something') }
const waitForMessage = promisify(notify)
await waitForMessage()  // -> 'something'

// here result is passed at index 1 and errors at index 0.
const callbackAPI = (cb: (error?: Error, data?: unknown) => void) => {}
const asyncAPI = promisify(callbackAPI, 1, 0)
const sleep = promisify(setTimeout).callbackFirst
await sleep(200)
const fs = require('node:fs');
const stat = promisify(fs.stat, 1, 0).callbackLast

try {
  const stats = await stat('.');
  console.log(`This directory is owned by ${stats.uid}`);
} catch (err) {
  console.error(err)
}

createQueue

() => Queue

source | tests

Creates a queue function that accepts a function as it's only parameter. When queue is invoked, the passed in function is executed after the last function passed to queue has finished executing. The queue function returns the result of the passed in function asynchronously.

Reading queue.done is true if no functions are currently executing / scheduled and otherwise a promise that resolves once the last function has stopped executing and no futher functions are queued.

Import

/* Node: */  import createQueue from "froebel/queue";
/* Deno: */  import createQueue from "https://deno.land/x/froebel@v0.23.2/queue.ts";

Example

const queue = createQueue()

queue(async () => {
  console.log('start a')
  await delay()
  return 'end a'
}).then(console.log)

queue(async () => {
  console.log('start b')
  await delay()
  return 'end b'
}).then(console.log)

queue(async () => {
  console.log('start c')
  await delay()
  return 'end c'
}).then(console.log)

await queue.done

// start a
// end a
// start b
// end b
// start c
// end c

isPromise

(value: unknown) => value is Promise<T>

source | tests

Checks if value looks like a promise.

Import

/* Node: */  import isPromise from "froebel/isPromise";
/* Deno: */  import isPromise from "https://deno.land/x/froebel@v0.23.2/isPromise.ts";

isNotPromise

(value: T) => value is Exclude<T, Promise<any>>

source | tests

Checks if value is not a promise.

Import

/* Node: */  import { isNotPromise } from "froebel/isPromise";
/* Deno: */  import { isNotPromise } from "https://deno.land/x/froebel@v0.23.2/isPromise.ts";

Example

(value: number | Promise<unknown>) => {
  if (isNotPromise(value)) return value / 2
}

Predicate

truthy

(value: T) => value is PickTruthy<T>

source | tests

Checks if value is truthy. Literal types are narrowed accordingly.

Import

/* Node: */  import { truthy } from "froebel/truthy";
/* Deno: */  import { truthy } from "https://deno.land/x/froebel@v0.23.2/truthy.ts";

falsy

(value: T) => value is PickFalsy<T>

source | tests

Checks if value is falsy. Literal types are narrowed accordingly.

Import

/* Node: */  import { falsy } from "froebel/truthy";
/* Deno: */  import { falsy } from "https://deno.land/x/froebel@v0.23.2/truthy.ts";

nullish

(value: T) => value is Nullish<T>

source | tests

Checks if value is nullish. Literal types are narrowed accordingly.

Import

/* Node: */  import { nullish } from "froebel/nullish";
/* Deno: */  import { nullish } from "https://deno.land/x/froebel@v0.23.2/nullish.ts";

notNullish

(value: null | T) => value is T

source | tests

Checks if value is not nullish. Literal types are narrowed accordingly.

Import

/* Node: */  import { notNullish } from "froebel/nullish";
/* Deno: */  import { notNullish } from "https://deno.land/x/froebel@v0.23.2/nullish.ts";

Example

const nums = (...values: (number | undefined)[]): number[] => values.filter(notNullish)

isFulfilled

(result: PromiseSettledResult<T>) => result is PromiseFulfilledResult<T>

source | tests

Checks if result (returned from Promise.allSettled) is fulfilled.

Import

/* Node: */  import { isFulfilled } from "froebel/settled";
/* Deno: */  import { isFulfilled } from "https://deno.land/x/froebel@v0.23.2/settled.ts";

isRejected

(result: PromiseSettledResult<unknown>) => result is PromiseRejectedResult

source | tests

Checks if result (returned from Promise.allSettled) is rejected.

Import

/* Node: */  import { isRejected } from "froebel/settled";
/* Deno: */  import { isRejected } from "https://deno.land/x/froebel@v0.23.2/settled.ts";

String

prefix

(prefix: T0, str: T1, caseMod?: C) => `${string}`

source | tests

Returns str prefixed with prefix. Optionally, allows prefxing in camel case, i.e. prefix('foo', 'bar', 'camel') => 'fooBar', or snake case, i.e. prefix('foo', 'bar', 'snake') => 'foo_bar'.

The result is strictly typed, so prefix('foo', 'bar') will return the type 'foobar', not just a generic string.

Import

/* Node: */  import prefix from "froebel/prefix";
/* Deno: */  import prefix from "https://deno.land/x/froebel@v0.23.2/prefix.ts";

suffix

(str: T1, suffix: T0, caseMod?: C) => `${string}`

source | tests

Returns str suffixed with suffix. Same case and type behavior as prefix.

Import

/* Node: */  import suffix from "froebel/suffix";
/* Deno: */  import suffix from "https://deno.land/x/froebel@v0.23.2/suffix.ts";

surround

(str: A, surrounding: B) => B extends "" ? A : Surround<A, B>

source | tests

Surrounds the str with surrounding. surrounding must have an even length.

Import

/* Node: */  import { surround } from "froebel/surround";
/* Deno: */  import { surround } from "https://deno.land/x/froebel@v0.23.2/surround.ts";

Example

surround("foo", "()")      // "(foo)"
surround("foo", "({[]})")  // "({[foo]})"

capitalize

(str: T) => Capitalize

source | tests

Upper-case first letter of string.

Import

/* Node: */  import { capitalize } from "froebel/case";
/* Deno: */  import { capitalize } from "https://deno.land/x/froebel@v0.23.2/case.ts";

uncapitalize

(str: T) => Uncapitalize

source | tests

Lower-case first letter of string

Import

/* Node: */  import { uncapitalize } from "froebel/case";
/* Deno: */  import { uncapitalize } from "https://deno.land/x/froebel@v0.23.2/case.ts";

upper

(str: T) => Uppercase

source | tests

Strictly typed String.toUpperCase().

Import

/* Node: */  import { upper } from "froebel/case";
/* Deno: */  import { upper } from "https://deno.land/x/froebel@v0.23.2/case.ts";

lower

(str: T) => Lowercase

source | tests

Strictly typed String.toLowerCase().

Import

/* Node: */  import { lower } from "froebel/case";
/* Deno: */  import { lower } from "https://deno.land/x/froebel@v0.23.2/case.ts";

snake

(str: T) => DelimitedCase<T, "_">

source | tests

Transforms a variable name to snake case.

Note: The rules for transforming anything to snake case are somewhat vague. So use this only for very simple names where the resulting value is absolutely unambiguous. For more examples of how names are transformed, have a look at the test cases.

Import

/* Node: */  import { snake } from "froebel/case";
/* Deno: */  import { snake } from "https://deno.land/x/froebel@v0.23.2/case.ts";

Example

snake('fooBar') // 'foo_bar'

kebab

(str: T) => DelimitedCase<T, "-">

source | tests

Transforms a variable name to kebab case.

Note: The rules for transforming anything to kebab case are somewhat vague. So use this only for very simple names where the resulting value is absolutely unambiguous. For more examples of how names are transformed, have a look at the test cases.

Import

/* Node: */  import { kebab } from "froebel/case";
/* Deno: */  import { kebab } from "https://deno.land/x/froebel@v0.23.2/case.ts";

Example

kebab('fooBar') // 'foo-bar'

camel

(str: T) => CamelCase<T>

source | tests

Transforms a variable name to camel case.

Note: The rules for transforming anything to camel case are somewhat vague. So use this only for very simple names where the resulting value is absolutely unambiguous. For more examples of how names are transformed, have a look at the test cases.

Import

/* Node: */  import { camel } from "froebel/case";
/* Deno: */  import { camel } from "https://deno.land/x/froebel@v0.23.2/case.ts";

Example

camel('foo_bar') // 'fooBar'

pascal

(str: T) => Capitalize

source | tests

Transforms a variable name to pascal case.

Note: The rules for transforming anything to pascal case are somewhat vague. So use this only for very simple names where the resulting value is absolutely unambiguous. For more examples of how names are transformed, have a look at the test cases.

Import

/* Node: */  import { pascal } from "froebel/case";
/* Deno: */  import { pascal } from "https://deno.land/x/froebel@v0.23.2/case.ts";

Example

pascal('foo_bar') // 'FooBar'

screamingSnake

(str: T) => Uppercase

source | tests

Transforms a variable name to screaming snake case.

see snake

Import

/* Node: */  import { screamingSnake } from "froebel/case";
/* Deno: */  import { screamingSnake } from "https://deno.land/x/froebel@v0.23.2/case.ts";

Example

screamingSnake('fooBar') // 'FOO_BAR'

transformCase

(str: T, targetCase: C) => DelimitedCase<T, "_">

source | tests

Transform a variable name to targetCase

see snake, kebab, camel, pascal, and screamingSnake

Import

/* Node: */  import { transformCase } from "froebel/case";
/* Deno: */  import { transformCase } from "https://deno.land/x/froebel@v0.23.2/case.ts";

Math

clamp

(min: number, num: number, max: number) => number

source | tests

Clamp num between min and max inclusively.

Import

/* Node: */  import clamp from "froebel/clamp";
/* Deno: */  import clamp from "https://deno.land/x/froebel@v0.23.2/clamp.ts";

Data Structures

BiMap

class BiMap<L, R>(data?: Map<L, R> | [L, R][], aliasLeft?: AL, aliasRight?: AR)

source | tests

Bidirectional map. Maps two sets of keys in a one-to-one relation.

Both sides are accessible (at .left & .right, or at their respective alias if one was provided in the constructor) with an interface similar to that of the built-in Map and the same iteration behavior.

Import

/* Node: */  import BiMap from "froebel/bimap";
/* Deno: */  import BiMap from "https://deno.land/x/froebel@v0.23.2/bimap.ts";

Examples

const nums = BiMap.from({ one: 1, two: 2 })

// different ways of iterating over the entries
[...nums.left]                 // [['one',1], ['two',2]]
[...nums.right]                // [[1,'one'], [2,'two']]
[...nums.left.keys()]          // ['one', 'two']
[...nums.left.values()]        // [1, 2]
[...nums.right.keys()]         // [1, 2]
[...nums.right.values()]       // ['one', 'two']
[...nums]                      // [['one',1], ['two',2]]
[...nums.right.entries()]      // [[1,'one'], [2,'two']]
Object.fromEntries(nums.right) // { '1': 'one', '2': 'two' }

// setting a value
nums.left.three = 3
// when accessing a property using bracket notation (i.e. nums.right[4]),
// JavaScript coerces the key to a string, so keys that aren't strings or
// symbols must be accessed using the same access methods known from Map.
nums.right.set(4, 'four')

// remapping values
nums.left.tres = 3          // {one: 1, two: 2, tres: 3, four: 4}
nums.right.set(4, 'cuatro') // {one: 1, two: 2, tres: 3, cuatro: 4}

// deleting
delete nums.left.tres    // {one: 1, two: 2, cuatro: 4}
nums.right.delete(4)     // {one: 1, two: 2}

// reversing the map
const num2Name = nums.reverse()
console.log([...num2Name.left])                 // [[1,'one'], [2,'two']]
console.log(Object.fromEntries(num2Name.right)) // {one: 1, two: 2}

// other methods known from built-in Map
nums.size               // 2
nums.[left|right].size  // 2
nums.clear() // equivalent to nums.[left|right].clear()
console.log(nums.size)  // 0
// giving aliases to both sides
const dictionary = new BiMap(
  [
    ['hello', 'hallo'],
    ['bye', 'tschüss'],
  ],
  'en',
  'de'
)

dictionary.de.get('hallo') // 'hello'
dictionary.en.get('bye')   // 'tschüss'

delete dictionary.de.hallo
console.log(Object.fromEntries(dictionary.en)) // { bye: 'tschüss' }

// you can also use the BiMap.alias method:
BiMap.alias('en', 'de')<string, string>()
BiMap.alias('en', 'de')([['hello', 'hallo']])
BiMap.alias('en', 'de')(new Map<string, string>())
BiMap.alias('en', 'de')({ hello: 'hallo' })
BiMap.alias('en', 'de')(new Set(['hello']), new Set(['hallo']))

// the same arguments can be used with BiMap.from, e.g.:
BiMap.from(new Set<number>(), new Set<number>())

SortedArray

class SortedArray<T>(compare: Cmp<T>, ...value: T[])

source | tests

Sorted array. Behaves much like a regular array but its elements remain sorted using the compare function supplied in the constructor.

Contains most of the methods defined on regular JavaScript arrays as long as they don't modify the array's content in place.

New elements are added using the add(...values) method.

Elements can still be accessed using bracket notation as in plain JavaScript arrays but can't be assigned to using bracket notation (as that could change the element's sort position).

Elements can be removed using the delete(...indices) method, which returns an array containing the deleted values. Deleting an element using delete sorted[index] will also work, but results in a TypeScript error because element access is marked readonly.

Array methods that pass a reference of the array to a callback (e.g. map, reduce, find) will pass a reference to the SortedArray instance instead.

The filter and slice methods will return SortedArray instances instead of plain arrays.

Import

/* Node: */  import SortedArray from "froebel/sortedArray";
/* Deno: */  import SortedArray from "https://deno.land/x/froebel@v0.23.2/sortedArray.ts";

SortedMap

class SortedMap<K, V>(compare: Cmp<K, V>, entries?: null | [K, V][])

source | tests

Behaves like a regular JavaScript Map, but its iteration order is dependant on the compare function supplied in the constructor.

Note: The item's sort position is only computed automatically on insertion. If you update one of the values that the compare function depends on, you must call the update(key) method afterwards to ensure the map stays sorted.

Import

/* Node: */  import SortedMap from "froebel/sortedMap";
/* Deno: */  import SortedMap from "https://deno.land/x/froebel@v0.23.2/sortedMap.ts";

Download Details:

Author: MathisBullinger
Source Code: https://github.com/MathisBullinger/froebel 
License: ISC license

#typescript #javascript #functional #programming #deno 

Froebel: A Strictly Typed Utility Library
Lawrence  Lesch

Lawrence Lesch

1676317440

Webview_deno: Deno Bindings for Webview

Webview_deno

deno bindings for webview

Webview is a tiny cross-platform library to make web-based GUIs for desktop applications.


⚠️ This project is still in development. Expect breaking changes.


Example Image

Example

import { Webview } from "https://deno.land/x/webview/mod.ts";

const html = `
  <html>
  <body>
    <h1>Hello from deno v${Deno.version.deno}</h1>
  </body>
  </html>
`;

const webview = new Webview();

webview.navigate(`data:text/html,${encodeURIComponent(html)}`);
webview.run();

You can run this example directly from the web:

deno run -Ar --unstable https://deno.land/x/webview/examples/local.ts

or in your development environment:

deno run -Ar --unstable examples/local.ts

you can find other examples in the examples/ directory.

Documentation

You can find the official documentation here.

Development

Prerequisites

Linux

  • webkit2gtk (to install using apt: sudo apt-get install libwebkit2gtk-4.0-dev)

Building

Make sure to init the webview submodule with:

$ git submodule update --init --recursive

Building on Windows requires admin privileges.

$ deno task build

Running

To run webview_deno without automatically downloading the binaries from releases you will need to use the environment variable PLUGIN_URL and set it to the path where the built binaries are located. This is usually file://./target/release.

$ deno task build
$ PLUGIN_URL=./build/
$ deno run --unstable -A examples/local.ts

or

$ deno task run examples/local.ts

or if you have the webview library already built and didn't make any changes to it, you can skip the building step with:

$ deno task run:fast examples/local.ts

Environment variables

  • PLUGIN_URL - Set a custom library URL. Defaults to the latest release assets on Github. Setting this also disables cache for plug.

Dependencies

Other

Contribution

Pull request, issues and feedback are very welcome. Code style is formatted with deno task fmt, linted with deno task lint and commit messages are done following Conventional Commits spec.

Download Details:

Author: Webview
Source Code: https://github.com/webview/webview_deno 
License: MIT license

#typescript #gui #webview #hacktoberfest #deno 

Webview_deno: Deno Bindings for Webview
Nat  Grady

Nat Grady

1675751345

Deno: A Modern Runtime for JavaScript and TypeScript

Deno

Deno is a simple, modern and secure runtime for JavaScript and TypeScript that uses V8 and is built in Rust.

Features

  • Secure by default. No file, network, or environment access, unless explicitly enabled.
  • Supports TypeScript out of the box.
  • Ships only a single executable file.
  • Built-in utilities.
  • Set of reviewed standard modules that are guaranteed to work with Deno.

Install

Shell (Mac, Linux):

curl -fsSL https://deno.land/install.sh | sh

PowerShell (Windows):

irm https://deno.land/install.ps1 | iex

Homebrew (Mac):

brew install deno

Chocolatey (Windows):

choco install deno

Scoop (Windows):

scoop install deno

Build and install from source using Cargo:

cargo install deno --locked

See deno_install and releases for other options.

Getting Started

Try running a simple program:

deno run https://deno.land/std/examples/welcome.ts

Or a more complex one:

const listener = Deno.listen({ port: 8000 });
console.log("http://localhost:8000/");

for await (const conn of listener) {
  serve(conn);
}

async function serve(conn: Deno.Conn) {
  for await (const { respondWith } of Deno.serveHttp(conn)) {
    respondWith(new Response("Hello world"));
  }
}

You can find a deeper introduction, examples, and environment setup guides in the manual.

The complete API reference is available at the runtime documentation.

Contributing

We appreciate your help!

To contribute, please read our contributing instructions.

Download Details:

Author: Denoland
Source Code: https://github.com/denoland/deno 
License: MIT license

#typescript #javascript #rust #deno 

Deno: A Modern Runtime for JavaScript and TypeScript

Deno Vue Example: An Example Of using Vue with Deno

How to use Vue with Deno

Vue is a progressive front-end JavaScript framework, built for performance and versatility.

This How To guide will show you how to create a simple app using Deno, Vite, and Vue.

Run npm:create-vite-extra

We'll use Vite to scaffold our Vue app. First, run:

deno run -A npm:create-vite-extra

Name your project, then select "deno-vue".

Then, cd into your new project and run:

deno task dev

You should now be able to view your default Deno and Vue app in your browser:

default vue app

Add a backend

The next step is to add a backend API. We'll create a very simple API that returns information about dinosaurs.

In the directory, let's create an api folder. In that folder, we'll create a main.ts file, which will run the server, and a data.json, which is the hard coded data.

mkdir api && touch api/data.json && touch api/main.ts

Copy and paste this json file into your api/data.json.

Then, let's update api/main.ts:

import { Application, Router } from "https://deno.land/x/oak@v11.1.0/mod.ts";
import { oakCors } from "https://deno.land/x/cors@v1.2.2/mod.ts";
import data from "./data.json" assert { type: "json" };

const router = new Router();
router
  .get("/", (context) => {
    context.response.body = "Welcome to dinosaur API!";
  })
  .get("/api", (context) => {
    context.response.body = data;
  })
  .get("/api/:dinosaur", (context) => {
    if (context?.params?.dinosaur) {
      const filtered = data.filter((item) =>
        item["name"].toLowerCase() === context.params.dinosaur.toLowerCase()
      );
      if (filtered.length === 0) {
        context.response.body = "No dinosaurs found.";
      } else {
        context.response.body = filtered[0];
      }
    }
  });

const app = new Application();
app.use(oakCors()); // Enable CORS for All Routes
app.use(router.routes());
app.use(router.allowedMethods());

await app.listen({ port: 8000 });

This is a very simple API server using oak that will return dinosaur information based on the route. Let's start the API server:

deno run --allow-env --allow-net api/main.ts

If we go to localhost:8000/api, we see:

json response of dinosaurs

Lookin' good so far.

Add Vue components

Let's update src/components. We'll add the files:

  • HomePage.vue, the component for the home page
  • Dinosaurs.vue, the component that lists all dinosaur names as anchor links, and
  • Dinosaur.vue, the component that shows an individual dinosaur's name and description
touch src/components/HomePage.vue src/components/Dinosaurs.vue src/components/Dinosaur.vue

Before we create the components, let's add some state management.

Maintain state with store

In order to maintain state across our <Dinosaur> and <Dinosaurs> components, we'll use Vue store. Note for more complex state management, check out the Vue-endorsed Pinia library.

Create a src/store.js file:

touch src/store.js

And in it, let's add:

import { reactive } from "vue";

export const store = reactive({
  dinosaur: {},
  setDinosaur(name, description) {
    this.dinosaur.name = name;
    this.dinosaur.description = description;
  },
});

We'll import store into both Dinosaurs.vue and Dinosaur.vue to set and retrieve dinosaur name and description.

Update Vue components

In Dinosaurs.vue, we'll three things:

  • send a GET request to our API and return that as dinosaurs
  • iterate through dinosaurs and render each dinosaur in <router-link> that points to the <Dinosaur> component
  • add store.setDinosaur() to @click on each dinosaur, which will set the store

Here is the complete code below:

<script>
import { ref } from 'vue'
import { store } from '../store.js'
export default ({
  async setup() {
    const res = await fetch("http://localhost:8000/api")
    const dinosaurs = await res.json();
    return {
      dinosaurs
    }
  },
  data() {
    return {
      store
    }
  }
})
</script>

<template>
  <div class="container">
    <div v-for="dinosaur in dinosaurs" class="dinosaur-wrapper">
      <span class="dinosaur">
        <router-link :to="{ name: 'Dinosaur', params: { dinosaur: `${dinosaur.name.toLowerCase()}` }}">
          <span @click="store.setDinosaur(dinosaur.name, dinosaur.description)">
            {{dinosaur.name}}
          </span>
        </router-link>
      </span>
    </div>
  </div>
</template>

<style scoped>
.dinosaur {
}
.dinosaur-wrapper {
  display: inline-block;
  margin: 0.15rem 1rem;
  padding: 0.15rem 1rem;
}
.container {
  text-align: left;
}
</style>

In Dinosaur.vue, we'll add:

  • importing store
  • rendering store.dinosaur in the HTML
<script>
import { store } from '../store.js';
export default {
  data() {
    return {
      store
    }
  }
}
</script>

<template>
  Name: {{ store.dinosaur.name }}
  <br />
  Description: {{ store.dinosaur.description }}
</template>

Next, we'll update HomePage.vue. Since the Dinosaurs component needs to fetch the data from the API, we'll use <Suspense>, which manages async dependencies in a component tree.

<script>
import { ref } from 'vue'
import Dinosaurs from './Dinosaurs.vue'
export default {
  components: {
    Dinosaurs
  }
}
</script>

<template>
  <Suspense>
    <template #default>
      <Dinosaurs />
    </template>
    <template #fallback>
      <div>Loading...</div>
    </template>
  </Suspense>

  <p>
    Check out
    <a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
      >create-vue</a
    >, the official Vue + Vite starter
  </p>
  <p class="read-the-docs">Learn more about using Deno and Vite.</p>
</template>

<style scoped>
.read-the-docs {
  color: #888;
}
</style>

Tying it all together, let's update src/App.vue:

<script setup>
</script>

<template>
  <router-view/>
</template>

<style scoped>
</style>

Add routing

You'll notice that we have used <router-link> and <router-view>. These components are part of the vue-router library, which we'll have to setup and configure in another file.

First, let's import vue-router in our vite.config.mjs file:

import { defineConfig } from "npm:vite@^3.1.3";
import vue from "npm:@vitejs/plugin-vue@^3.2.39";

import "npm:vue@^3.2.39";
import "npm:vue-router@4";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
});

Next, let's create a folder named router. In it, let's create index.ts:

mkdir router && touch router/index.ts

In router/index.ts, we'll create router, which contains information about each route and their component, and export it. For more information on using vue-router, check out their guide.

import { createRouter, createWebHistory } from "vue-router";
import HomePage from "../components/HomePage.vue";
import Dinosaur from "../components/Dinosaur.vue";

const routes = [
  {
    path: "/",
    name: "Home",
    component: HomePage,
  },
  {
    path: "/:dinosaur",
    name: "Dinosaur",
    component: Dinosaur,
    props: true,
  },
];

const router = createRouter({
  history: createWebHistory("/"),
  routes,
});

export default router;

Next, in our src/main.ts file, which contains all of the logic for the frontend app, we'll have to import and use router:

import { createApp } from "vue";
import "./style.css";
import App from "./App.vue";
import router from "./router/index.ts";

const app = createApp(App);
app.use(router);
app.mount("#app");

Let's run it and see what we get so far:

Awesome!


Download details:

Author: denoland
Source code: https://github.com/denoland/deno-vue-example

#vue #deno 

Deno Vue Example: An Example Of using Vue with Deno
Leonard  Paucek

Leonard Paucek

1673833408

DenoGres: A New Comprehensive ORM for PostgreSQL and Deno

Welcome to DenoGres! A new comprehensive ORM for PostgreSQL and Deno.

Getting Started

To begin, let's download DenoGres! Execute the below in the terminal - this will give you access to DenoGres's CLI functionality.

deno install --allow-read --allow-write --allow-net --allow-env --allow-run --name denogres https://deno.land/x/denogres/mod.ts

After installation is complete, ensure deno is added to PATH.

Quick Start

Before using DenoGres in a project, run the command below.

denogres --init

This will create the following in your project's root directory:

  • .env file for your database connection URI
  • a models folder for your model.ts file
  • a Migrations folder for migration logs and model snapshots

After running the init command, update the .env file to contain your database's connection URI.

DATABASE_URI=driver://user:password@host:port/database_name

With all the set-up steps complete, you're ready to introspect your database! Database introspection will automatically create TypeScript models of your database tables in the .models/model.ts file.

denogres --db-pull

Synchronizing your Database

Denogres features bi-directional synchronization that is designed to ensure that your database schema and your project Models in full alignment, maintaining a single, consistent source of truth.

To introspect and generate the associated models within the model.ts file, execute the the following CLI command:

denogres --db-pull

In addition to --db-pull, Denogres also includes --db-sync functionality that will revise the PostgreSQL schema to reflect changes within the DenoGres model.ts file.

Once completed changes to your model have been made, execute the following CLI command:

denogres --db-sync

Seeding Your Database

DenoGres allows data to be populated to the PostgreSQL schema through data seeding. This is primarily useful during database design/development (i.e. an application requires a certain amount of data to function properly) Create a seed.ts within the project root directory, and execute the following CLI command:

denogres --db-seed

The associated database schema will be pre-populated based on the user's seed.ts file.

Navigating the GUI

DenoGres includes a GUI that allows the user to test and run queries utilizing generated Models and associated methods. Furthermore, users can save database connections and previous queries to their accounts for later access.

Launch the DenoGres GUI by running the following CLI command:

denogres --gui

alt text

Connections

The Connections page allows users to connect to any database after providing its credentials. User can add and save multiple databases, but are only allowed to have one active connection at a time.

Connections.gif

Console

The Console page allows users to run database queries as needed. They can also be saved for later use.

Console.gif

The Console page also features active models for your databse tables. This allows users to have a reference when inputting query strings properly.

Model.gif

Diagram

The Diagram page offers a live ERD which visualizes the database for the user. This includes relational mapping for all of the database tables.

Some key features of the ERD are its ability to be adjusted to the user's preference with a live interface and the ability to save the diagram as an image.

ReactFlow.gif

Migration Logs and Restore

Any time a user opts to make a request for --db-pull or --db-sync, Denogres maintains a record of that request so that users can refer back to those historical records. Additionally, users can opt to restore the Model/database schema to prior iterations, in instances where users would like to roll back/forward changes that have been made.

To see a historical list of migration logs, execute the following CLI command:

denogres --log

To restore Models to a prior version, execute the following CLI command:

denogres --restore [PREVIOUS_MODEL_FOLDER]

Under Development

DenoGres is continually evolving. Features currently in development include:

  • Database sync method (denogres --db-sync) will account for multiple associations and composite unique keys.
  • "Compare" command (denogres --compare) will be implemented to display side-by-side diff between previous models.
  • Migrations log will be visible within the GUI, so that users can track/view/compare model versions.
  • Two-way ERD that allows users to change relational data that is then reflected onto their actual database
  • Additional support for MySQL, SQL Server, etc.

Documentation

More information on how to use DenoGres and leverage all its wonderful abstraction functionality can be found here: https://denogres.deno.dev/

Contributors

Version 3.0

Version 2.0

Version 1.0


Download details:

Author: open-source-labs
Source code: https://github.com/open-source-labs/DenoGres

#postgresql #deno 

DenoGres: A New Comprehensive ORM for PostgreSQL and Deno
Teagan  Taylor

Teagan Taylor

1673452800

Web3: Deno / TypeScript to Ethereum Connector

Web3

Thanks to ntrotner and thanks to the hints we have received in the context of this issue, Deno is ready for web3 with this module.

With this module you can connect your TypeScript in Deno program with the Ethereum Blockchain.

If you need to use nodejs instead of deno, check the web3 npm library. Some of you might also use the ethers library as an alternative.

In some months from now (writing this early 2022) it might be possible to just import such dependencies via skypack.dev.

Usage Example

Get Balance


deno run --allow-net https://deno.land/x/web3/usage-examples/get-balance.ts https://mainnet.infura.io/v3/<your-project-id>

import Web3 from 'https://deno.land/x/web3/mod.ts'

const providerURL = Deno.args[0]

const web3 = new Web3(new Web3.providers.HttpProvider(providerURL))

const balance = await web3.eth.getBalance("0x7a915e362353d72570dcf90aa5baa1c5b341c7aa")

console.log(`the balance is ${balance} wei`)

Get Transaction


deno run --allow-net https://deno.land/x/web3/usage-examples/get-transaction.ts https://mainnet.infura.io/v3/<your-project-id>

import Web3 from 'https://deno.land/x/web3/mod.ts'

const providerURL = Deno.args[0]

const web3 = new Web3(new Web3.providers.HttpProvider(providerURL))

const transactionHash = "0x0d558d490c89fc94ddfebd284e39da5c1bcff15d18c4e9fd2eb37a202d20c703"

const transaction = (await web3.eth.getTransaction(transactionHash))

console.log(transaction)

Create Account


deno run --allow-net https://deno.land/x/web3/usage-examples/create-account.ts https://mainnet.infura.io/v3/<your-project-id>

import Web3 from 'https://deno.land/x/web3/mod.ts'

const providerURL = Deno.args[0]

const web3 = new Web3(new Web3.providers.HttpProvider(providerURL))

const newAccount = await web3.eth.accounts.create()

console.log(newAccount)

Contributions

Feel free to contribute by raising Pull Requests. If you are a contributor at https://github.com/ethereum or https://github.com/chainsafe let us know if you want to move this repository to the corresponding organization.

Support

Feel free to create issues and fund their solutions e.g. via https://gitcoin.co/.


Download details:

Author: distributed-ledger-technology
Source code: https://github.com/distributed-ledger-technology/web3

License: MIT license

#TypeScript #deno #Ethereum  #web3 

Web3: Deno / TypeScript to Ethereum Connector
Lawrence  Lesch

Lawrence Lesch

1673415300

Deno_std: Deno Standard Library

Deno Standard Modules

These modules do not have external dependencies and they are reviewed by the Deno core team. The intention is to have a standard set of high quality code that all Deno projects can use fearlessly.

Contributions are welcome!

Releases

Standard library is currently tagged independently of Deno version. This will change once the library is stabilized.

To check compatibility of different version of standard library with Deno CLI see this list.

How to use

These modules will eventually be tagged in accordance with Deno releases but as of today we do not yet consider them stable and so we version the standard modules differently from the Deno runtime to reflect this.

It is strongly recommended that you link to tagged releases to avoid unintended updates and breaking changes.

Don't link to / import any module whose path:

  • Has a name or parent with an underscore prefix: _foo.ts, _util/bar.ts.
  • Is that of a test module or test data: test.ts, foo_test.ts, testdata/bar.txt.

Don't import any symbol with an underscore prefix: export function _baz() {}.

These elements are not considered part of the public API, thus no stability is guaranteed for them.

Documentation

To browse documentation for modules:

Contributing

NOTE: This repository was unarchived and synced on Feb, 1st, 2021. If you already had it cloned, we suggest to do a fresh clone to avoid git conflicts.

deno_std is a loose port of Go's standard library. When in doubt, simply port Go's source code, documentation, and tests. There are many times when the nature of JavaScript, TypeScript, or Deno itself justifies diverging from Go, but if possible we want to leverage the energy that went into building Go. We generally welcome direct ports of Go's code.

Please ensure the copyright headers cite the code's origin.

Follow the style guide.

Opening a pull request

After cloning don't forget to git submodule update --init.

Before opening a PR make sure to:

  • have the latest Deno version installed locally
  • add tests that cover your changes.
  • deno task test passes.
  • deno fmt --check passes.
  • deno task lint passes.

Give the PR a descriptive title.

Examples of good titles:

  • fix(http): Fix race condition in server
  • docs(fmt): Update docstrings
  • feat(log): Handle nested messages

Examples of bad titles:

  • fix #7123
  • update docs
  • fix bugs

Ensure there is a related issue and it is referenced in the PR text.

For contributions to the Node compatibility library please check the std/node contributing guide

About CI checks:

We currently have 9 checks on CI. Each PR should pass all of these checks to be accepted.

  • test with Deno canary on Windows
  • test with Deno canary on Linux
  • test with Deno canary on macOS
  • test Node polyfill with Deno canary on Windows
  • test Node polyfill with Deno canary on Linux
  • test Node polyfill with Deno canary on macOS
  • lint
  • wasm crypto check
  • CLA

For maintainers:

To release a new version a tag in the form of x.y.z should be added.

Internal Assertions

All internal non-test code, that is files that do not have test or bench in the name, must use the assertion functions within _utils/asserts.ts and not testing/asserts.ts. This is to create a separation of concerns between internal and testing assertions.

Types

Deno is moving away from non-native IO functions and interfaces in favor of the Streams API. These types are to be defined here, in the Standard Library, instead of in the Deno namespace in the future. As a rule, use the following corresponding and identical types from types.d.ts:

  • Deno.Reader
  • Deno.Writer
  • Deno.ReaderSync
  • Deno.WriterSync
  • Deno.Closer

See the tracking issue here.

Download Details:

Author: Denoland
Source Code: https://github.com/denoland/deno_std 
License: MIT license

#typescript #javascript #deno 

Deno_std: Deno Standard Library

Deno Vs Node.js: Compare The Differences

In this NodeJS tutorial, we will learn about Deno Vs Node.js: Compare The Differences. In this article, We will try to understand the framework, Deno, with its similarities and differences with Node.js

What is Deno?

Deno is a secure TypeScript runtime built on V8, the Google runtime engine for JavaScript. It is built with Rust, Tokio, TypeScript(Deno supports both JavaScript and TypeScript) and V8 (Google’s JavaScript runtime used in Chrome and Node).

Deno was announced almost 2 years ago by the creator of Node.js, Ryan Dahl, at JSConf EU.

 

Features of Deno

Let's try to understand its features

  • It is fully based on JavaScript modern features
  • It has no package manager like Node.js
  • It has a built-in testing facility
  • It embraces ES modules.
  • It has an extensive standard library
  • It has TypeScript at its core, Which makes eligible to make the robust applications. And here we don't need to compile the JavaScript code manually. 
  • It is also tried to make browser-compatible, As it provides built-in fetch and the global window object

 

Similarities and differences with Node.js

Similarities:

  • Both are developed upon the V8 Chromium Engine
  • Both are preferred for developing server-side applications with JavaScript

Differences:

  • Node.js is written in C++ and Javascript whereas Demo is written in Rust with Typescript.
  • In Node.js we have npm, it's official package manager for all the dependencies. Deno does not have anything like this, it directly allow us to import ES module from URLs.
  • Node.js uses common Javascript syntax for importing packages whereas Deno uses ES Modules
  • Node.js uses callback-based standard-library whereas Deno uses modern ECMAScript features.
  • Deno provides extra layer of security than Node.js

Original article sourced at: https://jsonworld.com

#nodejs #deno 

Deno Vs Node.js: Compare The Differences

How to Create a React App with Bun.js

In this tutorial, you'll learn how to create a react app with Bun.js. Bun is a fast new JavaScript runtime like Node.js or Deno. Getting Started with Bun.js on Windows 10 and Create a React App

Have you used Node.js (Node.js (nodejs.org)) or Deno (Deno — A modern runtime for JavaScript and TypeScript)? Do you know what Bun.js (Bun is a fast all-in-one JavaScript runtime) is?

Well, for those who do not know them, all three of them are JavaScript runtimes. Node.js and Deno were popular runtimes and Bun.js is the newborn runtime in 2022. In this guide, we will get to know about this newcomer and learn how to create a react app with bun. We will discuss,

  • Why Bun over Node or Deno?
  • About Bun
  • How to Install Bun on Windows 10
  • Getting started with Bun and
  • How to Create a React app with Bun, in this article.

Why Bun over Node or Deno?

According to bun’s statistics, Bun is,

  • Three times faster when it comes to server-side rendering React,
  • Seven times faster with WebSocket server chat and
  • Two times faster when loading a huge SQLite table compared to Node and Deno.

About Bun

Bun comes bundled with transpile, install and run JavaScript and TypeScript. It also has an npm client built-in with a native bundler, transpiler, and task runner. Bun focuses on main three things,

  • Start fast
  • The new level of performance through extending JavaScriptCore and
  • Being a great and complete tool.

You can even use bun on your current JavaScript or TypeScript apps. Bun has natively implemented 90% of Node API functions (as at October 2022). Bun intends to provide performance enhancements, complexity enhancements, and developer productivity through simple and better tools. The goal of Bun is to run JavaScript outside the browser. Ziglang (Home ⚡ Zig Programming Language (ziglang.org)) is the low-level programming language used to write bun. Which provides bun with the features like fastness and simplicity in writing software.

Installing Bun on Windows 10

You can install Bun on Linux or macOS easily by entering, curl https://bun.sh/install | bash on the CLI. However, by today, Bun cannot install directly on Windows operating systems. But we can use it on Windows with the help of ‘Windows Subsystem for Linux’ (WSL). First, we need to enable WSL on our Windows 10 computer.

Enabling WSL on Windows 10

You can easily do that by finding ‘Turn Windows Features on or off’, on settings or just typing it in the Windows search. Then find the WSL, tick it and press ‘ok’. Then you may need to restart your computer. The following figure shows how to turn on WSL.

Installing Ubuntu on windows 10

Once WSL is working, we should install Ubuntu on windows. To do that we can go to ‘Microsoft Store’ and install the latest Ubuntu LTS version. Ubuntu 22.04.1 LTS is about 681.5 MB. The below figure shows you the Ubuntu version on Microsoft Store.

After the installation, click the open button and the Linux terminal will be asking for a new username (test) and password. You may have similar output as the below figure. Then we can start the Bun installation.

Install Bun

In the Ubuntu terminal, we should install the ’unzip’ tool. We can use the sudo apt install unzip command as you can see in the below figure.

Then we can copy and paste the command for bun installation, curl https://bun.sh/install | bash. Then we should copy and paste the path for Bun on .bashrc file before starting bun. The following figure shows the output.

Then we should open .bashrc and edit it. Here we can use Visual Studio Code by typing code ~/.bashrc. If you do not have visual studio code installed in Ubuntu, it will be installed first. Otherwise, you can use ‘nano’ editor by typing nano .bashrc. In the nano editor, you can go to the bottom of the .bashrc file using the drop-down arrow and paste the two lines by right-clicking. Then save it by typing ctrl+x and providing ‘y’ to indicate yes, and press ‘enter’. The below figures indicate how and where to copy and paste the commands.

Finally we can check the bun installation by typing, bun –version on the terminal. To do that you need to exit and reopen the Ubuntu terminal. Below figure shows the command in the terminal with output.

Getting started with Bun

Now we have Bun installed on our computer. We can create a new directory (folder called bun) using the command mkdir bun. Then we can use the command touch app.js to create a JavaScript file inside our directory after changing our directory by typing cd bun. Then open the file using nano app.js and type the below lines to create and see a basic HTTP server request and response from bun.

// app.js

export default {

port: 3000,

fetch(request) {

return new Response(“Welcome to Bun on Windows 10!”);

},

};

Then we can run the file by typing bun run app.js on the terminal. Then let us check the response on our browser. It may look like the figures below. You can press ctrl+c on the command line to stop running the app.

Create a React app

Now we have tested a simple Bun response on our web browser, let’s start developing our React app with Bun.

Now we are in our home directory inside our Ubuntu. We can create a new directory (folder called react-bun) by using mkdir react-bun. Then navigate to the react-bun folder by typing cd react-bun. Then start a new React project (hello-react) by typing bun create react hello-react. The below figures show outputs respectively.

Finally, we can navigate to the hello-react folder and type bun dev to start our React app. As shown in our terminal, we can navigate to http://localhost:3000 and see our React app. The following figure shows the terminal outputs.

The below figure shows our first impression of the react app on the browser.

Tip: Bun creates a React app with JavaScript in default. But we can change .jsx files to .tsx and run TypeScript apps.

Final thoughts

As we have witnessed, Bun is the fastest JavaScript runtime environment yet. Also, it is an all-in-one native bundler, transpiler, task runner, and npm client built-in environment. Bun is young and promising, though still has some difficulty in using Bun directly on Windows operating systems. But its amazing fast nature will soon make new changes to JavaScript development worldwide.

Original article source at https://blog.bitsrc.io

#javascript #node #deno #react #reactjs #bunjs

How to Create a React App with Bun.js
Dexter  Goodwin

Dexter Goodwin

1667389921

Fresh: The Next-gen Web Framework

fresh

Fresh is a next generation web framework, built for speed, reliability, and simplicity.

Some stand-out features:

  • Just-in-time rendering on the edge.
  • Island based client hydration for maximum interactivity.
  • Zero runtime overhead: no JS is shipped to the client by default.
  • No build step.
  • No configuration necessary.
  • TypeScript support out of the box.
  • File-system routing à la Next.js.

📖 Documentation

The documentation is available on fresh.deno.dev.

🚀 Getting started

Install Deno CLI version 1.25.0 or higher.

You can scaffold a new project by running the Fresh init script. To scaffold a project in the deno-fresh-demo folder, run the following:

deno run -A -r https://fresh.deno.dev deno-fresh-demo

Then navigate to the newly created project folder:

cd deno-fresh-demo

From within your project folder, start the development server using the deno task command:

deno task start

Now open http://localhost:8000 in your browser to view the page. You make changes to the project source code and see them reflected in your browser.

To deploy the project to the live internet, you can use Deno Deploy:

  1. Push your project to GitHub.
  2. Create a Deno Deploy project.
  3. Link the Deno Deploy project to the main.ts file in the root of the created repository.
  4. The project will be deployed to a public $project.deno.dev subdomain.

For a more in-depth getting started guide, visit the Getting Started page in the Fresh docs.

Badges

Made with Fresh

[![Made with Fresh](https://fresh.deno.dev/fresh-badge.svg)](https://fresh.deno.dev)
<a href="https://fresh.deno.dev">
   <img width="197" height="37" src="https://fresh.deno.dev/fresh-badge.svg" alt="Made with Fresh" />
</a>

Made with Fresh(dark)

[![Made with Fresh](https://fresh.deno.dev/fresh-badge-dark.svg)](https://fresh.deno.dev)
<a href="https://fresh.deno.dev">
   <img width="197" height="37" src="https://fresh.deno.dev/fresh-badge-dark.svg" alt="Made with Fresh" />
</a>

Documentation | Getting started

Download Details:

Author: Denoland
Source Code: https://github.com/denoland/fresh 
License: MIT license

#typescript #javascript #preact #deno 

Fresh: The Next-gen Web Framework
Reid  Rohan

Reid Rohan

1667012580

Deno: A Modern Runtime for JavaScript and TypeScript

Deno

Deno is a simple, modern and secure runtime for JavaScript and TypeScript that uses V8 and is built in Rust.

Features

  • Secure by default. No file, network, or environment access, unless explicitly enabled.
  • Supports TypeScript out of the box.
  • Ships only a single executable file.
  • Built-in utilities.
  • Set of reviewed standard modules that are guaranteed to work with Deno.

Install

Shell (Mac, Linux):

curl -fsSL https://deno.land/install.sh | sh

PowerShell (Windows):

irm https://deno.land/install.ps1 | iex

Homebrew (Mac):

brew install deno

Chocolatey (Windows):

choco install deno

Scoop (Windows):

scoop install deno

Build and install from source using Cargo:

cargo install deno --locked

See deno_install and releases for other options.

Getting Started

Try running a simple program:

deno run https://deno.land/std/examples/welcome.ts

Or a more complex one:

const listener = Deno.listen({ port: 8000 });
console.log("http://localhost:8000/");

for await (const conn of listener) {
  serve(conn);
}

async function serve(conn: Deno.Conn) {
  for await (const { respondWith } of Deno.serveHttp(conn)) {
    respondWith(new Response("Hello world"));
  }
}

You can find a deeper introduction, examples, and environment setup guides in the manual.

The complete API reference is available at the runtime documentation.

Contributing

We appreciate your help!

To contribute, please read our contributing instructions.

Download Details:

Author: Denoland
Source Code: https://github.com/denoland/deno 
License: MIT license

#typescript #javascript #rust #deno 

Deno: A Modern Runtime for JavaScript and TypeScript