@angular-wave/angular.ts 0.14.0 → 0.14.1

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.
@@ -1,4 +1,4 @@
1
- /* Version: 0.14.0 - December 5, 2025 23:43:28 */
1
+ /* Version: 0.14.1 - December 7, 2025 02:50:02 */
2
2
  (function (global, factory) {
3
3
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
4
4
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
@@ -63,7 +63,6 @@
63
63
 
64
64
  const isProxySymbol = Symbol("isProxy");
65
65
  const BADARG = "badarg";
66
- const BADARGKEY = "badarg: key";
67
66
  const BADARGVALUE = "badarg: value";
68
67
 
69
68
  /**
@@ -225,10 +224,7 @@
225
224
  }
226
225
 
227
226
  /**
228
- * @module angular
229
- * @function isDate
230
227
  *
231
- * @description
232
228
  * Determines if a value is a date.
233
229
  *
234
230
  * @param {*} value Reference to check.
@@ -987,7 +983,7 @@
987
983
 
988
984
  /** @type {Map<ng.Validator, string>} */
989
985
  const reasons = new Map([
990
- [isNullOrUndefined, "required"],
986
+ [notNullOrUndefined, "required"],
991
987
  [Array.isArray, "notarray"],
992
988
  [isInjectable, "notinjectable"],
993
989
  [isDefined, "required"],
@@ -1006,6 +1002,7 @@
1006
1002
  /**
1007
1003
  * Validate a value using a predicate function.
1008
1004
  * Throws if the predicate returns false.
1005
+ * IMPORTANT: use this function only for developper errors and not for user/data errors
1009
1006
  *
1010
1007
  * @param {ng.Validator} fn - Predicate validator function.
1011
1008
  * @param {*} arg - The value to validate.
@@ -1047,6 +1044,16 @@
1047
1044
  return validate(Array.isArray, arg, name);
1048
1045
  }
1049
1046
 
1047
+ /**
1048
+ * @param {*} arg - The value to validate.
1049
+ * @param {string} name - Parameter name (included in error message).
1050
+ * @returns {*} The validated value.
1051
+ * @throws {TypeError} If the value does not satisfy the validator.
1052
+ */
1053
+ function validateIsString(arg, name) {
1054
+ return validate(isString, arg, name);
1055
+ }
1056
+
1050
1057
  /**
1051
1058
  * Throw error if the argument is falsy.
1052
1059
  */
@@ -1453,6 +1460,14 @@
1453
1460
  return { instance, exports: instance.exports, module };
1454
1461
  }
1455
1462
 
1463
+ /**
1464
+ * @param {*} fn
1465
+ * @returns {boolean}
1466
+ */
1467
+ function isArrowFunction(fn) {
1468
+ return typeof fn === "function" && !fn.prototype;
1469
+ }
1470
+
1456
1471
  /**
1457
1472
  * Expando cache for adding properties to DOM nodes with JavaScript.
1458
1473
  * This used to be an Object in JQLite decorator, but swapped out for a Map
@@ -2788,7 +2803,16 @@
2788
2803
  // Empty object at position 0 is ignored for invocation with `new`, but required.
2789
2804
  args.unshift(null);
2790
2805
 
2791
- return new (Function.prototype.bind.apply(ctor, args))();
2806
+ try {
2807
+ return new (Function.prototype.bind.apply(ctor, args))();
2808
+ } catch (err) {
2809
+ // try arrow function
2810
+ if (isArrowFunction(ctor)) {
2811
+ return ctor(args);
2812
+ } else {
2813
+ throw err;
2814
+ }
2815
+ }
2792
2816
  }
2793
2817
 
2794
2818
  /**
@@ -5381,6 +5405,8 @@
5381
5405
  * @returns {NgModule}
5382
5406
  */
5383
5407
  factory(name, providerFunction) {
5408
+ validate(isString, name, "name");
5409
+ validateRequired(providerFunction, "providerFunction");
5384
5410
  this.invokeQueue.push([$injectTokens.$provide, "factory", [name, providerFunction]]);
5385
5411
 
5386
5412
  return this;
@@ -5392,6 +5418,8 @@
5392
5418
  * @returns {NgModule}
5393
5419
  */
5394
5420
  service(name, serviceFunction) {
5421
+ validate(isString, name, "name");
5422
+ validateRequired(serviceFunction, "serviceFunction");
5395
5423
  this.services.push(name);
5396
5424
  this.invokeQueue.push([$injectTokens.$provide, "service", [name, serviceFunction]]);
5397
5425
 
@@ -5404,9 +5432,8 @@
5404
5432
  * @returns {NgModule}
5405
5433
  */
5406
5434
  provider(name, providerType) {
5407
- if (providerType && isFunction(providerType)) {
5408
- providerType.$$moduleName = name;
5409
- }
5435
+ validate(isString, name, "name");
5436
+ validateRequired(providerType, "providerType");
5410
5437
  this.invokeQueue.push([$injectTokens.$provide, "provider", [name, providerType]]);
5411
5438
 
5412
5439
  return this;
@@ -5418,9 +5445,8 @@
5418
5445
  * @returns {NgModule}
5419
5446
  */
5420
5447
  decorator(name, decorFn) {
5421
- if (decorFn && isFunction(decorFn)) {
5422
- decorFn.$$moduleName = name;
5423
- }
5448
+ validate(isString, name, "name");
5449
+ validateRequired(decorFn, "decorFn");
5424
5450
  this.configBlocks.push([$injectTokens.$provide, "decorator", [name, decorFn]]);
5425
5451
 
5426
5452
  return this;
@@ -5432,6 +5458,8 @@
5432
5458
  * @returns {NgModule}
5433
5459
  */
5434
5460
  directive(name, directiveFactory) {
5461
+ validate(isString, name, "name");
5462
+ validateRequired(directiveFactory, "directiveFactory");
5435
5463
  this.invokeQueue.push([
5436
5464
  $injectTokens.$compileProvider,
5437
5465
  "directive",
@@ -5447,6 +5475,8 @@
5447
5475
  * @returns {NgModule}
5448
5476
  */
5449
5477
  animation(name, animationFactory) {
5478
+ validate(isString, name, "name");
5479
+ validateRequired(animationFactory, "animationFactory");
5450
5480
  this.invokeQueue.push([
5451
5481
  $injectTokens.$animateProvider,
5452
5482
  "register",
@@ -5478,6 +5508,8 @@
5478
5508
  * @returns {NgModule}
5479
5509
  */
5480
5510
  controller(name, ctlFn) {
5511
+ validate(isString, name, "name");
5512
+ validateRequired(ctlFn, `fictlFnlterFn`);
5481
5513
  this.invokeQueue.push([$injectTokens.$controllerProvider, "register", [name, ctlFn]]);
5482
5514
 
5483
5515
  return this;
@@ -5505,6 +5537,8 @@
5505
5537
  * @returns {NgModule}
5506
5538
  */
5507
5539
  wasm(name, src, imports = {}, opts = {}) {
5540
+ validate(isString, name, "name");
5541
+ validate(isString, src, "src");
5508
5542
  const raw = !!opts.raw;
5509
5543
 
5510
5544
  this.invokeQueue.push([
@@ -5534,6 +5568,8 @@
5534
5568
  * @returns {NgModule}
5535
5569
  */
5536
5570
  worker(name, scriptPath, config) {
5571
+ validate(isString, name, "name");
5572
+ validate(isString, scriptPath, "scriptPath");
5537
5573
  this.invokeQueue.push([
5538
5574
  $injectTokens.$provide,
5539
5575
  "provider",
@@ -5550,16 +5586,18 @@
5550
5586
 
5551
5587
  /**
5552
5588
  * @param {string} name
5553
- * @param {Function} ctor
5589
+ * @param {Function|Object} ctor - A regular function, an arrow function or an object
5554
5590
  * @param {ng.StorageType} type
5555
5591
  * @param {ng.StorageBackend} [backendOrConfig]
5556
5592
  * @returns {NgModule}
5557
5593
  */
5558
5594
  store(name, ctor, type, backendOrConfig) {
5595
+ validate(isString, name, "name");
5596
+ validateRequired(ctor, "ctor");
5559
5597
  this.invokeQueue.push([
5560
5598
  $injectTokens.$provide,
5561
5599
  "store",
5562
- [name, ctor, type, backendOrConfig],
5600
+ [name, isObject(ctor) ? () => ctor : ctor, type, backendOrConfig],
5563
5601
  ]);
5564
5602
 
5565
5603
  return this;
@@ -5575,6 +5613,9 @@
5575
5613
  * @returns {NgModule}
5576
5614
  */
5577
5615
  rest(name, url, entityClass, options = {}) {
5616
+ validate(isString, name, "name");
5617
+ validate(isString, url, "url");
5618
+ validate(isFunction, entityClass, "entityClass");
5578
5619
  const def = { name, url, entityClass, options };
5579
5620
 
5580
5621
  this.restDefinitions.push(def);
@@ -31780,357 +31821,179 @@
31780
31821
  this.eventBus = EventBus;
31781
31822
  }
31782
31823
 
31783
- /**
31784
- * @returns {PubSub}
31785
- */
31786
- $get = () => this.eventBus;
31787
- }
31788
-
31789
- class PubSub {
31790
- static $nonscope;
31791
- /**
31792
- * Topic-based publish/subscribe channel. Maintains a map of topics to
31793
- * subscriptions. When a message is published to a topic, all functions
31794
- * subscribed to that topic are invoked in the order they were added.
31795
- * Uncaught errors abort publishing.
31796
- *
31797
- * Topics may be identified by any nonempty string, <strong>except</strong>
31798
- * strings corresponding to native Object properties, e.g. "constructor",
31799
- * "toString", "hasOwnProperty", etc.
31800
- *
31801
- * @param {boolean=} async Enable asynchronous behavior. Recommended for
31802
- * new code. See notes on the publish() method.
31803
- */
31804
- constructor(async = false) {
31805
- this.disposed = false;
31806
-
31807
- /**
31808
- * The next available subscription key. Internally, this is an index into the
31809
- * sparse array of subscriptions.
31810
- *
31811
- * @private {number}
31812
- */
31813
- this.key = 1;
31814
-
31824
+ $get = [
31825
+ $injectTokens.$exceptionHandler,
31815
31826
  /**
31816
- * Array of subscription keys pending removal once publishing is done.
31817
- *
31818
- * @private {!Array<number>}
31819
- * @const
31827
+ * @param {ng.ExceptionHandlerService} $exceptionHandler
31828
+ * @returns {PubSub}
31820
31829
  */
31821
- this.pendingKeys = [];
31830
+ ($exceptionHandler) => {
31831
+ this.$exceptionHandler = $exceptionHandler;
31822
31832
 
31823
- /**
31824
- * Lock to prevent the removal of subscriptions during publishing. Incremented
31825
- * at the beginning of {@link #publish}, and decremented at the end.
31826
- *
31827
- * @private {number}
31828
- */
31829
- this.publishDepth = 0;
31833
+ return this.eventBus;
31834
+ },
31835
+ ];
31836
+ }
31830
31837
 
31831
- /**
31832
- * Sparse array of subscriptions. Each subscription is represented by a tuple
31833
- * comprising a topic identifier, a function, and an optional context object.
31834
- * Each tuple occupies three consecutive positions in the array, with the
31835
- * topic identifier at index n, the function at index (n + 1), the context
31836
- * object at index (n + 2), the next topic at index (n + 3), etc. (This
31837
- * representation minimizes the number of object allocations and has been
31838
- * shown to be faster than an array of objects with three key-value pairs or
31839
- * three parallel arrays, especially on IE.) Once a subscription is removed
31840
- * via {@link unsubscribe} or {@link unsubscribeByKey}, the three
31841
- * corresponding array elements are deleted, and never reused. This means the
31842
- * total number of subscriptions during the lifetime of the pubsub channel is
31843
- * limited by the maximum length of a JavaScript array to (2^32 - 1) / 3 =
31844
- * 1,431,655,765 subscriptions, which should suffice for most applications.
31845
- *
31846
- * @private {!Array<?>}
31847
- * @const
31848
- */
31849
- this.subscriptions = [];
31838
+ class PubSub {
31839
+ constructor() {
31840
+ /** @private {Object<string, Array<{fn: Function, context: any}>>} */
31841
+ this._topics = Object.create(null);
31850
31842
 
31851
- /**
31852
- * Map of topics to arrays of subscription keys.
31853
- *
31854
- * @private {!Object<!Array<number>>}
31855
- */
31856
- this.topics = {};
31843
+ /** @private */
31844
+ this._disposed = false;
31857
31845
 
31858
- /**
31859
- * @private @const {boolean}
31860
- */
31861
- this.async_ = Boolean(async);
31846
+ /** @type {ng.ExceptionHandlerService} */
31847
+ this.$exceptionHandler = undefined;
31862
31848
  }
31863
31849
 
31864
31850
  /**
31865
- * Subscribes a function to a topic. The function is invoked as a method on
31866
- * the given `opt_context` object, or in the global scope if no context
31867
- * is specified. Subscribing the same function to the same topic multiple
31868
- * times will result in multiple function invocations while publishing.
31869
- * Returns a subscription key that can be used to unsubscribe the function from
31870
- * the topic via {@link unsubscribeByKey}.
31871
- *
31872
- * @param {string} topic Topic to subscribe to.
31873
- * @param {Function} fn Function to be invoked when a message is published to
31874
- * the given topic.
31875
- * @param {Object=} opt_context Object in whose context the function is to be
31876
- * called (the global scope if none).
31877
- * @return {number} Subscription key.
31851
+ * Set instance to initial state
31878
31852
  */
31879
- subscribe(topic, fn, opt_context = null) {
31880
- let keys = this.topics[topic];
31853
+ reset() {
31854
+ /** @private {Object<string, Array<{fn: Function, context: any}>>} */
31855
+ this._topics = Object.create(null);
31881
31856
 
31882
- if (!keys) {
31883
- // First subscription to this topic; initialize subscription key array.
31884
- keys = this.topics[topic] = [];
31885
- }
31886
-
31887
- // Push the tuple representing the subscription onto the subscription array.
31888
- const { key } = this;
31889
-
31890
- this.subscriptions[key] = topic;
31891
- this.subscriptions[key + 1] = fn;
31892
- this.subscriptions[key + 2] = opt_context;
31893
- this.key = key + 3;
31894
-
31895
- // Push the subscription key onto the list of subscriptions for the topic.
31896
- keys.push(key);
31897
-
31898
- // Return the subscription key.
31899
- return key;
31857
+ /** @private */
31858
+ this._disposed = false;
31900
31859
  }
31901
31860
 
31902
31861
  /**
31903
- * Subscribes a single-use function to a topic. The function is invoked as a
31904
- * method on the given `opt_context` object, or in the global scope if
31905
- * no context is specified, and is then unsubscribed. Returns a subscription
31906
- * key that can be used to unsubscribe the function from the topic via
31907
- * {@link unsubscribeByKey}.
31908
- *
31909
- * @param {string} topic Topic to subscribe to.
31910
- * @param {Function} fn Function to be invoked once and then unsubscribed when
31911
- * a message is published to the given topic.
31912
- * @param {Object=} opt_context Object in whose context the function is to be
31913
- * called (the global scope if none).
31914
- * @return {number} Subscription key.
31862
+ * Checks if instance has been disposed.
31863
+ * @returns {boolean} True if disposed.
31915
31864
  */
31916
- subscribeOnce(topic, fn, opt_context = null) {
31917
- let called = false;
31918
-
31919
- // Behold the power of lexical closures!
31920
- const key = this.subscribe(
31921
- topic,
31922
- (...args) => {
31923
- if (!called) {
31924
- called = true;
31925
-
31926
- // Unsubscribe before calling function so the function is unsubscribed
31927
- // even if it throws an exception.
31928
- this.unsubscribeByKey(key);
31929
-
31930
- fn.apply(opt_context, args);
31931
- }
31932
- },
31933
- this,
31934
- );
31935
-
31936
- return key;
31865
+ isDisposed() {
31866
+ return this._disposed;
31937
31867
  }
31938
31868
 
31939
31869
  /**
31940
- * Runs a function asynchronously.
31941
- *
31942
- * @private
31943
- * @param {Function} fn Function to run.
31944
- * @param {Object} context Context in which to run the function.
31945
- * @param {Array} args Arguments to pass to the function.
31870
+ * Dispose the instance, removing all topics and listeners.
31946
31871
  */
31947
- static runAsync_(fn, context, args) {
31948
- queueMicrotask(() => {
31949
- fn.apply(context, args);
31950
- });
31872
+ dispose() {
31873
+ if (this._disposed) return;
31874
+ this._disposed = true;
31875
+ this._topics = Object.create(null);
31951
31876
  }
31952
31877
 
31953
31878
  /**
31954
- * Unsubscribes a function from a topic. Only deletes the first match found.
31955
- * Returns a Boolean indicating whether a subscription was removed.
31956
- *
31957
- * @param {string} topic Topic to unsubscribe from.
31958
- * @param {Function} fn Function to unsubscribe.
31959
- * @param {Object=} opt_context Object in whose context the function was to be
31960
- * called (the global scope if none).
31961
- * @return {boolean} Whether a matching subscription was removed.
31879
+ * Subscribe a function to a topic.
31880
+ * @param {string} topic - The topic to subscribe to.
31881
+ * @param {Function} fn - The callback function to invoke when published.
31882
+ * @param {*} [context] - Optional `this` context for the callback.
31883
+ * @returns {() => boolean} A function that unsubscribes this listener.
31962
31884
  */
31963
- unsubscribe(topic, fn, opt_context = null) {
31964
- const keys = this.topics[topic];
31885
+ subscribe(topic, fn, context = undefined) {
31886
+ if (this._disposed) return () => false;
31965
31887
 
31966
- if (keys) {
31967
- const { subscriptions } = this;
31888
+ /** @type {Array<{fn: Function, context: any}>} */
31889
+ let listeners = this._topics[topic];
31968
31890
 
31969
- const key = keys.find(
31970
- (k) =>
31971
- subscriptions[k + 1] === fn && subscriptions[k + 2] === opt_context,
31972
- );
31891
+ if (!listeners) this._topics[topic] = listeners = [];
31973
31892
 
31974
- if (key !== undefined) {
31975
- return this.unsubscribeByKey(key);
31976
- }
31977
- }
31893
+ const entry = { fn, context };
31978
31894
 
31979
- return false;
31895
+ listeners.push(entry);
31896
+
31897
+ return () => this.unsubscribe(topic, fn, context);
31980
31898
  }
31981
31899
 
31982
31900
  /**
31983
- * Removes a subscription based on the key returned by {@link subscribe}.
31984
- * No-op if no matching subscription is found. Returns a Boolean indicating
31985
- * whether a subscription was removed.
31986
- *
31987
- * @param {number} key Subscription key.
31988
- * @return {boolean} Whether a matching subscription was removed.
31901
+ * Subscribe a function to a topic only once.
31902
+ * Listener is removed before the first invocation.
31903
+ * @param {string} topic - The topic to subscribe to.
31904
+ * @param {Function} fn - The callback function.
31905
+ * @param {*} [context] - Optional `this` context for the callback.
31906
+ * @returns {() => boolean} A function that unsubscribes this listener.
31989
31907
  */
31990
- unsubscribeByKey(key) {
31991
- const topic = this.subscriptions[key];
31908
+ subscribeOnce(topic, fn, context = undefined) {
31909
+ if (this._disposed) return () => false;
31992
31910
 
31993
- if (topic) {
31994
- const keys = this.topics[topic];
31911
+ let called = false;
31995
31912
 
31996
- if (this.publishDepth !== 0) {
31997
- // Defer removal until after publishing is complete, but replace the
31998
- // function with a no-op so it isn't called.
31999
- this.pendingKeys.push(key);
32000
- this.subscriptions[key + 1] = () => {
32001
- /* empty */
32002
- };
32003
- } else {
32004
- if (keys) {
32005
- this.topics[topic] = keys.filter((k) => k !== key);
32006
- }
32007
- delete this.subscriptions[key];
32008
- delete this.subscriptions[key + 1];
32009
- delete this.subscriptions[key + 2];
32010
- }
32011
- }
31913
+ const wrapper = (...args) => {
31914
+ if (called) return;
31915
+ called = true;
31916
+
31917
+ unsub(); // unsubscribe before running
31918
+ fn.apply(context, args);
31919
+ };
32012
31920
 
32013
- return !!topic;
31921
+ const unsub = this.subscribe(topic, wrapper);
31922
+
31923
+ return unsub;
32014
31924
  }
32015
31925
 
32016
31926
  /**
32017
- * Publishes a message to a topic. Calls functions subscribed to the topic in
32018
- * the order in which they were added, passing all arguments along.
32019
- *
32020
- * If this object was created with async=true, subscribed functions are called
32021
- * via `queueMicrotask`. Otherwise, the functions are called directly, and if
32022
- * any of them throw an uncaught error, publishing is aborted.
32023
- *
32024
- * @param {string} topic Topic to publish to.
32025
- * @param {...*} var_args Arguments that are applied to each subscription
32026
- * function.
32027
- * @return {boolean} Whether any subscriptions were called.
31927
+ * Unsubscribe a specific function from a topic.
31928
+ * Matches by function reference and optional context.
31929
+ * @param {string} topic - The topic to unsubscribe from.
31930
+ * @param {Function} fn - The listener function.
31931
+ * @param {*} [context] - Optional `this` context.
31932
+ * @returns {boolean} True if the listener was found and removed.
32028
31933
  */
32029
- publish(topic, ...var_args) {
32030
- const keys = this.topics[topic];
31934
+ unsubscribe(topic, fn, context = undefined) {
31935
+ if (this._disposed) return false;
32031
31936
 
32032
- if (keys) {
32033
- const args = var_args;
31937
+ const listeners = this._topics[topic];
32034
31938
 
32035
- if (this.async_) {
32036
- // For each key in the list of subscription keys for the topic, schedule
32037
- // the function to be applied to the arguments in the appropriate context.
32038
- for (let i = 0; i < keys.length; i++) {
32039
- const key = keys[i];
31939
+ if (!listeners || listeners.length === 0) return false;
32040
31940
 
32041
- PubSub.runAsync_(
32042
- this.subscriptions[key + 1],
32043
- this.subscriptions[key + 2],
32044
- args,
32045
- );
32046
- }
32047
- } else {
32048
- this.publishDepth++;
32049
-
32050
- try {
32051
- for (
32052
- let i = 0, len = keys.length;
32053
- i < len && !this.isDisposed();
32054
- i++
32055
- ) {
32056
- const key = keys[i];
32057
-
32058
- this.subscriptions[key + 1].apply(
32059
- this.subscriptions[key + 2],
32060
- args,
32061
- );
32062
- }
32063
- } finally {
32064
- this.publishDepth--;
31941
+ for (let i = 0; i < listeners.length; i++) {
31942
+ const l = listeners[i];
32065
31943
 
32066
- if (this.pendingKeys.length > 0 && this.publishDepth === 0) {
32067
- let pendingKey;
31944
+ if (l.fn === fn && l.context === context) {
31945
+ listeners.splice(i, 1);
32068
31946
 
32069
- while ((pendingKey = this.pendingKeys.pop())) {
32070
- this.unsubscribeByKey(pendingKey);
32071
- }
32072
- }
32073
- }
31947
+ return true;
32074
31948
  }
32075
-
32076
- return true;
32077
31949
  }
32078
31950
 
32079
31951
  return false;
32080
31952
  }
32081
31953
 
32082
31954
  /**
32083
- * Clears the subscription list for a topic, or all topics if unspecified.
32084
- * @param {string=} opt_topic Topic to clear (all topics if unspecified).
31955
+ * Get the number of subscribers for a topic.
31956
+ * @param {string} topic
31957
+ * @returns {number}
32085
31958
  */
32086
- clear(opt_topic) {
32087
- if (opt_topic) {
32088
- const keys = this.topics[opt_topic];
31959
+ getCount(topic) {
31960
+ const listeners = this._topics[topic];
32089
31961
 
32090
- if (keys) {
32091
- keys.forEach(this.unsubscribeByKey, this);
32092
- delete this.topics[opt_topic];
32093
- }
32094
- } else {
32095
- this.subscriptions.length = 0;
32096
- this.topics = {};
32097
- }
31962
+ return listeners ? listeners.length : 0;
32098
31963
  }
32099
31964
 
32100
31965
  /**
32101
- * Returns the number of subscriptions to the given topic (or all topics if
32102
- * unspecified). This number will not change while publishing any messages.
32103
- * @param {string=} opt_topic The topic (all topics if unspecified).
32104
- * @return {number} Number of subscriptions to the topic.
31966
+ * Publish a value to a topic asynchronously.
31967
+ * All listeners are invoked in the order they were added.
31968
+ * @param {string} topic - The topic to publish.
31969
+ * @param {...*} args - Arguments to pass to listeners.
31970
+ * @returns {boolean} True if any listeners exist for this topic.
32105
31971
  */
32106
- getCount(opt_topic) {
32107
- if (opt_topic) {
32108
- const keys = this.topics[opt_topic];
31972
+ publish(topic, ...args) {
31973
+ if (this._disposed) return false;
32109
31974
 
32110
- return keys ? keys.length : 0;
32111
- }
31975
+ const listeners = this._topics[topic];
32112
31976
 
32113
- let count = 0;
31977
+ if (!listeners || listeners.length === 0) return false;
32114
31978
 
32115
- for (const topic in this.topics) {
32116
- count += this.getCount(topic);
32117
- }
32118
-
32119
- return count;
32120
- }
31979
+ // snapshot to prevent modifications during publish from affecting this call
31980
+ const snapshot = listeners.slice();
32121
31981
 
32122
- isDisposed() {
32123
- return this.disposed;
32124
- }
31982
+ queueMicrotask(() => {
31983
+ for (const { fn, context } of snapshot) {
31984
+ try {
31985
+ fn.apply(context, args);
31986
+ } catch (err) {
31987
+ this.$exceptionHandler(err);
31988
+ }
31989
+ }
31990
+ });
32125
31991
 
32126
- dispose() {
32127
- this.clear();
32128
- this.pendingKeys.length = 0;
32129
- this.disposed = true;
31992
+ return true;
32130
31993
  }
32131
31994
  }
32132
31995
 
32133
- const EventBus = new PubSub(true);
31996
+ const EventBus = new PubSub();
32134
31997
 
32135
31998
  const defaultOptions = {
32136
31999
  current: () => {
@@ -39166,7 +39029,7 @@
39166
39029
 
39167
39030
  const hasTemplateContent = element.childNodes.length > 0;
39168
39031
 
39169
- const key = $eventBus.subscribe(channel, (value) => {
39032
+ const unsubscribe = $eventBus.subscribe(channel, (value) => {
39170
39033
  if (hasTemplateContent) {
39171
39034
  if (isObject(value)) {
39172
39035
  scope.$merge(value);
@@ -39176,9 +39039,7 @@
39176
39039
  }
39177
39040
  });
39178
39041
 
39179
- scope.$on("$destroy", () => {
39180
- $eventBus.unsubscribeByKey(key);
39181
- });
39042
+ scope.$on("$destroy", () => unsubscribe());
39182
39043
  },
39183
39044
  };
39184
39045
  }
@@ -39573,8 +39434,6 @@
39573
39434
  * @param {ng.ExceptionHandlerService} $exceptionHandler
39574
39435
  */
39575
39436
  constructor(defaults, $exceptionHandler) {
39576
- assert(isObject(defaults), BADARG);
39577
- assert(isFunction($exceptionHandler), BADARG);
39578
39437
  /** @type {ng.CookieOptions} */
39579
39438
  this.defaults = Object.freeze({ ...defaults });
39580
39439
  this.$exceptionHandler = $exceptionHandler;
@@ -39588,7 +39447,7 @@
39588
39447
  * @throws {URIError} – If decodeURIComponent fails.
39589
39448
  */
39590
39449
  get(key) {
39591
- assert(isString(key), BADARG);
39450
+ validateIsString(key, "key");
39592
39451
 
39593
39452
  try {
39594
39453
  const all = parseCookies();
@@ -39608,7 +39467,8 @@
39608
39467
  * @throws {SyntaxError} if cookie JSON is invalid
39609
39468
  */
39610
39469
  getObject(key) {
39611
- assert(isString(key), BADARG);
39470
+ validateIsString(key, "key");
39471
+
39612
39472
  const raw = this.get(key);
39613
39473
 
39614
39474
  if (!raw) return null;
@@ -39644,8 +39504,8 @@
39644
39504
  * @param {ng.CookieOptions} [options]
39645
39505
  */
39646
39506
  put(key, value, options = {}) {
39647
- assert(isString(key), BADARGKEY);
39648
- assert(isString(value), BADARGVALUE);
39507
+ validateIsString(key, "key");
39508
+ validateIsString(value, "value");
39649
39509
  const encodedKey = encodeURIComponent(key);
39650
39510
 
39651
39511
  const encodedVal = encodeURIComponent(value);
@@ -39669,7 +39529,8 @@
39669
39529
  * @throws {TypeError} if Object cannot be converted to JSON
39670
39530
  */
39671
39531
  putObject(key, value, options) {
39672
- assert(isString(key), BADARGKEY);
39532
+ validateIsString(key, "key");
39533
+ validateRequired(value, "value");
39673
39534
  assert(!isNullOrUndefined(value), BADARGVALUE);
39674
39535
 
39675
39536
  try {
@@ -39690,7 +39551,7 @@
39690
39551
  * @param {ng.CookieOptions} [options]
39691
39552
  */
39692
39553
  remove(key, options = {}) {
39693
- assert(isString(key), BADARG);
39554
+ validateIsString(key, "key");
39694
39555
  this.put(key, "", {
39695
39556
  ...this.defaults,
39696
39557
  ...options,
@@ -40507,7 +40368,7 @@
40507
40368
  /**
40508
40369
  * @type {string} `version` from `package.json`
40509
40370
  */
40510
- this.version = "0.14.0"; //inserted via rollup plugin
40371
+ this.version = "0.14.1"; //inserted via rollup plugin
40511
40372
 
40512
40373
  /** @type {!Array<string|any>} */
40513
40374
  this.bootsrappedModules = [];