@pooder/core 0.1.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/editor.ts DELETED
@@ -1,226 +0,0 @@
1
- import { Command, Editor, EditorState, EventHandler, Extension } from "./types";
2
- import { EventBus } from "./event";
3
- import { CommandManager, CommandMap, DefaultCommandManager } from "./command";
4
- import {
5
- DefaultExtensionManager,
6
- ExtensionManager,
7
- ExtensionMap,
8
- } from "./extension";
9
- import { PooderCanvas } from "./canvas";
10
- import { PooderObject } from "./obj";
11
- import { PooderLayer } from "./layer";
12
-
13
- export class PooderEditor implements Editor {
14
- public state: EditorState;
15
- public canvas: PooderCanvas;
16
- public extensions: ExtensionMap = new Map();
17
- public commands: CommandMap = new Map();
18
-
19
- private eventBus: EventBus;
20
- private commandManager: CommandManager;
21
- private extensionManager: ExtensionManager;
22
-
23
- private destroyed: boolean = false;
24
-
25
- constructor(
26
- el: HTMLCanvasElement,
27
- options: {
28
- width?: number;
29
- height?: number;
30
- extensions?: Extension[];
31
- } = {},
32
- ) {
33
- this.state = {
34
- width: options.width || 800,
35
- height: options.height || 600,
36
- };
37
- this.canvas = new PooderCanvas(el, {
38
- width: this.state.width,
39
- height: this.state.height,
40
- preserveObjectStacking: true,
41
- });
42
- this.eventBus = new EventBus();
43
- this.commandManager = new DefaultCommandManager(this);
44
-
45
- this.extensionManager = new DefaultExtensionManager(this);
46
- if (options.extensions && options.extensions.length > 0) {
47
- options.extensions.forEach(this.extensionManager.register);
48
- }
49
- this.extensionManager.mount();
50
-
51
- console.log(
52
- "Editor initialized with",
53
- this.extensionManager.count(),
54
- "plugins",
55
- );
56
- }
57
-
58
- use(extension: Extension) {
59
- if (this.destroyed) {
60
- throw new Error("Cannot register plugin: Editor is destroyed");
61
- }
62
-
63
- this.extensionManager.register(extension);
64
-
65
- this.emit("update", this.state);
66
- }
67
- unuse(name: string) {
68
- return this.extensionManager.unregister(name);
69
- }
70
- getExtension(name: string): Extension | undefined {
71
- return this.extensionManager.get(name);
72
- }
73
- getExtensions(): Extension[] {
74
- return this.extensionManager.list();
75
- }
76
- enableExtension(name: string) {
77
- this.extensionManager.enable(name);
78
- this.emit("update", this.state);
79
- }
80
- disableExtension(name: string) {
81
- this.extensionManager.disable(name);
82
- this.emit("update", this.state);
83
- }
84
-
85
- registerCommand(name: string, command: Command) {
86
- this.commandManager.register(name, command);
87
- }
88
- unregisterCommand(name: string) {
89
- this.commandManager.unregister(name);
90
- }
91
- executeCommand(name: string, ...args: any[]) {
92
- if (this.destroyed) {
93
- console.warn("Cannot execute command: Editor is destroyed");
94
- return false;
95
- }
96
-
97
- this.emit("beforeCommand", name, ...args);
98
-
99
- const result = this.commandManager.execute(name, ...args);
100
-
101
- this.emit("afterCommand", name, args, result);
102
-
103
- return result;
104
- }
105
-
106
- on(event: string, handler: EventHandler, priority?: number): void {
107
- this.eventBus.on(event, handler, priority);
108
- }
109
- off(event: string, handler: EventHandler): void {
110
- this.eventBus.off(event, handler);
111
- }
112
- emit(event: string, ...args: any[]): void {
113
- this.eventBus.emit(event, ...args);
114
- }
115
-
116
- getObjects(): PooderObject[] {
117
- if (this.destroyed) {
118
- throw new Error("Cannot get objects: Editor is destroyed");
119
- }
120
-
121
- return this.canvas.getObjects();
122
- }
123
- getObject(id: string, layerId?: string): PooderObject | undefined {
124
- let objs;
125
- if (layerId) {
126
- objs = this.getLayer(layerId)?.getObjects();
127
- } else {
128
- objs = this.getObjects();
129
- }
130
- return objs?.find((obj) => obj?.data?.id === id);
131
- }
132
- getLayers(): PooderLayer[] {
133
- return this.getObjects().filter(
134
- (obj) => obj.type === "group",
135
- ) as PooderLayer[];
136
- }
137
- getLayer(id: string): PooderLayer | undefined {
138
- return this.getLayers().find((obj) => obj?.data?.id === id);
139
- }
140
-
141
- updateState(updater: (state: EditorState) => EditorState) {
142
- if (this.destroyed) {
143
- console.warn("Cannot update state: Editor is destroyed");
144
- return;
145
- }
146
-
147
- this.state = updater(this.state);
148
-
149
- this.extensionManager.update();
150
- this.emit("update", this.state);
151
- }
152
-
153
- toJSON() {
154
- const extensions: Record<string, any> = {};
155
- this.extensionManager.list().forEach((ext) => {
156
- if (ext.toJSON) {
157
- extensions[ext.name] = ext.toJSON();
158
- } else if (ext.options) {
159
- extensions[ext.name] = ext.options;
160
- }
161
- });
162
-
163
- return {
164
- width: this.state.width,
165
- height: this.state.height,
166
- metadata: this.state.metadata,
167
- extensions,
168
- };
169
- }
170
-
171
- async loadFromJSON(json: any) {
172
- if (!json) return;
173
-
174
- this.extensionManager.unmount();
175
-
176
- this.canvas.clear();
177
-
178
- this.extensionManager.mount();
179
-
180
- if (json.extensions) {
181
- for (const [name, data] of Object.entries(json.extensions)) {
182
- const ext = this.extensionManager.get(name);
183
- if (ext) {
184
- if (ext.loadFromJSON) {
185
- await ext.loadFromJSON(data);
186
- } else if (data) {
187
- // Fallback: restore options if loadFromJSON is missing
188
- ext.options = data;
189
- }
190
- }
191
- }
192
- }
193
-
194
- this.updateState((state) => ({
195
- ...state,
196
- width: json.width,
197
- height: json.height,
198
- metadata: json.metadata,
199
- }));
200
- }
201
- getState(): EditorState {
202
- return { ...this.state };
203
- }
204
-
205
- destroy(): void {
206
- if (this.destroyed) return;
207
-
208
- this.emit("beforeDestroy");
209
-
210
- this.canvas.dispose();
211
-
212
- this.extensionManager.destroy();
213
-
214
- this.eventBus.clear();
215
-
216
- this.commandManager.clear();
217
-
218
- this.destroyed = true;
219
-
220
- console.log("Editor destroyed");
221
- }
222
-
223
- isDestroyed(): boolean {
224
- return this.destroyed;
225
- }
226
- }
package/src/layer.ts DELETED
@@ -1,13 +0,0 @@
1
- import { Group } from "fabric";
2
- declare module "fabric" {
3
- interface Group {
4
- data?: any;
5
- }
6
- interface GroupProps {
7
- data?: any;
8
- }
9
- interface SerializedGroupProps {
10
- data?: any;
11
- }
12
- }
13
- export { Group as PooderLayer };
package/src/obj.ts DELETED
@@ -1,7 +0,0 @@
1
- import { FabricObject } from "fabric";
2
- declare module "fabric" {
3
- interface FabricObject {
4
- data?: any;
5
- }
6
- }
7
- export { FabricObject as PooderObject };
package/src/types.ts DELETED
@@ -1,105 +0,0 @@
1
- import { PooderCanvas } from "./canvas";
2
- import { PooderObject } from "./obj";
3
- import { PooderLayer } from "./layer";
4
- import { ExtensionMap } from "./extension";
5
- import { CommandMap } from "./command";
6
-
7
- export interface CommandArgSchema {
8
- type: "string" | "number" | "boolean" | "object" | "any";
9
- label?: string;
10
- description?: string;
11
- required?: boolean;
12
- default?: any;
13
- // Type-specific constraints
14
- options?: string[] | { label: string; value: any }[];
15
- min?: number;
16
- max?: number;
17
- }
18
-
19
- export interface CommandSchema {
20
- [argName: string]: CommandArgSchema;
21
- }
22
-
23
- export interface Command {
24
- execute(...args: any[]): any;
25
- schema?: CommandSchema;
26
- }
27
-
28
- export interface Event {
29
- name: string;
30
- data: any;
31
- }
32
-
33
- export type EventHandler = (...args: any[]) => void | boolean;
34
-
35
- export interface ExtensionOptions {
36
- [key: string]: any;
37
- }
38
- export interface OptionSchema {
39
- type: "string" | "number" | "boolean" | "color" | "select";
40
- options?: string[] | { label: string; value: any }[];
41
- min?: number;
42
- max?: number;
43
- step?: number;
44
- label?: string;
45
- }
46
-
47
- export interface Extension<T extends ExtensionOptions = ExtensionOptions> {
48
- name: string;
49
- priority?: number;
50
- options?: T;
51
- schema?: Record<keyof T, OptionSchema>;
52
- enabled?: boolean;
53
-
54
- onCreate?(editor: Editor): void;
55
- onMount?(editor: Editor): void;
56
- onUpdate?(editor: Editor, state: EditorState): void;
57
- onUnmount?(editor: Editor): void;
58
- onDestroy?(editor: Editor): void;
59
-
60
- toJSON?(): any;
61
- loadFromJSON?(data: any): void | Promise<void>;
62
-
63
- commands?: Record<string, Command>;
64
- }
65
-
66
- export interface EditorState {
67
- width: number;
68
- height: number;
69
- metadata?: Record<string, any>;
70
- }
71
-
72
- export interface Editor {
73
- state: EditorState;
74
- canvas: PooderCanvas;
75
- extensions: ExtensionMap;
76
- commands: CommandMap;
77
-
78
- use(extension: Extension): void;
79
- unuse(name: string): void;
80
- getExtension(name: string): Extension | undefined;
81
- getExtensions(): Extension[];
82
- enableExtension(name: string): void;
83
- disableExtension(name: string): void;
84
-
85
- registerCommand(name: string, command: Command): void;
86
- unregisterCommand(name: string): void;
87
- executeCommand(name: string, ...args: any[]): void;
88
-
89
- on(event: string, handler: EventHandler, priority?: number): void;
90
- off(event: string, handler: EventHandler): void;
91
- emit(event: string, ...args: any[]): void;
92
-
93
- getObjects(): PooderObject[];
94
- getObject(id: string, layerId?: string): PooderObject | undefined;
95
- getLayers(): PooderLayer[];
96
- getLayer(id: string): PooderLayer | undefined;
97
-
98
- updateState(updater: (state: EditorState) => EditorState): void;
99
- getState(): EditorState;
100
-
101
- toJSON(): any;
102
- loadFromJSON(json: any): Promise<void>;
103
-
104
- destroy(): void;
105
- }