
Security News
Crates.io Users Targeted by Phishing Emails
The Rust Security Response WG is warning of phishing emails from rustfoundation.dev targeting crates.io users.
@itgenio/edik-reflection
Advanced tools
nanoid
для генерации ref idВсе данные об объекте хранятся в его типе в поле $$gemeta
. Удобно хранить связанные с типом мета-данные в его прототипе.
Дальнейшим развитием может быть сохранение не по строчному ключу, а символьному (Symbol, так делает Mobx)
Какие мета-данные есть у типа?
name:string
используется для поиска типа в качестве уникального идентификатора.Можно было бы использовать имя конструктора, но после минификации оно становится не пригодным для использования.
displayName?:string
для красивостиisComponent?:boolean
компонент или нет (доп. атрибут для инспектора)fields?:{ name:string }[]
поляinline?:boolean
нужно ли инлайнить,т.е. вставлять объекты такого типа по месту не вынося в map.Для типа SerializedRootObject
есть поддержка версионирования. (текущая версия схемы будет лежать в поле __meta.v
)
Библиотека позволяет сериализовывать циклические зависимости, а так же множественные ссылки на один объект и т.д.
Это работает благодаря тому, что все обработанные объекты помещяются в отдельный список. Перед тем, как обработать следующий объект, вначале проверяется, что он еще не обработан(т.е. его нет в списке).
Если объект есть в списке - значит мы уже обработали такой объект и можно идти дальше.
При этом, в поле будет записан идентификатор ссылки на этот объект. Т.е. сколько бы полей не ссылалось на данный объект, все они будут ссылаться на один конкретный экземпляр.
Важно: при копировании полей объекта такие ссылки на объекты не будут копироваться.
Пример:
class SomeComponent extends CBaseComponent {
field: CBaseComponent;// предположим наш компонент ссылается на какой-то компонент.
}
const comp:SomeComponent = /*...*/;
const copy = comp.clone(); //копируем
assert(comp.field === copy.field);//!!! хотя сам компонент скопировался, ссылка при этом указывает на старый объект!
Такие объекты имеют Обычный тип.
В некоторых случаях хочется, чтобы объект не выносился в такой список и не мог иметь ссылок на себя кроме одной.
Для этого нужны inline-типы.
Самый простой пример - тип Color
. Мы не хотим чтобы на него ссылались разные объекты, при этом при копировании создается новый экземпляр данного типа.
Пример:
class SomeComponent extends CBaseComponent {
color: Color; //Color - inline-тип
}
const some:SomeComponent = ...;
const copy = some.copy(); //копируем
assert(some.color !== copy.color);//ссылки разные, т.к. цвет скопировался!
Object.$$gemetamap : Map<string, Type>
чтобы в дальнейшем из любого места могли получить тип по имени.Если на верхнем уровне есть поле с именем, как и на нижних уровнях, то будет браться поле из верхнего уровня.
class CBase {
id: string; //для CBase регаем id=>string
}
class CSome extends CBase {
id: number; //для CSome регаем id=>number;
}
//getField(CSome,'id') => number;
//getField(CBase,'id') => string;
Возможна такая ситуация, когда базовый класс не успел зарегистрироваться, но уже регистрируется наследник.
В таком случае наступает ранняя регистрация для базового типа. Это значит:
Поэтому, для базового типа регистрируются поля и ставиться флаг, что была ранняя регистрация.
Типы:
type Primitives = string | number | boolean
Array<any>
Set<any>
Map<string, any>
Есть таблица
type ObjId = string;
type ObjData = any;
const objects = new Map<ObjId, ObjData>();
Все объекты(за исключением inline
-типов) сериализуются в таблицу. Ссылки на такие объекты сериализуются как строки-указатели на ID объекта из таблицы.
У Serialized***
есть поле __meta.map
хранящее все объекты, на которые могут ссылаться внутренние объекты.
Для объектов:
Тип при этом должен быть зареган в хранилище типов либо указан явно при десериализации.
Десериализация происходит в два этапа.
Первый этап
На первом этапе создаются экземпляры объектов. При этом берется тип из сериализованного объекта.
Второй этап
На втором этапе объекты связываются друг с другом
Запоминаем ID и помечаем поле как ссылка на объект
Запоминаем ID и помечаем, какие индексы как ссылки
Ссылки на общий raw object, raw array
import { Serializer } from './serializer';
const s1 = new Type();
const s2 = new Type();
const sharedRawObj = { a: '1' };
s1.raw = s2.raw = sharedRawObj; //вот так не работает!
const obj = { s1, s2 };
const dobj = Serializer.serialize(Serializer.deserialize(obj));
//после десериализации, dobj.s1.raw !== dobj.s2.raw, ссылка не сохранилась
Иногда требуется сериализовать и десериализовать объект, но при этом, часть объектов, на которые ссылаемся, не находятся в иерархии и хочется сохранить ссылку на них после десериализации.
@gtype({ name: 'SomeType' })
class SomeType {
@gserializable()
id: string = 'randomId';
@gserializable()
externalLink?: SomeType;
}
const exernalObj = new SomeType();
const obj = new SomeType();
obj.externalLink = exernalObj;
Как сейчас:
const dobj = Serializer.deserialize(Serializer.serialize(obj));
assert(dobj.externalLink !== exernalObj); // сейчас вот так!
Предложение:
//serialize
const externalLinks = [externalObj];
const serialized = Serializer.serialize(obj, { externalLinks });
// deserialize
const dobj = Serializer.deserialize(serialized, { externalLinks: allObjsAndComps });
assert(dobj.externalLink === exernalObj);
interface ILinkable {
id: string;
}
Подробнее:
Когда встречаем объект, который находится в externalLinks
, подменяем тип на новый тип ExternalLink
:
class ExternalLink {
id: string;
}
FAQs
We found that @itgenio/edik-reflection demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
The Rust Security Response WG is warning of phishing emails from rustfoundation.dev targeting crates.io users.
Product
Socket now lets you customize pull request alert headers, helping security teams share clear guidance right in PRs to speed reviews and reduce back-and-forth.
Product
Socket's Rust support is moving to Beta: all users can scan Cargo projects and generate SBOMs, including Cargo.toml-only crates, with Rust-aware supply chain checks.