oxjs/src/ox/core/Collection.js
Sanjay Bhangar 4c880728dc Begin ES modules migration and modern build infrastructure
This commit lays the foundation for migrating OxJS from its custom module
system to ES modules while maintaining backward compatibility.

Key changes:
- Set up npm project with Vite for modern build tooling
- Created ES module versions of core Ox utilities (Type, Collection, DOM, etc.)
- Implemented compatibility layer for legacy Ox.load() pattern
- Added Vitest for testing with initial test suite
- Created script to extract existing inline tests from documentation
- Updated .gitignore for Node.js/npm development

The migration preserves OxJS's innovative inline test system and maintains
backward compatibility. Original source files remain unchanged.

Next steps include migrating UI modules, replacing the Python build script,
and creating npm package distribution.

🤖 Generated with AI assistance
2026-02-09 17:17:52 +05:30

223 lines
No EOL
4.9 KiB
JavaScript

/**
* Collection utilities - ES Module Version
*/
import { typeOf, isObject, isArray, isString, isFunction } from './Type.js';
/**
* Iterate over collections
*/
export function forEach(collection, iterator, that) {
const type = typeOf(collection);
let i, key;
if (type === 'object') {
for (key in collection) {
if (collection.hasOwnProperty(key)) {
if (iterator.call(that, collection[key], key, collection) === false) {
break;
}
}
}
} else if (type === 'array' || type === 'string') {
for (i = 0; i < collection.length; i++) {
if (iterator.call(that, collection[i], i, collection) === false) {
break;
}
}
}
return collection;
}
/**
* Get length of collection
*/
export function len(collection) {
const type = typeOf(collection);
if (type === 'array' || type === 'string') {
return collection.length;
}
if (type === 'object') {
return Object.keys(collection).length;
}
return 0;
}
/**
* Extend objects (similar to Object.assign but deeper)
*/
export function extend(...args) {
let target = args[0] || {};
let deep = false;
let i = 1;
// Check if deep copy
if (typeof target === 'boolean') {
deep = target;
target = args[1] || {};
i = 2;
}
for (; i < args.length; i++) {
const source = args[i];
if (!source) continue;
for (const key in source) {
if (source.hasOwnProperty(key)) {
const src = target[key];
const copy = source[key];
// Prevent infinite loop
if (target === copy) continue;
if (deep && copy && (isObject(copy) || isArray(copy))) {
let clone;
if (isArray(copy)) {
clone = src && isArray(src) ? src : [];
} else {
clone = src && isObject(src) ? src : {};
}
target[key] = extend(deep, clone, copy);
} else if (copy !== undefined) {
target[key] = copy;
}
}
}
}
return target;
}
/**
* Map over collections
*/
export function map(collection, iterator, that) {
const type = typeOf(collection);
const result = [];
forEach(collection, function(value, key) {
result.push(iterator.call(that, value, key, collection));
});
return type === 'string' ? result.join('') : result;
}
/**
* Filter collections
*/
export function filter(collection, iterator, that) {
const type = typeOf(collection);
const result = type === 'object' ? {} : [];
forEach(collection, function(value, key) {
if (iterator.call(that, value, key, collection)) {
if (type === 'object') {
result[key] = value;
} else {
result.push(value);
}
}
});
return type === 'string' ? result.join('') : result;
}
/**
* Find in collection
*/
export function find(collection, iterator, that) {
let result;
forEach(collection, function(value, key) {
if (iterator.call(that, value, key, collection)) {
result = value;
return false; // break
}
});
return result;
}
/**
* Check if every element passes test
*/
export function every(collection, iterator, that) {
let result = true;
forEach(collection, function(value, key) {
if (!iterator.call(that, value, key, collection)) {
result = false;
return false; // break
}
});
return result;
}
/**
* Check if any element passes test
*/
export function some(collection, iterator, that) {
let result = false;
forEach(collection, function(value, key) {
if (iterator.call(that, value, key, collection)) {
result = true;
return false; // break
}
});
return result;
}
/**
* Get keys of object or indices of array
*/
export function keys(collection) {
if (isObject(collection)) {
return Object.keys(collection);
}
if (isArray(collection) || isString(collection)) {
return Array.from({ length: collection.length }, (_, i) => i);
}
return [];
}
/**
* Get values of collection
*/
export function values(collection) {
if (isObject(collection)) {
return Object.values(collection);
}
if (isArray(collection)) {
return [...collection];
}
if (isString(collection)) {
return collection.split('');
}
return [];
}
// Export all functions
export default {
forEach,
len,
extend,
map,
filter,
find,
every,
some,
keys,
values
};