@embedpdf/plugin-view-manager 2.0.0-next.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.
Files changed (61) hide show
  1. package/LICENSE +21 -0
  2. package/dist/index.cjs +2 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.js +549 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/lib/actions.d.ts +61 -0
  8. package/dist/lib/index.d.ts +9 -0
  9. package/dist/lib/manifest.d.ts +4 -0
  10. package/dist/lib/reducer.d.ts +5 -0
  11. package/dist/lib/types.d.ts +66 -0
  12. package/dist/lib/view-manager-plugin.d.ts +43 -0
  13. package/dist/preact/adapter.d.ts +5 -0
  14. package/dist/preact/core.d.ts +1 -0
  15. package/dist/preact/index.cjs +2 -0
  16. package/dist/preact/index.cjs.map +1 -0
  17. package/dist/preact/index.d.ts +1 -0
  18. package/dist/preact/index.js +141 -0
  19. package/dist/preact/index.js.map +1 -0
  20. package/dist/react/adapter.d.ts +2 -0
  21. package/dist/react/core.d.ts +1 -0
  22. package/dist/react/index.cjs +2 -0
  23. package/dist/react/index.cjs.map +1 -0
  24. package/dist/react/index.d.ts +1 -0
  25. package/dist/react/index.js +140 -0
  26. package/dist/react/index.js.map +1 -0
  27. package/dist/shared/components/index.d.ts +1 -0
  28. package/dist/shared/components/view-context.d.ts +23 -0
  29. package/dist/shared/hooks/index.d.ts +1 -0
  30. package/dist/shared/hooks/use-view-manager.d.ts +25 -0
  31. package/dist/shared/index.d.ts +3 -0
  32. package/dist/shared-preact/components/index.d.ts +1 -0
  33. package/dist/shared-preact/components/view-context.d.ts +23 -0
  34. package/dist/shared-preact/hooks/index.d.ts +1 -0
  35. package/dist/shared-preact/hooks/use-view-manager.d.ts +25 -0
  36. package/dist/shared-preact/index.d.ts +3 -0
  37. package/dist/shared-react/components/index.d.ts +1 -0
  38. package/dist/shared-react/components/view-context.d.ts +23 -0
  39. package/dist/shared-react/hooks/index.d.ts +1 -0
  40. package/dist/shared-react/hooks/use-view-manager.d.ts +25 -0
  41. package/dist/shared-react/index.d.ts +3 -0
  42. package/dist/svelte/components/ViewContext.svelte.d.ts +10 -0
  43. package/dist/svelte/components/index.d.ts +2 -0
  44. package/dist/svelte/components/types.d.ts +12 -0
  45. package/dist/svelte/hooks/index.d.ts +1 -0
  46. package/dist/svelte/hooks/use-view-manager.svelte.d.ts +30 -0
  47. package/dist/svelte/index.cjs +2 -0
  48. package/dist/svelte/index.cjs.map +1 -0
  49. package/dist/svelte/index.d.ts +3 -0
  50. package/dist/svelte/index.js +202 -0
  51. package/dist/svelte/index.js.map +1 -0
  52. package/dist/vue/components/index.d.ts +2 -0
  53. package/dist/vue/components/view-context.vue.d.ts +31 -0
  54. package/dist/vue/hooks/index.d.ts +1 -0
  55. package/dist/vue/hooks/use-view-manager.d.ts +39 -0
  56. package/dist/vue/index.cjs +2 -0
  57. package/dist/vue/index.cjs.map +1 -0
  58. package/dist/vue/index.d.ts +3 -0
  59. package/dist/vue/index.js +197 -0
  60. package/dist/vue/index.js.map +1 -0
  61. package/package.json +82 -0
package/dist/index.js ADDED
@@ -0,0 +1,549 @@
1
+ import { BasePlugin, createBehaviorEmitter } from "@embedpdf/core";
2
+ const CREATE_VIEW = "CREATE_VIEW";
3
+ const REMOVE_VIEW = "REMOVE_VIEW";
4
+ const ADD_DOCUMENT_TO_VIEW = "ADD_DOCUMENT_TO_VIEW";
5
+ const REMOVE_DOCUMENT_FROM_VIEW = "REMOVE_DOCUMENT_FROM_VIEW";
6
+ const MOVE_DOCUMENT_WITHIN_VIEW = "MOVE_DOCUMENT_WITHIN_VIEW";
7
+ const SET_VIEW_ACTIVE_DOCUMENT = "SET_VIEW_ACTIVE_DOCUMENT";
8
+ const SET_FOCUSED_VIEW = "SET_FOCUSED_VIEW";
9
+ function createView(viewId, createdAt) {
10
+ return { type: CREATE_VIEW, payload: { viewId, createdAt } };
11
+ }
12
+ function removeView(viewId) {
13
+ return { type: REMOVE_VIEW, payload: viewId };
14
+ }
15
+ function addDocumentToView(viewId, documentId, index) {
16
+ return { type: ADD_DOCUMENT_TO_VIEW, payload: { viewId, documentId, index } };
17
+ }
18
+ function removeDocumentFromView(viewId, documentId) {
19
+ return { type: REMOVE_DOCUMENT_FROM_VIEW, payload: { viewId, documentId } };
20
+ }
21
+ function moveDocumentWithinView(viewId, documentId, toIndex) {
22
+ return { type: MOVE_DOCUMENT_WITHIN_VIEW, payload: { viewId, documentId, toIndex } };
23
+ }
24
+ function setViewActiveDocument(viewId, documentId) {
25
+ return { type: SET_VIEW_ACTIVE_DOCUMENT, payload: { viewId, documentId } };
26
+ }
27
+ function setFocusedView(viewId) {
28
+ return { type: SET_FOCUSED_VIEW, payload: viewId };
29
+ }
30
+ const _ViewManagerPlugin = class _ViewManagerPlugin extends BasePlugin {
31
+ constructor(id, registry, config) {
32
+ super(id, registry);
33
+ this.id = id;
34
+ this.viewCreated$ = createBehaviorEmitter();
35
+ this.viewRemoved$ = createBehaviorEmitter();
36
+ this.viewFocusChanged$ = createBehaviorEmitter();
37
+ this.documentAddedToView$ = createBehaviorEmitter();
38
+ this.documentRemovedFromView$ = createBehaviorEmitter();
39
+ this.documentReordered$ = createBehaviorEmitter();
40
+ this.viewActiveDocumentChanged$ = createBehaviorEmitter();
41
+ }
42
+ buildCapability() {
43
+ return {
44
+ // View lifecycle
45
+ createView: (viewId) => this.createView(viewId),
46
+ removeView: (viewId) => this.removeView(viewId),
47
+ getAllViews: () => this.getAllViews(),
48
+ getViewCount: () => this.getViewCount(),
49
+ // Document management
50
+ addDocumentToView: (viewId, documentId, index) => this.addDocumentToView(viewId, documentId, index),
51
+ removeDocumentFromView: (viewId, documentId) => this.removeDocumentFromView(viewId, documentId),
52
+ moveDocumentWithinView: (viewId, documentId, toIndex) => this.moveDocumentWithinView(viewId, documentId, toIndex),
53
+ moveDocumentBetweenViews: (fromViewId, toViewId, documentId, toIndex) => this.moveDocumentBetweenViews(fromViewId, toViewId, documentId, toIndex),
54
+ setViewActiveDocument: (viewId, documentId) => this.setViewActiveDocument(viewId, documentId),
55
+ // Focus management
56
+ setFocusedView: (viewId) => this.setFocusedView(viewId),
57
+ getFocusedViewId: () => this.state.focusedViewId,
58
+ getFocusedView: () => this.getFocusedView(),
59
+ // Queries
60
+ getView: (viewId) => this.getView(viewId),
61
+ getViewDocuments: (viewId) => this.getViewDocuments(viewId),
62
+ getViewActiveDocument: (viewId) => this.getViewActiveDocument(viewId),
63
+ getDocumentView: (documentId) => this.getDocumentView(documentId),
64
+ isDocumentInAnyView: (documentId) => this.isDocumentInAnyView(documentId),
65
+ getUnassignedDocuments: (documentStates) => this.getUnassignedDocuments(documentStates),
66
+ // Events
67
+ onViewCreated: this.viewCreated$.on,
68
+ onViewRemoved: this.viewRemoved$.on,
69
+ onViewFocusChanged: this.viewFocusChanged$.on,
70
+ onDocumentAddedToView: this.documentAddedToView$.on,
71
+ onDocumentRemovedFromView: this.documentRemovedFromView$.on,
72
+ onDocumentReordered: this.documentReordered$.on,
73
+ onViewActiveDocumentChanged: this.viewActiveDocumentChanged$.on
74
+ };
75
+ }
76
+ // ─────────────────────────────────────────────────────────
77
+ // Plugin Lifecycle
78
+ // ─────────────────────────────────────────────────────────
79
+ async initialize(config) {
80
+ const docManager = this.registry.getPlugin("document-manager");
81
+ if (docManager && docManager.provides) {
82
+ this.docManagerCapability = docManager.provides();
83
+ this.docManagerCapability.onDocumentClosed((documentId) => {
84
+ const viewId = this.getDocumentView(documentId);
85
+ if (viewId) {
86
+ this.removeDocumentFromView(viewId, documentId);
87
+ }
88
+ });
89
+ }
90
+ if (config.defaultViewCount && config.defaultViewCount > 0) {
91
+ for (let i = 0; i < config.defaultViewCount; i++) {
92
+ this.createView(`view-${i + 1}`);
93
+ }
94
+ }
95
+ this.logger.info("ViewManagerPlugin", "Initialize", "View Manager Plugin initialized", {
96
+ defaultViewCount: config.defaultViewCount,
97
+ hasDocumentManager: !!this.docManagerCapability
98
+ });
99
+ }
100
+ async destroy() {
101
+ this.viewCreated$.clear();
102
+ this.viewRemoved$.clear();
103
+ this.viewFocusChanged$.clear();
104
+ this.documentAddedToView$.clear();
105
+ this.documentRemovedFromView$.clear();
106
+ this.documentReordered$.clear();
107
+ this.viewActiveDocumentChanged$.clear();
108
+ super.destroy();
109
+ }
110
+ // ─────────────────────────────────────────────────────────
111
+ // View Lifecycle
112
+ // ─────────────────────────────────────────────────────────
113
+ createView(viewId) {
114
+ const id = viewId || this.generateViewId();
115
+ if (this.state.views[id]) {
116
+ this.logger.warn("ViewManagerPlugin", "CreateView", `View ${id} already exists`);
117
+ return id;
118
+ }
119
+ this.dispatch(createView(id, Date.now()));
120
+ this.viewCreated$.emit(id);
121
+ this.logger.info("ViewManagerPlugin", "CreateView", `View ${id} created`);
122
+ return id;
123
+ }
124
+ removeView(viewId) {
125
+ const view = this.state.views[viewId];
126
+ if (!view) {
127
+ this.logger.warn("ViewManagerPlugin", "RemoveView", `View ${viewId} not found`);
128
+ return;
129
+ }
130
+ if (this.getViewCount() === 1) {
131
+ this.logger.warn("ViewManagerPlugin", "RemoveView", "Cannot remove the last view");
132
+ return;
133
+ }
134
+ this.dispatch(removeView(viewId));
135
+ this.viewRemoved$.emit(viewId);
136
+ this.logger.info("ViewManagerPlugin", "RemoveView", `View ${viewId} removed`);
137
+ }
138
+ // ─────────────────────────────────────────────────────────
139
+ // Document Assignment
140
+ // ─────────────────────────────────────────────────────────
141
+ // Document Management Methods
142
+ addDocumentToView(viewId, documentId, index) {
143
+ const view = this.state.views[viewId];
144
+ if (!view) {
145
+ throw new Error(`View ${viewId} not found`);
146
+ }
147
+ if (this.docManagerCapability) {
148
+ if (!this.docManagerCapability.isDocumentOpen(documentId)) {
149
+ throw new Error(`Document ${documentId} is not open`);
150
+ }
151
+ }
152
+ const previousViewId = this.getDocumentView(documentId);
153
+ let nextActiveDocumentIdForPreviousView;
154
+ if (previousViewId && previousViewId !== viewId) {
155
+ nextActiveDocumentIdForPreviousView = this.calculateNextActiveDocumentInView(
156
+ previousViewId,
157
+ documentId
158
+ );
159
+ }
160
+ const actualIndex = index ?? view.documentIds.length;
161
+ this.logger.info(
162
+ "ViewManagerPlugin",
163
+ "AddDocumentToView",
164
+ `Adding document ${documentId} to view ${viewId}`,
165
+ {
166
+ requestedIndex: index,
167
+ calculatedIndex: actualIndex,
168
+ currentDocumentIds: view.documentIds,
169
+ previousViewId
170
+ }
171
+ );
172
+ this.dispatch(addDocumentToView(viewId, documentId, actualIndex));
173
+ if (previousViewId && previousViewId !== viewId) {
174
+ if (nextActiveDocumentIdForPreviousView !== void 0) {
175
+ this.dispatch(setViewActiveDocument(previousViewId, nextActiveDocumentIdForPreviousView));
176
+ this.viewActiveDocumentChanged$.emit({
177
+ viewId: previousViewId,
178
+ previousDocumentId: documentId,
179
+ currentDocumentId: nextActiveDocumentIdForPreviousView
180
+ });
181
+ }
182
+ this.documentRemovedFromView$.emit({
183
+ viewId: previousViewId,
184
+ documentId
185
+ });
186
+ this.logger.info(
187
+ "ViewManagerPlugin",
188
+ "AddDocumentToView",
189
+ `Document ${documentId} moved from view ${previousViewId} to ${viewId}`
190
+ );
191
+ }
192
+ this.documentAddedToView$.emit({
193
+ viewId,
194
+ documentId,
195
+ index: actualIndex
196
+ });
197
+ this.logger.info(
198
+ "ViewManagerPlugin",
199
+ "AddDocumentToView",
200
+ `Document ${documentId} added to view ${viewId} at index ${actualIndex}`
201
+ );
202
+ }
203
+ removeDocumentFromView(viewId, documentId) {
204
+ const view = this.state.views[viewId];
205
+ if (!view) {
206
+ throw new Error(`View ${viewId} not found`);
207
+ }
208
+ if (!view.documentIds.includes(documentId)) {
209
+ this.logger.warn(
210
+ "ViewManagerPlugin",
211
+ "RemoveDocumentFromView",
212
+ `Document ${documentId} not in view ${viewId}`
213
+ );
214
+ return;
215
+ }
216
+ const nextActiveDocumentId = this.calculateNextActiveDocumentInView(viewId, documentId);
217
+ this.dispatch(removeDocumentFromView(viewId, documentId));
218
+ if (nextActiveDocumentId !== void 0) {
219
+ this.dispatch(setViewActiveDocument(viewId, nextActiveDocumentId));
220
+ this.viewActiveDocumentChanged$.emit({
221
+ viewId,
222
+ previousDocumentId: documentId,
223
+ currentDocumentId: nextActiveDocumentId
224
+ });
225
+ }
226
+ this.documentRemovedFromView$.emit({
227
+ viewId,
228
+ documentId
229
+ });
230
+ this.logger.info(
231
+ "ViewManagerPlugin",
232
+ "RemoveDocumentFromView",
233
+ `Document ${documentId} removed from view ${viewId}`
234
+ );
235
+ }
236
+ moveDocumentWithinView(viewId, documentId, toIndex) {
237
+ const view = this.state.views[viewId];
238
+ if (!view) {
239
+ throw new Error(`View ${viewId} not found`);
240
+ }
241
+ const fromIndex = view.documentIds.indexOf(documentId);
242
+ if (fromIndex === -1) {
243
+ throw new Error(`Document ${documentId} not found in view ${viewId}`);
244
+ }
245
+ if (toIndex < 0 || toIndex >= view.documentIds.length) {
246
+ throw new Error(`Invalid index ${toIndex}`);
247
+ }
248
+ this.dispatch(moveDocumentWithinView(viewId, documentId, toIndex));
249
+ this.documentReordered$.emit({
250
+ viewId,
251
+ documentId,
252
+ fromIndex,
253
+ toIndex
254
+ });
255
+ }
256
+ moveDocumentBetweenViews(fromViewId, toViewId, documentId, toIndex) {
257
+ this.addDocumentToView(toViewId, documentId, toIndex);
258
+ }
259
+ setViewActiveDocument(viewId, documentId) {
260
+ const view = this.state.views[viewId];
261
+ if (!view) {
262
+ throw new Error(`View ${viewId} not found`);
263
+ }
264
+ if (documentId !== null && !view.documentIds.includes(documentId)) {
265
+ throw new Error(`Document ${documentId} not in view ${viewId}`);
266
+ }
267
+ const previousDocumentId = view.activeDocumentId;
268
+ if (previousDocumentId === documentId) return;
269
+ this.dispatch(setViewActiveDocument(viewId, documentId));
270
+ this.viewActiveDocumentChanged$.emit({
271
+ viewId,
272
+ previousDocumentId,
273
+ currentDocumentId: documentId
274
+ });
275
+ }
276
+ // Query Methods
277
+ getViewDocuments(viewId) {
278
+ var _a;
279
+ return ((_a = this.state.views[viewId]) == null ? void 0 : _a.documentIds) ?? [];
280
+ }
281
+ getViewActiveDocument(viewId) {
282
+ var _a;
283
+ return ((_a = this.state.views[viewId]) == null ? void 0 : _a.activeDocumentId) ?? null;
284
+ }
285
+ getDocumentView(documentId) {
286
+ for (const viewId in this.state.views) {
287
+ if (this.state.views[viewId].documentIds.includes(documentId)) {
288
+ return viewId;
289
+ }
290
+ }
291
+ return null;
292
+ }
293
+ isDocumentInAnyView(documentId) {
294
+ return this.getDocumentView(documentId) !== null;
295
+ }
296
+ getUnassignedDocuments(documentStates) {
297
+ const assignedDocIds = new Set(Object.values(this.state.views).flatMap((v) => v.documentIds));
298
+ return documentStates.filter((doc) => !assignedDocIds.has(doc.id));
299
+ }
300
+ // ─────────────────────────────────────────────────────────
301
+ // Focus Management
302
+ // ─────────────────────────────────────────────────────────
303
+ setFocusedView(viewId) {
304
+ if (!this.state.views[viewId]) {
305
+ throw new Error(`View ${viewId} not found`);
306
+ }
307
+ const previousViewId = this.state.focusedViewId;
308
+ if (previousViewId === viewId) {
309
+ return;
310
+ }
311
+ this.dispatch(setFocusedView(viewId));
312
+ this.viewFocusChanged$.emit({
313
+ previousViewId,
314
+ currentViewId: viewId
315
+ });
316
+ this.logger.info(
317
+ "ViewManagerPlugin",
318
+ "SetFocusedView",
319
+ `Focus changed from ${previousViewId} to ${viewId}`
320
+ );
321
+ }
322
+ // ─────────────────────────────────────────────────────────
323
+ // Queries
324
+ // ─────────────────────────────────────────────────────────
325
+ getView(viewId) {
326
+ return this.state.views[viewId] ?? null;
327
+ }
328
+ getFocusedView() {
329
+ const focusedViewId = this.state.focusedViewId;
330
+ if (!focusedViewId) return null;
331
+ return this.getView(focusedViewId);
332
+ }
333
+ getAllViews() {
334
+ return this.state.viewOrder.map((viewId) => this.state.views[viewId]).filter((view) => view !== void 0);
335
+ }
336
+ getViewCount() {
337
+ return Object.keys(this.state.views).length;
338
+ }
339
+ // ─────────────────────────────────────────────────────────
340
+ // Helper Methods
341
+ // ─────────────────────────────────────────────────────────
342
+ /**
343
+ * Calculate the next active document when removing a document from a view
344
+ * Returns undefined if the document being removed is not the active document
345
+ * Returns the next document ID (left first, then right) or null if no documents remain
346
+ */
347
+ calculateNextActiveDocumentInView(viewId, removingDocumentId) {
348
+ const view = this.state.views[viewId];
349
+ if (!view) return void 0;
350
+ const currentActiveId = view.activeDocumentId;
351
+ if (currentActiveId !== removingDocumentId) {
352
+ return void 0;
353
+ }
354
+ const documentIds = view.documentIds;
355
+ const removingIndex = documentIds.indexOf(removingDocumentId);
356
+ if (removingIndex === -1) return void 0;
357
+ if (removingIndex > 0) {
358
+ return documentIds[removingIndex - 1];
359
+ } else if (removingIndex < documentIds.length - 1) {
360
+ return documentIds[removingIndex + 1];
361
+ } else {
362
+ return null;
363
+ }
364
+ }
365
+ generateViewId() {
366
+ return `view-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
367
+ }
368
+ };
369
+ _ViewManagerPlugin.id = "view-manager";
370
+ let ViewManagerPlugin = _ViewManagerPlugin;
371
+ const VIEW_MANAGER_PLUGIN_ID = "view-manager";
372
+ const manifest = {
373
+ id: VIEW_MANAGER_PLUGIN_ID,
374
+ name: "View Manager Plugin",
375
+ version: "1.0.0",
376
+ provides: ["view-manager"],
377
+ requires: [],
378
+ optional: ["document-manager"],
379
+ defaultConfig: {
380
+ enabled: true,
381
+ defaultViewCount: 1
382
+ }
383
+ };
384
+ const initialState = {
385
+ views: {},
386
+ viewOrder: [],
387
+ focusedViewId: null
388
+ };
389
+ const viewManagerReducer = (state = initialState, action) => {
390
+ switch (action.type) {
391
+ case CREATE_VIEW: {
392
+ const { viewId, createdAt } = action.payload;
393
+ if (state.views[viewId]) {
394
+ return state;
395
+ }
396
+ return {
397
+ ...state,
398
+ views: {
399
+ ...state.views,
400
+ [viewId]: {
401
+ id: viewId,
402
+ documentIds: [],
403
+ activeDocumentId: null,
404
+ createdAt
405
+ }
406
+ },
407
+ viewOrder: [...state.viewOrder, viewId],
408
+ focusedViewId: state.focusedViewId ?? viewId
409
+ };
410
+ }
411
+ case REMOVE_VIEW: {
412
+ const viewId = action.payload;
413
+ const { [viewId]: removed, ...remainingViews } = state.views;
414
+ let newFocusedViewId = state.focusedViewId;
415
+ if (state.focusedViewId === viewId) {
416
+ const remainingIds = state.viewOrder.filter((id) => id !== viewId);
417
+ newFocusedViewId = remainingIds.length > 0 ? remainingIds[0] : null;
418
+ }
419
+ return {
420
+ ...state,
421
+ views: remainingViews,
422
+ viewOrder: state.viewOrder.filter((id) => id !== viewId),
423
+ focusedViewId: newFocusedViewId
424
+ };
425
+ }
426
+ case ADD_DOCUMENT_TO_VIEW: {
427
+ const { viewId, documentId, index } = action.payload;
428
+ const view = state.views[viewId];
429
+ if (!view) return state;
430
+ const updatedViews = { ...state.views };
431
+ for (const vid in updatedViews) {
432
+ if (updatedViews[vid].documentIds.includes(documentId)) {
433
+ updatedViews[vid] = {
434
+ ...updatedViews[vid],
435
+ documentIds: updatedViews[vid].documentIds.filter((id) => id !== documentId)
436
+ // Don't modify activeDocumentId here - let the plugin handle it explicitly
437
+ };
438
+ }
439
+ }
440
+ const newDocumentIds = [...updatedViews[viewId].documentIds];
441
+ if (index !== void 0 && index >= 0 && index <= newDocumentIds.length) {
442
+ newDocumentIds.splice(index, 0, documentId);
443
+ } else {
444
+ newDocumentIds.push(documentId);
445
+ }
446
+ updatedViews[viewId] = {
447
+ ...updatedViews[viewId],
448
+ documentIds: newDocumentIds,
449
+ // Auto-set as active if it's the first document or no active document
450
+ activeDocumentId: updatedViews[viewId].activeDocumentId || documentId
451
+ };
452
+ return {
453
+ ...state,
454
+ views: updatedViews
455
+ };
456
+ }
457
+ case REMOVE_DOCUMENT_FROM_VIEW: {
458
+ const { viewId, documentId } = action.payload;
459
+ const view = state.views[viewId];
460
+ if (!view || !view.documentIds.includes(documentId)) return state;
461
+ const newDocumentIds = view.documentIds.filter((id) => id !== documentId);
462
+ return {
463
+ ...state,
464
+ views: {
465
+ ...state.views,
466
+ [viewId]: {
467
+ ...view,
468
+ documentIds: newDocumentIds
469
+ }
470
+ }
471
+ };
472
+ }
473
+ case MOVE_DOCUMENT_WITHIN_VIEW: {
474
+ const { viewId, documentId, toIndex } = action.payload;
475
+ const view = state.views[viewId];
476
+ if (!view || !view.documentIds.includes(documentId)) return state;
477
+ const fromIndex = view.documentIds.indexOf(documentId);
478
+ if (fromIndex === toIndex) return state;
479
+ const newDocumentIds = [...view.documentIds];
480
+ newDocumentIds.splice(fromIndex, 1);
481
+ newDocumentIds.splice(toIndex, 0, documentId);
482
+ return {
483
+ ...state,
484
+ views: {
485
+ ...state.views,
486
+ [viewId]: {
487
+ ...view,
488
+ documentIds: newDocumentIds
489
+ }
490
+ }
491
+ };
492
+ }
493
+ case SET_VIEW_ACTIVE_DOCUMENT: {
494
+ const { viewId, documentId } = action.payload;
495
+ const view = state.views[viewId];
496
+ if (!view) return state;
497
+ if (documentId !== null && !view.documentIds.includes(documentId)) return state;
498
+ return {
499
+ ...state,
500
+ views: {
501
+ ...state.views,
502
+ [viewId]: {
503
+ ...view,
504
+ activeDocumentId: documentId
505
+ }
506
+ }
507
+ };
508
+ }
509
+ case SET_FOCUSED_VIEW: {
510
+ const viewId = action.payload;
511
+ if (viewId !== null && !state.views[viewId]) {
512
+ return state;
513
+ }
514
+ return {
515
+ ...state,
516
+ focusedViewId: viewId
517
+ };
518
+ }
519
+ default:
520
+ return state;
521
+ }
522
+ };
523
+ const ViewManagerPluginPackage = {
524
+ manifest,
525
+ create: (registry, config) => new ViewManagerPlugin(VIEW_MANAGER_PLUGIN_ID, registry, config),
526
+ reducer: viewManagerReducer,
527
+ initialState
528
+ };
529
+ export {
530
+ ADD_DOCUMENT_TO_VIEW,
531
+ CREATE_VIEW,
532
+ MOVE_DOCUMENT_WITHIN_VIEW,
533
+ REMOVE_DOCUMENT_FROM_VIEW,
534
+ REMOVE_VIEW,
535
+ SET_FOCUSED_VIEW,
536
+ SET_VIEW_ACTIVE_DOCUMENT,
537
+ VIEW_MANAGER_PLUGIN_ID,
538
+ ViewManagerPlugin,
539
+ ViewManagerPluginPackage,
540
+ addDocumentToView,
541
+ createView,
542
+ manifest,
543
+ moveDocumentWithinView,
544
+ removeDocumentFromView,
545
+ removeView,
546
+ setFocusedView,
547
+ setViewActiveDocument
548
+ };
549
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/lib/actions.ts","../src/lib/view-manager-plugin.ts","../src/lib/manifest.ts","../src/lib/reducer.ts","../src/lib/index.ts"],"sourcesContent":["import { Action } from '@embedpdf/core';\n\nexport const CREATE_VIEW = 'CREATE_VIEW';\nexport const REMOVE_VIEW = 'REMOVE_VIEW';\nexport const ADD_DOCUMENT_TO_VIEW = 'ADD_DOCUMENT_TO_VIEW';\nexport const REMOVE_DOCUMENT_FROM_VIEW = 'REMOVE_DOCUMENT_FROM_VIEW';\nexport const MOVE_DOCUMENT_WITHIN_VIEW = 'MOVE_DOCUMENT_WITHIN_VIEW';\nexport const SET_VIEW_ACTIVE_DOCUMENT = 'SET_VIEW_ACTIVE_DOCUMENT';\nexport const SET_FOCUSED_VIEW = 'SET_FOCUSED_VIEW';\n\nexport interface CreateViewAction extends Action {\n type: typeof CREATE_VIEW;\n payload: {\n viewId: string;\n createdAt: number;\n };\n}\n\nexport interface RemoveViewAction extends Action {\n type: typeof REMOVE_VIEW;\n payload: string; // viewId\n}\n\nexport interface AddDocumentToViewAction extends Action {\n type: typeof ADD_DOCUMENT_TO_VIEW;\n payload: {\n viewId: string;\n documentId: string;\n index?: number;\n };\n}\n\nexport interface RemoveDocumentFromViewAction extends Action {\n type: typeof REMOVE_DOCUMENT_FROM_VIEW;\n payload: {\n viewId: string;\n documentId: string;\n };\n}\n\nexport interface MoveDocumentWithinViewAction extends Action {\n type: typeof MOVE_DOCUMENT_WITHIN_VIEW;\n payload: {\n viewId: string;\n documentId: string;\n toIndex: number;\n };\n}\n\nexport interface SetViewActiveDocumentAction extends Action {\n type: typeof SET_VIEW_ACTIVE_DOCUMENT;\n payload: {\n viewId: string;\n documentId: string | null;\n };\n}\n\nexport interface SetFocusedViewAction extends Action {\n type: typeof SET_FOCUSED_VIEW;\n payload: string | null; // viewId or null\n}\n\nexport type ViewManagerAction =\n | CreateViewAction\n | RemoveViewAction\n | AddDocumentToViewAction\n | RemoveDocumentFromViewAction\n | MoveDocumentWithinViewAction\n | SetViewActiveDocumentAction\n | SetFocusedViewAction;\n\nexport function createView(viewId: string, createdAt: number): CreateViewAction {\n return { type: CREATE_VIEW, payload: { viewId, createdAt } };\n}\n\nexport function removeView(viewId: string): RemoveViewAction {\n return { type: REMOVE_VIEW, payload: viewId };\n}\n\nexport function addDocumentToView(\n viewId: string,\n documentId: string,\n index?: number,\n): AddDocumentToViewAction {\n return { type: ADD_DOCUMENT_TO_VIEW, payload: { viewId, documentId, index } };\n}\n\nexport function removeDocumentFromView(\n viewId: string,\n documentId: string,\n): RemoveDocumentFromViewAction {\n return { type: REMOVE_DOCUMENT_FROM_VIEW, payload: { viewId, documentId } };\n}\n\nexport function moveDocumentWithinView(\n viewId: string,\n documentId: string,\n toIndex: number,\n): MoveDocumentWithinViewAction {\n return { type: MOVE_DOCUMENT_WITHIN_VIEW, payload: { viewId, documentId, toIndex } };\n}\n\nexport function setViewActiveDocument(\n viewId: string,\n documentId: string | null,\n): SetViewActiveDocumentAction {\n return { type: SET_VIEW_ACTIVE_DOCUMENT, payload: { viewId, documentId } };\n}\n\nexport function setFocusedView(viewId: string | null): SetFocusedViewAction {\n return { type: SET_FOCUSED_VIEW, payload: viewId };\n}\n","import { BasePlugin, PluginRegistry, createBehaviorEmitter, DocumentState } from '@embedpdf/core';\nimport type {\n DocumentManagerCapability,\n DocumentManagerPlugin,\n} from '@embedpdf/plugin-document-manager';\n\nimport {\n ViewManagerPluginConfig,\n ViewManagerState,\n ViewManagerCapability,\n View,\n ViewChangeEvent,\n ViewActiveDocumentChangedEvent,\n ViewDocumentReorderedEvent,\n ViewDocumentRemovedEvent,\n ViewDocumentAddedEvent,\n} from './types';\nimport {\n ViewManagerAction,\n createView as createViewAction,\n removeView as removeViewAction,\n setFocusedView as setFocusedViewAction,\n setViewActiveDocument,\n moveDocumentWithinView,\n removeDocumentFromView,\n addDocumentToView,\n} from './actions';\n\nexport class ViewManagerPlugin extends BasePlugin<\n ViewManagerPluginConfig,\n ViewManagerCapability,\n ViewManagerState,\n ViewManagerAction\n> {\n static readonly id = 'view-manager' as const;\n\n private readonly viewCreated$ = createBehaviorEmitter<string>();\n private readonly viewRemoved$ = createBehaviorEmitter<string>();\n private readonly viewFocusChanged$ = createBehaviorEmitter<ViewChangeEvent>();\n private readonly documentAddedToView$ = createBehaviorEmitter<ViewDocumentAddedEvent>();\n private readonly documentRemovedFromView$ = createBehaviorEmitter<ViewDocumentRemovedEvent>();\n private readonly documentReordered$ = createBehaviorEmitter<ViewDocumentReorderedEvent>();\n private readonly viewActiveDocumentChanged$ =\n createBehaviorEmitter<ViewActiveDocumentChangedEvent>();\n\n // Optional integration with DocumentManager\n private docManagerCapability?: DocumentManagerCapability;\n\n constructor(\n public readonly id: string,\n registry: PluginRegistry,\n config?: ViewManagerPluginConfig,\n ) {\n super(id, registry);\n }\n\n protected buildCapability(): ViewManagerCapability {\n return {\n // View lifecycle\n createView: (viewId) => this.createView(viewId),\n removeView: (viewId) => this.removeView(viewId),\n getAllViews: () => this.getAllViews(),\n getViewCount: () => this.getViewCount(),\n\n // Document management\n addDocumentToView: (viewId, documentId, index) =>\n this.addDocumentToView(viewId, documentId, index),\n removeDocumentFromView: (viewId, documentId) =>\n this.removeDocumentFromView(viewId, documentId),\n moveDocumentWithinView: (viewId, documentId, toIndex) =>\n this.moveDocumentWithinView(viewId, documentId, toIndex),\n moveDocumentBetweenViews: (fromViewId, toViewId, documentId, toIndex) =>\n this.moveDocumentBetweenViews(fromViewId, toViewId, documentId, toIndex),\n setViewActiveDocument: (viewId, documentId) => this.setViewActiveDocument(viewId, documentId),\n\n // Focus management\n setFocusedView: (viewId) => this.setFocusedView(viewId),\n getFocusedViewId: () => this.state.focusedViewId,\n getFocusedView: () => this.getFocusedView(),\n\n // Queries\n getView: (viewId) => this.getView(viewId),\n getViewDocuments: (viewId) => this.getViewDocuments(viewId),\n getViewActiveDocument: (viewId) => this.getViewActiveDocument(viewId),\n getDocumentView: (documentId) => this.getDocumentView(documentId),\n isDocumentInAnyView: (documentId) => this.isDocumentInAnyView(documentId),\n getUnassignedDocuments: (documentStates) => this.getUnassignedDocuments(documentStates),\n\n // Events\n onViewCreated: this.viewCreated$.on,\n onViewRemoved: this.viewRemoved$.on,\n onViewFocusChanged: this.viewFocusChanged$.on,\n onDocumentAddedToView: this.documentAddedToView$.on,\n onDocumentRemovedFromView: this.documentRemovedFromView$.on,\n onDocumentReordered: this.documentReordered$.on,\n onViewActiveDocumentChanged: this.viewActiveDocumentChanged$.on,\n };\n }\n\n // ─────────────────────────────────────────────────────────\n // Plugin Lifecycle\n // ─────────────────────────────────────────────────────────\n\n async initialize(config: ViewManagerPluginConfig): Promise<void> {\n // Try to get DocumentManager if it exists (optional dependency)\n const docManager = this.registry.getPlugin<DocumentManagerPlugin>('document-manager');\n if (docManager && docManager.provides) {\n this.docManagerCapability = docManager.provides();\n\n this.docManagerCapability.onDocumentClosed((documentId) => {\n const viewId = this.getDocumentView(documentId);\n if (viewId) {\n this.removeDocumentFromView(viewId, documentId);\n }\n });\n }\n\n // Create default views if configured\n if (config.defaultViewCount && config.defaultViewCount > 0) {\n for (let i = 0; i < config.defaultViewCount; i++) {\n this.createView(`view-${i + 1}`);\n }\n }\n\n this.logger.info('ViewManagerPlugin', 'Initialize', 'View Manager Plugin initialized', {\n defaultViewCount: config.defaultViewCount,\n hasDocumentManager: !!this.docManagerCapability,\n });\n }\n\n async destroy(): Promise<void> {\n // Clear all emitters\n this.viewCreated$.clear();\n this.viewRemoved$.clear();\n this.viewFocusChanged$.clear();\n this.documentAddedToView$.clear();\n this.documentRemovedFromView$.clear();\n this.documentReordered$.clear();\n this.viewActiveDocumentChanged$.clear();\n\n super.destroy();\n }\n\n // ─────────────────────────────────────────────────────────\n // View Lifecycle\n // ─────────────────────────────────────────────────────────\n\n private createView(viewId?: string): string {\n const id = viewId || this.generateViewId();\n\n if (this.state.views[id]) {\n this.logger.warn('ViewManagerPlugin', 'CreateView', `View ${id} already exists`);\n return id;\n }\n\n this.dispatch(createViewAction(id, Date.now()));\n this.viewCreated$.emit(id);\n\n this.logger.info('ViewManagerPlugin', 'CreateView', `View ${id} created`);\n\n return id;\n }\n\n private removeView(viewId: string): void {\n const view = this.state.views[viewId];\n\n if (!view) {\n this.logger.warn('ViewManagerPlugin', 'RemoveView', `View ${viewId} not found`);\n return;\n }\n\n // Don't allow removing the last view\n if (this.getViewCount() === 1) {\n this.logger.warn('ViewManagerPlugin', 'RemoveView', 'Cannot remove the last view');\n return;\n }\n\n this.dispatch(removeViewAction(viewId));\n this.viewRemoved$.emit(viewId);\n\n this.logger.info('ViewManagerPlugin', 'RemoveView', `View ${viewId} removed`);\n }\n\n // ─────────────────────────────────────────────────────────\n // Document Assignment\n // ─────────────────────────────────────────────────────────\n\n // Document Management Methods\n private addDocumentToView(viewId: string, documentId: string, index?: number): void {\n const view = this.state.views[viewId];\n if (!view) {\n throw new Error(`View ${viewId} not found`);\n }\n\n // Validate document exists if DocumentManager is present\n if (this.docManagerCapability) {\n if (!this.docManagerCapability.isDocumentOpen(documentId)) {\n throw new Error(`Document ${documentId} is not open`);\n }\n }\n\n // Check if document is already in another view (before state update)\n const previousViewId = this.getDocumentView(documentId);\n\n // Calculate next active document for the previous view if needed\n let nextActiveDocumentIdForPreviousView: string | null | undefined;\n if (previousViewId && previousViewId !== viewId) {\n nextActiveDocumentIdForPreviousView = this.calculateNextActiveDocumentInView(\n previousViewId,\n documentId,\n );\n }\n\n // Calculate the actual index - must account for the document being removed from this view\n // if it was already here (though we checked above, the reducer also handles this)\n const actualIndex = index ?? view.documentIds.length;\n\n this.logger.info(\n 'ViewManagerPlugin',\n 'AddDocumentToView',\n `Adding document ${documentId} to view ${viewId}`,\n {\n requestedIndex: index,\n calculatedIndex: actualIndex,\n currentDocumentIds: view.documentIds,\n previousViewId,\n },\n );\n\n this.dispatch(addDocumentToView(viewId, documentId, actualIndex));\n\n // Handle the previous view if document was moved\n if (previousViewId && previousViewId !== viewId) {\n // Set the next active document in the previous view if needed\n if (nextActiveDocumentIdForPreviousView !== undefined) {\n this.dispatch(setViewActiveDocument(previousViewId, nextActiveDocumentIdForPreviousView));\n\n // Emit active document changed event for the previous view\n this.viewActiveDocumentChanged$.emit({\n viewId: previousViewId,\n previousDocumentId: documentId,\n currentDocumentId: nextActiveDocumentIdForPreviousView,\n });\n }\n\n // Emit removal event\n this.documentRemovedFromView$.emit({\n viewId: previousViewId,\n documentId,\n });\n\n this.logger.info(\n 'ViewManagerPlugin',\n 'AddDocumentToView',\n `Document ${documentId} moved from view ${previousViewId} to ${viewId}`,\n );\n }\n\n // Emit addition event\n this.documentAddedToView$.emit({\n viewId,\n documentId,\n index: actualIndex,\n });\n\n this.logger.info(\n 'ViewManagerPlugin',\n 'AddDocumentToView',\n `Document ${documentId} added to view ${viewId} at index ${actualIndex}`,\n );\n }\n\n private removeDocumentFromView(viewId: string, documentId: string): void {\n const view = this.state.views[viewId];\n if (!view) {\n throw new Error(`View ${viewId} not found`);\n }\n\n if (!view.documentIds.includes(documentId)) {\n this.logger.warn(\n 'ViewManagerPlugin',\n 'RemoveDocumentFromView',\n `Document ${documentId} not in view ${viewId}`,\n );\n return;\n }\n\n // Calculate next active document if we're removing the currently active one\n const nextActiveDocumentId = this.calculateNextActiveDocumentInView(viewId, documentId);\n\n this.dispatch(removeDocumentFromView(viewId, documentId));\n\n // Set the next active document if needed\n if (nextActiveDocumentId !== undefined) {\n this.dispatch(setViewActiveDocument(viewId, nextActiveDocumentId));\n\n // Emit active document changed event\n this.viewActiveDocumentChanged$.emit({\n viewId,\n previousDocumentId: documentId,\n currentDocumentId: nextActiveDocumentId,\n });\n }\n\n this.documentRemovedFromView$.emit({\n viewId,\n documentId,\n });\n\n this.logger.info(\n 'ViewManagerPlugin',\n 'RemoveDocumentFromView',\n `Document ${documentId} removed from view ${viewId}`,\n );\n }\n\n private moveDocumentWithinView(viewId: string, documentId: string, toIndex: number): void {\n const view = this.state.views[viewId];\n if (!view) {\n throw new Error(`View ${viewId} not found`);\n }\n\n const fromIndex = view.documentIds.indexOf(documentId);\n if (fromIndex === -1) {\n throw new Error(`Document ${documentId} not found in view ${viewId}`);\n }\n\n if (toIndex < 0 || toIndex >= view.documentIds.length) {\n throw new Error(`Invalid index ${toIndex}`);\n }\n\n this.dispatch(moveDocumentWithinView(viewId, documentId, toIndex));\n\n this.documentReordered$.emit({\n viewId,\n documentId,\n fromIndex,\n toIndex,\n });\n }\n\n private moveDocumentBetweenViews(\n fromViewId: string,\n toViewId: string,\n documentId: string,\n toIndex?: number,\n ): void {\n // Just use addDocumentToView - it handles removing from the source view\n // and all the next active document calculations\n this.addDocumentToView(toViewId, documentId, toIndex);\n }\n\n private setViewActiveDocument(viewId: string, documentId: string | null): void {\n const view = this.state.views[viewId];\n if (!view) {\n throw new Error(`View ${viewId} not found`);\n }\n\n if (documentId !== null && !view.documentIds.includes(documentId)) {\n throw new Error(`Document ${documentId} not in view ${viewId}`);\n }\n\n const previousDocumentId = view.activeDocumentId;\n if (previousDocumentId === documentId) return;\n\n this.dispatch(setViewActiveDocument(viewId, documentId));\n\n this.viewActiveDocumentChanged$.emit({\n viewId,\n previousDocumentId,\n currentDocumentId: documentId,\n });\n }\n\n // Query Methods\n private getViewDocuments(viewId: string): string[] {\n return this.state.views[viewId]?.documentIds ?? [];\n }\n\n private getViewActiveDocument(viewId: string): string | null {\n return this.state.views[viewId]?.activeDocumentId ?? null;\n }\n\n private getDocumentView(documentId: string): string | null {\n for (const viewId in this.state.views) {\n if (this.state.views[viewId].documentIds.includes(documentId)) {\n return viewId;\n }\n }\n return null;\n }\n\n private isDocumentInAnyView(documentId: string): boolean {\n return this.getDocumentView(documentId) !== null;\n }\n\n private getUnassignedDocuments(documentStates: DocumentState[]): DocumentState[] {\n const assignedDocIds = new Set(Object.values(this.state.views).flatMap((v) => v.documentIds));\n\n return documentStates.filter((doc) => !assignedDocIds.has(doc.id));\n }\n\n // ─────────────────────────────────────────────────────────\n // Focus Management\n // ─────────────────────────────────────────────────────────\n\n private setFocusedView(viewId: string): void {\n if (!this.state.views[viewId]) {\n throw new Error(`View ${viewId} not found`);\n }\n\n const previousViewId = this.state.focusedViewId;\n\n if (previousViewId === viewId) {\n return; // Already focused\n }\n\n this.dispatch(setFocusedViewAction(viewId));\n\n this.viewFocusChanged$.emit({\n previousViewId,\n currentViewId: viewId,\n });\n\n this.logger.info(\n 'ViewManagerPlugin',\n 'SetFocusedView',\n `Focus changed from ${previousViewId} to ${viewId}`,\n );\n }\n\n // ─────────────────────────────────────────────────────────\n // Queries\n // ─────────────────────────────────────────────────────────\n\n private getView(viewId: string): View | null {\n return this.state.views[viewId] ?? null;\n }\n\n private getFocusedView(): View | null {\n const focusedViewId = this.state.focusedViewId;\n if (!focusedViewId) return null;\n return this.getView(focusedViewId);\n }\n\n private getAllViews(): View[] {\n return this.state.viewOrder\n .map((viewId) => this.state.views[viewId])\n .filter((view): view is View => view !== undefined);\n }\n\n private getViewCount(): number {\n return Object.keys(this.state.views).length;\n }\n\n // ─────────────────────────────────────────────────────────\n // Helper Methods\n // ─────────────────────────────────────────────────────────\n\n /**\n * Calculate the next active document when removing a document from a view\n * Returns undefined if the document being removed is not the active document\n * Returns the next document ID (left first, then right) or null if no documents remain\n */\n private calculateNextActiveDocumentInView(\n viewId: string,\n removingDocumentId: string,\n ): string | null | undefined {\n const view = this.state.views[viewId];\n if (!view) return undefined;\n\n const currentActiveId = view.activeDocumentId;\n\n // Only calculate if we're removing the active document\n if (currentActiveId !== removingDocumentId) {\n return undefined;\n }\n\n const documentIds = view.documentIds;\n const removingIndex = documentIds.indexOf(removingDocumentId);\n\n if (removingIndex === -1) return undefined;\n\n // Try left first, then right, then null\n if (removingIndex > 0) {\n return documentIds[removingIndex - 1];\n } else if (removingIndex < documentIds.length - 1) {\n return documentIds[removingIndex + 1];\n } else {\n return null;\n }\n }\n\n private generateViewId(): string {\n return `view-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n}\n","import { PluginManifest } from '@embedpdf/core';\nimport { ViewManagerPluginConfig } from './types';\n\nexport const VIEW_MANAGER_PLUGIN_ID = 'view-manager';\n\nexport const manifest: PluginManifest<ViewManagerPluginConfig> = {\n id: VIEW_MANAGER_PLUGIN_ID,\n name: 'View Manager Plugin',\n version: '1.0.0',\n provides: ['view-manager'],\n requires: [],\n optional: ['document-manager'],\n defaultConfig: {\n enabled: true,\n defaultViewCount: 1,\n },\n};\n","import { Reducer } from '@embedpdf/core';\nimport { ViewManagerState } from './types';\nimport {\n ViewManagerAction,\n CREATE_VIEW,\n REMOVE_VIEW,\n SET_FOCUSED_VIEW,\n ADD_DOCUMENT_TO_VIEW,\n REMOVE_DOCUMENT_FROM_VIEW,\n MOVE_DOCUMENT_WITHIN_VIEW,\n SET_VIEW_ACTIVE_DOCUMENT,\n} from './actions';\n\nexport const initialState: ViewManagerState = {\n views: {},\n viewOrder: [],\n focusedViewId: null,\n};\n\nexport const viewManagerReducer: Reducer<ViewManagerState, ViewManagerAction> = (\n state = initialState,\n action,\n) => {\n switch (action.type) {\n case CREATE_VIEW: {\n const { viewId, createdAt } = action.payload;\n\n if (state.views[viewId]) {\n return state;\n }\n\n return {\n ...state,\n views: {\n ...state.views,\n [viewId]: {\n id: viewId,\n documentIds: [],\n activeDocumentId: null,\n createdAt,\n },\n },\n viewOrder: [...state.viewOrder, viewId],\n focusedViewId: state.focusedViewId ?? viewId,\n };\n }\n\n case REMOVE_VIEW: {\n const viewId = action.payload;\n const { [viewId]: removed, ...remainingViews } = state.views;\n\n let newFocusedViewId = state.focusedViewId;\n if (state.focusedViewId === viewId) {\n const remainingIds = state.viewOrder.filter((id) => id !== viewId);\n newFocusedViewId = remainingIds.length > 0 ? remainingIds[0] : null;\n }\n\n return {\n ...state,\n views: remainingViews,\n viewOrder: state.viewOrder.filter((id) => id !== viewId),\n focusedViewId: newFocusedViewId,\n };\n }\n\n case ADD_DOCUMENT_TO_VIEW: {\n const { viewId, documentId, index } = action.payload;\n const view = state.views[viewId];\n\n if (!view) return state;\n\n // Remove document from any other view first\n const updatedViews = { ...state.views };\n for (const vid in updatedViews) {\n if (updatedViews[vid].documentIds.includes(documentId)) {\n updatedViews[vid] = {\n ...updatedViews[vid],\n documentIds: updatedViews[vid].documentIds.filter((id) => id !== documentId),\n // Don't modify activeDocumentId here - let the plugin handle it explicitly\n };\n }\n }\n\n // Add to target view\n const newDocumentIds = [...updatedViews[viewId].documentIds];\n if (index !== undefined && index >= 0 && index <= newDocumentIds.length) {\n newDocumentIds.splice(index, 0, documentId);\n } else {\n newDocumentIds.push(documentId);\n }\n\n updatedViews[viewId] = {\n ...updatedViews[viewId],\n documentIds: newDocumentIds,\n // Auto-set as active if it's the first document or no active document\n activeDocumentId: updatedViews[viewId].activeDocumentId || documentId,\n };\n\n return {\n ...state,\n views: updatedViews,\n };\n }\n\n case REMOVE_DOCUMENT_FROM_VIEW: {\n const { viewId, documentId } = action.payload;\n const view = state.views[viewId];\n\n if (!view || !view.documentIds.includes(documentId)) return state;\n\n const newDocumentIds = view.documentIds.filter((id) => id !== documentId);\n\n // Don't modify activeDocumentId here - let the plugin handle it explicitly\n return {\n ...state,\n views: {\n ...state.views,\n [viewId]: {\n ...view,\n documentIds: newDocumentIds,\n },\n },\n };\n }\n\n case MOVE_DOCUMENT_WITHIN_VIEW: {\n const { viewId, documentId, toIndex } = action.payload;\n const view = state.views[viewId];\n\n if (!view || !view.documentIds.includes(documentId)) return state;\n\n const fromIndex = view.documentIds.indexOf(documentId);\n if (fromIndex === toIndex) return state;\n\n const newDocumentIds = [...view.documentIds];\n newDocumentIds.splice(fromIndex, 1);\n newDocumentIds.splice(toIndex, 0, documentId);\n\n return {\n ...state,\n views: {\n ...state.views,\n [viewId]: {\n ...view,\n documentIds: newDocumentIds,\n },\n },\n };\n }\n\n case SET_VIEW_ACTIVE_DOCUMENT: {\n const { viewId, documentId } = action.payload;\n const view = state.views[viewId];\n\n if (!view) return state;\n if (documentId !== null && !view.documentIds.includes(documentId)) return state;\n\n return {\n ...state,\n views: {\n ...state.views,\n [viewId]: {\n ...view,\n activeDocumentId: documentId,\n },\n },\n };\n }\n\n case SET_FOCUSED_VIEW: {\n const viewId = action.payload;\n\n if (viewId !== null && !state.views[viewId]) {\n return state;\n }\n\n return {\n ...state,\n focusedViewId: viewId,\n };\n }\n\n default:\n return state;\n }\n};\n","import { PluginPackage } from '@embedpdf/core';\nimport { ViewManagerPlugin } from './view-manager-plugin';\nimport { manifest, VIEW_MANAGER_PLUGIN_ID } from './manifest';\nimport { ViewManagerPluginConfig, ViewManagerState } from './types';\nimport { viewManagerReducer, initialState } from './reducer';\nimport { ViewManagerAction } from './actions';\n\nexport const ViewManagerPluginPackage: PluginPackage<\n ViewManagerPlugin,\n ViewManagerPluginConfig,\n ViewManagerState,\n ViewManagerAction\n> = {\n manifest,\n create: (registry, config) => new ViewManagerPlugin(VIEW_MANAGER_PLUGIN_ID, registry, config),\n reducer: viewManagerReducer,\n initialState,\n};\n\nexport * from './view-manager-plugin';\nexport * from './types';\nexport * from './manifest';\nexport * from './actions';\n"],"names":["createViewAction","removeViewAction","setFocusedViewAction"],"mappings":"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"}