- Delete old Vite+Svelte frontend - Initialize new SvelteKit project with TypeScript - Configure Tailwind CSS v4 + DaisyUI - Implement JWT authentication with auto-refresh - Create login page with form validation (Zod) - Add protected route guards - Update Docker configuration for single-stage build - Add E2E tests with Playwright (6/11 passing) - Fix Svelte 5 reactivity with $state() runes Known issues: - 5 E2E tests failing (timing/async issues) - Token refresh implementation needs debugging - Validation error display timing
125 lines
3.8 KiB
JavaScript
125 lines
3.8 KiB
JavaScript
// index.ts
|
|
var Macroable = class {
|
|
/**
|
|
* Set of instance properties that will be added to each instance during construction.
|
|
* Each entry contains a key and value pair representing the property name and its value.
|
|
*/
|
|
static instanceMacros = /* @__PURE__ */ new Set();
|
|
/**
|
|
* Adds a macro (property or method) to the class prototype.
|
|
* Macros are standard properties that get added to the class prototype,
|
|
* making them available on all instances of the class.
|
|
*
|
|
* @param name - The name of the property or method to add
|
|
* @param value - The value to assign to the property or method
|
|
*
|
|
* @example
|
|
* ```ts
|
|
* // Add a property macro
|
|
* MyClass.macro('version', '1.0.0')
|
|
*
|
|
* // Add a method macro
|
|
* MyClass.macro('greet', function() {
|
|
* return 'Hello!'
|
|
* })
|
|
*
|
|
* const instance = new MyClass()
|
|
* instance.version // "1.0.0"
|
|
* instance.greet() // "Hello!"
|
|
* ```
|
|
*/
|
|
static macro(name, value) {
|
|
this.prototype[name] = value;
|
|
}
|
|
/**
|
|
* Adds an instance property that will be assigned to each instance during construction.
|
|
* Unlike macros which are added to the prototype, instance properties are unique to each instance.
|
|
*
|
|
* @param name - The name of the property to add to instances
|
|
* @param value - The value to assign to the property on each instance
|
|
*
|
|
* @example
|
|
* ```ts
|
|
* // Add an instance method
|
|
* MyClass.instanceProperty('save', function() {
|
|
* console.log('Saving...', this.id)
|
|
* })
|
|
*
|
|
* const { save } = new MyClass()
|
|
* save()
|
|
* ```
|
|
*/
|
|
static instanceProperty(name, value) {
|
|
const self = this;
|
|
if (!self.hasOwnProperty("instanceMacros")) {
|
|
const inheritedProperties = self.instanceMacros;
|
|
Object.defineProperty(self, "instanceMacros", {
|
|
value: new Set(inheritedProperties),
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true
|
|
});
|
|
}
|
|
self.instanceMacros.add({ key: name, value });
|
|
}
|
|
/**
|
|
* Adds a getter property to the class prototype using Object.defineProperty.
|
|
* Getters are computed properties that are evaluated each time they are accessed,
|
|
* unless the singleton flag is enabled.
|
|
*
|
|
* @param name - The name of the getter property
|
|
* @param accumulator - Function that computes and returns the property value
|
|
* @param singleton - If true, the getter value is cached after first access
|
|
*
|
|
* @example
|
|
* ```ts
|
|
* // Add a regular getter
|
|
* MyClass.getter('timestamp', function() {
|
|
* return Date.now()
|
|
* })
|
|
*
|
|
* // Add a singleton getter (cached after first access)
|
|
* MyClass.getter('config', function() {
|
|
* return loadConfig()
|
|
* }, true)
|
|
*
|
|
* const instance = new MyClass()
|
|
* instance.timestamp // Computed each time
|
|
* instance.config // Computed once, then cached
|
|
* ```
|
|
*/
|
|
static getter(name, accumulator, singleton = false) {
|
|
Object.defineProperty(this.prototype, name, {
|
|
get() {
|
|
const value = accumulator.call(this);
|
|
if (singleton) {
|
|
Object.defineProperty(this, name, {
|
|
configurable: false,
|
|
enumerable: false,
|
|
value,
|
|
writable: false
|
|
});
|
|
}
|
|
return value;
|
|
},
|
|
configurable: true,
|
|
enumerable: false
|
|
});
|
|
}
|
|
/**
|
|
* Constructor that applies all registered instance properties to the new instance.
|
|
* This method iterates through the instanceMacros set and assigns each property
|
|
* to the instance, binding functions to the instance context.
|
|
*/
|
|
constructor() {
|
|
const self = this;
|
|
const Constructor = this.constructor;
|
|
Constructor.instanceMacros.forEach(({ key, value }) => {
|
|
self[key] = typeof value === "function" ? value.bind(this) : value;
|
|
});
|
|
}
|
|
};
|
|
export {
|
|
Macroable as default
|
|
};
|