Announcing @mightylittle TypeScript Libraries
I’m pleased to announce the open-source release of four TypeScript/JavaScript libraries, each made available under the Apache-2.0 license. These libraries can provide a simple foundation for building browser applications, or can be used as components of a larger browser application framework.
The source for each package is hosted on GitHub, under the GitHub organization mightylittle.
@mightylittle/router
GitHub: https://github.com/mightylittle/router
NPM: https://www.npmjs.com/package/@mightylittle/router
Package @mightylittle/router
is a simple, regex-based URL dispatcher. I have been experimenting
lately with defining route handlers within web-workers and shared-workers, so I developed this
library to provide a flexible routing solution which does not assume that the router is running in the
main window. You can find an example of a SPA, featuring dynamic imports of route handlers, in the demo
subdirectory here.
Snippet from the demo, defining a router:
const router = new Router<RoutePaths, Promise<Element>, DispatchData>({
notFound: async (context: RouteContext<DispatchData>): Promise<Element> => {
const NotFound = (await import("./view/NotFound.js")).default;
return NotFound(context);
},
routes: {
"/": async (context: RouteContext<DispatchData>): Promise<Element> => {
const Home = (await import("./view/Home.js")).default;
return Home(context);
},
"/about": async (context: RouteContext<DispatchData>): Promise<Element> => {
const About = (await import("./view/About.js")).default;
return About(context);
},
"/widgets/:widget": async (context: RouteContext<DispatchData>): Promise<Element> => {
const Widget = (await import("./view/Widget.js")).default;
return Widget(context);
}
}
});
@mightylittle/event-emitter
GitHub: https://github.com/mightylittle/event-emitter
NPM: https://www.npmjs.com/package/@mightylittle/event-emitter
Package @mightylittle/event-emitter
provides a small and simple API for registering and triggering callbacks.
type Foo = {
foo: string;
}
const emitter = new EventEmitter();
const onFooHandler = (data?: Foo) => console.log("'on' triggered", data);
emitter.once<Foo>("foo", (data?: Foo) => console.log("'once' triggered", data));
emitter.on<Foo>("foo", onFooHandler);
emitter.emit<Foo>("foo", {foo: "bar"});
emitter.emit<Foo>("foo", {foo: "baaz"});
emitter.off<Foo>("foo", onFooHandler);
emitter.emit<Foo>("foo", {foo: "quux"});
// Output:
// 'once' triggered { foo: 'bar' }
// 'on' triggered { foo: 'bar' }
// 'on' triggered { foo: 'baaz' }
@mightylittle/transaction-log
GitHub: https://github.com/mightylittle/transaction-log
NPM: https://www.npmjs.com/package/@mightylittle/transaction-log
Package @mightylittle/transaction-log
provides two types of in-memory, replayable transaction logs, simple and
batched. For the simple type, calling append
writes to the log, whereas the batched version requires calling
commit()
to write buffered transactions to the log. An in-memory transaction log likely has only limited utility:
the purpose of this library is to define interfaces implemented by persistent adapters, i.e.
@mightylittle/transaction-log-idb
; the in-memory logs can also be used as substitutes for persistent adapters
in automated tests where IndexedDB is unavailable.
Simple log JavaScript example:
import { MemorySimpleTransactionLog } from "@mightylittle/transaction-log";
async function start () {
const log = new MemorySimpleTransactionLog();
await log.open();
await log.append("foo");
await log.append("bar");
await log.countTransactions(); // => 2
await log.replay((data) => console.log("data", data));
console.log("transactions", await log.getSeqRangeTransactions(1, 2)); // returns the first and second entries
await log.close();
await log.clear();
}
Batched log JavaScript example:
import { MemoryBatchedTransactionLog } from "@mightylittle/transaction-log";
async function start () {
const log = new MemoryBatchedTransactionLog();
await log.open();
log.append("foo");
log.append("bar");
await log.commit();
await log.countTransactions(); // => 2
await log.countCommits(); // => 1
await log.replay((data) => console.log("data", data), true);
console.log("transactions", await log.getSeqRangeTransactions(1, 2)); // prints the first and second entries
console.log("commits", await log.getSeqRangeCommits(1)); // prints the first and any later commits
await log.close();
await log.clear();
}
@mightylittle/transaction-log-idb
GitHub: https://github.com/mightylittle/transaction-log-idb
NPM: https://www.npmjs.com/package/@mightylittle/transaction-log-idb
Package @mightylittle/transaction-log-idb
implements the same interfaces as the in-memory implementations
defined in @mightylittle/transaction-log
, but writes data to IndexedDB. This library can be used as the
basis of an event-sourcing system within browser applications.
Simple log JavaScript example:
import { IDBSimpleTransactionLog } from "@mightylittle/transaction-log-idb";
async function start () {
const log = new IDBSimpleTransactionLog();
await log.open();
await log.append("foo");
await log.append("bar");
await log.countTransactions(); // => 2
await log.replay((data) => console.log("data", data));
console.log("transactions", await log.getSeqRangeTransactions(1, 2)); // returns the first and second entries
await log.close();
await log.clear();
}
Batched log JavaScript example:
import { IDBBatchedTransactionLog } from "@mightylittle/transaction-log-idb";
async function start () {
const log = new IDBBatchedTransactionLog();
await log.open();
log.append("foo");
log.append("bar");
await log.commit();
await log.countTransactions(); // => 2
await log.countCommits(); // => 1
await log.replay((data) => console.log("data", data), true);
console.log("transactions", await log.getSeqRangeTransactions(1, 2)); // prints the first and second entries
console.log("commits", await log.getSeqRangeCommits(1)); // prints the first and any later commits
await log.close();
await log.clear();
}