@axi-engine/utils 0.2.6 → 0.2.8

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/dist/index.d.mts CHANGED
@@ -263,6 +263,21 @@ declare class Emitter<T extends any[]> implements Subscribable<T> {
263
263
  */
264
264
  clear(): void;
265
265
  }
266
+ /**
267
+ * An Emitter that stores the last emitted value.
268
+ * New subscribers immediately receive the last value upon subscription.
269
+ */
270
+ declare class StateEmitter<T extends any[]> extends Emitter<T> {
271
+ private _lastValue;
272
+ constructor(initialValue?: T);
273
+ /**
274
+ * Gets the current value synchronously without subscribing.
275
+ */
276
+ get value(): T | undefined;
277
+ emit(...args: T): void;
278
+ subscribe(listener: (...args: T) => void): () => void;
279
+ clear(): void;
280
+ }
266
281
 
267
282
  /**
268
283
  * Type guard that checks if a value is a valid ScalarType.
@@ -270,12 +285,64 @@ declare class Emitter<T extends any[]> implements Subscribable<T> {
270
285
  * @returns True if the value is a string, number, or boolean.
271
286
  */
272
287
  declare function isScalar(value: unknown): value is ScalarType;
273
- declare function isNullOrUndefined(val: unknown): val is null | undefined;
288
+ /**
289
+ * Type guard that checks if a value is `null`.
290
+ * @param val The value to check.
291
+ * @returns {boolean} `true` if the value is `null`, otherwise `false`.
292
+ */
293
+ declare function isNull(val: unknown): val is null;
294
+ /**
295
+ * Type guard that checks if a value is `undefined`.
296
+ * @param val The value to check.
297
+ * @returns {boolean} `true` if the value is `undefined`, otherwise `false`.
298
+ */
274
299
  declare function isUndefined(val: unknown): val is undefined;
300
+ /**
301
+ * Type guard that checks if a value is either `null` or `undefined`.
302
+ * @param val The value to check.
303
+ * @returns {boolean} `true` if the value is `null` or `undefined`, otherwise `false`.
304
+ */
305
+ declare function isNullOrUndefined(val: unknown): val is null | undefined;
306
+ /**
307
+ * Type guard that checks if a value is a `number`.
308
+ * @param val The value to check.
309
+ * @returns {boolean} `true` if the value is a `number`, otherwise `false`.
310
+ */
275
311
  declare function isNumber(val: unknown): val is number;
312
+ /**
313
+ * Type guard that checks if a value is a `boolean`.
314
+ * @param val The value to check.
315
+ * @returns {boolean} `true` if the value is a `boolean`, otherwise `false`.
316
+ */
276
317
  declare function isBoolean(val: unknown): val is boolean;
318
+ /**
319
+ * Type guard that checks if a value is a `string`.
320
+ * @param val The value to check.
321
+ * @returns {boolean} `true` if the value is a `string`, otherwise `false`.
322
+ */
277
323
  declare function isString(val: unknown): val is string;
278
- declare function isNull(val: unknown): val is null;
324
+ /**
325
+ * Check if a value is a plain object.
326
+ * Correctly handles `null` and arrays, returning `false` for them.
327
+ *
328
+ * @param value The value to check.
329
+ * @returns {boolean} `true` if the value is a non-null, non-array object.
330
+ */
331
+ declare function isObject(value: unknown): value is Record<PropertyKey, unknown>;
332
+ /**
333
+ * Type guard that checks if a value is a function.
334
+ *
335
+ * @param value The value to check.
336
+ * @returns {boolean} `true` if the value is a function.
337
+ */
338
+ declare function isFunction(value: unknown): value is (...args: any[]) => any;
339
+ /**
340
+ * Type guard that checks if a value is a Promise-like object.
341
+ *
342
+ * @param value The value to check.
343
+ * @returns {boolean} `true` if the value has a `then` function.
344
+ */
345
+ declare function isPromise(value: unknown): value is Promise<unknown>;
279
346
  /**
280
347
  * Type guard to check if a value is a string that ends with '%'.
281
348
  * @param val The value to check.
@@ -338,7 +405,7 @@ declare function randId(): string;
338
405
  * @template K - The type of the key (must be a string).
339
406
  * @template V - The type of the value being stored.
340
407
  */
341
- declare class Registry<K extends string, V> {
408
+ declare class Registry<K extends PropertyKey, V> {
342
409
  protected readonly items: Map<K, V>;
343
410
  /**
344
411
  * Registers an item with a specific key.
@@ -372,4 +439,4 @@ declare class Registry<K extends string, V> {
372
439
  clear(): void;
373
440
  }
374
441
 
375
- export { type AxiEngineConfig, type Constructor, type DataSink, type DataSource, type DataStorage, Emitter, type PathType, Registry, type ScalarType, type Subscribable, areArraysEqual, axiSettings, clampNumber, configure, ensurePathArray, ensurePathString, firstKeyOf, genArray, getPercentOf, getRandomElement, haveSameElements, isBoolean, isNull, isNullOrUndefined, isNumber, isPercentageString, isScalar, isSequentialStart, isString, isUndefined, last, randId, randInt, shuffleArray, throwError, throwIf, throwIfEmpty, unique };
442
+ export { type AxiEngineConfig, type Constructor, type DataSink, type DataSource, type DataStorage, Emitter, type PathType, Registry, type ScalarType, StateEmitter, type Subscribable, areArraysEqual, axiSettings, clampNumber, configure, ensurePathArray, ensurePathString, firstKeyOf, genArray, getPercentOf, getRandomElement, haveSameElements, isBoolean, isFunction, isNull, isNullOrUndefined, isNumber, isObject, isPercentageString, isPromise, isScalar, isSequentialStart, isString, isUndefined, last, randId, randInt, shuffleArray, throwError, throwIf, throwIfEmpty, unique };
package/dist/index.d.ts CHANGED
@@ -263,6 +263,21 @@ declare class Emitter<T extends any[]> implements Subscribable<T> {
263
263
  */
264
264
  clear(): void;
265
265
  }
266
+ /**
267
+ * An Emitter that stores the last emitted value.
268
+ * New subscribers immediately receive the last value upon subscription.
269
+ */
270
+ declare class StateEmitter<T extends any[]> extends Emitter<T> {
271
+ private _lastValue;
272
+ constructor(initialValue?: T);
273
+ /**
274
+ * Gets the current value synchronously without subscribing.
275
+ */
276
+ get value(): T | undefined;
277
+ emit(...args: T): void;
278
+ subscribe(listener: (...args: T) => void): () => void;
279
+ clear(): void;
280
+ }
266
281
 
267
282
  /**
268
283
  * Type guard that checks if a value is a valid ScalarType.
@@ -270,12 +285,64 @@ declare class Emitter<T extends any[]> implements Subscribable<T> {
270
285
  * @returns True if the value is a string, number, or boolean.
271
286
  */
272
287
  declare function isScalar(value: unknown): value is ScalarType;
273
- declare function isNullOrUndefined(val: unknown): val is null | undefined;
288
+ /**
289
+ * Type guard that checks if a value is `null`.
290
+ * @param val The value to check.
291
+ * @returns {boolean} `true` if the value is `null`, otherwise `false`.
292
+ */
293
+ declare function isNull(val: unknown): val is null;
294
+ /**
295
+ * Type guard that checks if a value is `undefined`.
296
+ * @param val The value to check.
297
+ * @returns {boolean} `true` if the value is `undefined`, otherwise `false`.
298
+ */
274
299
  declare function isUndefined(val: unknown): val is undefined;
300
+ /**
301
+ * Type guard that checks if a value is either `null` or `undefined`.
302
+ * @param val The value to check.
303
+ * @returns {boolean} `true` if the value is `null` or `undefined`, otherwise `false`.
304
+ */
305
+ declare function isNullOrUndefined(val: unknown): val is null | undefined;
306
+ /**
307
+ * Type guard that checks if a value is a `number`.
308
+ * @param val The value to check.
309
+ * @returns {boolean} `true` if the value is a `number`, otherwise `false`.
310
+ */
275
311
  declare function isNumber(val: unknown): val is number;
312
+ /**
313
+ * Type guard that checks if a value is a `boolean`.
314
+ * @param val The value to check.
315
+ * @returns {boolean} `true` if the value is a `boolean`, otherwise `false`.
316
+ */
276
317
  declare function isBoolean(val: unknown): val is boolean;
318
+ /**
319
+ * Type guard that checks if a value is a `string`.
320
+ * @param val The value to check.
321
+ * @returns {boolean} `true` if the value is a `string`, otherwise `false`.
322
+ */
277
323
  declare function isString(val: unknown): val is string;
278
- declare function isNull(val: unknown): val is null;
324
+ /**
325
+ * Check if a value is a plain object.
326
+ * Correctly handles `null` and arrays, returning `false` for them.
327
+ *
328
+ * @param value The value to check.
329
+ * @returns {boolean} `true` if the value is a non-null, non-array object.
330
+ */
331
+ declare function isObject(value: unknown): value is Record<PropertyKey, unknown>;
332
+ /**
333
+ * Type guard that checks if a value is a function.
334
+ *
335
+ * @param value The value to check.
336
+ * @returns {boolean} `true` if the value is a function.
337
+ */
338
+ declare function isFunction(value: unknown): value is (...args: any[]) => any;
339
+ /**
340
+ * Type guard that checks if a value is a Promise-like object.
341
+ *
342
+ * @param value The value to check.
343
+ * @returns {boolean} `true` if the value has a `then` function.
344
+ */
345
+ declare function isPromise(value: unknown): value is Promise<unknown>;
279
346
  /**
280
347
  * Type guard to check if a value is a string that ends with '%'.
281
348
  * @param val The value to check.
@@ -338,7 +405,7 @@ declare function randId(): string;
338
405
  * @template K - The type of the key (must be a string).
339
406
  * @template V - The type of the value being stored.
340
407
  */
341
- declare class Registry<K extends string, V> {
408
+ declare class Registry<K extends PropertyKey, V> {
342
409
  protected readonly items: Map<K, V>;
343
410
  /**
344
411
  * Registers an item with a specific key.
@@ -372,4 +439,4 @@ declare class Registry<K extends string, V> {
372
439
  clear(): void;
373
440
  }
374
441
 
375
- export { type AxiEngineConfig, type Constructor, type DataSink, type DataSource, type DataStorage, Emitter, type PathType, Registry, type ScalarType, type Subscribable, areArraysEqual, axiSettings, clampNumber, configure, ensurePathArray, ensurePathString, firstKeyOf, genArray, getPercentOf, getRandomElement, haveSameElements, isBoolean, isNull, isNullOrUndefined, isNumber, isPercentageString, isScalar, isSequentialStart, isString, isUndefined, last, randId, randInt, shuffleArray, throwError, throwIf, throwIfEmpty, unique };
442
+ export { type AxiEngineConfig, type Constructor, type DataSink, type DataSource, type DataStorage, Emitter, type PathType, Registry, type ScalarType, StateEmitter, type Subscribable, areArraysEqual, axiSettings, clampNumber, configure, ensurePathArray, ensurePathString, firstKeyOf, genArray, getPercentOf, getRandomElement, haveSameElements, isBoolean, isFunction, isNull, isNullOrUndefined, isNumber, isObject, isPercentageString, isPromise, isScalar, isSequentialStart, isString, isUndefined, last, randId, randInt, shuffleArray, throwError, throwIf, throwIfEmpty, unique };
package/dist/index.js CHANGED
@@ -22,6 +22,7 @@ var index_exports = {};
22
22
  __export(index_exports, {
23
23
  Emitter: () => Emitter,
24
24
  Registry: () => Registry,
25
+ StateEmitter: () => StateEmitter,
25
26
  areArraysEqual: () => areArraysEqual,
26
27
  axiSettings: () => axiSettings,
27
28
  clampNumber: () => clampNumber,
@@ -34,10 +35,13 @@ __export(index_exports, {
34
35
  getRandomElement: () => getRandomElement,
35
36
  haveSameElements: () => haveSameElements,
36
37
  isBoolean: () => isBoolean,
38
+ isFunction: () => isFunction,
37
39
  isNull: () => isNull,
38
40
  isNullOrUndefined: () => isNullOrUndefined,
39
41
  isNumber: () => isNumber,
42
+ isObject: () => isObject,
40
43
  isPercentageString: () => isPercentageString,
44
+ isPromise: () => isPromise,
41
45
  isScalar: () => isScalar,
42
46
  isSequentialStart: () => isSequentialStart,
43
47
  isString: () => isString,
@@ -104,11 +108,14 @@ function isScalar(value) {
104
108
  const type = typeof value;
105
109
  return type === "string" || type === "number" || type === "boolean";
106
110
  }
107
- function isNullOrUndefined(val) {
108
- return val === void 0 || val === null;
111
+ function isNull(val) {
112
+ return val === null;
109
113
  }
110
114
  function isUndefined(val) {
111
- return typeof val === "undefined";
115
+ return val === void 0;
116
+ }
117
+ function isNullOrUndefined(val) {
118
+ return val === null || val === void 0;
112
119
  }
113
120
  function isNumber(val) {
114
121
  return typeof val === "number";
@@ -119,8 +126,14 @@ function isBoolean(val) {
119
126
  function isString(val) {
120
127
  return typeof val === "string";
121
128
  }
122
- function isNull(val) {
123
- return val === null;
129
+ function isObject(value) {
130
+ return value !== null && !Array.isArray(value) && typeof value === "object";
131
+ }
132
+ function isFunction(value) {
133
+ return typeof value === "function";
134
+ }
135
+ function isPromise(value) {
136
+ return value != null && typeof value.then === "function";
124
137
  }
125
138
  function isPercentageString(val) {
126
139
  return typeof val === "string" && val.endsWith("%");
@@ -188,6 +201,34 @@ var Emitter = class {
188
201
  this.listeners.clear();
189
202
  }
190
203
  };
204
+ var StateEmitter = class extends Emitter {
205
+ _lastValue;
206
+ constructor(initialValue) {
207
+ super();
208
+ this._lastValue = initialValue ?? void 0;
209
+ }
210
+ /**
211
+ * Gets the current value synchronously without subscribing.
212
+ */
213
+ get value() {
214
+ return this._lastValue;
215
+ }
216
+ emit(...args) {
217
+ this._lastValue = args;
218
+ super.emit(...args);
219
+ }
220
+ subscribe(listener) {
221
+ const unsubscribe = super.subscribe(listener);
222
+ if (!isUndefined(this._lastValue)) {
223
+ listener(...this._lastValue);
224
+ }
225
+ return unsubscribe;
226
+ }
227
+ clear() {
228
+ super.clear();
229
+ this._lastValue = void 0;
230
+ }
231
+ };
191
232
 
192
233
  // src/math.ts
193
234
  function clampNumber(val, min, max) {
@@ -233,7 +274,7 @@ var Registry = class {
233
274
  * @param value The item to register.
234
275
  */
235
276
  register(key, value) {
236
- throwIf(this.items.has(key), `An item with the key '${key}' is already registered and will be overwritten.`);
277
+ throwIf(this.items.has(key), `An item with the key '${String(key)}' is already registered and will be overwritten.`);
237
278
  this.items.set(key, value);
238
279
  }
239
280
  /**
@@ -259,7 +300,7 @@ var Registry = class {
259
300
  */
260
301
  getOrThrow(key) {
261
302
  const item = this.get(key);
262
- throwIfEmpty(item, `No item registered for the key '${key}'.`);
303
+ throwIfEmpty(item, `No item registered for the key '${String(key)}'.`);
263
304
  return item;
264
305
  }
265
306
  delete(key) {
@@ -276,6 +317,7 @@ var Registry = class {
276
317
  0 && (module.exports = {
277
318
  Emitter,
278
319
  Registry,
320
+ StateEmitter,
279
321
  areArraysEqual,
280
322
  axiSettings,
281
323
  clampNumber,
@@ -288,10 +330,13 @@ var Registry = class {
288
330
  getRandomElement,
289
331
  haveSameElements,
290
332
  isBoolean,
333
+ isFunction,
291
334
  isNull,
292
335
  isNullOrUndefined,
293
336
  isNumber,
337
+ isObject,
294
338
  isPercentageString,
339
+ isPromise,
295
340
  isScalar,
296
341
  isSequentialStart,
297
342
  isString,
package/dist/index.mjs CHANGED
@@ -49,11 +49,14 @@ function isScalar(value) {
49
49
  const type = typeof value;
50
50
  return type === "string" || type === "number" || type === "boolean";
51
51
  }
52
- function isNullOrUndefined(val) {
53
- return val === void 0 || val === null;
52
+ function isNull(val) {
53
+ return val === null;
54
54
  }
55
55
  function isUndefined(val) {
56
- return typeof val === "undefined";
56
+ return val === void 0;
57
+ }
58
+ function isNullOrUndefined(val) {
59
+ return val === null || val === void 0;
57
60
  }
58
61
  function isNumber(val) {
59
62
  return typeof val === "number";
@@ -64,8 +67,14 @@ function isBoolean(val) {
64
67
  function isString(val) {
65
68
  return typeof val === "string";
66
69
  }
67
- function isNull(val) {
68
- return val === null;
70
+ function isObject(value) {
71
+ return value !== null && !Array.isArray(value) && typeof value === "object";
72
+ }
73
+ function isFunction(value) {
74
+ return typeof value === "function";
75
+ }
76
+ function isPromise(value) {
77
+ return value != null && typeof value.then === "function";
69
78
  }
70
79
  function isPercentageString(val) {
71
80
  return typeof val === "string" && val.endsWith("%");
@@ -133,6 +142,34 @@ var Emitter = class {
133
142
  this.listeners.clear();
134
143
  }
135
144
  };
145
+ var StateEmitter = class extends Emitter {
146
+ _lastValue;
147
+ constructor(initialValue) {
148
+ super();
149
+ this._lastValue = initialValue ?? void 0;
150
+ }
151
+ /**
152
+ * Gets the current value synchronously without subscribing.
153
+ */
154
+ get value() {
155
+ return this._lastValue;
156
+ }
157
+ emit(...args) {
158
+ this._lastValue = args;
159
+ super.emit(...args);
160
+ }
161
+ subscribe(listener) {
162
+ const unsubscribe = super.subscribe(listener);
163
+ if (!isUndefined(this._lastValue)) {
164
+ listener(...this._lastValue);
165
+ }
166
+ return unsubscribe;
167
+ }
168
+ clear() {
169
+ super.clear();
170
+ this._lastValue = void 0;
171
+ }
172
+ };
136
173
 
137
174
  // src/math.ts
138
175
  function clampNumber(val, min, max) {
@@ -178,7 +215,7 @@ var Registry = class {
178
215
  * @param value The item to register.
179
216
  */
180
217
  register(key, value) {
181
- throwIf(this.items.has(key), `An item with the key '${key}' is already registered and will be overwritten.`);
218
+ throwIf(this.items.has(key), `An item with the key '${String(key)}' is already registered and will be overwritten.`);
182
219
  this.items.set(key, value);
183
220
  }
184
221
  /**
@@ -204,7 +241,7 @@ var Registry = class {
204
241
  */
205
242
  getOrThrow(key) {
206
243
  const item = this.get(key);
207
- throwIfEmpty(item, `No item registered for the key '${key}'.`);
244
+ throwIfEmpty(item, `No item registered for the key '${String(key)}'.`);
208
245
  return item;
209
246
  }
210
247
  delete(key) {
@@ -220,6 +257,7 @@ var Registry = class {
220
257
  export {
221
258
  Emitter,
222
259
  Registry,
260
+ StateEmitter,
223
261
  areArraysEqual,
224
262
  axiSettings,
225
263
  clampNumber,
@@ -232,10 +270,13 @@ export {
232
270
  getRandomElement,
233
271
  haveSameElements,
234
272
  isBoolean,
273
+ isFunction,
235
274
  isNull,
236
275
  isNullOrUndefined,
237
276
  isNumber,
277
+ isObject,
238
278
  isPercentageString,
279
+ isPromise,
239
280
  isScalar,
240
281
  isSequentialStart,
241
282
  isString,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axi-engine/utils",
3
- "version": "0.2.6",
3
+ "version": "0.2.8",
4
4
  "description": "Core utility library for Axi Engine, providing common functions for arrays, math, type guards, and more.",
5
5
  "license": "MIT",
6
6
  "repository": {