feat: add core domain model foundations

This commit is contained in:
syntaxbullet
2026-07-02 23:11:14 +02:00
parent 5f767a6688
commit 02df52c978
14 changed files with 133 additions and 1 deletions

11
commands/command.ts Normal file
View File

@@ -0,0 +1,11 @@
import type { ImageDocument } from "@core/document";
export type CommandContext = {
document: ImageDocument;
};
export type Command<TPayload = void> = {
id: string;
name: string;
execute(context: CommandContext, payload: TPayload): ImageDocument;
};

1
commands/index.ts Normal file
View File

@@ -0,0 +1 @@
export type { Command, CommandContext } from "./command";

11
core/artboard.ts Normal file
View File

@@ -0,0 +1,11 @@
import type { Rect } from "./geometry";
import type { ArtboardId } from "./id";
import type { Layer } from "./layer";
export type Artboard = {
id: ArtboardId;
name: string;
bounds: Rect;
backgroundColor: string;
layers: Layer[];
};

8
core/asset.ts Normal file
View File

@@ -0,0 +1,8 @@
import type { AssetId } from "./id";
export type Asset = {
id: AssetId;
name: string;
mimeType: string;
source: string;
};

16
core/base-layer.ts Normal file
View File

@@ -0,0 +1,16 @@
import type { Transform } from "./geometry";
import type { LayerId } from "./id";
export type LayerClippingMask = {
maskLayerId: LayerId;
};
export type BaseLayer = {
id: LayerId;
name: string;
visible: boolean;
locked: boolean;
opacity: number;
transform: Transform;
clippingMask?: LayerClippingMask;
};

11
core/document.ts Normal file
View File

@@ -0,0 +1,11 @@
import type { Artboard } from "./artboard";
import type { Asset } from "./asset";
import type { DocumentId } from "./id";
export type ImageDocument = {
id: DocumentId;
name: string;
version: number;
artboards: Artboard[];
assets: Asset[];
};

32
core/geometry.ts Normal file
View File

@@ -0,0 +1,32 @@
export type Vec2D = {
x: number;
y: number;
};
export type Size = {
w: number;
h: number;
};
export type Rect = Vec2D & Size;
export type Bounds = Rect;
export type Angle = number;
export type Transform = {
position: Vec2D;
scale: Vec2D;
rotation: Angle;
};
export type Mat2D = {
a: number;
b: number;
c: number;
d: number;
tx: number;
ty: number;
};
export type CoordinateSpace = "document" | "artboard" | "viewport" | "layer";

4
core/id.ts Normal file
View File

@@ -0,0 +1,4 @@
export type DocumentId = string;
export type ArtboardId = string;
export type LayerId = string;
export type AssetId = string;

7
core/image-layer.ts Normal file
View File

@@ -0,0 +1,7 @@
import type { BaseLayer } from "./base-layer";
import type { AssetId } from "./id";
export type ImageLayer = BaseLayer & {
type: "image";
assetId: AssetId;
};

18
core/index.ts Normal file
View File

@@ -0,0 +1,18 @@
export type { Artboard } from "./artboard";
export type { Asset } from "./asset";
export type { BaseLayer, LayerClippingMask } from "./base-layer";
export type { ImageDocument } from "./document";
export type {
Angle,
Bounds,
CoordinateSpace,
Mat2D,
Rect,
Size,
Transform,
Vec2D,
} from "./geometry";
export type { ArtboardId, AssetId, DocumentId, LayerId } from "./id";
export type { ImageLayer } from "./image-layer";
export type { Layer } from "./layer";
export type { LayerGroup } from "./layer-group";

7
core/layer-group.ts Normal file
View File

@@ -0,0 +1,7 @@
import type { BaseLayer } from "./base-layer";
import type { Layer } from "./layer";
export type LayerGroup = BaseLayer & {
type: "group";
children: Layer[];
};

4
core/layer.ts Normal file
View File

@@ -0,0 +1,4 @@
import type { ImageLayer } from "./image-layer";
import type { LayerGroup } from "./layer-group";
export type Layer = ImageLayer | LayerGroup;

0
renderer/.gitkeep Normal file
View File

View File

@@ -25,7 +25,9 @@
"paths": { "paths": {
"@/*": ["./view/*"], "@/*": ["./view/*"],
"@view/*": ["./view/*"], "@view/*": ["./view/*"],
"@core/*": ["./core/*"] "@core/*": ["./core/*"],
"@renderer/*": ["./renderer/*"],
"@commands/*": ["./commands/*"]
}, },
// Some stricter flags (disabled by default) // Some stricter flags (disabled by default)