@ai-matrx/canvas 0.1.0 → 0.1.1

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/react.d.ts CHANGED
@@ -1,283 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { ComponentType, ReactNode, CSSProperties } from 'react';
3
-
4
- /**
5
- * @ai-matrx/canvas — core types.
6
- *
7
- * The canvas is ONE docked column on the right edge of an application. It holds
8
- * panes; panes hold tabs; every tab is one CanvasItem. A CanvasItem is
9
- * identified by `kind` + `key`, so opening the same thing twice always lands on
10
- * the existing tab instead of creating a duplicate.
11
- *
12
- * Everything in CanvasState is plain JSON: it lives in the host's Redux store
13
- * (or the package's own standalone store), it is persisted between sessions,
14
- * and it can be inspected. No functions, no class instances, no React nodes.
15
- */
16
- /** Any value that survives JSON.stringify → JSON.parse unchanged. */
17
- type CanvasJson = string | number | boolean | null | readonly CanvasJson[] | {
18
- readonly [key: string]: CanvasJson | undefined;
19
- };
20
- declare const itemIdBrand: unique symbol;
21
- declare const paneIdBrand: unique symbol;
22
- declare const splitIdBrand: unique symbol;
23
- /** `${kind}::${key}` — the identity of one thing on the canvas. */
24
- type CanvasItemId = string & {
25
- readonly [itemIdBrand]: true;
26
- };
27
- type CanvasPaneId = string & {
28
- readonly [paneIdBrand]: true;
29
- };
30
- type CanvasSplitId = string & {
31
- readonly [splitIdBrand]: true;
32
- };
33
- interface CanvasItem {
34
- readonly id: CanvasItemId;
35
- /** Registered kind id (see `registerCanvasKind`). */
36
- readonly kind: string;
37
- /** Stable key inside the kind — an artifact id, a conversation id, "default". */
38
- readonly key: string;
39
- /** Explicit tab title. `null` ⇒ the kind's `title(data)` or its label. */
40
- readonly title: string | null;
41
- readonly data: CanvasJson;
42
- readonly openedAt: number;
43
- readonly updatedAt: number;
44
- }
45
- interface CanvasPane {
46
- readonly id: CanvasPaneId;
47
- readonly itemIds: readonly CanvasItemId[];
48
- readonly activeItemId: CanvasItemId | null;
49
- }
50
- /** "horizontal" = children side by side; "vertical" = children stacked. */
51
- type CanvasOrientation = "horizontal" | "vertical";
52
- type CanvasLayoutNode = {
53
- readonly type: "pane";
54
- readonly paneId: CanvasPaneId;
55
- } | {
56
- readonly type: "split";
57
- readonly id: CanvasSplitId;
58
- readonly orientation: CanvasOrientation;
59
- readonly children: readonly CanvasLayoutNode[];
60
- /** Fractions, one per child, summing to 1. */
61
- readonly sizes: readonly number[];
62
- };
63
- interface CanvasState {
64
- readonly version: 1;
65
- readonly isOpen: boolean;
66
- readonly isFullscreen: boolean;
67
- /** Column width in CSS pixels (desktop). */
68
- readonly width: number;
69
- readonly layout: CanvasLayoutNode;
70
- readonly panes: {
71
- readonly [paneId: string]: CanvasPane;
72
- };
73
- readonly items: {
74
- readonly [itemId: string]: CanvasItem;
75
- };
76
- readonly focusedPaneId: CanvasPaneId;
77
- /** Monotonic counter for minting pane/split ids — keeps the reducer pure. */
78
- readonly seq: number;
79
- /** True once a persisted snapshot was applied (or there was none). */
80
- readonly hydrated: boolean;
81
- }
82
- /** Where a newly opened item goes. Existing items never move on open. */
83
- type CanvasOpenTarget = "focused" | "split-right" | "split-down" | {
84
- readonly paneId: CanvasPaneId;
85
- };
86
- interface CanvasOpenInput {
87
- readonly kind: string;
88
- readonly key: string;
89
- readonly title?: string | null | undefined;
90
- readonly data?: CanvasJson | undefined;
91
- readonly target?: CanvasOpenTarget | undefined;
92
- /** Reveal the canvas when it is put away. Default true. */
93
- readonly reveal?: boolean | undefined;
94
- /** Make the item the pane's active tab. Default true. */
95
- readonly activate?: boolean | undefined;
96
- }
97
-
98
- /**
99
- * THE canvas reducer. Plain Redux-compatible reducer + action creators with no
100
- * Redux Toolkit dependency, so it mounts in a host's RTK store
101
- * (`canvasHost: canvasReducer`) or runs inside the package's own standalone
102
- * store with identical behaviour.
103
- *
104
- * Identity law: an item is `kind::key`. Opening an item that is already on the
105
- * canvas never duplicates it — it refreshes its data/title, activates its tab
106
- * and focuses its pane, wherever that pane is.
107
- */
108
-
109
- declare const P = "matrxCanvas/";
110
- type CanvasAction = {
111
- type: `${typeof P}open`;
112
- payload: CanvasOpenInput & {
113
- now: number;
114
- };
115
- } | {
116
- type: `${typeof P}update`;
117
- payload: {
118
- itemId: CanvasItemId;
119
- data?: CanvasJson | undefined;
120
- title?: string | null | undefined;
121
- now: number;
122
- };
123
- } | {
124
- type: `${typeof P}rekey`;
125
- payload: {
126
- itemId: CanvasItemId;
127
- key: string;
128
- };
129
- } | {
130
- type: `${typeof P}closeItem`;
131
- payload: {
132
- itemId: CanvasItemId;
133
- };
134
- } | {
135
- type: `${typeof P}closeOthers`;
136
- payload: {
137
- itemId: CanvasItemId;
138
- };
139
- } | {
140
- type: `${typeof P}activate`;
141
- payload: {
142
- itemId: CanvasItemId;
143
- };
144
- } | {
145
- type: `${typeof P}focusPane`;
146
- payload: {
147
- paneId: CanvasPaneId;
148
- };
149
- } | {
150
- type: `${typeof P}moveItem`;
151
- payload: {
152
- itemId: CanvasItemId;
153
- toPaneId: CanvasPaneId;
154
- index?: number | undefined;
155
- };
156
- } | {
157
- type: `${typeof P}splitPane`;
158
- payload: {
159
- paneId: CanvasPaneId;
160
- orientation: CanvasOrientation;
161
- moveItemId?: CanvasItemId | undefined;
162
- };
163
- } | {
164
- type: `${typeof P}closePane`;
165
- payload: {
166
- paneId: CanvasPaneId;
167
- };
168
- } | {
169
- type: `${typeof P}resizeSplit`;
170
- payload: {
171
- splitId: CanvasSplitId;
172
- sizes: readonly number[];
173
- };
174
- } | {
175
- type: `${typeof P}setOpen`;
176
- payload: {
177
- open: boolean;
178
- };
179
- } | {
180
- type: `${typeof P}toggle`;
181
- } | {
182
- type: `${typeof P}setFullscreen`;
183
- payload: {
184
- fullscreen: boolean;
185
- };
186
- } | {
187
- type: `${typeof P}setWidth`;
188
- payload: {
189
- width: number;
190
- };
191
- } | {
192
- type: `${typeof P}hydrate`;
193
- payload: {
194
- snapshot: CanvasState | null;
195
- };
196
- } | {
197
- type: `${typeof P}reset`;
198
- };
199
-
200
- /**
201
- * The store seam. The canvas never owns a second copy of its state: it reads
202
- * and writes through a CanvasStoreBinding.
203
- *
204
- * - A host WITH Redux mounts `canvasReducer` in its root reducer and binds it:
205
- * bindCanvasToReduxStore(store, (root) => root.canvasHost)
206
- * - A host WITHOUT Redux (a Vite tool, an Electron window) calls
207
- * createCanvasStore()
208
- * which runs the very same reducer in a tiny standalone store.
209
- */
210
-
211
- interface CanvasStoreBinding {
212
- getState(): CanvasState;
213
- dispatch(action: CanvasAction): void;
214
- subscribe(listener: () => void): () => void;
215
- }
216
-
217
- /**
218
- * Remembering the canvas between sessions — a table stake, never optional.
219
- *
220
- * The default port writes to localStorage under a versioned key. Items whose
221
- * kind opts out (`restore: false`, e.g. a live session that cannot come back)
222
- * are dropped from the snapshot, and panes they leave empty are dropped too.
223
- */
224
-
225
- interface CanvasPersistencePort {
226
- load(): CanvasState | null | Promise<CanvasState | null>;
227
- save(snapshot: CanvasState): void | Promise<void>;
228
- }
229
-
230
- /**
231
- * The canvas controller: the ONE imperative API every caller uses. It wraps a
232
- * store binding, validates what callers hand it (so the reducer stays pure and
233
- * trusting), and owns hydration + autosave.
234
- *
235
- * Nothing fails silently: a refused open (non-JSON data, unknown kind) is
236
- * reported through the error sink and returns false.
237
- */
238
-
239
- interface CanvasErrorReport {
240
- readonly code: "non-json-data" | "unknown-kind" | "persistence-load" | "persistence-save";
241
- readonly message: string;
242
- readonly detail?: unknown;
243
- }
244
- type CanvasErrorSink = (report: CanvasErrorReport) => void;
245
- interface CanvasController {
246
- readonly store: CanvasStoreBinding;
247
- getState(): CanvasState;
248
- open(input: CanvasOpenInput): CanvasItemId | null;
249
- update(itemId: CanvasItemId, patch: {
250
- data?: CanvasJson | undefined;
251
- title?: string | null | undefined;
252
- }): boolean;
253
- /** Gives an item a new identity in place (a draft that was saved and now has a durable id). */
254
- rekey(itemId: CanvasItemId, key: string): CanvasItemId | null;
255
- close(itemId: CanvasItemId): void;
256
- closeOthers(itemId: CanvasItemId): void;
257
- activate(itemId: CanvasItemId): void;
258
- focusPane(paneId: CanvasPaneId): void;
259
- moveItem(itemId: CanvasItemId, toPaneId: CanvasPaneId, index?: number): void;
260
- splitPane(paneId: CanvasPaneId, orientation: CanvasOrientation, moveItemId?: CanvasItemId): void;
261
- closePane(paneId: CanvasPaneId): void;
262
- resizeSplit(splitId: CanvasSplitId, sizes: readonly number[]): void;
263
- show(): void;
264
- hide(): void;
265
- toggle(): void;
266
- setFullscreen(fullscreen: boolean): void;
267
- setWidth(width: number): void;
268
- /** Is this exact thing on the canvas right now? */
269
- has(kind: string, key: string): boolean;
270
- /**
271
- * Is a canvas column on screen? A store can exist in a layout that shows no
272
- * column (a kiosk, a meeting stage); opening there must be refused aloud.
273
- */
274
- isPresented(): boolean;
275
- /** Called by a column on mount; returns the unmount callback. */
276
- registerPresentation(): () => void;
277
- subscribePresentation(listener: () => void): () => void;
278
- /** Loads the persisted snapshot and starts autosave. Returns a disposer. */
279
- start(): () => void;
280
- }
3
+ import { a as CanvasJson, e as CanvasItem, c as CanvasPaneId, l as CanvasController, u as CanvasStoreBinding, s as CanvasPersistencePort, o as CanvasErrorSink, d as CanvasState } from './controller-oY84BN2c.js';
281
4
 
282
5
  /**
283
6
  * THE canvas kind registry. A kind is one sort of thing the canvas can show —
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-matrx/canvas",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "The AI Matrx canvas: a docked right-hand column with split panes, tabs, full screen, a kind registry, Redux-compatible state and persistence.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",