@fieldnotes/core 0.1.1 → 0.2.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/dist/index.cjs +72 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +52 -30
- package/dist/index.d.ts +52 -30
- package/dist/index.js +71 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -73,6 +73,34 @@ declare function exportState(elements: CanvasElement[], camera: {
|
|
|
73
73
|
}): CanvasState;
|
|
74
74
|
declare function parseState(json: string): CanvasState;
|
|
75
75
|
|
|
76
|
+
interface ElementUpdateEvent {
|
|
77
|
+
previous: CanvasElement;
|
|
78
|
+
current: CanvasElement;
|
|
79
|
+
}
|
|
80
|
+
interface ElementStoreEvents {
|
|
81
|
+
add: CanvasElement;
|
|
82
|
+
remove: CanvasElement;
|
|
83
|
+
update: ElementUpdateEvent;
|
|
84
|
+
clear: null;
|
|
85
|
+
}
|
|
86
|
+
declare class ElementStore {
|
|
87
|
+
private elements;
|
|
88
|
+
private bus;
|
|
89
|
+
get count(): number;
|
|
90
|
+
getAll(): CanvasElement[];
|
|
91
|
+
getById(id: string): CanvasElement | undefined;
|
|
92
|
+
getElementsByType<T extends ElementType>(type: T): Extract<CanvasElement, {
|
|
93
|
+
type: T;
|
|
94
|
+
}>[];
|
|
95
|
+
add(element: CanvasElement): void;
|
|
96
|
+
update(id: string, partial: Partial<CanvasElement>): void;
|
|
97
|
+
remove(id: string): void;
|
|
98
|
+
clear(): void;
|
|
99
|
+
snapshot(): CanvasElement[];
|
|
100
|
+
loadSnapshot(elements: CanvasElement[]): void;
|
|
101
|
+
on<K extends keyof ElementStoreEvents>(event: K, listener: (data: ElementStoreEvents[K]) => void): () => void;
|
|
102
|
+
}
|
|
103
|
+
|
|
76
104
|
interface CameraOptions {
|
|
77
105
|
minZoom?: number;
|
|
78
106
|
maxZoom?: number;
|
|
@@ -98,6 +126,27 @@ declare class Camera {
|
|
|
98
126
|
private notifyChange;
|
|
99
127
|
}
|
|
100
128
|
|
|
129
|
+
interface AutoSaveOptions {
|
|
130
|
+
key?: string;
|
|
131
|
+
debounceMs?: number;
|
|
132
|
+
}
|
|
133
|
+
declare class AutoSave {
|
|
134
|
+
private readonly store;
|
|
135
|
+
private readonly camera;
|
|
136
|
+
private readonly key;
|
|
137
|
+
private readonly debounceMs;
|
|
138
|
+
private timerId;
|
|
139
|
+
private unsubscribers;
|
|
140
|
+
constructor(store: ElementStore, camera: Camera, options?: AutoSaveOptions);
|
|
141
|
+
start(): void;
|
|
142
|
+
stop(): void;
|
|
143
|
+
load(): CanvasState | null;
|
|
144
|
+
clear(): void;
|
|
145
|
+
private scheduleSave;
|
|
146
|
+
private cancelPending;
|
|
147
|
+
private save;
|
|
148
|
+
}
|
|
149
|
+
|
|
101
150
|
type BackgroundPattern = 'dots' | 'grid' | 'none';
|
|
102
151
|
interface BackgroundOptions {
|
|
103
152
|
pattern?: BackgroundPattern;
|
|
@@ -114,38 +163,11 @@ declare class Background {
|
|
|
114
163
|
private readonly lineWidth;
|
|
115
164
|
constructor(options?: BackgroundOptions);
|
|
116
165
|
render(ctx: CanvasRenderingContext2D, camera: Camera): void;
|
|
166
|
+
private adaptSpacing;
|
|
117
167
|
private renderDots;
|
|
118
168
|
private renderGrid;
|
|
119
169
|
}
|
|
120
170
|
|
|
121
|
-
interface ElementUpdateEvent {
|
|
122
|
-
previous: CanvasElement;
|
|
123
|
-
current: CanvasElement;
|
|
124
|
-
}
|
|
125
|
-
interface ElementStoreEvents {
|
|
126
|
-
add: CanvasElement;
|
|
127
|
-
remove: CanvasElement;
|
|
128
|
-
update: ElementUpdateEvent;
|
|
129
|
-
clear: null;
|
|
130
|
-
}
|
|
131
|
-
declare class ElementStore {
|
|
132
|
-
private elements;
|
|
133
|
-
private bus;
|
|
134
|
-
get count(): number;
|
|
135
|
-
getAll(): CanvasElement[];
|
|
136
|
-
getById(id: string): CanvasElement | undefined;
|
|
137
|
-
getElementsByType<T extends ElementType>(type: T): Extract<CanvasElement, {
|
|
138
|
-
type: T;
|
|
139
|
-
}>[];
|
|
140
|
-
add(element: CanvasElement): void;
|
|
141
|
-
update(id: string, partial: Partial<CanvasElement>): void;
|
|
142
|
-
remove(id: string): void;
|
|
143
|
-
clear(): void;
|
|
144
|
-
snapshot(): CanvasElement[];
|
|
145
|
-
loadSnapshot(elements: CanvasElement[]): void;
|
|
146
|
-
on<K extends keyof ElementStoreEvents>(event: K, listener: (data: ElementStoreEvents[K]) => void): () => void;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
171
|
interface ToolContext {
|
|
150
172
|
camera: Camera;
|
|
151
173
|
store: ElementStore;
|
|
@@ -577,6 +599,6 @@ declare class ImageTool implements Tool {
|
|
|
577
599
|
onPointerUp(state: PointerState, ctx: ToolContext): void;
|
|
578
600
|
}
|
|
579
601
|
|
|
580
|
-
declare const VERSION = "0.1.
|
|
602
|
+
declare const VERSION = "0.1.2";
|
|
581
603
|
|
|
582
|
-
export { AddElementCommand, type ArrowElement, ArrowTool, type ArrowToolOptions, Background, type BackgroundOptions, type BackgroundPattern, BatchCommand, type Bounds, Camera, type CameraOptions, type CanvasElement, type CanvasState, type Command, ElementRenderer, ElementStore, type ElementType, type ElementUpdateEvent, EraserTool, type EraserToolOptions, EventBus, HandTool, HistoryRecorder, HistoryStack, type HistoryStackOptions, type HtmlElement, type ImageElement, ImageTool, type ImageToolOptions, InputHandler, NoteEditor, type NoteElement, NoteTool, type NoteToolOptions, PencilTool, type PencilToolOptions, type Point, type PointerState, RemoveElementCommand, SelectTool, type Size, type StrokeElement, type Tool, type ToolContext, ToolManager, type ToolName, UpdateElementCommand, VERSION, Viewport, type ViewportOptions, createArrow, createHtmlElement, createId, createImage, createNote, createStroke, exportState, getArrowBounds, getArrowControlPoint, getArrowMidpoint, getArrowTangentAngle, getBendFromPoint, isNearBezier, parseState };
|
|
604
|
+
export { AddElementCommand, type ArrowElement, ArrowTool, type ArrowToolOptions, AutoSave, type AutoSaveOptions, Background, type BackgroundOptions, type BackgroundPattern, BatchCommand, type Bounds, Camera, type CameraOptions, type CanvasElement, type CanvasState, type Command, ElementRenderer, ElementStore, type ElementType, type ElementUpdateEvent, EraserTool, type EraserToolOptions, EventBus, HandTool, HistoryRecorder, HistoryStack, type HistoryStackOptions, type HtmlElement, type ImageElement, ImageTool, type ImageToolOptions, InputHandler, NoteEditor, type NoteElement, NoteTool, type NoteToolOptions, PencilTool, type PencilToolOptions, type Point, type PointerState, RemoveElementCommand, SelectTool, type Size, type StrokeElement, type Tool, type ToolContext, ToolManager, type ToolName, UpdateElementCommand, VERSION, Viewport, type ViewportOptions, createArrow, createHtmlElement, createId, createImage, createNote, createStroke, exportState, getArrowBounds, getArrowControlPoint, getArrowMidpoint, getArrowTangentAngle, getBendFromPoint, isNearBezier, parseState };
|
package/dist/index.d.ts
CHANGED
|
@@ -73,6 +73,34 @@ declare function exportState(elements: CanvasElement[], camera: {
|
|
|
73
73
|
}): CanvasState;
|
|
74
74
|
declare function parseState(json: string): CanvasState;
|
|
75
75
|
|
|
76
|
+
interface ElementUpdateEvent {
|
|
77
|
+
previous: CanvasElement;
|
|
78
|
+
current: CanvasElement;
|
|
79
|
+
}
|
|
80
|
+
interface ElementStoreEvents {
|
|
81
|
+
add: CanvasElement;
|
|
82
|
+
remove: CanvasElement;
|
|
83
|
+
update: ElementUpdateEvent;
|
|
84
|
+
clear: null;
|
|
85
|
+
}
|
|
86
|
+
declare class ElementStore {
|
|
87
|
+
private elements;
|
|
88
|
+
private bus;
|
|
89
|
+
get count(): number;
|
|
90
|
+
getAll(): CanvasElement[];
|
|
91
|
+
getById(id: string): CanvasElement | undefined;
|
|
92
|
+
getElementsByType<T extends ElementType>(type: T): Extract<CanvasElement, {
|
|
93
|
+
type: T;
|
|
94
|
+
}>[];
|
|
95
|
+
add(element: CanvasElement): void;
|
|
96
|
+
update(id: string, partial: Partial<CanvasElement>): void;
|
|
97
|
+
remove(id: string): void;
|
|
98
|
+
clear(): void;
|
|
99
|
+
snapshot(): CanvasElement[];
|
|
100
|
+
loadSnapshot(elements: CanvasElement[]): void;
|
|
101
|
+
on<K extends keyof ElementStoreEvents>(event: K, listener: (data: ElementStoreEvents[K]) => void): () => void;
|
|
102
|
+
}
|
|
103
|
+
|
|
76
104
|
interface CameraOptions {
|
|
77
105
|
minZoom?: number;
|
|
78
106
|
maxZoom?: number;
|
|
@@ -98,6 +126,27 @@ declare class Camera {
|
|
|
98
126
|
private notifyChange;
|
|
99
127
|
}
|
|
100
128
|
|
|
129
|
+
interface AutoSaveOptions {
|
|
130
|
+
key?: string;
|
|
131
|
+
debounceMs?: number;
|
|
132
|
+
}
|
|
133
|
+
declare class AutoSave {
|
|
134
|
+
private readonly store;
|
|
135
|
+
private readonly camera;
|
|
136
|
+
private readonly key;
|
|
137
|
+
private readonly debounceMs;
|
|
138
|
+
private timerId;
|
|
139
|
+
private unsubscribers;
|
|
140
|
+
constructor(store: ElementStore, camera: Camera, options?: AutoSaveOptions);
|
|
141
|
+
start(): void;
|
|
142
|
+
stop(): void;
|
|
143
|
+
load(): CanvasState | null;
|
|
144
|
+
clear(): void;
|
|
145
|
+
private scheduleSave;
|
|
146
|
+
private cancelPending;
|
|
147
|
+
private save;
|
|
148
|
+
}
|
|
149
|
+
|
|
101
150
|
type BackgroundPattern = 'dots' | 'grid' | 'none';
|
|
102
151
|
interface BackgroundOptions {
|
|
103
152
|
pattern?: BackgroundPattern;
|
|
@@ -114,38 +163,11 @@ declare class Background {
|
|
|
114
163
|
private readonly lineWidth;
|
|
115
164
|
constructor(options?: BackgroundOptions);
|
|
116
165
|
render(ctx: CanvasRenderingContext2D, camera: Camera): void;
|
|
166
|
+
private adaptSpacing;
|
|
117
167
|
private renderDots;
|
|
118
168
|
private renderGrid;
|
|
119
169
|
}
|
|
120
170
|
|
|
121
|
-
interface ElementUpdateEvent {
|
|
122
|
-
previous: CanvasElement;
|
|
123
|
-
current: CanvasElement;
|
|
124
|
-
}
|
|
125
|
-
interface ElementStoreEvents {
|
|
126
|
-
add: CanvasElement;
|
|
127
|
-
remove: CanvasElement;
|
|
128
|
-
update: ElementUpdateEvent;
|
|
129
|
-
clear: null;
|
|
130
|
-
}
|
|
131
|
-
declare class ElementStore {
|
|
132
|
-
private elements;
|
|
133
|
-
private bus;
|
|
134
|
-
get count(): number;
|
|
135
|
-
getAll(): CanvasElement[];
|
|
136
|
-
getById(id: string): CanvasElement | undefined;
|
|
137
|
-
getElementsByType<T extends ElementType>(type: T): Extract<CanvasElement, {
|
|
138
|
-
type: T;
|
|
139
|
-
}>[];
|
|
140
|
-
add(element: CanvasElement): void;
|
|
141
|
-
update(id: string, partial: Partial<CanvasElement>): void;
|
|
142
|
-
remove(id: string): void;
|
|
143
|
-
clear(): void;
|
|
144
|
-
snapshot(): CanvasElement[];
|
|
145
|
-
loadSnapshot(elements: CanvasElement[]): void;
|
|
146
|
-
on<K extends keyof ElementStoreEvents>(event: K, listener: (data: ElementStoreEvents[K]) => void): () => void;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
171
|
interface ToolContext {
|
|
150
172
|
camera: Camera;
|
|
151
173
|
store: ElementStore;
|
|
@@ -577,6 +599,6 @@ declare class ImageTool implements Tool {
|
|
|
577
599
|
onPointerUp(state: PointerState, ctx: ToolContext): void;
|
|
578
600
|
}
|
|
579
601
|
|
|
580
|
-
declare const VERSION = "0.1.
|
|
602
|
+
declare const VERSION = "0.1.2";
|
|
581
603
|
|
|
582
|
-
export { AddElementCommand, type ArrowElement, ArrowTool, type ArrowToolOptions, Background, type BackgroundOptions, type BackgroundPattern, BatchCommand, type Bounds, Camera, type CameraOptions, type CanvasElement, type CanvasState, type Command, ElementRenderer, ElementStore, type ElementType, type ElementUpdateEvent, EraserTool, type EraserToolOptions, EventBus, HandTool, HistoryRecorder, HistoryStack, type HistoryStackOptions, type HtmlElement, type ImageElement, ImageTool, type ImageToolOptions, InputHandler, NoteEditor, type NoteElement, NoteTool, type NoteToolOptions, PencilTool, type PencilToolOptions, type Point, type PointerState, RemoveElementCommand, SelectTool, type Size, type StrokeElement, type Tool, type ToolContext, ToolManager, type ToolName, UpdateElementCommand, VERSION, Viewport, type ViewportOptions, createArrow, createHtmlElement, createId, createImage, createNote, createStroke, exportState, getArrowBounds, getArrowControlPoint, getArrowMidpoint, getArrowTangentAngle, getBendFromPoint, isNearBezier, parseState };
|
|
604
|
+
export { AddElementCommand, type ArrowElement, ArrowTool, type ArrowToolOptions, AutoSave, type AutoSaveOptions, Background, type BackgroundOptions, type BackgroundPattern, BatchCommand, type Bounds, Camera, type CameraOptions, type CanvasElement, type CanvasState, type Command, ElementRenderer, ElementStore, type ElementType, type ElementUpdateEvent, EraserTool, type EraserToolOptions, EventBus, HandTool, HistoryRecorder, HistoryStack, type HistoryStackOptions, type HtmlElement, type ImageElement, ImageTool, type ImageToolOptions, InputHandler, NoteEditor, type NoteElement, NoteTool, type NoteToolOptions, PencilTool, type PencilToolOptions, type Point, type PointerState, RemoveElementCommand, SelectTool, type Size, type StrokeElement, type Tool, type ToolContext, ToolManager, type ToolName, UpdateElementCommand, VERSION, Viewport, type ViewportOptions, createArrow, createHtmlElement, createId, createImage, createNote, createStroke, exportState, getArrowBounds, getArrowControlPoint, getArrowMidpoint, getArrowTangentAngle, getBendFromPoint, isNearBezier, parseState };
|
package/dist/index.js
CHANGED
|
@@ -91,6 +91,65 @@ function migrateElement(obj) {
|
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
// src/core/auto-save.ts
|
|
95
|
+
var DEFAULT_KEY = "fieldnotes-autosave";
|
|
96
|
+
var DEFAULT_DEBOUNCE_MS = 1e3;
|
|
97
|
+
var AutoSave = class {
|
|
98
|
+
constructor(store, camera, options = {}) {
|
|
99
|
+
this.store = store;
|
|
100
|
+
this.camera = camera;
|
|
101
|
+
this.key = options.key ?? DEFAULT_KEY;
|
|
102
|
+
this.debounceMs = options.debounceMs ?? DEFAULT_DEBOUNCE_MS;
|
|
103
|
+
}
|
|
104
|
+
key;
|
|
105
|
+
debounceMs;
|
|
106
|
+
timerId = null;
|
|
107
|
+
unsubscribers = [];
|
|
108
|
+
start() {
|
|
109
|
+
const schedule = () => this.scheduleSave();
|
|
110
|
+
this.unsubscribers = [
|
|
111
|
+
this.store.on("add", schedule),
|
|
112
|
+
this.store.on("remove", schedule),
|
|
113
|
+
this.store.on("update", schedule),
|
|
114
|
+
this.camera.onChange(schedule)
|
|
115
|
+
];
|
|
116
|
+
}
|
|
117
|
+
stop() {
|
|
118
|
+
this.cancelPending();
|
|
119
|
+
this.unsubscribers.forEach((fn) => fn());
|
|
120
|
+
this.unsubscribers = [];
|
|
121
|
+
}
|
|
122
|
+
load() {
|
|
123
|
+
if (typeof localStorage === "undefined") return null;
|
|
124
|
+
const json = localStorage.getItem(this.key);
|
|
125
|
+
if (!json) return null;
|
|
126
|
+
try {
|
|
127
|
+
return parseState(json);
|
|
128
|
+
} catch {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
clear() {
|
|
133
|
+
if (typeof localStorage === "undefined") return;
|
|
134
|
+
localStorage.removeItem(this.key);
|
|
135
|
+
}
|
|
136
|
+
scheduleSave() {
|
|
137
|
+
this.cancelPending();
|
|
138
|
+
this.timerId = setTimeout(() => this.save(), this.debounceMs);
|
|
139
|
+
}
|
|
140
|
+
cancelPending() {
|
|
141
|
+
if (this.timerId !== null) {
|
|
142
|
+
clearTimeout(this.timerId);
|
|
143
|
+
this.timerId = null;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
save() {
|
|
147
|
+
if (typeof localStorage === "undefined") return;
|
|
148
|
+
const state = exportState(this.store.snapshot(), this.camera);
|
|
149
|
+
localStorage.setItem(this.key, JSON.stringify(state));
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
|
|
94
153
|
// src/canvas/camera.ts
|
|
95
154
|
var DEFAULT_MIN_ZOOM = 0.1;
|
|
96
155
|
var DEFAULT_MAX_ZOOM = 10;
|
|
@@ -158,6 +217,7 @@ var Camera = class {
|
|
|
158
217
|
};
|
|
159
218
|
|
|
160
219
|
// src/canvas/background.ts
|
|
220
|
+
var MIN_PATTERN_SPACING = 16;
|
|
161
221
|
var DEFAULTS = {
|
|
162
222
|
pattern: "dots",
|
|
163
223
|
spacing: 24,
|
|
@@ -193,8 +253,15 @@ var Background = class {
|
|
|
193
253
|
}
|
|
194
254
|
ctx.restore();
|
|
195
255
|
}
|
|
256
|
+
adaptSpacing(baseSpacing, zoom) {
|
|
257
|
+
let spacing = baseSpacing * zoom;
|
|
258
|
+
while (spacing < MIN_PATTERN_SPACING) {
|
|
259
|
+
spacing *= 2;
|
|
260
|
+
}
|
|
261
|
+
return spacing;
|
|
262
|
+
}
|
|
196
263
|
renderDots(ctx, camera, width, height) {
|
|
197
|
-
const spacing = this.spacing
|
|
264
|
+
const spacing = this.adaptSpacing(this.spacing, camera.zoom);
|
|
198
265
|
const offsetX = camera.position.x % spacing;
|
|
199
266
|
const offsetY = camera.position.y % spacing;
|
|
200
267
|
const radius = this.dotRadius * Math.min(camera.zoom, 2);
|
|
@@ -209,7 +276,7 @@ var Background = class {
|
|
|
209
276
|
ctx.fill();
|
|
210
277
|
}
|
|
211
278
|
renderGrid(ctx, camera, width, height) {
|
|
212
|
-
const spacing = this.spacing
|
|
279
|
+
const spacing = this.adaptSpacing(this.spacing, camera.zoom);
|
|
213
280
|
const offsetX = camera.position.x % spacing;
|
|
214
281
|
const offsetY = camera.position.y % spacing;
|
|
215
282
|
const lineW = this.lineWidth * Math.min(camera.zoom, 2);
|
|
@@ -2150,10 +2217,11 @@ var ImageTool = class {
|
|
|
2150
2217
|
};
|
|
2151
2218
|
|
|
2152
2219
|
// src/index.ts
|
|
2153
|
-
var VERSION = "0.1.
|
|
2220
|
+
var VERSION = "0.1.2";
|
|
2154
2221
|
export {
|
|
2155
2222
|
AddElementCommand,
|
|
2156
2223
|
ArrowTool,
|
|
2224
|
+
AutoSave,
|
|
2157
2225
|
Background,
|
|
2158
2226
|
BatchCommand,
|
|
2159
2227
|
Camera,
|