worktop

The next generation web framework for Cloudflare Workers

MIT License

Downloads
324K
Stars
1.7K
Committers
6
worktop -

Published by lukeed over 3 years ago

Patches

  • (router): Ensure custom onerror handler is always run (#51): 1a1645bcb8a3d73bc6642b9ffbe29a2f83e533a1
worktop -

Published by lukeed over 3 years ago

Patches

  • (kv): Fix the until exit condition: 20e663617035932393bd5ba631c12a3240902a89
    Meant to be updated along with the the breaking 0.6.0 changes to read empty condition (a2edaa4449393d0ad30008d6e6844c98b4057432)

Examples

  • (NEW) Added "ws" example for new worktop/ws module

Chores

  • (types) Get the types/check.ts test passing: 1bed24e2610425ded40e258b58e333cc0c7b972a
worktop -

Published by lukeed over 3 years ago

Patches

  • (types) Fix worktop/kv definitions for the listen parameters: e236bd7
    Missed a rename occurrence during the #48 work
worktop -

Published by lukeed over 3 years ago

Breaking

  • (kv) The read export now returns Promise<T | null> instead of Promise<T | false>: a2edaa4
    This is only breaking if your data integrity checks did strict comparison against false values.
    Note: This also affects the Database.get method.

    import { read } from 'worktop/kv';
    import type { Item } from 'lib/example';
    
    let item = await read<Item>(binding, 'my:key');
    //   ^ BEFORE: Item | false
    //   ^ AFTER:  Item | null
    
  • (kv): Move the toJSON parameter for write and Database.put into a new options argument: 861a4e9
    Note: The default behavior is unchanged.

    import { write, Database } from 'worktop/kv';
    
    let DB = new Database(binding);
    
    // BEFORE:
    await write(binding, 'my:key', 'value', false);
    await DB.put('my:key', 'value', false);
    
    // AFTER:
    await write(binding, 'my:key', 'value', { toJSON: false });
    await DB.put('my:key', 'value', { toJSON: false });
    

Features

  • Add worktop/ws module (#48): 8beefdf
    Check out #48 for examples and documentation

    import { Router, compose } from 'worktop';
    import * as ws from 'worktop/ws';
    
    // userland code
    import * as Token from 'lib/token';
    import * as Chat from 'lib/chat';
    
    const API = new Router;
    
    API.add('GET', '/chat/:lobby', compose(
        Token.isValid, // verify token exists & is valid
        Chat.isAuthorized, // verify user can access this room
        ws.listen(Chat.handler) // the SocketHandler for WS events
    ));
    
  • (kv) Add list method for keys generator (#47): e97bb57
    Returns an AsyncGenerator you can use to manually apply your own stop-until-X logic.

  • (kv) Add paginate method for keys paging (#47): abbdf7f, e14e1bd
    Applies the 90% use case for consuming the list() iterator:

    let keys = await database.paginate(BINDING, { 
      prefix: 'users::1234::projects',
      limit: 25,
      page: 3
    });
    // ^ This will skip the first 50 keys (2 x 25) and 
    //     then return the 0-25 keys that constitute a "page 3".
    // If you supply a `limit` x `page` combination that exceeds
    //     the total keys, then an empty array is returned early.
    
  • (kv) Add options.metadata support to all read and write methods (#46): 73e8160
    Metadata allows you to assign additional information/context to a key. This is particularly useful when listing or paginateing keys.

  • (crypto) Add timingSafeEqual method (#34, #45): 200999a
    A constant-time TypedArray comparison utility.

Examples

  • Include new paginate utility within the kv-todos example: e14e1bd

Patches

  • (kv): Add KV.Namespace[getWithMetadata] types: d381808
  • (kv): Aefine all read type overloads: e609be2
  • (kv): Define null return type from KV.Namespace[get]: 58beaec
  • (kv): Add options variants to KV.Namespace[get] method: 7c9ab8b

Chores

  • (utils): Decrease unique-check test counts (1M -> 50k): 9717931
  • (kv): Reorganize KV types: 807f927
worktop -

Published by lukeed over 3 years ago

Features

  • (cache): Attempt a GET match in Cache.lookup method with incoming HEAD request (#44): 1a27c9c
    When the incoming request is a HEAD method, try to look for its GET counterpart in the Cache.

    API.add('GET', '/articles', async (req, res) => {
      // heavy DB query processing, etc
      const items = await expensive('task');
      res.send(200, items);
    });
    
    // BEFORE
    // ---
    // request -> "GET  /articles" -> Cache MISS -> execute -> Cache PUT -> Response
    // request -> "GET  /articles" -> Cache HIT  -> Response
    // request -> "HEAD /articles" -> Cache HIT  -> execute -> Cache PUT -> Response
    
    // AFTER
    // ---
    // request -> "GET  /articles" -> Cache MISS -> execute -> Cache PUT -> Response
    // request -> "GET  /articles" -> Cache HIT  -> Response
    // request -> "HEAD /articles" -> Cache HIT  -> Response
    

Patches

  • (router): Prevent early exit via compose in prepare hook (#43): a1ab931
    When using compose() to create a $.prepare handler, a Response was always returned from $.prepare, preventing any/all route handlers from running. This has been fixed.

  • (cache): Do not try to Cache.put for HEAD requests (#44): e69859c
    This technically was throwing at runtime error, which didn't affect the Response – thanks to event.waitUntil.

worktop -

Published by lukeed over 3 years ago

Patches

  • (kv) Pass-through KV.WriteOptions value via write and Database.put methods: 93df321
    This enables the ability to set expiration and/or expirationTtl values, which was previously missing.

  • (types) Add Method definition for request and router (#39): 9757ed6
    Thank you @cometkim!

  • (types) Add scheduled event & listener definitions: 108e463, d110d60

Chores

  • Include worktop/cors and worktop/crypto modules in README (#36): 84dd7b1
    Thank you @leader22!
  • Add /.vsconfig override for tsc location: 9178737
  • Bump devdep versions: a7cc828, 5857c86
worktop -

Published by lukeed over 3 years ago

Features

  • Add conditional exports support for CommonJS (#27, #31, #32): cacf3e2
    See #32 for details. TLDR: This is meant for testing purposes only.

  • (crypto) Add additional export methods (#15, #30): f3322ac

    • keyload – generate a CryptoKey with a raw secret value
    • keygen – generate a CryptoKey without a base value
    • sign – generate a digital signature for a payload using the specified algorithm and CryptoKey
    • verify – verify the digital signature of a payload using the specified algorithm and CryptoKey
    • PBKDF2 – apply the PBKDF2 function to an input using a salt and derivation function
  • (utils): Add ulid export (#25, #28): b854b00
    A lexicographically sortable random identifier; see ulid/spec

  • (utils): Add randomize export: f3322ac
    Wrapper for crypto.getRandomValues utility.

Patches

  • (request): Remove the "Requires Business or Enterprise" notes for req.cf properties: 3f74f6b
    More location-based information available to all plans! See the Cloudflare Blog

Chores

  • (bin): Drop banner approach for require hook: 7862dee
worktop -

Published by lukeed over 3 years ago

Features

  • (utils): Add viaHEX helper: 34e65a2
    Decodes a hexadecimal string into a Uint8Array
    Note: This is the inverse of the existing toHEX helper.

Patches

  • (cache): Clone Response before Set-Cookie guard: ac19ee9

    This fixes a bug with worktop that only occurred when a handler returned a fetch() call directly and the subrequest was to a resource that was cacheable & had a "Set-Cookie" header.

    In code, this may have looked like:

    API.add('GET', '/example', (req, res) => {
    	return fetch('https://other.com/foobar');
    });
    

    And where the response from 'https://other.com/foobar' was both cacheable and had a "Set-Cookie" header.

    Any/All other cache usage was (and remains) unaffected.

worktop -

Published by lukeed over 3 years ago

Patches

  • (cache) Add missing FetchHandler type import: 4e1b591
worktop -

Published by lukeed over 3 years ago

Breaking

  • (router): Allow find() to return void: f6cadf3

Features

  • Add worktop/cors module (#1, #22): c2e83e7, 9482d6a, 9eee191

  • Add compose utility to main worktop module (#23): b7103b7, c5d49c1
    Note: Updated #7 to add explicit type-safety at later date.

  • Add named UID and UUID types from worktop/utils module (#21): dc600c3, 35c2a1b
    More explicit type interfaces by default, while still satisfying string types.

  • Allow Router.prepare function to return Response instance directly: 50383e8
    This makes it a true Handler signature.

Patches

  • (response): Make res.send stringify non-obj/str data to String: dd597db
    Otherwise TextEncoder throws when determining byteLength

  • Add __PURE__ directives for better tree-shaking: ed4159a, 1fa1b5f

Examples

Chores

  • (examples) Update playground links: 0326044
  • Squash /bin devDependencies into root package.json file: 54663a1
worktop -

Published by lukeed over 3 years ago

Features

  • Add worktop/cookie module (#20): b148f46
  • Add intelligent req.params type safety! (#16, #17): b048388, fbf6e48
    Thank you @dummdidumm!

Patches

  • (kv): Check for nullish read values: (#19): a024283
    Thank you @JakeChampion!

Chores

  • Update /examples builder: 21a6af9, 4d90405
worktop -

Published by lukeed over 3 years ago

Breaking

Important: For a complete rundown of all breaking changes, including points not mentioned in this section, please see #10

The base Router class no longer has an implicit dependency on the worktop/cache module. By disassociating, developers can now choose whether or not their application(s) should interact with the Cache, allowing worktop to now be used as a framework for authoring Service Workers – yes, for the browser!

Note: There will eventually be a worktop/sw module that provides Service Worker utilities. Other modules must come first, though.

In [email protected], the default behavior was to pass all incoming FetchEvents through worktop/cache in search of a matching cache entry. To regain this behavior, please make the following changes after upgrading to [email protected]:

import { Router } from 'worktop';
++ import { reply } from 'worktop/cache';

const API = new Router();
// ... routes

-- addEventListener('fetch', API.listen);
++ addEventListener('fetch', reply(API.run));

Or, you may choose to involve the new listen utility, which invokes the addEventListener call for you:

import { Router } from 'worktop';
++ import * as Cache from 'worktop/cache';

const API = new Router();
// ... routes

-- addEventListener('fetch', API.listen);
++ Cache.listen(API.run);

Features

  • Add worktop/utils module (#8): a0123be..4e0a0b2
  • Add worktop/crypto module (#11): d8ee779
  • Add worktop/base64 module (#12, #14): 6695b54

Patches

  • (request): Bind req.body method assignments (#9): 693c15a, aacb152

Chores

  • (bin) Prettify build table summary (#13): 87bcf51
  • (readme) Allow responsive readme logo: fd842c2
Package Rankings
Top 1.57% on Npmjs.org
Related Projects