refactor: Move attributes and entity to @omnia/core

This commit is contained in:
2026-07-05 21:37:06 +05:30
parent 23f4b29fd0
commit 4b3a253751
6 changed files with 126 additions and 115 deletions

View File

@@ -1,113 +1 @@
export enum AttributeVisibility {
PUBLIC = "PUBLIC",
PRIVATE = "PRIVATE",
}
export class Attribute {
readonly name: string;
private value: string;
private visibility: AttributeVisibility;
private allowedEntities: Set<string>;
constructor(name: string, value: string, visibility: AttributeVisibility) {
this.name = name;
this.value = value;
this.visibility = visibility;
this.allowedEntities = new Set();
}
setValue(newValue: string) {
this.value = newValue;
}
getValue(): string {
return this.value;
}
hasAccess(objectId: string): boolean {
return (
this.visibility === AttributeVisibility.PUBLIC ||
this.allowedEntities.has(objectId)
);
}
getVisibility(): AttributeVisibility {
return this.visibility;
}
setPublic() {
this.visibility = AttributeVisibility.PUBLIC;
}
setPrivate() {
this.allowedEntities.clear();
this.visibility = AttributeVisibility.PRIVATE;
}
grantAccess(objectId: string) {
if (this.visibility === AttributeVisibility.PRIVATE) {
this.allowedEntities.add(objectId);
}
}
revokeAccess(objectId: string) {
if (
this.visibility === AttributeVisibility.PRIVATE &&
this.allowedEntities.has(objectId)
) {
this.allowedEntities.delete(objectId);
}
}
}
export interface IAttribute {
id: string;
attributes: Map<string, Attribute>;
addAttribute(
name: string,
value: string,
visibility: AttributeVisibility,
): void;
getVisibileAttributesFor(viewerId: string): Attribute[];
}
export abstract class AttributableObject implements IAttribute {
readonly id: string = crypto.randomUUID();
readonly attributes: Map<string, Attribute> = new Map<string, Attribute>();
addAttribute(
name: string,
value: string,
visibility: AttributeVisibility = AttributeVisibility.PRIVATE,
allowedEntities: Set<string> | null = null,
): void {
if (this.attributes.has(name))
throw Error(`Attribute ${name} already exists`);
this.attributes.set(name, new Attribute(name, value, visibility));
if (visibility === AttributeVisibility.PRIVATE && allowedEntities != null) {
for (const entity of allowedEntities) {
this.attributes.get(name)?.grantAccess(entity);
}
}
}
removeAttribute(name: string): void {
if (!this.attributes.has(name))
throw Error(`Attribute ${name} does not exist`);
this.attributes.delete(name);
}
getVisibileAttributesFor(viewerId: string): Attribute[] {
return Array.from(this.attributes.values()).filter((attr) =>
attr.hasAccess(viewerId),
);
}
}
export class Entity extends AttributableObject {
constructor(name: string) {
super();
}
}
export {};

View File

@@ -0,0 +1,107 @@
export enum AttributeVisibility {
PUBLIC = "PUBLIC",
PRIVATE = "PRIVATE",
}
export class Attribute {
readonly name: string;
private value: string;
private visibility: AttributeVisibility;
private allowedEntities: Set<string>;
constructor(name: string, value: string, visibility: AttributeVisibility) {
this.name = name;
this.value = value;
this.visibility = visibility;
this.allowedEntities = new Set();
}
setValue(newValue: string) {
this.value = newValue;
}
getValue(): string {
return this.value;
}
hasAccess(objectId: string): boolean {
return (
this.visibility === AttributeVisibility.PUBLIC ||
this.allowedEntities.has(objectId)
);
}
getVisibility(): AttributeVisibility {
return this.visibility;
}
setPublic() {
this.visibility = AttributeVisibility.PUBLIC;
}
setPrivate() {
this.allowedEntities.clear();
this.visibility = AttributeVisibility.PRIVATE;
}
grantAccess(objectId: string) {
if (this.visibility === AttributeVisibility.PRIVATE) {
this.allowedEntities.add(objectId);
}
}
revokeAccess(objectId: string) {
if (
this.visibility === AttributeVisibility.PRIVATE &&
this.allowedEntities.has(objectId)
) {
this.allowedEntities.delete(objectId);
}
}
}
export interface IAttribute {
id: string;
attributes: Map<string, Attribute>;
addAttribute(
name: string,
value: string,
visibility: AttributeVisibility,
): void;
getVisibileAttributesFor(viewerId: string): Attribute[];
}
export abstract class AttributableObject implements IAttribute {
readonly id: string = crypto.randomUUID();
readonly attributes: Map<string, Attribute> = new Map<string, Attribute>();
addAttribute(
name: string,
value: string,
visibility: AttributeVisibility = AttributeVisibility.PRIVATE,
allowedEntities: Set<string> | null = null,
): void {
if (this.attributes.has(name))
throw Error(`Attribute ${name} already exists`);
this.attributes.set(name, new Attribute(name, value, visibility));
if (visibility === AttributeVisibility.PRIVATE && allowedEntities != null) {
for (const entity of allowedEntities) {
this.attributes.get(name)?.grantAccess(entity);
}
}
}
removeAttribute(name: string): void {
if (!this.attributes.has(name))
throw Error(`Attribute ${name} does not exist`);
this.attributes.delete(name);
}
getVisibileAttributesFor(viewerId: string): Attribute[] {
return Array.from(this.attributes.values()).filter((attr) =>
attr.hasAccess(viewerId),
);
}
}

View File

@@ -0,0 +1,7 @@
import { AttributableObject } from "./attribute.js";
export class Entity extends AttributableObject {
constructor() {
super();
}
}

View File

@@ -1 +1,3 @@
export {};
export * from "./attribute.js";
export * from "./entity.js";
export * from "./world.js";

View File

@@ -0,0 +1,7 @@
import { AttributableObject } from "./attribute.js";
export class World extends AttributableObject {
constructor() {
super();
}
}

File diff suppressed because one or more lines are too long