From 02df52c978916247bacbe04bc93674505166f6a8 Mon Sep 17 00:00:00 2001 From: syntaxbullet Date: Thu, 2 Jul 2026 23:11:14 +0200 Subject: [PATCH] feat: add core domain model foundations --- commands/command.ts | 11 +++++++++++ commands/index.ts | 1 + core/artboard.ts | 11 +++++++++++ core/asset.ts | 8 ++++++++ core/base-layer.ts | 16 ++++++++++++++++ core/document.ts | 11 +++++++++++ core/geometry.ts | 32 ++++++++++++++++++++++++++++++++ core/id.ts | 4 ++++ core/image-layer.ts | 7 +++++++ core/index.ts | 18 ++++++++++++++++++ core/layer-group.ts | 7 +++++++ core/layer.ts | 4 ++++ renderer/.gitkeep | 0 tsconfig.json | 4 +++- 14 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 commands/command.ts create mode 100644 commands/index.ts create mode 100644 core/artboard.ts create mode 100644 core/asset.ts create mode 100644 core/base-layer.ts create mode 100644 core/document.ts create mode 100644 core/geometry.ts create mode 100644 core/id.ts create mode 100644 core/image-layer.ts create mode 100644 core/index.ts create mode 100644 core/layer-group.ts create mode 100644 core/layer.ts create mode 100644 renderer/.gitkeep diff --git a/commands/command.ts b/commands/command.ts new file mode 100644 index 0000000..a855412 --- /dev/null +++ b/commands/command.ts @@ -0,0 +1,11 @@ +import type { ImageDocument } from "@core/document"; + +export type CommandContext = { + document: ImageDocument; +}; + +export type Command = { + id: string; + name: string; + execute(context: CommandContext, payload: TPayload): ImageDocument; +}; diff --git a/commands/index.ts b/commands/index.ts new file mode 100644 index 0000000..8eb46a4 --- /dev/null +++ b/commands/index.ts @@ -0,0 +1 @@ +export type { Command, CommandContext } from "./command"; diff --git a/core/artboard.ts b/core/artboard.ts new file mode 100644 index 0000000..cc8b6fb --- /dev/null +++ b/core/artboard.ts @@ -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[]; +}; diff --git a/core/asset.ts b/core/asset.ts new file mode 100644 index 0000000..b9b514b --- /dev/null +++ b/core/asset.ts @@ -0,0 +1,8 @@ +import type { AssetId } from "./id"; + +export type Asset = { + id: AssetId; + name: string; + mimeType: string; + source: string; +}; diff --git a/core/base-layer.ts b/core/base-layer.ts new file mode 100644 index 0000000..a1f6fda --- /dev/null +++ b/core/base-layer.ts @@ -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; +}; diff --git a/core/document.ts b/core/document.ts new file mode 100644 index 0000000..a00ab9c --- /dev/null +++ b/core/document.ts @@ -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[]; +}; diff --git a/core/geometry.ts b/core/geometry.ts new file mode 100644 index 0000000..4846881 --- /dev/null +++ b/core/geometry.ts @@ -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"; diff --git a/core/id.ts b/core/id.ts new file mode 100644 index 0000000..b7a1e55 --- /dev/null +++ b/core/id.ts @@ -0,0 +1,4 @@ +export type DocumentId = string; +export type ArtboardId = string; +export type LayerId = string; +export type AssetId = string; diff --git a/core/image-layer.ts b/core/image-layer.ts new file mode 100644 index 0000000..b874396 --- /dev/null +++ b/core/image-layer.ts @@ -0,0 +1,7 @@ +import type { BaseLayer } from "./base-layer"; +import type { AssetId } from "./id"; + +export type ImageLayer = BaseLayer & { + type: "image"; + assetId: AssetId; +}; diff --git a/core/index.ts b/core/index.ts new file mode 100644 index 0000000..747f5ba --- /dev/null +++ b/core/index.ts @@ -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"; diff --git a/core/layer-group.ts b/core/layer-group.ts new file mode 100644 index 0000000..780b023 --- /dev/null +++ b/core/layer-group.ts @@ -0,0 +1,7 @@ +import type { BaseLayer } from "./base-layer"; +import type { Layer } from "./layer"; + +export type LayerGroup = BaseLayer & { + type: "group"; + children: Layer[]; +}; diff --git a/core/layer.ts b/core/layer.ts new file mode 100644 index 0000000..87c0871 --- /dev/null +++ b/core/layer.ts @@ -0,0 +1,4 @@ +import type { ImageLayer } from "./image-layer"; +import type { LayerGroup } from "./layer-group"; + +export type Layer = ImageLayer | LayerGroup; diff --git a/renderer/.gitkeep b/renderer/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tsconfig.json b/tsconfig.json index 5530418..7c34690 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -25,7 +25,9 @@ "paths": { "@/*": ["./view/*"], "@view/*": ["./view/*"], - "@core/*": ["./core/*"] + "@core/*": ["./core/*"], + "@renderer/*": ["./renderer/*"], + "@commands/*": ["./commands/*"] }, // Some stricter flags (disabled by default)