@logosdx/hooks 1.0.0-beta.0 → 1.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/browser/bundle.js +1 -1
- package/dist/browser/bundle.js.map +1 -1
- package/dist/cjs/index.js +415 -305
- package/dist/esm/index.mjs +427 -347
- package/dist/types/index.d.ts +196 -132
- package/package.json +15 -8
- package/readme.md +1 -5
- package/src/index.ts +385 -260
package/dist/cjs/index.js
CHANGED
|
@@ -28,6 +28,9 @@ function _array_like_to_array(arr, len) {
|
|
|
28
28
|
function _array_with_holes(arr) {
|
|
29
29
|
if (Array.isArray(arr)) return arr;
|
|
30
30
|
}
|
|
31
|
+
function _array_without_holes(arr) {
|
|
32
|
+
if (Array.isArray(arr)) return _array_like_to_array(arr);
|
|
33
|
+
}
|
|
31
34
|
function _assert_this_initialized(self) {
|
|
32
35
|
if (self === void 0) {
|
|
33
36
|
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
|
|
@@ -112,6 +115,16 @@ function _class_private_field_set(receiver, privateMap, value) {
|
|
|
112
115
|
_class_apply_descriptor_set(receiver, descriptor, value);
|
|
113
116
|
return value;
|
|
114
117
|
}
|
|
118
|
+
function _class_private_method_get(receiver, privateSet, fn) {
|
|
119
|
+
if (!privateSet.has(receiver)) {
|
|
120
|
+
throw new TypeError("attempted to get private field on non-instance");
|
|
121
|
+
}
|
|
122
|
+
return fn;
|
|
123
|
+
}
|
|
124
|
+
function _class_private_method_init(obj, privateSet) {
|
|
125
|
+
_check_private_redeclaration(obj, privateSet);
|
|
126
|
+
privateSet.add(obj);
|
|
127
|
+
}
|
|
115
128
|
function _construct(Parent, args, Class) {
|
|
116
129
|
if (_is_native_reflect_construct()) {
|
|
117
130
|
_construct = Reflect.construct;
|
|
@@ -185,6 +198,9 @@ function _instanceof(left, right) {
|
|
|
185
198
|
function _is_native_function(fn) {
|
|
186
199
|
return Function.toString.call(fn).indexOf("[native code]") !== -1;
|
|
187
200
|
}
|
|
201
|
+
function _iterable_to_array(iter) {
|
|
202
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
203
|
+
}
|
|
188
204
|
function _iterable_to_array_limit(arr, i) {
|
|
189
205
|
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
|
|
190
206
|
if (_i == null) return;
|
|
@@ -212,6 +228,9 @@ function _iterable_to_array_limit(arr, i) {
|
|
|
212
228
|
function _non_iterable_rest() {
|
|
213
229
|
throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
214
230
|
}
|
|
231
|
+
function _non_iterable_spread() {
|
|
232
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
233
|
+
}
|
|
215
234
|
function _object_spread(target) {
|
|
216
235
|
for(var i = 1; i < arguments.length; i++){
|
|
217
236
|
var source = arguments[i] != null ? arguments[i] : {};
|
|
@@ -243,6 +262,9 @@ function _set_prototype_of(o, p) {
|
|
|
243
262
|
function _sliced_to_array(arr, i) {
|
|
244
263
|
return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
|
|
245
264
|
}
|
|
265
|
+
function _to_consumable_array(arr) {
|
|
266
|
+
return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
|
|
267
|
+
}
|
|
246
268
|
function _type_of(obj) {
|
|
247
269
|
"@swc/helpers - typeof";
|
|
248
270
|
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
@@ -402,7 +424,7 @@ var HookError = /*#__PURE__*/ function(Error1) {
|
|
|
402
424
|
var _this;
|
|
403
425
|
_this = _call_super(this, HookError, [
|
|
404
426
|
message
|
|
405
|
-
]), /** Name of the hook where the error occurred */ _define_property(_this, "hookName", void 0), /**
|
|
427
|
+
]), /** Name of the hook where the error occurred */ _define_property(_this, "hookName", void 0), /** Original error if `fail()` was called with an Error instance */ _define_property(_this, "originalError", void 0);
|
|
406
428
|
return _this;
|
|
407
429
|
}
|
|
408
430
|
return HookError;
|
|
@@ -411,386 +433,474 @@ var isHookError = function(error) {
|
|
|
411
433
|
var _error_constructor;
|
|
412
434
|
return (error === null || error === void 0 ? void 0 : (_error_constructor = error.constructor) === null || _error_constructor === void 0 ? void 0 : _error_constructor.name) === HookError.name;
|
|
413
435
|
};
|
|
414
|
-
var
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
_define_property(this, "before", new Set());
|
|
418
|
-
_define_property(this, "after", new Set());
|
|
419
|
-
_define_property(this, "error", new Set());
|
|
420
|
-
};
|
|
421
|
-
var allowedExtPoints = new Set([
|
|
422
|
-
'before',
|
|
423
|
-
'after',
|
|
424
|
-
'error'
|
|
425
|
-
]);
|
|
426
|
-
var _registered = /*#__PURE__*/ new WeakMap(), _hooks = /*#__PURE__*/ new WeakMap(), _hookFnOpts = /*#__PURE__*/ new WeakMap(), _wrapped = /*#__PURE__*/ new WeakMap();
|
|
436
|
+
var _hooks = /*#__PURE__*/ new WeakMap(), _hookOpts = /*#__PURE__*/ new WeakMap(), _handleFail = /*#__PURE__*/ new WeakMap(), _registered = /*#__PURE__*/ new WeakMap(), /**
|
|
437
|
+
* Validate that a hook is registered (if registration is enabled).
|
|
438
|
+
*/ _assertRegistered = /*#__PURE__*/ new WeakSet();
|
|
427
439
|
var HookEngine = /*#__PURE__*/ function() {
|
|
428
440
|
"use strict";
|
|
429
441
|
function HookEngine() {
|
|
442
|
+
var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
|
|
430
443
|
_class_call_check(this, HookEngine);
|
|
431
|
-
|
|
432
|
-
writable: true,
|
|
433
|
-
value: new Set()
|
|
434
|
-
});
|
|
444
|
+
_class_private_method_init(this, _assertRegistered);
|
|
435
445
|
_class_private_field_init(this, _hooks, {
|
|
436
446
|
writable: true,
|
|
437
447
|
value: new Map()
|
|
438
448
|
});
|
|
439
|
-
_class_private_field_init(this,
|
|
449
|
+
_class_private_field_init(this, _hookOpts, {
|
|
440
450
|
writable: true,
|
|
441
451
|
value: new WeakMap()
|
|
442
452
|
});
|
|
443
|
-
_class_private_field_init(this,
|
|
453
|
+
_class_private_field_init(this, _handleFail, {
|
|
444
454
|
writable: true,
|
|
445
|
-
value:
|
|
455
|
+
value: void 0
|
|
456
|
+
});
|
|
457
|
+
_class_private_field_init(this, _registered, {
|
|
458
|
+
writable: true,
|
|
459
|
+
value: null
|
|
460
|
+
});
|
|
461
|
+
var _options_handleFail;
|
|
462
|
+
_class_private_field_set(this, _handleFail, (_options_handleFail = options.handleFail) !== null && _options_handleFail !== void 0 ? _options_handleFail : function(message) {
|
|
463
|
+
throw new HookError(message);
|
|
446
464
|
});
|
|
447
465
|
}
|
|
448
466
|
_create_class(HookEngine, [
|
|
449
467
|
{
|
|
450
468
|
/**
|
|
451
|
-
*
|
|
469
|
+
* Register hook names for runtime validation.
|
|
470
|
+
* Once any hooks are registered, all hooks must be registered before use.
|
|
452
471
|
*
|
|
453
|
-
*
|
|
454
|
-
*
|
|
455
|
-
* - `after`: Runs after successful execution. Can modify the result.
|
|
456
|
-
* - `error`: Runs when the original function throws. Can handle or transform errors.
|
|
472
|
+
* @param names - Hook names to register
|
|
473
|
+
* @returns this (for chaining)
|
|
457
474
|
*
|
|
458
|
-
* @
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
*
|
|
475
|
+
* @example
|
|
476
|
+
* const hooks = new HookEngine<FetchLifecycle>()
|
|
477
|
+
* .register('preRequest', 'postRequest', 'rateLimit');
|
|
478
|
+
*
|
|
479
|
+
* hooks.on('preRequest', cb); // OK
|
|
480
|
+
* hooks.on('preRequset', cb); // Error: not registered (typo caught!)
|
|
481
|
+
*/ key: "register",
|
|
482
|
+
value: function register() {
|
|
483
|
+
for(var _len = arguments.length, names = new Array(_len), _key = 0; _key < _len; _key++){
|
|
484
|
+
names[_key] = arguments[_key];
|
|
485
|
+
}
|
|
486
|
+
(0, _utils.assert)(names.length > 0, 'register() requires at least one hook name');
|
|
487
|
+
if (_class_private_field_get(this, _registered) === null) {
|
|
488
|
+
_class_private_field_set(this, _registered, new Set());
|
|
489
|
+
}
|
|
490
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
491
|
+
try {
|
|
492
|
+
for(var _iterator = names[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
493
|
+
var name = _step.value;
|
|
494
|
+
(0, _utils.assert)(typeof name === 'string', "Hook name must be a string, got ".concat(typeof name === "undefined" ? "undefined" : _type_of(name)));
|
|
495
|
+
_class_private_field_get(this, _registered).add(name);
|
|
496
|
+
}
|
|
497
|
+
} catch (err) {
|
|
498
|
+
_didIteratorError = true;
|
|
499
|
+
_iteratorError = err;
|
|
500
|
+
} finally{
|
|
501
|
+
try {
|
|
502
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
503
|
+
_iterator.return();
|
|
504
|
+
}
|
|
505
|
+
} finally{
|
|
506
|
+
if (_didIteratorError) {
|
|
507
|
+
throw _iteratorError;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
return this;
|
|
512
|
+
}
|
|
513
|
+
},
|
|
514
|
+
{
|
|
515
|
+
/**
|
|
516
|
+
* Subscribe to a lifecycle hook.
|
|
517
|
+
*
|
|
518
|
+
* @param name - Name of the lifecycle hook
|
|
519
|
+
* @param cbOrOpts - Callback function or options object
|
|
520
|
+
* @returns Cleanup function to remove the subscription
|
|
462
521
|
*
|
|
463
522
|
* @example
|
|
464
523
|
* // Simple callback
|
|
465
|
-
* const cleanup = hooks.
|
|
466
|
-
* console.log('
|
|
524
|
+
* const cleanup = hooks.on('preRequest', async (ctx) => {
|
|
525
|
+
* console.log('Request:', ctx.args[0]);
|
|
467
526
|
* });
|
|
468
527
|
*
|
|
469
528
|
* // With options
|
|
470
|
-
* hooks.
|
|
471
|
-
* callback: async (ctx) => {
|
|
529
|
+
* hooks.on('analytics', {
|
|
530
|
+
* callback: async (ctx) => { track(ctx.args); },
|
|
472
531
|
* once: true, // Remove after first run
|
|
473
|
-
* ignoreOnFail: true // Don't throw if
|
|
532
|
+
* ignoreOnFail: true // Don't throw if callback fails
|
|
474
533
|
* });
|
|
475
534
|
*
|
|
476
|
-
* //
|
|
535
|
+
* // Remove subscription
|
|
477
536
|
* cleanup();
|
|
478
|
-
*/ key: "
|
|
479
|
-
value: function
|
|
537
|
+
*/ key: "on",
|
|
538
|
+
value: function on(name, cbOrOpts) {
|
|
480
539
|
var callback = typeof cbOrOpts === 'function' ? cbOrOpts : cbOrOpts === null || cbOrOpts === void 0 ? void 0 : cbOrOpts.callback;
|
|
481
540
|
var opts = typeof cbOrOpts === 'function' ? {} : cbOrOpts;
|
|
482
541
|
(0, _utils.assert)(typeof name === 'string', '"name" must be a string');
|
|
483
|
-
(0, _utils.assert)(
|
|
484
|
-
(0, _utils.assert)(typeof extensionPoint === 'string', '"extensionPoint" must be a string');
|
|
485
|
-
(0, _utils.assert)(allowedExtPoints.has(extensionPoint), "'".concat(extensionPoint, "' is not a valid extension point"));
|
|
486
|
-
(0, _utils.assert)((0, _utils.isFunction)(callback) || (0, _utils.isObject)(cbOrOpts), '"cbOrOpts" must be a extension callback or options');
|
|
542
|
+
(0, _utils.assert)((0, _utils.isFunction)(callback) || (0, _utils.isObject)(cbOrOpts), '"cbOrOpts" must be a callback or options');
|
|
487
543
|
(0, _utils.assert)((0, _utils.isFunction)(callback), 'callback must be a function');
|
|
544
|
+
_class_private_method_get(this, _assertRegistered, assertRegistered).call(this, name, 'on');
|
|
488
545
|
var _class_private_field_get_get;
|
|
489
|
-
var
|
|
490
|
-
|
|
491
|
-
_class_private_field_get(this, _hooks).set(name,
|
|
492
|
-
_class_private_field_get(this,
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
*/ return function() {
|
|
496
|
-
hook[extensionPoint].delete(callback);
|
|
546
|
+
var hooks = (_class_private_field_get_get = _class_private_field_get(this, _hooks).get(name)) !== null && _class_private_field_get_get !== void 0 ? _class_private_field_get_get : new Set();
|
|
547
|
+
hooks.add(callback);
|
|
548
|
+
_class_private_field_get(this, _hooks).set(name, hooks);
|
|
549
|
+
_class_private_field_get(this, _hookOpts).set(callback, opts);
|
|
550
|
+
return function() {
|
|
551
|
+
hooks.delete(callback);
|
|
497
552
|
};
|
|
498
553
|
}
|
|
499
554
|
},
|
|
500
555
|
{
|
|
501
556
|
/**
|
|
502
|
-
*
|
|
557
|
+
* Subscribe to a lifecycle hook that fires only once.
|
|
558
|
+
* Sugar for `on(name, { callback, once: true })`.
|
|
559
|
+
*
|
|
560
|
+
* @param name - Name of the lifecycle hook
|
|
561
|
+
* @param callback - Callback function
|
|
562
|
+
* @returns Cleanup function to remove the subscription
|
|
503
563
|
*
|
|
504
|
-
*
|
|
505
|
-
*
|
|
506
|
-
*
|
|
564
|
+
* @example
|
|
565
|
+
* // Log only the first request
|
|
566
|
+
* hooks.once('preRequest', async (ctx) => {
|
|
567
|
+
* console.log('First request:', ctx.args[0]);
|
|
568
|
+
* });
|
|
569
|
+
*/ key: "once",
|
|
570
|
+
value: function once(name, callback) {
|
|
571
|
+
return this.on(name, {
|
|
572
|
+
callback: callback,
|
|
573
|
+
once: true
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
},
|
|
577
|
+
{
|
|
578
|
+
key: "emit",
|
|
579
|
+
value: /**
|
|
580
|
+
* Emit a lifecycle hook, running all subscribed callbacks.
|
|
507
581
|
*
|
|
508
|
-
* @param name -
|
|
509
|
-
* @param
|
|
510
|
-
* @
|
|
511
|
-
* @returns Wrapped function with hook support
|
|
582
|
+
* @param name - Name of the lifecycle hook to emit
|
|
583
|
+
* @param args - Arguments to pass to callbacks
|
|
584
|
+
* @returns EmitResult with final args, result, and earlyReturn flag
|
|
512
585
|
*
|
|
513
586
|
* @example
|
|
514
|
-
* const
|
|
587
|
+
* const result = await hooks.emit('cacheCheck', url);
|
|
515
588
|
*
|
|
516
|
-
*
|
|
589
|
+
* if (result.earlyReturn && result.result) {
|
|
590
|
+
* return result.result; // Use cached value
|
|
591
|
+
* }
|
|
517
592
|
*
|
|
518
|
-
*
|
|
519
|
-
*
|
|
593
|
+
* // Continue with modified args
|
|
594
|
+
* const [modifiedUrl] = result.args;
|
|
595
|
+
*/ function emit(name) {
|
|
596
|
+
for(var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++){
|
|
597
|
+
args[_key - 1] = arguments[_key];
|
|
598
|
+
}
|
|
599
|
+
return _async_to_generator(function() {
|
|
600
|
+
var _this, earlyReturn, hooks, context, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _this1, _loop, _iterator, _step, _ret, err;
|
|
601
|
+
return _ts_generator(this, function(_state) {
|
|
602
|
+
switch(_state.label){
|
|
603
|
+
case 0:
|
|
604
|
+
_this = this;
|
|
605
|
+
_class_private_method_get(this, _assertRegistered, assertRegistered).call(this, name, 'emit');
|
|
606
|
+
earlyReturn = false;
|
|
607
|
+
hooks = _class_private_field_get(this, _hooks).get(name);
|
|
608
|
+
context = {
|
|
609
|
+
args: args,
|
|
610
|
+
removeHook: function removeHook() {},
|
|
611
|
+
returnEarly: function returnEarly() {
|
|
612
|
+
earlyReturn = true;
|
|
613
|
+
},
|
|
614
|
+
setArgs: function(next) {
|
|
615
|
+
(0, _utils.assert)(Array.isArray(next), "setArgs: args for '".concat(String(name), "' must be an array"));
|
|
616
|
+
context.args = next;
|
|
617
|
+
},
|
|
618
|
+
setResult: function(next) {
|
|
619
|
+
context.result = next;
|
|
620
|
+
},
|
|
621
|
+
fail: function() {
|
|
622
|
+
for(var _len = arguments.length, failArgs = new Array(_len), _key = 0; _key < _len; _key++){
|
|
623
|
+
failArgs[_key] = arguments[_key];
|
|
624
|
+
}
|
|
625
|
+
var _handler_prototype;
|
|
626
|
+
var handler = _class_private_field_get(_this, _handleFail);
|
|
627
|
+
// Check if handler is a constructor (class or function with prototype)
|
|
628
|
+
var isConstructor = typeof handler === 'function' && ((_handler_prototype = handler.prototype) === null || _handler_prototype === void 0 ? void 0 : _handler_prototype.constructor) === handler;
|
|
629
|
+
var _attemptSync = _sliced_to_array((0, _utils.attemptSync)(function() {
|
|
630
|
+
if (isConstructor) {
|
|
631
|
+
throw _construct(handler, _to_consumable_array(failArgs));
|
|
632
|
+
}
|
|
633
|
+
handler.apply(void 0, _to_consumable_array(failArgs));
|
|
634
|
+
}), 2), error = _attemptSync[1];
|
|
635
|
+
if (error) {
|
|
636
|
+
if (_instanceof(error, HookError)) {
|
|
637
|
+
error.hookName = String(name);
|
|
638
|
+
}
|
|
639
|
+
throw error;
|
|
640
|
+
}
|
|
641
|
+
// If handler didn't throw, we need to throw something
|
|
642
|
+
throw new HookError('ctx.fail() handler did not throw');
|
|
643
|
+
}
|
|
644
|
+
};
|
|
645
|
+
if (!hooks || hooks.size === 0) {
|
|
646
|
+
return [
|
|
647
|
+
2,
|
|
648
|
+
{
|
|
649
|
+
args: context.args,
|
|
650
|
+
result: context.result,
|
|
651
|
+
earlyReturn: false
|
|
652
|
+
}
|
|
653
|
+
];
|
|
654
|
+
}
|
|
655
|
+
_iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
656
|
+
_state.label = 1;
|
|
657
|
+
case 1:
|
|
658
|
+
_state.trys.push([
|
|
659
|
+
1,
|
|
660
|
+
6,
|
|
661
|
+
7,
|
|
662
|
+
8
|
|
663
|
+
]);
|
|
664
|
+
_loop = function() {
|
|
665
|
+
var fn, _class_private_field_get_get, opts, _ref, _$err;
|
|
666
|
+
return _ts_generator(this, function(_state) {
|
|
667
|
+
switch(_state.label){
|
|
668
|
+
case 0:
|
|
669
|
+
fn = _step.value;
|
|
670
|
+
context.removeHook = function() {
|
|
671
|
+
return hooks.delete(fn);
|
|
672
|
+
};
|
|
673
|
+
opts = (_class_private_field_get_get = _class_private_field_get(_this1, _hookOpts).get(fn)) !== null && _class_private_field_get_get !== void 0 ? _class_private_field_get_get : {
|
|
674
|
+
callback: fn
|
|
675
|
+
};
|
|
676
|
+
return [
|
|
677
|
+
4,
|
|
678
|
+
(0, _utils.attempt)(function() {
|
|
679
|
+
return fn(_object_spread({}, context));
|
|
680
|
+
})
|
|
681
|
+
];
|
|
682
|
+
case 1:
|
|
683
|
+
_ref = _sliced_to_array.apply(void 0, [
|
|
684
|
+
_state.sent(),
|
|
685
|
+
2
|
|
686
|
+
]), _$err = _ref[1];
|
|
687
|
+
if (opts.once) context.removeHook();
|
|
688
|
+
if (_$err && opts.ignoreOnFail !== true) {
|
|
689
|
+
throw _$err;
|
|
690
|
+
}
|
|
691
|
+
if (earlyReturn) return [
|
|
692
|
+
2,
|
|
693
|
+
"break"
|
|
694
|
+
];
|
|
695
|
+
return [
|
|
696
|
+
2
|
|
697
|
+
];
|
|
698
|
+
}
|
|
699
|
+
});
|
|
700
|
+
};
|
|
701
|
+
_iterator = hooks[Symbol.iterator]();
|
|
702
|
+
_state.label = 2;
|
|
703
|
+
case 2:
|
|
704
|
+
if (!!(_iteratorNormalCompletion = (_step = _iterator.next()).done)) return [
|
|
705
|
+
3,
|
|
706
|
+
5
|
|
707
|
+
];
|
|
708
|
+
_this1 = this;
|
|
709
|
+
return [
|
|
710
|
+
5,
|
|
711
|
+
_ts_values(_loop())
|
|
712
|
+
];
|
|
713
|
+
case 3:
|
|
714
|
+
_ret = _state.sent();
|
|
715
|
+
if (_ret === "break") return [
|
|
716
|
+
3,
|
|
717
|
+
5
|
|
718
|
+
];
|
|
719
|
+
_state.label = 4;
|
|
720
|
+
case 4:
|
|
721
|
+
_iteratorNormalCompletion = true;
|
|
722
|
+
return [
|
|
723
|
+
3,
|
|
724
|
+
2
|
|
725
|
+
];
|
|
726
|
+
case 5:
|
|
727
|
+
return [
|
|
728
|
+
3,
|
|
729
|
+
8
|
|
730
|
+
];
|
|
731
|
+
case 6:
|
|
732
|
+
err = _state.sent();
|
|
733
|
+
_didIteratorError = true;
|
|
734
|
+
_iteratorError = err;
|
|
735
|
+
return [
|
|
736
|
+
3,
|
|
737
|
+
8
|
|
738
|
+
];
|
|
739
|
+
case 7:
|
|
740
|
+
try {
|
|
741
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
742
|
+
_iterator.return();
|
|
743
|
+
}
|
|
744
|
+
} finally{
|
|
745
|
+
if (_didIteratorError) {
|
|
746
|
+
throw _iteratorError;
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
return [
|
|
750
|
+
7
|
|
751
|
+
];
|
|
752
|
+
case 8:
|
|
753
|
+
return [
|
|
754
|
+
2,
|
|
755
|
+
{
|
|
756
|
+
args: context.args,
|
|
757
|
+
result: context.result,
|
|
758
|
+
earlyReturn: earlyReturn
|
|
759
|
+
}
|
|
760
|
+
];
|
|
761
|
+
}
|
|
762
|
+
});
|
|
763
|
+
}).call(this);
|
|
764
|
+
}
|
|
765
|
+
},
|
|
766
|
+
{
|
|
767
|
+
/**
|
|
768
|
+
* Clear all registered hooks.
|
|
769
|
+
*
|
|
770
|
+
* @example
|
|
771
|
+
* hooks.on('preRequest', validator);
|
|
772
|
+
* hooks.on('postRequest', logger);
|
|
773
|
+
*
|
|
774
|
+
* // Reset for testing
|
|
775
|
+
* hooks.clear();
|
|
776
|
+
*/ key: "clear",
|
|
777
|
+
value: function clear() {
|
|
778
|
+
_class_private_field_get(this, _hooks).clear();
|
|
779
|
+
_class_private_field_set(this, _hookOpts, new WeakMap());
|
|
780
|
+
_class_private_field_set(this, _registered, null);
|
|
781
|
+
}
|
|
782
|
+
},
|
|
783
|
+
{
|
|
784
|
+
/**
|
|
785
|
+
* Wrap a function with pre/post lifecycle hooks.
|
|
786
|
+
*
|
|
787
|
+
* - Pre hook: emitted with function args, can modify args or returnEarly with result
|
|
788
|
+
* - Post hook: emitted with [result, ...args], can modify result
|
|
789
|
+
*
|
|
790
|
+
* @param fn - The async function to wrap
|
|
791
|
+
* @param hooks - Object with optional pre and post hook names
|
|
792
|
+
* @returns Wrapped function with same signature
|
|
793
|
+
*
|
|
794
|
+
* @example
|
|
795
|
+
* interface Lifecycle {
|
|
796
|
+
* preRequest(url: string, opts: RequestInit): Promise<Response>;
|
|
797
|
+
* postRequest(result: Response, url: string, opts: RequestInit): Promise<Response>;
|
|
798
|
+
* }
|
|
799
|
+
*
|
|
800
|
+
* const hooks = new HookEngine<Lifecycle>();
|
|
801
|
+
*
|
|
802
|
+
* // Add cache check in pre hook
|
|
803
|
+
* hooks.on('preRequest', async (ctx) => {
|
|
804
|
+
* const cached = cache.get(ctx.args[0]);
|
|
805
|
+
* if (cached) {
|
|
806
|
+
* ctx.setResult(cached);
|
|
807
|
+
* ctx.returnEarly();
|
|
808
|
+
* }
|
|
809
|
+
* });
|
|
810
|
+
*
|
|
811
|
+
* // Log result in post hook
|
|
812
|
+
* hooks.on('postRequest', async (ctx) => {
|
|
813
|
+
* const [result, url] = ctx.args;
|
|
814
|
+
* console.log(`Fetched ${url}:`, result.status);
|
|
520
815
|
* });
|
|
521
816
|
*
|
|
522
|
-
*
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
817
|
+
* // Wrap the fetch function
|
|
818
|
+
* const wrappedFetch = hooks.wrap(
|
|
819
|
+
* async (url: string, opts: RequestInit) => fetch(url, opts),
|
|
820
|
+
* { pre: 'preRequest', post: 'postRequest' }
|
|
821
|
+
* );
|
|
822
|
+
*/ key: "wrap",
|
|
823
|
+
value: function wrap(fn, hooks) {
|
|
526
824
|
var _this = this;
|
|
527
|
-
(0, _utils.assert)(
|
|
528
|
-
(
|
|
529
|
-
(
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
return _class_private_field_get(this, _wrapped).get(cb);
|
|
534
|
-
}
|
|
535
|
-
var callback = function() {
|
|
536
|
-
for(var _len = arguments.length, origArgs = new Array(_len), _key = 0; _key < _len; _key++){
|
|
537
|
-
origArgs[_key] = arguments[_key];
|
|
825
|
+
(0, _utils.assert)(hooks.pre || hooks.post, 'wrap() requires at least one of "pre" or "post" hooks');
|
|
826
|
+
if (hooks.pre) _class_private_method_get(this, _assertRegistered, assertRegistered).call(this, hooks.pre, 'wrap');
|
|
827
|
+
if (hooks.post) _class_private_method_get(this, _assertRegistered, assertRegistered).call(this, hooks.post, 'wrap');
|
|
828
|
+
return function() {
|
|
829
|
+
for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
|
|
830
|
+
args[_key] = arguments[_key];
|
|
538
831
|
}
|
|
539
832
|
return _async_to_generator(function() {
|
|
540
|
-
var
|
|
833
|
+
var currentArgs, result, preResult, postResult;
|
|
541
834
|
return _ts_generator(this, function(_state) {
|
|
542
835
|
switch(_state.label){
|
|
543
836
|
case 0:
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
point: 'before',
|
|
550
|
-
removeHook: function removeHook() {},
|
|
551
|
-
returnEarly: function returnEarly1() {
|
|
552
|
-
returnEarly = true;
|
|
553
|
-
},
|
|
554
|
-
setArgs: function setArgs(next) {
|
|
555
|
-
(0, _utils.assert)(Array.isArray(next), "setArgs: next args for '".concat(context.point, "' '").concat(name.toString(), "' must be an array of arguments"));
|
|
556
|
-
context.args = next;
|
|
557
|
-
},
|
|
558
|
-
setResult: function setResult(next) {
|
|
559
|
-
context.results = next;
|
|
560
|
-
},
|
|
561
|
-
fail: function fail(reason) {
|
|
562
|
-
var error = new HookError("Hook Aborted: ".concat(reason !== null && reason !== void 0 ? reason : 'unknown'));
|
|
563
|
-
if (_instanceof(reason, Error)) {
|
|
564
|
-
error.originalError = reason;
|
|
565
|
-
}
|
|
566
|
-
error.extPoint = context.point;
|
|
567
|
-
error.hookName = name;
|
|
568
|
-
throw error;
|
|
569
|
-
}
|
|
570
|
-
};
|
|
571
|
-
_ref = hook !== null && hook !== void 0 ? hook : new Hook(), before = _ref.before, after = _ref.after, errorFns = _ref.error;
|
|
572
|
-
handleSet = function(which, point) {
|
|
573
|
-
return _async_to_generator(function() {
|
|
574
|
-
var _iteratorNormalCompletion, _didIteratorError, _iteratorError, _this, _loop, _iterator, _step, _ret, err;
|
|
575
|
-
return _ts_generator(this, function(_state) {
|
|
576
|
-
switch(_state.label){
|
|
577
|
-
case 0:
|
|
578
|
-
context.point = point;
|
|
579
|
-
_iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
580
|
-
_state.label = 1;
|
|
581
|
-
case 1:
|
|
582
|
-
_state.trys.push([
|
|
583
|
-
1,
|
|
584
|
-
6,
|
|
585
|
-
7,
|
|
586
|
-
8
|
|
587
|
-
]);
|
|
588
|
-
_loop = function() {
|
|
589
|
-
var fn, opts, _ref, _$err;
|
|
590
|
-
return _ts_generator(this, function(_state) {
|
|
591
|
-
switch(_state.label){
|
|
592
|
-
case 0:
|
|
593
|
-
fn = _step.value;
|
|
594
|
-
context.removeHook = function() {
|
|
595
|
-
return which.delete(fn);
|
|
596
|
-
};
|
|
597
|
-
opts = _class_private_field_get(_this, _hookFnOpts).get(fn);
|
|
598
|
-
return [
|
|
599
|
-
4,
|
|
600
|
-
(0, _utils.attempt)(function() {
|
|
601
|
-
return fn(_object_spread({}, context));
|
|
602
|
-
})
|
|
603
|
-
];
|
|
604
|
-
case 1:
|
|
605
|
-
_ref = _sliced_to_array.apply(void 0, [
|
|
606
|
-
_state.sent(),
|
|
607
|
-
2
|
|
608
|
-
]), _$err = _ref[1];
|
|
609
|
-
if (opts.once) context.removeHook();
|
|
610
|
-
if (_$err && opts.ignoreOnFail !== true) {
|
|
611
|
-
throw _$err;
|
|
612
|
-
}
|
|
613
|
-
if (returnEarly) return [
|
|
614
|
-
2,
|
|
615
|
-
"break"
|
|
616
|
-
];
|
|
617
|
-
return [
|
|
618
|
-
2
|
|
619
|
-
];
|
|
620
|
-
}
|
|
621
|
-
});
|
|
622
|
-
};
|
|
623
|
-
_iterator = which[Symbol.iterator]();
|
|
624
|
-
_state.label = 2;
|
|
625
|
-
case 2:
|
|
626
|
-
if (!!(_iteratorNormalCompletion = (_step = _iterator.next()).done)) return [
|
|
627
|
-
3,
|
|
628
|
-
5
|
|
629
|
-
];
|
|
630
|
-
_this = this;
|
|
631
|
-
return [
|
|
632
|
-
5,
|
|
633
|
-
_ts_values(_loop())
|
|
634
|
-
];
|
|
635
|
-
case 3:
|
|
636
|
-
_ret = _state.sent();
|
|
637
|
-
if (_ret === "break") return [
|
|
638
|
-
3,
|
|
639
|
-
5
|
|
640
|
-
];
|
|
641
|
-
_state.label = 4;
|
|
642
|
-
case 4:
|
|
643
|
-
_iteratorNormalCompletion = true;
|
|
644
|
-
return [
|
|
645
|
-
3,
|
|
646
|
-
2
|
|
647
|
-
];
|
|
648
|
-
case 5:
|
|
649
|
-
return [
|
|
650
|
-
3,
|
|
651
|
-
8
|
|
652
|
-
];
|
|
653
|
-
case 6:
|
|
654
|
-
err = _state.sent();
|
|
655
|
-
_didIteratorError = true;
|
|
656
|
-
_iteratorError = err;
|
|
657
|
-
return [
|
|
658
|
-
3,
|
|
659
|
-
8
|
|
660
|
-
];
|
|
661
|
-
case 7:
|
|
662
|
-
try {
|
|
663
|
-
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
664
|
-
_iterator.return();
|
|
665
|
-
}
|
|
666
|
-
} finally{
|
|
667
|
-
if (_didIteratorError) {
|
|
668
|
-
throw _iteratorError;
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
return [
|
|
672
|
-
7
|
|
673
|
-
];
|
|
674
|
-
case 8:
|
|
675
|
-
return [
|
|
676
|
-
2
|
|
677
|
-
];
|
|
678
|
-
}
|
|
679
|
-
});
|
|
680
|
-
}).call(_this);
|
|
681
|
-
};
|
|
837
|
+
currentArgs = args;
|
|
838
|
+
if (!hooks.pre) return [
|
|
839
|
+
3,
|
|
840
|
+
2
|
|
841
|
+
];
|
|
682
842
|
return [
|
|
683
843
|
4,
|
|
684
|
-
|
|
844
|
+
this.emit.apply(this, [
|
|
845
|
+
hooks.pre
|
|
846
|
+
].concat(_to_consumable_array(currentArgs)))
|
|
685
847
|
];
|
|
686
848
|
case 1:
|
|
687
|
-
_state.sent();
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
849
|
+
preResult = _state.sent();
|
|
850
|
+
currentArgs = preResult.args;
|
|
851
|
+
if (preResult.earlyReturn && preResult.result !== undefined) {
|
|
852
|
+
return [
|
|
853
|
+
2,
|
|
854
|
+
preResult.result
|
|
855
|
+
];
|
|
856
|
+
}
|
|
857
|
+
_state.label = 2;
|
|
858
|
+
case 2:
|
|
692
859
|
return [
|
|
693
860
|
4,
|
|
694
|
-
(0,
|
|
695
|
-
return cb.apply((opts === null || opts === void 0 ? void 0 : opts.bindTo) || cb, context.args);
|
|
696
|
-
})
|
|
861
|
+
fn.apply(void 0, _to_consumable_array(currentArgs))
|
|
697
862
|
];
|
|
698
|
-
case
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
]), res = _ref1[0], err = _ref1[1];
|
|
703
|
-
context.results = res;
|
|
704
|
-
context.error = err;
|
|
705
|
-
if (!err) return [
|
|
863
|
+
case 3:
|
|
864
|
+
// Execute function
|
|
865
|
+
result = _state.sent();
|
|
866
|
+
if (!hooks.post) return [
|
|
706
867
|
3,
|
|
707
|
-
|
|
868
|
+
5
|
|
708
869
|
];
|
|
709
|
-
context.point = 'error';
|
|
710
870
|
return [
|
|
711
871
|
4,
|
|
712
|
-
|
|
872
|
+
this.emit.apply(this, [
|
|
873
|
+
hooks.post
|
|
874
|
+
].concat(_to_consumable_array([
|
|
875
|
+
result
|
|
876
|
+
].concat(_to_consumable_array(currentArgs)))))
|
|
713
877
|
];
|
|
714
|
-
case 3:
|
|
715
|
-
_state.sent();
|
|
716
|
-
throw err;
|
|
717
878
|
case 4:
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
879
|
+
postResult = _state.sent();
|
|
880
|
+
if (postResult.result !== undefined) {
|
|
881
|
+
return [
|
|
882
|
+
2,
|
|
883
|
+
postResult.result
|
|
884
|
+
];
|
|
885
|
+
}
|
|
886
|
+
_state.label = 5;
|
|
722
887
|
case 5:
|
|
723
|
-
_state.sent();
|
|
724
888
|
return [
|
|
725
889
|
2,
|
|
726
|
-
|
|
890
|
+
result
|
|
727
891
|
];
|
|
728
892
|
}
|
|
729
893
|
});
|
|
730
894
|
}).call(_this);
|
|
731
895
|
};
|
|
732
|
-
return callback;
|
|
733
|
-
}
|
|
734
|
-
},
|
|
735
|
-
{
|
|
736
|
-
/**
|
|
737
|
-
* Wrap an object method in-place to make it hookable.
|
|
738
|
-
*
|
|
739
|
-
* This is a convenience method that combines `make()` with automatic
|
|
740
|
-
* binding and reassignment. The method is replaced on the instance
|
|
741
|
-
* with the wrapped version.
|
|
742
|
-
*
|
|
743
|
-
* @param instance - Object containing the method to wrap
|
|
744
|
-
* @param name - Name of the method to wrap
|
|
745
|
-
* @param opts - Additional options
|
|
746
|
-
*
|
|
747
|
-
* @example
|
|
748
|
-
* class UserService {
|
|
749
|
-
* async save(user: User) { ... }
|
|
750
|
-
* }
|
|
751
|
-
*
|
|
752
|
-
* const service = new UserService();
|
|
753
|
-
* const hooks = new HookEngine<UserService>();
|
|
754
|
-
*
|
|
755
|
-
* hooks.wrap(service, 'save');
|
|
756
|
-
*
|
|
757
|
-
* // Now service.save() is hookable
|
|
758
|
-
* hooks.extend('save', 'before', async (ctx) => {
|
|
759
|
-
* console.log('Saving user:', ctx.args[0]);
|
|
760
|
-
* });
|
|
761
|
-
*/ key: "wrap",
|
|
762
|
-
value: function wrap(instance, name, opts) {
|
|
763
|
-
(0, _utils.assert)((0, _utils.isObject)(instance), '"instance" must be an object');
|
|
764
|
-
var wrapped = this.make(name, instance[name], _object_spread({
|
|
765
|
-
bindTo: instance
|
|
766
|
-
}, opts));
|
|
767
|
-
_class_private_field_get(this, _wrapped).set(wrapped, instance[name]);
|
|
768
|
-
instance[name] = wrapped;
|
|
769
|
-
}
|
|
770
|
-
},
|
|
771
|
-
{
|
|
772
|
-
/**
|
|
773
|
-
* Clear all registered hooks and extensions.
|
|
774
|
-
*
|
|
775
|
-
* After calling this method, all hooks are unregistered and all
|
|
776
|
-
* extensions are removed. Previously wrapped functions will continue
|
|
777
|
-
* to work but without any extensions.
|
|
778
|
-
*
|
|
779
|
-
* @example
|
|
780
|
-
* hooks.wrap(app, 'save');
|
|
781
|
-
* hooks.extend('save', 'before', validator);
|
|
782
|
-
*
|
|
783
|
-
* // Reset for testing
|
|
784
|
-
* hooks.clear();
|
|
785
|
-
*
|
|
786
|
-
* // app.save() still works, but validator no longer runs
|
|
787
|
-
*/ key: "clear",
|
|
788
|
-
value: function clear() {
|
|
789
|
-
_class_private_field_get(this, _registered).clear();
|
|
790
|
-
_class_private_field_get(this, _hooks).clear();
|
|
791
|
-
_class_private_field_set(this, _hookFnOpts, new WeakMap());
|
|
792
896
|
}
|
|
793
897
|
}
|
|
794
898
|
]);
|
|
795
899
|
return HookEngine;
|
|
796
900
|
}();
|
|
901
|
+
function assertRegistered(name, method) {
|
|
902
|
+
if (_class_private_field_get(this, _registered) !== null && !_class_private_field_get(this, _registered).has(name)) {
|
|
903
|
+
var registered = _to_consumable_array(_class_private_field_get(this, _registered)).map(String).join(', ');
|
|
904
|
+
throw new Error('Hook "'.concat(String(name), '" is not registered. ') + 'Call register("'.concat(String(name), '") before using ').concat(method, "(). ") + "Registered hooks: ".concat(registered || '(none)'));
|
|
905
|
+
}
|
|
906
|
+
}
|