UNPKG

ripple

Version:

Ripple is an elegant TypeScript UI framework

84 lines (68 loc) 1.92 kB
/** @import { Block, Derived } from '#client' */ import { safe_scope, tracked, get, derived, set, with_scope } from './internal/client/runtime.js'; var init = false; export class RippleDate extends Date { #time; /** @type {Map<keyof Date, Derived>} */ #deriveds = new Map(); /** @type {Block} */ #block; /** @param {ConstructorParameters<typeof Date>} params */ constructor(...params) { super(...params); var block = (this.#block = safe_scope()); this.#time = tracked(super.getTime(), block); if (!init) this.#init(); } #init() { init = true; var proto = RippleDate.prototype; var date_proto = Date.prototype; var methods = /** @type {Array<keyof Date & string>} */ ( Object.getOwnPropertyNames(date_proto) ); for (const method of methods) { if (method.startsWith('get') || method.startsWith('to') || method === 'valueOf') { // @ts-ignore proto[method] = function (...args) { // don't memoize if there are arguments // @ts-ignore if (args.length > 0) { get(this.#time); // @ts-ignore return date_proto[method].apply(this, args); } var d = this.#deriveds.get(method); if (d === undefined) { d = derived(() => { get(this.#time); // @ts-ignore return date_proto[method].apply(this, args); }, this.#block); this.#deriveds.set(method, d); } return get(d); }; } if (method.startsWith('set')) { // @ts-ignore proto[method] = function (...args) { // @ts-ignore var result = date_proto[method].apply(this, args); set(this.#time, date_proto.getTime.call(this)); return result; }; } } } } /** * @param {Block} block * @param {ConstructorParameters<typeof Date>} params * @returns {RippleDate} */ export function ripple_date(block, ...params) { return with_scope(block, () => { return new RippleDate(...params); }); }