juxscript 1.1.28 → 1.1.31
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/index.d.ts +4 -1
- package/index.d.ts.map +1 -1
- package/index.js +4 -1
- package/lib/components/base/BaseComponent.d.ts +20 -7
- package/lib/components/base/BaseComponent.d.ts.map +1 -1
- package/lib/components/base/BaseComponent.js +64 -15
- package/lib/components/base/BaseComponent.ts +75 -15
- package/lib/components/history/StateHistory.d.ts +91 -0
- package/lib/components/history/StateHistory.d.ts.map +1 -0
- package/lib/components/history/StateHistory.js +154 -0
- package/lib/components/history/StateHistory.ts +200 -0
- package/lib/components/pen.d.ts +125 -0
- package/lib/components/pen.d.ts.map +1 -0
- package/lib/components/pen.js +443 -0
- package/lib/components/pen.ts +567 -0
- package/lib/components/registry.d.ts +10 -36
- package/lib/components/registry.d.ts.map +1 -1
- package/lib/components/registry.js +122 -105
- package/lib/components/registry.ts +141 -112
- package/package.json +1 -1
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State History Tracker
|
|
3
|
+
* Tracks all state mutations for time-travel debugging and undo/redo
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export interface StateSnapshot<T = any> {
|
|
7
|
+
timestamp: number;
|
|
8
|
+
componentId: string;
|
|
9
|
+
property: string;
|
|
10
|
+
oldValue: T;
|
|
11
|
+
newValue: T;
|
|
12
|
+
stackTrace?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface EventSnapshot {
|
|
16
|
+
timestamp: number;
|
|
17
|
+
componentId: string;
|
|
18
|
+
eventType: 'bind' | 'sync' | 'callback' | 'trigger';
|
|
19
|
+
eventName: string;
|
|
20
|
+
details: Record<string, any>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class StateHistory {
|
|
24
|
+
private stateSnapshots: StateSnapshot[] = [];
|
|
25
|
+
private eventSnapshots: EventSnapshot[] = [];
|
|
26
|
+
private maxHistory: number = 100;
|
|
27
|
+
private currentIndex: number = -1;
|
|
28
|
+
private isReplaying: boolean = false;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Record a state change
|
|
32
|
+
*/
|
|
33
|
+
recordStateChange<T>(
|
|
34
|
+
componentId: string,
|
|
35
|
+
property: string,
|
|
36
|
+
oldValue: T,
|
|
37
|
+
newValue: T
|
|
38
|
+
): void {
|
|
39
|
+
if (this.isReplaying) return; // Don't record during replay
|
|
40
|
+
|
|
41
|
+
const snapshot: StateSnapshot<T> = {
|
|
42
|
+
timestamp: Date.now(),
|
|
43
|
+
componentId,
|
|
44
|
+
property,
|
|
45
|
+
oldValue,
|
|
46
|
+
newValue,
|
|
47
|
+
stackTrace: new Error().stack
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// Trim future history if we're not at the end
|
|
51
|
+
if (this.currentIndex < this.stateSnapshots.length - 1) {
|
|
52
|
+
this.stateSnapshots = this.stateSnapshots.slice(0, this.currentIndex + 1);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
this.stateSnapshots.push(snapshot);
|
|
56
|
+
this.currentIndex = this.stateSnapshots.length - 1;
|
|
57
|
+
|
|
58
|
+
// Trim if exceeds max
|
|
59
|
+
if (this.stateSnapshots.length > this.maxHistory) {
|
|
60
|
+
this.stateSnapshots.shift();
|
|
61
|
+
this.currentIndex--;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Record an event (bind, sync, callback, trigger)
|
|
67
|
+
*/
|
|
68
|
+
recordEvent(
|
|
69
|
+
componentId: string,
|
|
70
|
+
eventType: 'bind' | 'sync' | 'callback' | 'trigger',
|
|
71
|
+
eventName: string,
|
|
72
|
+
details: Record<string, any> = {}
|
|
73
|
+
): void {
|
|
74
|
+
const snapshot: EventSnapshot = {
|
|
75
|
+
timestamp: Date.now(),
|
|
76
|
+
componentId,
|
|
77
|
+
eventType,
|
|
78
|
+
eventName,
|
|
79
|
+
details
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
this.eventSnapshots.push(snapshot);
|
|
83
|
+
|
|
84
|
+
// Trim if exceeds max
|
|
85
|
+
if (this.eventSnapshots.length > this.maxHistory) {
|
|
86
|
+
this.eventSnapshots.shift();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Get timeline of all changes and events
|
|
92
|
+
*/
|
|
93
|
+
getTimeline(): Array<StateSnapshot | EventSnapshot> {
|
|
94
|
+
return [...this.stateSnapshots, ...this.eventSnapshots]
|
|
95
|
+
.sort((a, b) => a.timestamp - b.timestamp);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Get state snapshots for a specific component
|
|
100
|
+
*/
|
|
101
|
+
getComponentHistory(componentId: string): StateSnapshot[] {
|
|
102
|
+
return this.stateSnapshots.filter(s => s.componentId === componentId);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Get event snapshots for a specific component
|
|
107
|
+
*/
|
|
108
|
+
getComponentEvents(componentId: string): EventSnapshot[] {
|
|
109
|
+
return this.eventSnapshots.filter(s => s.componentId === componentId);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Check if we can roll back
|
|
114
|
+
*/
|
|
115
|
+
canRollback(): boolean {
|
|
116
|
+
return this.currentIndex > 0;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Check if we can roll forward
|
|
121
|
+
*/
|
|
122
|
+
canRollforward(): boolean {
|
|
123
|
+
return this.currentIndex < this.stateSnapshots.length - 1;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Get the current snapshot (for rollback)
|
|
128
|
+
*/
|
|
129
|
+
getCurrentSnapshot(): StateSnapshot | null {
|
|
130
|
+
if (this.currentIndex >= 0 && this.currentIndex < this.stateSnapshots.length) {
|
|
131
|
+
return this.stateSnapshots[this.currentIndex];
|
|
132
|
+
}
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Move index for rollback
|
|
138
|
+
*/
|
|
139
|
+
moveBack(): StateSnapshot | null {
|
|
140
|
+
if (this.canRollback()) {
|
|
141
|
+
this.currentIndex--;
|
|
142
|
+
return this.stateSnapshots[this.currentIndex];
|
|
143
|
+
}
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Move index for rollforward
|
|
149
|
+
*/
|
|
150
|
+
moveForward(): StateSnapshot | null {
|
|
151
|
+
if (this.canRollforward()) {
|
|
152
|
+
this.currentIndex++;
|
|
153
|
+
return this.stateSnapshots[this.currentIndex];
|
|
154
|
+
}
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Mark as replaying to prevent recursive recording
|
|
160
|
+
*/
|
|
161
|
+
startReplay(): void {
|
|
162
|
+
this.isReplaying = true;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* End replay mode
|
|
167
|
+
*/
|
|
168
|
+
endReplay(): void {
|
|
169
|
+
this.isReplaying = false;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Clear all history
|
|
174
|
+
*/
|
|
175
|
+
clear(): void {
|
|
176
|
+
this.stateSnapshots = [];
|
|
177
|
+
this.eventSnapshots = [];
|
|
178
|
+
this.currentIndex = -1;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Get summary statistics
|
|
183
|
+
*/
|
|
184
|
+
getStats() {
|
|
185
|
+
return {
|
|
186
|
+
totalStateChanges: this.stateSnapshots.length,
|
|
187
|
+
totalEvents: this.eventSnapshots.length,
|
|
188
|
+
currentIndex: this.currentIndex,
|
|
189
|
+
canRollback: this.canRollback(),
|
|
190
|
+
canRollforward: this.canRollforward(),
|
|
191
|
+
components: new Set([
|
|
192
|
+
...this.stateSnapshots.map(s => s.componentId),
|
|
193
|
+
...this.eventSnapshots.map(s => s.componentId)
|
|
194
|
+
]).size
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Global singleton
|
|
200
|
+
export const stateHistory = new StateHistory();
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { BaseComponent, BaseState } from './base/BaseComponent.js';
|
|
2
|
+
export interface PenShape {
|
|
3
|
+
id: string;
|
|
4
|
+
type: 'line' | 'rectangle' | 'circle' | 'text';
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
width?: number;
|
|
8
|
+
height?: number;
|
|
9
|
+
radius?: number;
|
|
10
|
+
text?: string;
|
|
11
|
+
color?: string;
|
|
12
|
+
fillColor?: string;
|
|
13
|
+
strokeWidth?: number;
|
|
14
|
+
connectedTo?: string[];
|
|
15
|
+
}
|
|
16
|
+
export interface PenConnection {
|
|
17
|
+
from: string;
|
|
18
|
+
to: string;
|
|
19
|
+
color?: string;
|
|
20
|
+
strokeWidth?: number;
|
|
21
|
+
dashed?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface PenOptions {
|
|
24
|
+
width?: number | string;
|
|
25
|
+
height?: number | string;
|
|
26
|
+
backgroundColor?: string;
|
|
27
|
+
backgroundImage?: string;
|
|
28
|
+
border?: string;
|
|
29
|
+
text?: string;
|
|
30
|
+
radius?: number;
|
|
31
|
+
gridEnabled?: boolean;
|
|
32
|
+
gridSize?: number;
|
|
33
|
+
gridColor?: string;
|
|
34
|
+
style?: string;
|
|
35
|
+
class?: string;
|
|
36
|
+
}
|
|
37
|
+
type PenState = BaseState & {
|
|
38
|
+
width: number | string;
|
|
39
|
+
height: number | string;
|
|
40
|
+
backgroundColor: string;
|
|
41
|
+
backgroundImage: string;
|
|
42
|
+
border: string;
|
|
43
|
+
text: string;
|
|
44
|
+
radius: number;
|
|
45
|
+
gridEnabled: boolean;
|
|
46
|
+
gridSize: number;
|
|
47
|
+
gridColor: string;
|
|
48
|
+
shapes: PenShape[];
|
|
49
|
+
connections: PenConnection[];
|
|
50
|
+
};
|
|
51
|
+
export declare class Pen extends BaseComponent<PenState> {
|
|
52
|
+
private _canvas;
|
|
53
|
+
private _ctx;
|
|
54
|
+
private _animationFrame?;
|
|
55
|
+
constructor(id: string, options?: PenOptions);
|
|
56
|
+
protected getTriggerEvents(): readonly string[];
|
|
57
|
+
protected getCallbackEvents(): readonly string[];
|
|
58
|
+
update(prop: string, value: any): void;
|
|
59
|
+
width(value: number | string): this;
|
|
60
|
+
height(value: number | string): this;
|
|
61
|
+
backgroundColor(value: string): this;
|
|
62
|
+
backgroundImage(value: string): this;
|
|
63
|
+
border(value: string): this;
|
|
64
|
+
text(value: string): this;
|
|
65
|
+
radius(value: number): this;
|
|
66
|
+
grid(enabled: boolean, size?: number, color?: string): this;
|
|
67
|
+
/**
|
|
68
|
+
* Add a line shape
|
|
69
|
+
*/
|
|
70
|
+
drawLine(x1: number, y1: number, x2: number, y2: number, options?: Partial<PenShape>): this;
|
|
71
|
+
/**
|
|
72
|
+
* Add a rectangle shape
|
|
73
|
+
*/
|
|
74
|
+
drawRect(x: number, y: number, width: number, height: number, options?: Partial<PenShape>): this;
|
|
75
|
+
/**
|
|
76
|
+
* Add a circle shape
|
|
77
|
+
*/
|
|
78
|
+
drawCircle(x: number, y: number, radius: number, options?: Partial<PenShape>): this;
|
|
79
|
+
/**
|
|
80
|
+
* Add text to canvas
|
|
81
|
+
*/
|
|
82
|
+
drawText(x: number, y: number, text: string, options?: Partial<PenShape>): this;
|
|
83
|
+
/**
|
|
84
|
+
* Connect two shapes with a line
|
|
85
|
+
*/
|
|
86
|
+
connect(fromId: string, toId: string, options?: Partial<PenConnection>): this;
|
|
87
|
+
/**
|
|
88
|
+
* Remove a shape by ID
|
|
89
|
+
*/
|
|
90
|
+
removeShape(id: string): this;
|
|
91
|
+
/**
|
|
92
|
+
* Clear all shapes and connections
|
|
93
|
+
*/
|
|
94
|
+
clear(): this;
|
|
95
|
+
/**
|
|
96
|
+
* Get shape by ID
|
|
97
|
+
*/
|
|
98
|
+
getShape(id: string): PenShape | undefined;
|
|
99
|
+
/**
|
|
100
|
+
* Get all shapes
|
|
101
|
+
*/
|
|
102
|
+
getShapes(): PenShape[];
|
|
103
|
+
/**
|
|
104
|
+
* Export canvas as data URL
|
|
105
|
+
*/
|
|
106
|
+
toDataURL(type?: string): string;
|
|
107
|
+
/**
|
|
108
|
+
* Download canvas as image
|
|
109
|
+
*/
|
|
110
|
+
download(filename?: string): this;
|
|
111
|
+
private _updateCanvasSize;
|
|
112
|
+
private _redraw;
|
|
113
|
+
private _drawContent;
|
|
114
|
+
private _drawGrid;
|
|
115
|
+
private _drawShape;
|
|
116
|
+
private _drawConnection;
|
|
117
|
+
render(targetId?: string): this;
|
|
118
|
+
/**
|
|
119
|
+
* Cleanup on destroy
|
|
120
|
+
*/
|
|
121
|
+
destroy(): void;
|
|
122
|
+
}
|
|
123
|
+
export declare function pen(id: string, options?: PenOptions): Pen;
|
|
124
|
+
export {};
|
|
125
|
+
//# sourceMappingURL=pen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pen.d.ts","sourceRoot":"","sources":["pen.ts"],"names":[],"mappings":"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"}
|