Added first files
All checks were successful
CI / build (push) Successful in 21s

This commit is contained in:
Andrey Kernichniy 2026-03-08 12:31:52 +07:00
parent 41a325f5e1
commit 0f8546bc69
10 changed files with 149 additions and 1 deletions

View file

@ -0,0 +1,15 @@
import { ModelConstructor } from "../interfaces";
export const IGNORABLE_FIELDS = new WeakMap<ModelConstructor, Set<string>>();
export function ignore(value: unknown, context: ClassFieldDecoratorContext) {
context.addInitializer(function () {
const ctor = this.constructor as ModelConstructor;
let set = IGNORABLE_FIELDS.get(ctor);
if (!set) {
set = new Set<string>();
IGNORABLE_FIELDS.set(ctor, set);
}
set.add(context.name as string);
});
}

View file

@ -0,0 +1,15 @@
import { ModelConstructor } from "../interfaces";
export const IMMUTABLE_FIELDS = new WeakMap<ModelConstructor, Set<string>>();
export function immutable(value: unknown, context: ClassFieldDecoratorContext) {
context.addInitializer(function () {
const ctor = this.constructor as ModelConstructor;
let set = IMMUTABLE_FIELDS.get(ctor);
if (!set) {
set = new Set<string>();
IMMUTABLE_FIELDS.set(ctor, set);
}
set.add(context.name as string);
});
}

View file

@ -0,0 +1,3 @@
export * from "./ignore";
export * from "./immutable";
export * from "./utils";

View file

@ -0,0 +1,11 @@
export class PropertyMetadata {
get(object: any, property: string) {
console.warn(object, property);
}
}
export function property() {
return function (target: object, property: string) {
console.warn(target, property);
};
}

View file

@ -0,0 +1,17 @@
import { IMMUTABLE_FIELDS } from "./immutable";
import { IGNORABLE_FIELDS } from "./ignore";
export const getImmutableKeys = (obj: any): string[] => {
const ctor = obj.constructor;
return IMMUTABLE_FIELDS.has(ctor) ? Array.from(IMMUTABLE_FIELDS.get(ctor) as Set<string>) : [];
};
export const isImmutableKey = (object: any, key: string) => getImmutableKeys(object).includes(key);
export const getIgnorableKeys = (obj: any): string[] => {
const ctor = obj.constructor;
return IGNORABLE_FIELDS.has(ctor) ? Array.from(IGNORABLE_FIELDS.get(ctor) as Set<string>) : [];
};
export const isIgnorableKey = (object: any, key: string) => getIgnorableKeys(object).includes(key);

View file

@ -0,0 +1,3 @@
export * from "./models";
export * from "./decorators";
export * from "./interfaces";

View file

@ -0,0 +1,8 @@
export type ModelConstructor = new (...args: any[]) => IModel;
export type TypeOfModel = "collection";
export interface IModel {
readonly id: string;
readonly type: TypeOfModel;
}

View file

@ -0,0 +1,75 @@
import { ignore } from "../decorators/ignore";
export class Collection<T> {
@ignore readonly id = crypto.randomUUID();
private _store: Record<number, T> = {};
get length() {
return Object.keys(this._store).length;
}
constructor(args: T[] = []) {
args.forEach((item, index) => (this._store[index] = item));
}
*[Symbol.iterator]() {
const array = this.toArray();
for (const item of array) {
yield item;
}
}
push(...args: T[]) {
const diff: Record<number, T> = {};
args.forEach((item) => {
const index = this.length;
this._store[index] = item;
diff[index] = item;
});
return { ...diff, length: this.length };
}
remove(item: T) {
const backup: Record<number, T> = { ...this._store };
Object.keys(this._store).forEach((key) => {
const index = Number(key);
const itemOfIndex = this.get(index);
if (item !== itemOfIndex) return;
Reflect.deleteProperty(this._store, Number(key));
});
const diff: Record<number, T> = {};
const values = Object.values(this._store);
const newStore: Record<number, T> = {};
for (let index = 0; index < values.length; index++) {
newStore[index] = values[index];
if (backup[index] !== newStore[index]) {
diff[index] = newStore[index];
}
}
this._store = newStore;
return { ...diff, length: this.length };
}
indexOf(item: T) {
return this.toArray().indexOf(item);
}
get(index: number): T {
return this._store[index];
}
set(index: number, value: T) {
this._store[index] = value;
return { [index]: value, length: this.length };
}
toArray(): T[] {
return Object.keys(this._store).map((index) => this._store[index]);
}
}

1
lib/src/models/index.ts Normal file
View file

@ -0,0 +1 @@
export * from "./collection";

View file

@ -1,5 +1,5 @@
{
"name": "@gxc-solutions/lib",
"name": "@gxc-solutions/model-base",
"version": "0.0.1",
"main": "index.js",
"author": "GXC Solutions",