Fix @mutex decorator, text input, modal docs, group management polish
Add user groups feature, simplify flash alerts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -9,11 +9,16 @@
|
||||
* @mutex('operation_name')
|
||||
* async my_method() { ... }
|
||||
*
|
||||
* Uses the 2023-11 decorator proposal (Stage 3).
|
||||
* Decorator receives (value, context) where:
|
||||
* - value: the original method function
|
||||
* - context: { kind, name, static, private, access, addInitializer }
|
||||
*
|
||||
* @decorator
|
||||
* @param {string} [global_id] - Optional global mutex ID for cross-instance locking
|
||||
*/
|
||||
function mutex(global_id) {
|
||||
// Storage (using IIFEs to keep WeakMap/Map in closure scope)
|
||||
function mutex(arg) {
|
||||
// Storage for mutex locks
|
||||
const instance_mutexes = (function() {
|
||||
if (!mutex._instance_storage) {
|
||||
mutex._instance_storage = new WeakMap();
|
||||
@@ -89,39 +94,48 @@ function mutex(global_id) {
|
||||
});
|
||||
}
|
||||
|
||||
// If called with an ID argument: @mutex('id')
|
||||
if (typeof global_id === 'string') {
|
||||
return function(target, key, descriptor) {
|
||||
const original_method = descriptor.value;
|
||||
|
||||
if (typeof original_method !== 'function') {
|
||||
throw new Error(`@mutex can only be applied to methods (tried to apply to ${key})`);
|
||||
/**
|
||||
* Create the wrapper method for a given original method
|
||||
* @param {Function} original_method - The original method
|
||||
* @param {string} method_name - The method name
|
||||
* @param {string|null} global_id - Global mutex ID (null for instance-level)
|
||||
*/
|
||||
function create_mutex_wrapper(original_method, method_name, global_id) {
|
||||
return function(...args) {
|
||||
let lock_state;
|
||||
if (global_id) {
|
||||
lock_state = get_global_mutex(global_id);
|
||||
} else {
|
||||
lock_state = get_instance_mutex(this, method_name);
|
||||
}
|
||||
|
||||
descriptor.value = function(...args) {
|
||||
const lock_state = get_global_mutex(global_id);
|
||||
return acquire_lock(lock_state, () => original_method.apply(this, args));
|
||||
};
|
||||
|
||||
return descriptor;
|
||||
return acquire_lock(lock_state, () => original_method.apply(this, args));
|
||||
};
|
||||
}
|
||||
|
||||
// If called without arguments: @mutex (target is the first argument)
|
||||
const target = global_id; // In this case, first arg is target
|
||||
const key = arguments[1];
|
||||
const descriptor = arguments[2];
|
||||
// 2023-11 decorator spec: decorators receive (value, context)
|
||||
// If called with a string argument: @mutex('id') - returns decorator function
|
||||
// If called directly on method: @mutex - arg is the method function, second arg is context
|
||||
|
||||
const original_method = descriptor.value;
|
||||
|
||||
if (typeof original_method !== 'function') {
|
||||
throw new Error(`@mutex can only be applied to methods (tried to apply to ${key})`);
|
||||
if (typeof arg === 'string') {
|
||||
// Called with ID: @mutex('operation_name')
|
||||
// Returns a decorator function
|
||||
const global_id = arg;
|
||||
return function(value, context) {
|
||||
if (context.kind !== 'method') {
|
||||
throw new Error(`@mutex can only be applied to methods, not ${context.kind}`);
|
||||
}
|
||||
return create_mutex_wrapper(value, context.name, global_id);
|
||||
};
|
||||
}
|
||||
|
||||
descriptor.value = function(...args) {
|
||||
const lock_state = get_instance_mutex(this, key);
|
||||
return acquire_lock(lock_state, () => original_method.apply(this, args));
|
||||
};
|
||||
// Called without arguments: @mutex
|
||||
// In 2023-11 spec, arg is the method function, second argument is context
|
||||
const value = arg;
|
||||
const context = arguments[1];
|
||||
|
||||
return descriptor;
|
||||
if (!context || context.kind !== 'method') {
|
||||
throw new Error(`@mutex can only be applied to methods`);
|
||||
}
|
||||
|
||||
return create_mutex_wrapper(value, context.name, null);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user