A JavaScript framework for creating ambitious web applications
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Enhanced array and enumerable interfaces with change tracking and computed properties for reactive data management.
Enhanced array interface with observable properties and computed capabilities.
/**
* Enhanced array interface with observable properties and computed capabilities
*/
interface EmberArray extends Array<any> {
/**
* Get property value with support for array-specific properties
* @param key - Property key (can be array index or property name)
* @returns Property value
*/
get(key: string | number): any;
/**
* Set property value and notify observers
* @param key - Property key
* @param value - Value to set
* @returns The value that was set
*/
set(key: string | number, value: any): any;
/**
* Add object to end of array
* @param item - Item to add
* @returns The added item
*/
pushObject(item: any): any;
/**
* Add multiple objects to end of array
* @param items - Items to add
* @returns The array
*/
pushObjects(items: any[]): EmberArray;
/**
* Remove object from array
* @param item - Item to remove
* @returns The removed item or null
*/
removeObject(item: any): any;
/**
* Remove multiple objects from array
* @param items - Items to remove
* @returns The array
*/
removeObjects(items: any[]): EmberArray;
/**
* Insert object at specific index
* @param index - Index to insert at
* @param item - Item to insert
* @returns The array
*/
insertAt(index: number, item: any): EmberArray;
/**
* Remove object at specific index
* @param index - Index to remove from
* @returns The removed item
*/
removeAt(index: number): any;
/**
* Find first object matching property value
* @param key - Property key to match
* @param value - Value to match
* @returns First matching object or undefined
*/
findBy(key: string, value: any): any;
/**
* Filter objects by property value
* @param key - Property key to match
* @param value - Value to match
* @returns Array of matching objects
*/
filterBy(key: string, value: any): any[];
/**
* Map array to property values
* @param key - Property key to extract
* @returns Array of property values
*/
mapBy(key: string): any[];
/**
* Sort array by property
* @param key - Property key to sort by
* @returns New sorted array
*/
sortBy(key: string): any[];
/**
* Get unique values by property
* @param key - Property key for uniqueness
* @returns Array with unique values
*/
uniqBy(key: string): any[];
/**
* Check if array contains object
* @param item - Item to check for
* @returns Whether array contains item
*/
includes(item: any): boolean;
/** First object in array */
readonly firstObject: any;
/** Last object in array */
readonly lastObject: any;
/** Array length */
readonly length: number;
}Interface for arrays that can be modified with change notifications.
/**
* Interface for arrays that can be modified with change notifications
*/
interface MutableArray extends EmberArray {
/**
* Add object to array if not already present
* @param item - Item to add
* @returns The array
*/
addObject(item: any): MutableArray;
/**
* Add multiple objects to array, skipping duplicates
* @param items - Items to add
* @returns The array
*/
addObjects(items: any[]): MutableArray;
/**
* Replace portion of array with new objects
* @param start - Starting index
* @param deleteCount - Number of items to delete
* @param items - Items to insert
* @returns Array of removed items
*/
replace(start: number, deleteCount: number, items: any[]): any[];
/**
* Clear all objects from array
* @returns The empty array
*/
clear(): MutableArray;
/**
* Reverse array in place
* @returns The reversed array
*/
reverseObjects(): MutableArray;
/**
* Remove all instances of objects
* @param items - Items to remove
* @returns The array
*/
removeObjects(items: any[]): MutableArray;
}Proxy class that provides array interface for underlying content.
/**
* Proxy class that provides array interface for underlying content
*/
class ArrayProxy extends EmberObject implements MutableArray {
/**
* Create ArrayProxy instance
* @param properties - Initial properties including content
* @returns ArrayProxy instance
*/
static create(properties?: { content?: any[] }): ArrayProxy;
/** Underlying array content */
content: any[];
/** Whether array is arranged (sorted/filtered) */
isArranged: boolean;
/**
* Get object at index
* @param index - Array index
* @returns Object at index
*/
objectAt(index: number): any;
/**
* Get objects at multiple indexes
* @param indexes - Array of indexes
* @returns Array of objects
*/
objectsAt(indexes: number[]): any[];
// Implements all EmberArray and MutableArray methods
pushObject(item: any): any;
removeObject(item: any): any;
findBy(key: string, value: any): any;
// ... (inherits all array methods)
}Functions for creating and working with Ember arrays.
/**
* Create Ember array from regular array or array-like object
* @param array - Array or array-like object to convert
* @returns EmberArray instance
*/
function A(array?: any[]): EmberArray;
/**
* Check if object is array or array-like
* @param obj - Object to test
* @returns Whether object is array-like
*/
function isArray(obj: any): boolean;
/**
* Convert value to array
* @param obj - Value to convert to array
* @returns Array containing the value(s)
*/
function makeArray(obj: any): any[];Usage Examples:
import { A } from "@ember/array";
import ArrayProxy from "@ember/array/proxy";
// Create Ember array
const users = A([
{ name: 'Alice', role: 'admin', active: true },
{ name: 'Bob', role: 'user', active: false },
{ name: 'Charlie', role: 'admin', active: true }
]);
// Array methods with change tracking
users.pushObject({ name: 'Diana', role: 'user', active: true });
users.removeObject(users.findBy('name', 'Bob'));
// Query methods
const admins = users.filterBy('role', 'admin');
const activeUsers = users.filterBy('active', true);
const names = users.mapBy('name');
const firstAdmin = users.findBy('role', 'admin');
console.log(admins.length); // 2
console.log(names); // ['Alice', 'Charlie', 'Diana']
// Array proxy for computed arrays
const UserListProxy = ArrayProxy.extend({
content: users,
activeUsers: computed('content.@each.active', function() {
return this.content.filterBy('active', true);
}),
adminCount: computed('content.@each.role', function() {
return this.content.filterBy('role', 'admin').length;
})
});
const userList = UserListProxy.create();
console.log(userList.get('activeUsers.length')); // 3
console.log(userList.get('adminCount')); // 2Base interface for collections that can be enumerated.
/**
* Base interface for collections that can be enumerated
*/
interface Enumerable {
/**
* Iterate over all objects in collection
* @param callback - Function called for each object
* @param target - Context for callback
* @returns The enumerable
*/
forEach(callback: (item: any, index: number) => void, target?: any): Enumerable;
/**
* Map collection to new values
* @param callback - Mapping function
* @param target - Context for callback
* @returns Array of mapped values
*/
map(callback: (item: any, index: number) => any, target?: any): any[];
/**
* Filter collection by predicate
* @param callback - Filter predicate
* @param target - Context for callback
* @returns Filtered array
*/
filter(callback: (item: any, index: number) => boolean, target?: any): any[];
/**
* Find first matching object
* @param callback - Search predicate
* @param target - Context for callback
* @returns First matching object or undefined
*/
find(callback: (item: any, index: number) => boolean, target?: any): any;
/**
* Check if any object matches predicate
* @param callback - Test predicate
* @param target - Context for callback
* @returns Whether any object matches
*/
any(callback: (item: any, index: number) => boolean, target?: any): boolean;
/**
* Check if all objects match predicate
* @param callback - Test predicate
* @param target - Context for callback
* @returns Whether all objects match
*/
every(callback: (item: any, index: number) => boolean, target?: any): boolean;
/**
* Reduce collection to single value
* @param callback - Reducer function
* @param initialValue - Initial value for reduction
* @param target - Context for callback
* @returns Reduced value
*/
reduce(callback: (previousValue: any, item: any, index: number) => any, initialValue?: any, target?: any): any;
/**
* Convert enumerable to array
* @returns Array representation
*/
toArray(): any[];
}Interface for enumerables that can be modified.
/**
* Interface for enumerables that can be modified
*/
interface MutableEnumerable extends Enumerable {
/**
* Add object to enumerable
* @param item - Object to add
* @returns The enumerable
*/
addObject(item: any): MutableEnumerable;
/**
* Remove object from enumerable
* @param item - Object to remove
* @returns The enumerable
*/
removeObject(item: any): MutableEnumerable;
}Usage Examples:
import EmberObject from "@ember/object";
import { A } from "@ember/array";
// Working with enumerable collections
const Collection = EmberObject.extend({
items: null,
init() {
this._super(...arguments);
this.items = A([]);
},
activeItems: computed('items.@each.active', function() {
return this.items.filterBy('active', true);
}),
hasActiveItems: computed('activeItems.length', function() {
return this.activeItems.length > 0;
}),
totalValue: computed('items.@each.value', function() {
return this.items.reduce((sum, item) => sum + (item.value || 0), 0);
})
});
const collection = Collection.create();
collection.items.pushObjects([
{ name: 'Item 1', active: true, value: 10 },
{ name: 'Item 2', active: false, value: 20 },
{ name: 'Item 3', active: true, value: 15 }
]);
console.log(collection.get('activeItems.length')); // 2
console.log(collection.get('totalValue')); // 45interface ArrayLike {
/** Array length */
length: number;
/** Index access */
[index: number]: any;
}
interface ArrayObserver {
/** Called when array changes */
arrayWillChange?(array: EmberArray, start: number, removeCount: number, addCount: number): void;
/** Called after array changes */
arrayDidChange?(array: EmberArray, start: number, removeCount: number, addCount: number): void;
}
interface SortDescriptor {
/** Property to sort by */
property: string;
/** Sort direction */
direction: 'asc' | 'desc';
}Install with Tessl CLI
npx tessl i tessl/npm-ember-source