1678882982
typescript@4.9.5
in VS Code— no extensions or plugins required (how?) (try in-browser)
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.
12KB
gzipped, 0
dependencies
npm install arktype
(or whatever package manager you prefer)
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! ⛵
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)
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!
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>
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!
This project is licensed under the terms of the MIT license.
I'd love to hear about what you're working on and how ArkType can help. Please reach out to david@arktype.io.
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.
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!
Author: arktypeio
Source Code: https://github.com/arktypeio/arktype
License: MIT license
1678779240
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.
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"
Author: ascorbic
Source Code: https://github.com/ascorbic/get-pixels
License: MIT licensed
1678775344
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.
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.
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.
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.
Basically all of the credit for this goes to shuding. I just ported it to Deno and added a few tweaks.
Author: ascorbic
Source Code: https://github.com/ascorbic/og-edge
License: MPL-2.0 license
1678524960
Desktop App Framework (not there yet!) for Deno, based on Tauri.
A lot is still missing, but we will get there!
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
deno_runtime
version (and also things like Deno.build
) with Deno's releasesastrodon clean
to remove cached runtimesastrodon run
also support HTTPs urisRequisites:
Running both Deno and Rust tests:
deno task test
Author: Astrodon
Source Code: https://github.com/astrodon/astrodon
License: MIT license
1677079560
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.
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';
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"
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.
ident
(value: T) => T
Identity function.
/* Node: */ import ident from "froebel/ident";
/* Deno: */ import ident from "https://deno.land/x/froebel@v0.23.2/ident.ts";
noop
() => void
/* 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>
Partially apply a function.
/* Node: */ import partial from "froebel/partial";
/* Deno: */ import partial from "https://deno.land/x/froebel@v0.23.2/partial.ts";
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>
Given a function and its nth..last arguments, return a function accepting arguments 0..n-1.
/* Node: */ import forward from "froebel/forward";
/* Deno: */ import forward from "https://deno.land/x/froebel@v0.23.2/forward.ts";
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>
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.
/* Node: */ import unary from "froebel/unary";
/* Deno: */ import unary from "https://deno.land/x/froebel@v0.23.2/unary.ts";
['1', '2', '3'].map(unary(parseInt)) // -> [1, 2, 3]
callAll
(funs: F[], ...args: P) => ReturnTypes<F>
Take a list of functions that accept the same parameters and call them all with the provided arguments.
/* Node: */ import callAll from "froebel/callAll";
/* Deno: */ import callAll from "https://deno.land/x/froebel@v0.23.2/callAll.ts";
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>
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.
/* Node: */ import pipe from "froebel/pipe";
/* Deno: */ import pipe from "https://deno.land/x/froebel@v0.23.2/pipe.ts";
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>
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
/* Node: */ import { applyPipe } from "froebel/pipe";
/* Deno: */ import { applyPipe } from "https://deno.land/x/froebel@v0.23.2/pipe.ts";
applyPipe(2, double, square, half) // -> 8
bundle
(...funs: λ<T>[]) => (...args: T) => Promise<void>
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.
/* 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
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.
/* 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]>
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.
/* Node: */ import { nullishChain } from "froebel/nullishChain";
/* Deno: */ import { nullishChain } from "https://deno.land/x/froebel@v0.23.2/nullishChain.ts";
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]>>>
Same as nullishChain but accept asynchronous functions too.
/* Node: */ import { asyncNullishChain } from "froebel/nullishChain";
/* Deno: */ import { asyncNullishChain } from "https://deno.land/x/froebel@v0.23.2/nullishChain.ts";
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}
Create a throttled function that invokes
fun
at most everyms
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.
/* 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}
Creates a debounced function that delays invoking
fun
untilms
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.
/* 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>>}
Returns a copy of
fun
that remembers its result for any given arguments and only invokesfun
for unknown arguments.The cache key is computed using the
key
function. The defaultkey
function simply stringifies the arguments.If
limit
is specified, only thelimit
-last entries are kept in cache.The function's cache is available at
memoized.cache
.If
opt.weak
istrue
, 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 alimit
.
/* Node: */ import memoize from "froebel/memoize";
/* Deno: */ import memoize from "https://deno.land/x/froebel@v0.23.2/memoize.ts";
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
Returns a version of the function
fun
that can only be invokedlimit
times. An optionalexcept
function will be called with the same parameters on any additional invocations.If
fun
returns anything butvoid
(orPromise<void>
), supplying anexcept
function is mandatory.The
except
function must have the same return type asfun
, or — iffun
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.
/* 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
Special case of limitInvocations.
fun
can only be invoked once.see limitInvocations
/* Node: */ import { once } from "froebel/invoke";
/* Deno: */ import { once } from "https://deno.land/x/froebel@v0.23.2/invoke.ts";
atWrap
(arr: T[], i: number) => T
Access list at
i % length
. Negative indexes start indexing the last element as[-1]
and wrap around to the back.
/* 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>
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.
/* Node: */ import zip from "froebel/zip";
/* Deno: */ import zip from "https://deno.land/x/froebel@v0.23.2/zip.ts";
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[]
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 ofzipper
is the element at current index in the list returned fromzipWith
.
/* Node: */ import { zipWith } from "froebel/zip";
/* Deno: */ import { zipWith } from "https://deno.land/x/froebel@v0.23.2/zip.ts";
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>
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.
/* Node: */ import unzip from "froebel/unzip";
/* Deno: */ import unzip from "https://deno.land/x/froebel@v0.23.2/unzip.ts";
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]>}
Same as unzip but accepts an
unzipper
function for each tuple index. Theunzipper
's return value is used as the value in the list at that index returned fromunzipWith
.The
unzipper
takes the current element as its first argument, an accumulator as second argument (initiallyundefined
) and its return value is the accumulator passed into the next invocation.
/* Node: */ import { unzipWith } from "froebel/unzip";
/* Deno: */ import { unzipWith } from "https://deno.land/x/froebel@v0.23.2/unzip.ts";
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[][]
Takes a
list
and returns it in multiple smaller lists of the sizebatchSize
. The last batch may be smaller thanbatchSize
depending on iflist
size is divisible bybatchSize
.
/* Node: */ import batch from "froebel/batch";
/* Deno: */ import batch from "https://deno.land/x/froebel@v0.23.2/batch.ts";
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>[]]
Takes a
list
and returns a pair of lists containing: the elements that match thepredicate
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.
/* Node: */ import partition from "froebel/partition";
/* Deno: */ import partition from "https://deno.land/x/froebel@v0.23.2/partition.ts";
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[]
Shuffles
list
using the Fisher-Yates shuffle algorithm. The originallist
is not modified and the shuffled list is returned.
/* Node: */ import shuffle from "froebel/shuffle";
/* Deno: */ import shuffle from "https://deno.land/x/froebel@v0.23.2/shuffle.ts";
shuffleInPlace
(list: unknown[]) => void
Same as shuffle but shuffles
list
in place.
/* 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[]
Takes
n
elements from the iterablelist
and returns them as an array.
/* Node: */ import { take } from "froebel/list";
/* Deno: */ import { take } from "https://deno.land/x/froebel@v0.23.2/list.ts";
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
Creates a range between two values.
see numberRange and alphaRange
/* 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[]
Constructs a numeric between
start
andend
inclusively.
/* Node: */ import { numberRange } from "froebel/range";
/* Deno: */ import { numberRange } from "https://deno.land/x/froebel@v0.23.2/range.ts";
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[]
Constructs a range between characters.
/* Node: */ import { alphaRange } from "froebel/range";
/* Deno: */ import { alphaRange } from "https://deno.land/x/froebel@v0.23.2/range.ts";
range('a', 'd') // -> ['a', 'b', 'c', 'd']
range('Z', 'W') // -> ['Z', 'Y', 'X', 'W']
repeat
(...sequence: [T, ...T[]]) => Generator<T>
Returns a generator that repeats
sequence
.
/* Node: */ import repeat from "froebel/repeat";
/* Deno: */ import repeat from "https://deno.land/x/froebel@v0.23.2/repeat.ts";
// 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>
Takes
n
elements from the iterablelist
and returns them as a generator.
/* Node: */ import { take } from "froebel/iterable";
/* Deno: */ import { take } from "https://deno.land/x/froebel@v0.23.2/iterable.ts";
[...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]
pick
(obj: T, ...keys: K[]) => Pick<T, K>
From
obj
, create a new object that only includeskeys
.
/* Node: */ import pick from "froebel/pick";
/* Deno: */ import pick from "https://deno.land/x/froebel@v0.23.2/pick.ts";
pick({ a: 1, b: 2, c: 3 }, 'a', 'c') // { a: 1, c: 3 }
omit
(obj: T, ...keys: K[]) => Omit<T, K>
From
obj
, create a new object that does not includekeys
.
/* Node: */ import omit from "froebel/omit";
/* Deno: */ import omit from "https://deno.land/x/froebel@v0.23.2/omit.ts";
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>
Map over
data
.data
can be a regular object, aMap
, aSet
, or an array.
/* Node: */ import map from "froebel/map";
/* Deno: */ import map from "https://deno.land/x/froebel@v0.23.2/map.ts";
// -> { 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])
select
(obj: T, ...path: P) => PickPath<T, P>
Returns the value in
obj
atpath
. If the given path does not exist, the symbolnone
is returned.
/* Node: */ import select from "froebel/select";
/* Deno: */ import select from "https://deno.land/x/froebel@v0.23.2/select.ts";
// -> 'something'
select(
{ a: { deeply: [{ nested: { object: 'something' } }] } },
'a', 'deeply', 0, 'nested', 'object'
)
oneOf
(value: T, ...cmps: TT) => value is TT[number]
Checks if
v
is one ofcmps
.
/* 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
Checks if
a
andb
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
/* Node: */ import equal from "froebel/equal";
/* Deno: */ import equal from "https://deno.land/x/froebel@v0.23.2/equal.ts";
clone
(value: T) => T
Returns a copied version of
value
.If
value
is primitive, returnsvalue
. Otherwise, properties ofvalue
are copied recursively. Onlyvalue
'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).
/* 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>
Recursively merges
A
andB
. If a property inA
andB
is of a different type (i.e. it's not an array, Set, Map, or plain object in both, the value fromB
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.
/* Node: */ import merge from "froebel/merge";
/* Deno: */ import merge from "https://deno.land/x/froebel@v0.23.2/merge.ts";
promisify
(withCallback: T, resultIndex?: N, errorIndex: null | number) => Promisified<T, N>
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
toresultIndex
orerrorIndex
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 andcallbackLast
will pass additional parameters before the callback.
/* Node: */ import promisify from "froebel/promisify";
/* Deno: */ import promisify from "https://deno.land/x/froebel@v0.23.2/promisify.ts";
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
Creates a
queue
function that accepts a function as it's only parameter. Whenqueue
is invoked, the passed in function is executed after the last function passed toqueue
has finished executing. Thequeue
function returns the result of the passed in function asynchronously.Reading
queue.done
istrue
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.
/* Node: */ import createQueue from "froebel/queue";
/* Deno: */ import createQueue from "https://deno.land/x/froebel@v0.23.2/queue.ts";
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>
Checks if
value
looks like a promise.
/* 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>>
Checks if
value
is not a promise.
/* Node: */ import { isNotPromise } from "froebel/isPromise";
/* Deno: */ import { isNotPromise } from "https://deno.land/x/froebel@v0.23.2/isPromise.ts";
(value: number | Promise<unknown>) => {
if (isNotPromise(value)) return value / 2
}
truthy
(value: T) => value is PickTruthy<T>
Checks if
value
is truthy. Literal types are narrowed accordingly.
/* 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>
Checks if
value
is falsy. Literal types are narrowed accordingly.
/* 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>
Checks if
value
is nullish. Literal types are narrowed accordingly.
/* 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
Checks if
value
is not nullish. Literal types are narrowed accordingly.
/* Node: */ import { notNullish } from "froebel/nullish";
/* Deno: */ import { notNullish } from "https://deno.land/x/froebel@v0.23.2/nullish.ts";
const nums = (...values: (number | undefined)[]): number[] => values.filter(notNullish)
isFulfilled
(result: PromiseSettledResult<T>) => result is PromiseFulfilledResult<T>
Checks if
result
(returned fromPromise.allSettled
) is fulfilled.
/* 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
Checks if
result
(returned fromPromise.allSettled
) is rejected.
/* Node: */ import { isRejected } from "froebel/settled";
/* Deno: */ import { isRejected } from "https://deno.land/x/froebel@v0.23.2/settled.ts";
prefix
(prefix: T0, str: T1, caseMod?: C) => `${string}`
Returns
str
prefixed withprefix
. 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 genericstring
.
/* 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}`
Returns
str
suffixed withsuffix
. Same case and type behavior as prefix.
/* 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>
Surrounds the
str
withsurrounding
.surrounding
must have an even length.
/* Node: */ import { surround } from "froebel/surround";
/* Deno: */ import { surround } from "https://deno.land/x/froebel@v0.23.2/surround.ts";
surround("foo", "()") // "(foo)"
surround("foo", "({[]})") // "({[foo]})"
capitalize
(str: T) => Capitalize
Upper-case first letter of string.
/* Node: */ import { capitalize } from "froebel/case";
/* Deno: */ import { capitalize } from "https://deno.land/x/froebel@v0.23.2/case.ts";
uncapitalize
(str: T) => Uncapitalize
Lower-case first letter of string
/* Node: */ import { uncapitalize } from "froebel/case";
/* Deno: */ import { uncapitalize } from "https://deno.land/x/froebel@v0.23.2/case.ts";
upper
(str: T) => Uppercase
Strictly typed
String.toUpperCase()
.
/* Node: */ import { upper } from "froebel/case";
/* Deno: */ import { upper } from "https://deno.land/x/froebel@v0.23.2/case.ts";
lower
(str: T) => Lowercase
Strictly typed
String.toLowerCase()
.
/* 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, "_">
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.
/* Node: */ import { snake } from "froebel/case";
/* Deno: */ import { snake } from "https://deno.land/x/froebel@v0.23.2/case.ts";
snake('fooBar') // 'foo_bar'
kebab
(str: T) => DelimitedCase<T, "-">
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.
/* Node: */ import { kebab } from "froebel/case";
/* Deno: */ import { kebab } from "https://deno.land/x/froebel@v0.23.2/case.ts";
kebab('fooBar') // 'foo-bar'
camel
(str: T) => CamelCase<T>
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.
/* Node: */ import { camel } from "froebel/case";
/* Deno: */ import { camel } from "https://deno.land/x/froebel@v0.23.2/case.ts";
camel('foo_bar') // 'fooBar'
pascal
(str: T) => Capitalize
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.
/* Node: */ import { pascal } from "froebel/case";
/* Deno: */ import { pascal } from "https://deno.land/x/froebel@v0.23.2/case.ts";
pascal('foo_bar') // 'FooBar'
screamingSnake
(str: T) => Uppercase
Transforms a variable name to screaming snake case.
see snake
/* Node: */ import { screamingSnake } from "froebel/case";
/* Deno: */ import { screamingSnake } from "https://deno.land/x/froebel@v0.23.2/case.ts";
screamingSnake('fooBar') // 'FOO_BAR'
transformCase
(str: T, targetCase: C) => DelimitedCase<T, "_">
Transform a variable name to
targetCase
see snake, kebab, camel, pascal, and screamingSnake
/* Node: */ import { transformCase } from "froebel/case";
/* Deno: */ import { transformCase } from "https://deno.land/x/froebel@v0.23.2/case.ts";
clamp
(min: number, num: number, max: number) => number
Clamp
num
betweenmin
andmax
inclusively.
/* Node: */ import clamp from "froebel/clamp";
/* Deno: */ import clamp from "https://deno.land/x/froebel@v0.23.2/clamp.ts";
BiMap
class BiMap<L, R>(data?: Map<L, R> | [L, R][], aliasLeft?: AL, aliasRight?: AR)
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.
/* Node: */ import BiMap from "froebel/bimap";
/* Deno: */ import BiMap from "https://deno.land/x/froebel@v0.23.2/bimap.ts";
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[])
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 usingdelete 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
andslice
methods will return SortedArray instances instead of plain arrays.
/* 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][])
Behaves like a regular JavaScript
Map
, but its iteration order is dependant on thecompare
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 theupdate(key)
method afterwards to ensure the map stays sorted.
/* Node: */ import SortedMap from "froebel/sortedMap";
/* Deno: */ import SortedMap from "https://deno.land/x/froebel@v0.23.2/sortedMap.ts";
Author: MathisBullinger
Source Code: https://github.com/MathisBullinger/froebel
License: ISC license
1676317440
Webview is a tiny cross-platform library to make web-based GUIs for desktop applications.
⚠️ This project is still in development. Expect breaking changes.
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.
You can find the official documentation here.
sudo apt-get install libwebkit2gtk-4.0-dev
)Make sure to init the webview submodule with:
$ git submodule update --init --recursive
Building on Windows requires admin privileges.
$ deno task build
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
PLUGIN_URL
- Set a custom library URL. Defaults to the latest release assets on Github. Setting this also disables cache for plug
.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.
Author: Webview
Source Code: https://github.com/webview/webview_deno
License: MIT license
1675751345
Deno is a simple, modern and secure runtime for JavaScript and TypeScript that uses V8 and is built in Rust.
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.
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.
We appreciate your help!
To contribute, please read our contributing instructions.
Author: Denoland
Source Code: https://github.com/denoland/deno
License: MIT license
1674936960
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.
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:
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:
Lookin' good so far.
Let's update src/components
. We'll add the files:
HomePage.vue
, the component for the home pageDinosaurs.vue
, the component that lists all dinosaur names as anchor links, andDinosaur.vue
, the component that shows an individual dinosaur's name and descriptiontouch src/components/HomePage.vue src/components/Dinosaurs.vue src/components/Dinosaur.vue
Before we create the components, let's add some state management.
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.
In Dinosaurs.vue
, we'll three things:
GET
request to our API and return that as dinosaurs
dinosaurs
and render each dinosaur
in <router-link>
that points to the <Dinosaur>
componentstore.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:
store
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>
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!
Author: denoland
Source code: https://github.com/denoland/deno-vue-example
1673833408
Welcome to DenoGres! A new comprehensive ORM for PostgreSQL and Deno.
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.
Before using DenoGres in a project, run the command below.
denogres --init
This will create the following in your project's root directory:
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
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
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.
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
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.
The Console page allows users to run database queries as needed. They can also be saved for later use.
The Console page also features active models for your databse tables. This allows users to have a reference when inputting query strings properly.
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.
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]
DenoGres is continually evolving. Features currently in development include:
denogres --db-sync
) will account for multiple associations and composite unique keys.denogres --compare
) will be implemented to display side-by-side diff between previous models.More information on how to use DenoGres and leverage all its wonderful abstraction functionality can be found here: https://denogres.deno.dev/
Author: open-source-labs
Source code: https://github.com/open-source-labs/DenoGres
1673452800
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.
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`)
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)
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)
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.
Feel free to create issues and fund their solutions e.g. via https://gitcoin.co/.
Author: distributed-ledger-technology
Source code: https://github.com/distributed-ledger-technology/web3
License: MIT license
1673415300
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!
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.
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:
_foo.ts
, _util/bar.ts
.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.
To browse documentation for modules:
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.
After cloning don't forget to git submodule update --init
.
Before opening a PR make sure to:
deno task test
passes.deno fmt --check
passes.deno task lint
passes.Give the PR a descriptive title.
Examples of good titles:
Examples of bad titles:
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.
For maintainers:
To release a new version a tag in the form of x.y.z
should be added.
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.
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.
Author: Denoland
Source Code: https://github.com/denoland/deno_std
License: MIT license
1670686380
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
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.
Let's try to understand its features
Similarities:
Differences:
Original article sourced at: https://jsonworld.com
1667810421
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?
According to bun’s statistics, Bun is,
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,
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
1667389921
Fresh is a next generation web framework, built for speed, reliability, and simplicity.
Some stand-out features:
The documentation is available on fresh.deno.dev.
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:
main.ts
file in the root of the created repository.For a more in-depth getting started guide, visit the Getting Started page in the Fresh docs.
[](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>
[](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
Author: Denoland
Source Code: https://github.com/denoland/fresh
License: MIT license
1667012580
Deno is a simple, modern and secure runtime for JavaScript and TypeScript that uses V8 and is built in Rust.
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.
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.
We appreciate your help!
To contribute, please read our contributing instructions.
Author: Denoland
Source Code: https://github.com/denoland/deno
License: MIT license