@embedpdf/plugin-interaction-manager 1.0.11 → 1.0.13

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 (56) hide show
  1. package/dist/index.cjs +2 -359
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.ts +1 -177
  4. package/dist/index.js +42 -42
  5. package/dist/index.js.map +1 -1
  6. package/dist/lib/actions.d.ts +28 -0
  7. package/dist/lib/helper.d.ts +2 -0
  8. package/dist/lib/index.d.ts +9 -0
  9. package/dist/lib/interaction-manager-plugin.d.ts +38 -0
  10. package/dist/lib/manifest.d.ts +4 -0
  11. package/dist/lib/reducer.d.ts +5 -0
  12. package/dist/{index.d.cts → lib/types.d.ts} +14 -83
  13. package/dist/preact/adapter.d.ts +4 -0
  14. package/dist/preact/core.d.ts +1 -0
  15. package/dist/preact/index.cjs +2 -258
  16. package/dist/preact/index.cjs.map +1 -1
  17. package/dist/preact/index.d.ts +1 -58
  18. package/dist/preact/index.js +85 -40
  19. package/dist/preact/index.js.map +1 -1
  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 -258
  23. package/dist/react/index.cjs.map +1 -1
  24. package/dist/react/index.d.ts +1 -55
  25. package/dist/react/index.js +85 -38
  26. package/dist/react/index.js.map +1 -1
  27. package/dist/shared-preact/components/global-pointer-provider.d.ts +7 -0
  28. package/dist/shared-preact/components/index.d.ts +2 -0
  29. package/dist/shared-preact/components/page-pointer-provider.d.ts +14 -0
  30. package/dist/shared-preact/hooks/index.d.ts +1 -0
  31. package/dist/shared-preact/hooks/use-interaction-manager.d.ts +31 -0
  32. package/dist/shared-preact/index.d.ts +2 -0
  33. package/dist/shared-preact/utils.d.ts +8 -0
  34. package/dist/shared-react/components/global-pointer-provider.d.ts +7 -0
  35. package/dist/shared-react/components/index.d.ts +2 -0
  36. package/dist/shared-react/components/page-pointer-provider.d.ts +14 -0
  37. package/dist/shared-react/hooks/index.d.ts +1 -0
  38. package/dist/shared-react/hooks/use-interaction-manager.d.ts +31 -0
  39. package/dist/shared-react/index.d.ts +2 -0
  40. package/dist/shared-react/utils.d.ts +8 -0
  41. package/dist/shared-vue/utils.d.ts +8 -0
  42. package/dist/vue/components/global-pointer-provider.vue.d.ts +12 -0
  43. package/dist/vue/components/index.d.ts +2 -0
  44. package/dist/vue/components/page-pointer-provider.vue.d.ts +21 -0
  45. package/dist/vue/hooks/index.d.ts +1 -0
  46. package/dist/vue/hooks/use-interaction-manager.d.ts +31 -0
  47. package/dist/vue/index.cjs +2 -0
  48. package/dist/vue/index.cjs.map +1 -0
  49. package/dist/vue/index.d.ts +2 -0
  50. package/dist/vue/index.js +224 -0
  51. package/dist/vue/index.js.map +1 -0
  52. package/package.json +19 -11
  53. package/dist/chunk-Z7V2G6MS.js +0 -64
  54. package/dist/chunk-Z7V2G6MS.js.map +0 -1
  55. package/dist/preact/index.d.cts +0 -58
  56. package/dist/react/index.d.cts +0 -55
package/dist/index.cjs CHANGED
@@ -1,359 +1,2 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
23
- INTERACTION_MANAGER_PLUGIN_ID: () => INTERACTION_MANAGER_PLUGIN_ID,
24
- InteractionManagerPlugin: () => InteractionManagerPlugin,
25
- InteractionManagerPluginPackage: () => InteractionManagerPluginPackage,
26
- initialState: () => initialState,
27
- manifest: () => manifest,
28
- reducer: () => reducer
29
- });
30
- module.exports = __toCommonJS(index_exports);
31
-
32
- // src/lib/interaction-manager-plugin.ts
33
- var import_core = require("@embedpdf/core");
34
-
35
- // src/lib/actions.ts
36
- var ACTIVATE_MODE = "INTERACTION/ACTIVATE_MODE";
37
- var PAUSE_INTERACTION = "INTERACTION/PAUSE";
38
- var RESUME_INTERACTION = "INTERACTION/RESUME";
39
- var SET_CURSOR = "INTERACTION/SET_CURSOR";
40
- var activateMode = (mode) => ({
41
- type: ACTIVATE_MODE,
42
- payload: { mode }
43
- });
44
- var setCursor = (cursor) => ({
45
- type: SET_CURSOR,
46
- payload: { cursor }
47
- });
48
- var pauseInteraction = () => ({
49
- type: PAUSE_INTERACTION
50
- });
51
- var resumeInteraction = () => ({
52
- type: RESUME_INTERACTION
53
- });
54
-
55
- // src/lib/helper.ts
56
- function mergeHandlers(list) {
57
- const keys = [
58
- "onPointerDown",
59
- "onPointerUp",
60
- "onPointerMove",
61
- "onPointerEnter",
62
- "onPointerLeave",
63
- "onPointerCancel"
64
- ];
65
- const out = {};
66
- for (const k of keys) {
67
- out[k] = (evt, nativeEvt, modeId) => {
68
- for (const h of list) h[k]?.(evt, nativeEvt, modeId);
69
- };
70
- }
71
- return out;
72
- }
73
-
74
- // src/lib/interaction-manager-plugin.ts
75
- var InteractionManagerPlugin = class extends import_core.BasePlugin {
76
- constructor(id, registry) {
77
- super(id, registry);
78
- this.modes = /* @__PURE__ */ new Map();
79
- this.cursorClaims = /* @__PURE__ */ new Map();
80
- this.buckets = /* @__PURE__ */ new Map();
81
- this.alwaysGlobal = /* @__PURE__ */ new Set();
82
- this.alwaysPage = /* @__PURE__ */ new Map();
83
- this.onModeChange$ = (0, import_core.createEmitter)();
84
- this.onHandlerChange$ = (0, import_core.createEmitter)();
85
- this.onCursorChange$ = (0, import_core.createEmitter)();
86
- this.onStateChange$ = (0, import_core.createBehaviorEmitter)();
87
- this.registerMode({
88
- id: "default",
89
- scope: "page",
90
- exclusive: false,
91
- cursor: "auto"
92
- });
93
- }
94
- async initialize(_) {
95
- }
96
- buildCapability() {
97
- return {
98
- activate: (modeId) => this.activate(modeId),
99
- onModeChange: this.onModeChange$.on,
100
- onCursorChange: this.onCursorChange$.on,
101
- onHandlerChange: this.onHandlerChange$.on,
102
- onStateChange: this.onStateChange$.on,
103
- getActiveMode: () => this.state.activeMode,
104
- getActiveInteractionMode: () => this.getActiveInteractionMode(),
105
- finish: () => this.activate("default"),
106
- registerMode: (mode) => this.registerMode(mode),
107
- registerHandlers: (options) => this.registerHandlers(options),
108
- registerAlways: (options) => this.registerAlways(options),
109
- setCursor: (token, cursor, priority = 0) => this.setCursor(token, cursor, priority),
110
- removeCursor: (token) => this.removeCursor(token),
111
- getCurrentCursor: () => this.state.cursor,
112
- getHandlersForScope: (scope) => this.getHandlersForScope(scope),
113
- activeModeIsExclusive: () => this.activeModeIsExclusive(),
114
- pause: () => this.dispatch(pauseInteraction()),
115
- resume: () => this.dispatch(resumeInteraction()),
116
- isPaused: () => this.state.paused
117
- };
118
- }
119
- activate(mode) {
120
- if (!this.modes.has(mode)) {
121
- throw new Error(`[interaction] unknown mode '${mode}'`);
122
- }
123
- if (mode === this.state.activeMode) return;
124
- const previousMode = this.state.activeMode;
125
- this.cursorClaims.clear();
126
- this.notifyHandlersInactive(previousMode);
127
- this.dispatch(activateMode(mode));
128
- this.emitCursor();
129
- this.notifyHandlersActive(mode);
130
- this.onModeChange$.emit({ ...this.state, activeMode: mode });
131
- }
132
- notifyHandlersActive(modeId) {
133
- this.alwaysGlobal.forEach((handler) => {
134
- handler.onHandlerActiveStart?.(modeId);
135
- });
136
- this.alwaysPage.forEach((handlerSet) => {
137
- handlerSet.forEach((handler) => {
138
- handler.onHandlerActiveStart?.(modeId);
139
- });
140
- });
141
- const mode = this.modes.get(modeId);
142
- if (!mode) return;
143
- const bucket = this.buckets.get(modeId);
144
- if (!bucket) return;
145
- if (mode.scope === "global") {
146
- bucket.global.forEach((handler) => {
147
- handler.onHandlerActiveStart?.(modeId);
148
- });
149
- }
150
- if (mode.scope === "page") {
151
- bucket.page.forEach((handlerSet, pageIndex) => {
152
- handlerSet.forEach((handler) => {
153
- handler.onHandlerActiveStart?.(modeId);
154
- });
155
- });
156
- }
157
- }
158
- notifyHandlersInactive(modeId) {
159
- this.alwaysGlobal.forEach((handler) => {
160
- handler.onHandlerActiveEnd?.(modeId);
161
- });
162
- this.alwaysPage.forEach((handlerSet) => {
163
- handlerSet.forEach((handler) => {
164
- handler.onHandlerActiveEnd?.(modeId);
165
- });
166
- });
167
- const mode = this.modes.get(modeId);
168
- if (!mode) return;
169
- const bucket = this.buckets.get(modeId);
170
- if (!bucket) return;
171
- if (mode.scope === "global") {
172
- bucket.global.forEach((handler) => {
173
- handler.onHandlerActiveEnd?.(modeId);
174
- });
175
- }
176
- if (mode.scope === "page") {
177
- bucket.page.forEach((handlerSet, pageIndex) => {
178
- handlerSet.forEach((handler) => {
179
- handler.onHandlerActiveEnd?.(modeId);
180
- });
181
- });
182
- }
183
- }
184
- registerMode(mode) {
185
- this.modes.set(mode.id, mode);
186
- if (!this.buckets.has(mode.id)) {
187
- this.buckets.set(mode.id, { global: /* @__PURE__ */ new Set(), page: /* @__PURE__ */ new Map() });
188
- }
189
- }
190
- /** ---------- pointer-handler handling ------------ */
191
- registerHandlers({ modeId, handlers, pageIndex }) {
192
- const modeIds = Array.isArray(modeId) ? modeId : [modeId];
193
- const cleanupFunctions = [];
194
- for (const id of modeIds) {
195
- const bucket = this.buckets.get(id);
196
- if (!bucket) throw new Error(`unknown mode '${id}'`);
197
- if (pageIndex == null) {
198
- bucket.global.add(handlers);
199
- } else {
200
- const set = bucket.page.get(pageIndex) ?? /* @__PURE__ */ new Set();
201
- set.add(handlers);
202
- bucket.page.set(pageIndex, set);
203
- }
204
- cleanupFunctions.push(() => {
205
- if (pageIndex == null) {
206
- bucket.global.delete(handlers);
207
- } else {
208
- const set = bucket.page.get(pageIndex);
209
- if (set) {
210
- set.delete(handlers);
211
- if (set.size === 0) {
212
- bucket.page.delete(pageIndex);
213
- }
214
- }
215
- }
216
- });
217
- }
218
- this.onHandlerChange$.emit({ ...this.state });
219
- return () => {
220
- cleanupFunctions.forEach((cleanup) => cleanup());
221
- this.onHandlerChange$.emit({ ...this.state });
222
- };
223
- }
224
- registerAlways({ scope, handlers }) {
225
- if (scope.type === "global") {
226
- this.alwaysGlobal.add(handlers);
227
- this.onHandlerChange$.emit({ ...this.state });
228
- return () => this.alwaysGlobal.delete(handlers);
229
- }
230
- const set = this.alwaysPage.get(scope.pageIndex) ?? /* @__PURE__ */ new Set();
231
- set.add(handlers);
232
- this.alwaysPage.set(scope.pageIndex, set);
233
- this.onHandlerChange$.emit({ ...this.state });
234
- return () => {
235
- set.delete(handlers);
236
- this.onHandlerChange$.emit({ ...this.state });
237
- };
238
- }
239
- /** Returns the *merged* handler set that should be active for the given
240
- * provider (`global` wrapper or a single page wrapper).
241
- * – `alwaysGlobal` / `alwaysPage` are **always** active.
242
- * – Handlers that belong to the current mode are added on top **iff**
243
- * the mode’s own scope matches the provider’s scope. */
244
- getHandlersForScope(scope) {
245
- if (!this.state) return null;
246
- const mode = this.modes.get(this.state.activeMode);
247
- if (!mode) return null;
248
- const bucket = this.buckets.get(mode.id);
249
- if (!bucket) return null;
250
- const mergeSets = (a, b) => a.size || b.size ? mergeHandlers([...a, ...b]) : null;
251
- if (scope.type === "global") {
252
- const modeSpecific = mode.scope === "global" ? bucket.global : /* @__PURE__ */ new Set();
253
- return mergeSets(this.alwaysGlobal, modeSpecific);
254
- }
255
- const alwaysPageSet = this.alwaysPage.get(scope.pageIndex) ?? /* @__PURE__ */ new Set();
256
- const modePageSet = mode.scope === "page" ? bucket.page.get(scope.pageIndex) ?? /* @__PURE__ */ new Set() : /* @__PURE__ */ new Set();
257
- return mergeSets(alwaysPageSet, modePageSet);
258
- }
259
- /** ---------- cursor handling --------------------- */
260
- setCursor(token, cursor, priority = 0) {
261
- this.cursorClaims.set(token, { cursor, priority });
262
- this.emitCursor();
263
- }
264
- removeCursor(token) {
265
- this.cursorClaims.delete(token);
266
- this.emitCursor();
267
- }
268
- emitCursor() {
269
- const top = [...this.cursorClaims.values()].sort((a, b) => b.priority - a.priority)[0] ?? {
270
- cursor: this.modes.get(this.state.activeMode)?.cursor ?? "auto"
271
- };
272
- if (top.cursor !== this.state.cursor) {
273
- this.dispatch(setCursor(top.cursor));
274
- this.onCursorChange$.emit(top.cursor);
275
- }
276
- }
277
- onStoreUpdated(_, newState) {
278
- this.onStateChange$.emit(newState);
279
- }
280
- activeModeIsExclusive() {
281
- const mode = this.modes.get(this.state.activeMode);
282
- return !!mode?.exclusive;
283
- }
284
- getActiveInteractionMode() {
285
- return this.modes.get(this.state.activeMode) ?? null;
286
- }
287
- // keep emitter clean
288
- async destroy() {
289
- this.onModeChange$.clear();
290
- this.onCursorChange$.clear();
291
- await super.destroy();
292
- }
293
- };
294
- InteractionManagerPlugin.id = "interaction-manager";
295
-
296
- // src/lib/manifest.ts
297
- var INTERACTION_MANAGER_PLUGIN_ID = "interaction-manager";
298
- var manifest = {
299
- id: INTERACTION_MANAGER_PLUGIN_ID,
300
- name: "Interaction Manager Plugin",
301
- version: "1.0.0",
302
- provides: ["interaction-manager"],
303
- requires: [],
304
- optional: [],
305
- defaultConfig: {
306
- enabled: true
307
- }
308
- };
309
-
310
- // src/lib/reducer.ts
311
- var initialState = {
312
- activeMode: "default",
313
- cursor: "auto",
314
- paused: false
315
- };
316
- var reducer = (state, action) => {
317
- switch (action.type) {
318
- case ACTIVATE_MODE:
319
- return {
320
- ...state,
321
- activeMode: action.payload.mode
322
- };
323
- case SET_CURSOR:
324
- return {
325
- ...state,
326
- cursor: action.payload.cursor
327
- };
328
- case PAUSE_INTERACTION:
329
- return {
330
- ...state,
331
- paused: true
332
- };
333
- case RESUME_INTERACTION:
334
- return {
335
- ...state,
336
- paused: false
337
- };
338
- default:
339
- return state;
340
- }
341
- };
342
-
343
- // src/lib/index.ts
344
- var InteractionManagerPluginPackage = {
345
- manifest,
346
- create: (registry) => new InteractionManagerPlugin(INTERACTION_MANAGER_PLUGIN_ID, registry),
347
- reducer,
348
- initialState
349
- };
350
- // Annotate the CommonJS export names for ESM import in node:
351
- 0 && (module.exports = {
352
- INTERACTION_MANAGER_PLUGIN_ID,
353
- InteractionManagerPlugin,
354
- InteractionManagerPluginPackage,
355
- initialState,
356
- manifest,
357
- reducer
358
- });
359
- //# sourceMappingURL=index.cjs.map
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core"),t="INTERACTION/ACTIVATE_MODE",a="INTERACTION/PAUSE",s="INTERACTION/RESUME",r="INTERACTION/SET_CURSOR";const o=class extends e.BasePlugin{constructor(t,a){super(t,a),this.modes=new Map,this.cursorClaims=new Map,this.buckets=new Map,this.alwaysGlobal=new Set,this.alwaysPage=new Map,this.onModeChange$=e.createEmitter(),this.onHandlerChange$=e.createEmitter(),this.onCursorChange$=e.createEmitter(),this.onStateChange$=e.createBehaviorEmitter(),this.registerMode({id:"default",scope:"page",exclusive:!1,cursor:"auto"})}async initialize(e){}buildCapability(){return{activate:e=>this.activate(e),onModeChange:this.onModeChange$.on,onCursorChange:this.onCursorChange$.on,onHandlerChange:this.onHandlerChange$.on,onStateChange:this.onStateChange$.on,getActiveMode:()=>this.state.activeMode,getActiveInteractionMode:()=>this.getActiveInteractionMode(),finish:()=>this.activate("default"),registerMode:e=>this.registerMode(e),registerHandlers:e=>this.registerHandlers(e),registerAlways:e=>this.registerAlways(e),setCursor:(e,t,a=0)=>this.setCursor(e,t,a),removeCursor:e=>this.removeCursor(e),getCurrentCursor:()=>this.state.cursor,getHandlersForScope:e=>this.getHandlersForScope(e),activeModeIsExclusive:()=>this.activeModeIsExclusive(),pause:()=>this.dispatch({type:a}),resume:()=>this.dispatch({type:s}),isPaused:()=>this.state.paused}}activate(e){if(!this.modes.has(e))throw new Error(`[interaction] unknown mode '${e}'`);if(e===this.state.activeMode)return;const a=this.state.activeMode;this.cursorClaims.clear(),this.notifyHandlersInactive(a),this.dispatch((e=>({type:t,payload:{mode:e}}))(e)),this.emitCursor(),this.notifyHandlersActive(e),this.onModeChange$.emit({...this.state,activeMode:e})}notifyHandlersActive(e){this.alwaysGlobal.forEach((t=>{var a;null==(a=t.onHandlerActiveStart)||a.call(t,e)})),this.alwaysPage.forEach((t=>{t.forEach((t=>{var a;null==(a=t.onHandlerActiveStart)||a.call(t,e)}))}));const t=this.modes.get(e);if(!t)return;const a=this.buckets.get(e);a&&("global"===t.scope&&a.global.forEach((t=>{var a;null==(a=t.onHandlerActiveStart)||a.call(t,e)})),"page"===t.scope&&a.page.forEach(((t,a)=>{t.forEach((t=>{var a;null==(a=t.onHandlerActiveStart)||a.call(t,e)}))})))}notifyHandlersInactive(e){this.alwaysGlobal.forEach((t=>{var a;null==(a=t.onHandlerActiveEnd)||a.call(t,e)})),this.alwaysPage.forEach((t=>{t.forEach((t=>{var a;null==(a=t.onHandlerActiveEnd)||a.call(t,e)}))}));const t=this.modes.get(e);if(!t)return;const a=this.buckets.get(e);a&&("global"===t.scope&&a.global.forEach((t=>{var a;null==(a=t.onHandlerActiveEnd)||a.call(t,e)})),"page"===t.scope&&a.page.forEach(((t,a)=>{t.forEach((t=>{var a;null==(a=t.onHandlerActiveEnd)||a.call(t,e)}))})))}registerMode(e){this.modes.set(e.id,e),this.buckets.has(e.id)||this.buckets.set(e.id,{global:new Set,page:new Map})}registerHandlers({modeId:e,handlers:t,pageIndex:a}){const s=Array.isArray(e)?e:[e],r=[];for(const o of s){const e=this.buckets.get(o);if(!e)throw new Error(`unknown mode '${o}'`);if(null==a)e.global.add(t);else{const s=e.page.get(a)??new Set;s.add(t),e.page.set(a,s)}r.push((()=>{if(null==a)e.global.delete(t);else{const s=e.page.get(a);s&&(s.delete(t),0===s.size&&e.page.delete(a))}}))}return this.onHandlerChange$.emit({...this.state}),()=>{r.forEach((e=>e())),this.onHandlerChange$.emit({...this.state})}}registerAlways({scope:e,handlers:t}){if("global"===e.type)return this.alwaysGlobal.add(t),this.onHandlerChange$.emit({...this.state}),()=>this.alwaysGlobal.delete(t);const a=this.alwaysPage.get(e.pageIndex)??new Set;return a.add(t),this.alwaysPage.set(e.pageIndex,a),this.onHandlerChange$.emit({...this.state}),()=>{a.delete(t),this.onHandlerChange$.emit({...this.state})}}getHandlersForScope(e){if(!this.state)return null;const t=this.modes.get(this.state.activeMode);if(!t)return null;const a=this.buckets.get(t.id);if(!a)return null;const s=(e,t)=>e.size||t.size?function(e){const t=["onPointerDown","onPointerUp","onPointerMove","onPointerEnter","onPointerLeave","onPointerCancel","onClick","onDoubleClick"],a={};for(const s of t)a[s]=(t,a,r)=>{var o;for(const i of e)null==(o=i[s])||o.call(i,t,a,r)};return a}([...e,...t]):null;if("global"===e.type){const e="global"===t.scope?a.global:new Set;return s(this.alwaysGlobal,e)}return s(this.alwaysPage.get(e.pageIndex)??new Set,"page"===t.scope?a.page.get(e.pageIndex)??new Set:new Set)}setCursor(e,t,a=0){this.cursorClaims.set(e,{cursor:t,priority:a}),this.emitCursor()}removeCursor(e){this.cursorClaims.delete(e),this.emitCursor()}emitCursor(){var e;const t=[...this.cursorClaims.values()].sort(((e,t)=>t.priority-e.priority))[0]??{cursor:(null==(e=this.modes.get(this.state.activeMode))?void 0:e.cursor)??"auto"};var a;t.cursor!==this.state.cursor&&(this.dispatch((a=t.cursor,{type:r,payload:{cursor:a}})),this.onCursorChange$.emit(t.cursor))}onStoreUpdated(e,t){this.onStateChange$.emit(t)}activeModeIsExclusive(){const e=this.modes.get(this.state.activeMode);return!!(null==e?void 0:e.exclusive)}getActiveInteractionMode(){return this.modes.get(this.state.activeMode)??null}async destroy(){this.onModeChange$.clear(),this.onCursorChange$.clear(),await super.destroy()}};o.id="interaction-manager";let i=o;const n="interaction-manager",l={id:n,name:"Interaction Manager Plugin",version:"1.0.0",provides:["interaction-manager"],requires:[],optional:[],defaultConfig:{enabled:!0}},c={activeMode:"default",cursor:"auto",paused:!1},h=(e,o)=>{switch(o.type){case t:return{...e,activeMode:o.payload.mode};case r:return{...e,cursor:o.payload.cursor};case a:return{...e,paused:!0};case s:return{...e,paused:!1};default:return e}},d={manifest:l,create:e=>new i(n,e),reducer:h,initialState:c};exports.INTERACTION_MANAGER_PLUGIN_ID=n,exports.InteractionManagerPlugin=i,exports.InteractionManagerPluginPackage=d,exports.initialState=c,exports.manifest=l,exports.reducer=h;
2
+ //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/lib/interaction-manager-plugin.ts","../src/lib/actions.ts","../src/lib/helper.ts","../src/lib/manifest.ts","../src/lib/reducer.ts","../src/lib/index.ts"],"sourcesContent":["export * from './lib';\n","import { BasePlugin, createBehaviorEmitter, createEmitter, PluginRegistry } from '@embedpdf/core';\n\nimport {\n InteractionManagerCapability,\n InteractionManagerPluginConfig,\n InteractionManagerState,\n InteractionMode,\n InteractionScope,\n PointerEventHandlers,\n PointerEventHandlersWithLifecycle,\n RegisterAlwaysOptions,\n RegisterHandlersOptions,\n} from './types';\nimport { activateMode, pauseInteraction, resumeInteraction, setCursor } from './actions';\nimport { mergeHandlers } from './helper';\n\ninterface CursorClaim {\n cursor: string;\n priority: number;\n}\n\ntype HandlerSet = Set<PointerEventHandlersWithLifecycle>;\ntype PageHandlerMap = Map<number /*pageIdx*/, HandlerSet>;\n\ninterface ModeBuckets {\n /** handlers that listen on the global wrapper (only once per viewer) */\n global: HandlerSet;\n /** handlers that listen on a *specific* page wrapper */\n page: PageHandlerMap;\n}\n\nexport class InteractionManagerPlugin extends BasePlugin<\n InteractionManagerPluginConfig,\n InteractionManagerCapability,\n InteractionManagerState\n> {\n static readonly id = 'interaction-manager' as const;\n\n private modes = new Map<string, InteractionMode>();\n private cursorClaims = new Map<string, CursorClaim>();\n private buckets = new Map<string, ModeBuckets>();\n\n private alwaysGlobal = new Set<PointerEventHandlersWithLifecycle>();\n private alwaysPage = new Map<number, Set<PointerEventHandlersWithLifecycle>>();\n\n private readonly onModeChange$ = createEmitter<InteractionManagerState>();\n private readonly onHandlerChange$ = createEmitter<InteractionManagerState>();\n private readonly onCursorChange$ = createEmitter<string>();\n private readonly onStateChange$ = createBehaviorEmitter<InteractionManagerState>();\n\n constructor(id: string, registry: PluginRegistry) {\n super(id, registry);\n\n this.registerMode({\n id: 'default',\n scope: 'page',\n exclusive: false,\n cursor: 'auto',\n });\n }\n\n async initialize(_: InteractionManagerPluginConfig): Promise<void> {}\n\n protected buildCapability(): InteractionManagerCapability {\n return {\n activate: (modeId: string) => this.activate(modeId),\n onModeChange: this.onModeChange$.on,\n onCursorChange: this.onCursorChange$.on,\n onHandlerChange: this.onHandlerChange$.on,\n onStateChange: this.onStateChange$.on,\n getActiveMode: () => this.state.activeMode,\n getActiveInteractionMode: () => this.getActiveInteractionMode(),\n finish: () => this.activate('default'),\n registerMode: (mode: InteractionMode) => this.registerMode(mode),\n registerHandlers: (options: RegisterHandlersOptions) => this.registerHandlers(options),\n registerAlways: (options: RegisterAlwaysOptions) => this.registerAlways(options),\n setCursor: (token: string, cursor: string, priority = 0) =>\n this.setCursor(token, cursor, priority),\n removeCursor: (token: string) => this.removeCursor(token),\n getCurrentCursor: () => this.state.cursor,\n getHandlersForScope: (scope: InteractionScope) => this.getHandlersForScope(scope),\n activeModeIsExclusive: () => this.activeModeIsExclusive(),\n pause: () => this.dispatch(pauseInteraction()),\n resume: () => this.dispatch(resumeInteraction()),\n isPaused: () => this.state.paused,\n };\n }\n\n private activate(mode: string) {\n if (!this.modes.has(mode)) {\n throw new Error(`[interaction] unknown mode '${mode}'`);\n }\n if (mode === this.state.activeMode) return;\n\n const previousMode = this.state.activeMode;\n this.cursorClaims.clear(); // prevent cursor leaks\n\n this.notifyHandlersInactive(previousMode);\n\n this.dispatch(activateMode(mode));\n this.emitCursor();\n\n // Call lifecycle hooks for handlers going active\n this.notifyHandlersActive(mode);\n\n this.onModeChange$.emit({ ...this.state, activeMode: mode });\n }\n\n private notifyHandlersActive(modeId: string) {\n this.alwaysGlobal.forEach((handler) => {\n handler.onHandlerActiveStart?.(modeId);\n });\n\n this.alwaysPage.forEach((handlerSet) => {\n handlerSet.forEach((handler) => {\n handler.onHandlerActiveStart?.(modeId);\n });\n });\n\n const mode = this.modes.get(modeId);\n if (!mode) return;\n\n const bucket = this.buckets.get(modeId);\n if (!bucket) return;\n\n // Notify global handlers if mode is global\n if (mode.scope === 'global') {\n bucket.global.forEach((handler) => {\n handler.onHandlerActiveStart?.(modeId);\n });\n }\n\n // Notify page handlers if mode is page\n if (mode.scope === 'page') {\n bucket.page.forEach((handlerSet, pageIndex) => {\n handlerSet.forEach((handler) => {\n handler.onHandlerActiveStart?.(modeId);\n });\n });\n }\n }\n\n private notifyHandlersInactive(modeId: string) {\n this.alwaysGlobal.forEach((handler) => {\n handler.onHandlerActiveEnd?.(modeId);\n });\n\n this.alwaysPage.forEach((handlerSet) => {\n handlerSet.forEach((handler) => {\n handler.onHandlerActiveEnd?.(modeId);\n });\n });\n\n const mode = this.modes.get(modeId);\n if (!mode) return;\n\n const bucket = this.buckets.get(modeId);\n if (!bucket) return;\n\n // Notify global handlers if mode is global\n if (mode.scope === 'global') {\n bucket.global.forEach((handler) => {\n handler.onHandlerActiveEnd?.(modeId);\n });\n }\n\n // Notify page handlers if mode is page\n if (mode.scope === 'page') {\n bucket.page.forEach((handlerSet, pageIndex) => {\n handlerSet.forEach((handler) => {\n handler.onHandlerActiveEnd?.(modeId);\n });\n });\n }\n }\n\n private registerMode(mode: InteractionMode) {\n this.modes.set(mode.id, mode);\n if (!this.buckets.has(mode.id)) {\n this.buckets.set(mode.id, { global: new Set(), page: new Map() });\n }\n }\n\n /** ---------- pointer-handler handling ------------ */\n private registerHandlers({ modeId, handlers, pageIndex }: RegisterHandlersOptions): () => void {\n const modeIds = Array.isArray(modeId) ? modeId : [modeId];\n const cleanupFunctions: (() => void)[] = [];\n\n for (const id of modeIds) {\n const bucket = this.buckets.get(id);\n if (!bucket) throw new Error(`unknown mode '${id}'`);\n\n if (pageIndex == null) {\n bucket.global.add(handlers);\n } else {\n const set = bucket.page.get(pageIndex) ?? new Set();\n set.add(handlers);\n bucket.page.set(pageIndex, set);\n }\n\n // Create cleanup function for this specific mode\n cleanupFunctions.push(() => {\n if (pageIndex == null) {\n bucket.global.delete(handlers);\n } else {\n const set = bucket.page.get(pageIndex);\n if (set) {\n set.delete(handlers);\n if (set.size === 0) {\n bucket.page.delete(pageIndex);\n }\n }\n }\n });\n }\n\n this.onHandlerChange$.emit({ ...this.state });\n\n // Return a cleanup function that removes handlers from all registered modes\n return () => {\n cleanupFunctions.forEach((cleanup) => cleanup());\n this.onHandlerChange$.emit({ ...this.state });\n };\n }\n\n public registerAlways({ scope, handlers }: RegisterAlwaysOptions): () => void {\n if (scope.type === 'global') {\n this.alwaysGlobal.add(handlers);\n this.onHandlerChange$.emit({ ...this.state });\n return () => this.alwaysGlobal.delete(handlers);\n }\n const set = this.alwaysPage.get(scope.pageIndex) ?? new Set();\n set.add(handlers);\n this.alwaysPage.set(scope.pageIndex, set);\n this.onHandlerChange$.emit({ ...this.state });\n return () => {\n set.delete(handlers);\n this.onHandlerChange$.emit({ ...this.state });\n };\n }\n\n /** Returns the *merged* handler set that should be active for the given\n * provider (`global` wrapper or a single page wrapper).\n * – `alwaysGlobal` / `alwaysPage` are **always** active.\n * – Handlers that belong to the current mode are added on top **iff**\n * the mode’s own scope matches the provider’s scope. */\n private getHandlersForScope(scope: InteractionScope): PointerEventHandlers | null {\n if (!this.state) return null;\n\n const mode = this.modes.get(this.state.activeMode);\n if (!mode) return null;\n\n const bucket = this.buckets.get(mode.id);\n if (!bucket) return null;\n\n /** helper – merge two handler sets into one object (or `null` if both are empty) */\n const mergeSets = (a: HandlerSet, b: HandlerSet) =>\n a.size || b.size ? mergeHandlers([...a, ...b]) : null;\n\n /* ───────────────────── GLOBAL PROVIDER ─────────────────────── */\n if (scope.type === 'global') {\n const modeSpecific =\n mode.scope === 'global' // only include mode handlers if the\n ? bucket.global // mode itself is global-scoped\n : new Set<PointerEventHandlers>();\n return mergeSets(this.alwaysGlobal, modeSpecific);\n }\n\n /* ─────────────────────── PAGE PROVIDER ──────────────────────── */\n const alwaysPageSet = this.alwaysPage.get(scope.pageIndex) ?? new Set<PointerEventHandlers>();\n const modePageSet =\n mode.scope === 'page'\n ? (bucket.page.get(scope.pageIndex) ?? new Set<PointerEventHandlers>())\n : new Set<PointerEventHandlers>(); // global-scoped mode → ignore page buckets\n\n return mergeSets(alwaysPageSet, modePageSet);\n }\n\n /** ---------- cursor handling --------------------- */\n private setCursor(token: string, cursor: string, priority = 0) {\n this.cursorClaims.set(token, { cursor, priority });\n this.emitCursor();\n }\n private removeCursor(token: string) {\n this.cursorClaims.delete(token);\n this.emitCursor();\n }\n\n private emitCursor() {\n /* pick highest priority claim, else mode baseline */\n const top = [...this.cursorClaims.values()].sort((a, b) => b.priority - a.priority)[0] ?? {\n cursor: this.modes.get(this.state.activeMode)?.cursor ?? 'auto',\n };\n\n if (top.cursor !== this.state.cursor) {\n this.dispatch(setCursor(top.cursor));\n this.onCursorChange$.emit(top.cursor);\n }\n }\n\n override onStoreUpdated(_: InteractionManagerState, newState: InteractionManagerState): void {\n this.onStateChange$.emit(newState);\n }\n\n private activeModeIsExclusive(): boolean {\n const mode = this.modes.get(this.state.activeMode);\n return !!mode?.exclusive;\n }\n\n private getActiveInteractionMode(): InteractionMode | null {\n return this.modes.get(this.state.activeMode) ?? null;\n }\n\n // keep emitter clean\n async destroy(): Promise<void> {\n this.onModeChange$.clear();\n this.onCursorChange$.clear();\n await super.destroy();\n }\n}\n","import { Action } from '@embedpdf/core';\n\nexport const ACTIVATE_MODE = 'INTERACTION/ACTIVATE_MODE';\nexport const PAUSE_INTERACTION = 'INTERACTION/PAUSE';\nexport const RESUME_INTERACTION = 'INTERACTION/RESUME';\nexport const SET_CURSOR = 'INTERACTION/SET_CURSOR';\n\nexport interface ActivateModeAction extends Action {\n type: typeof ACTIVATE_MODE;\n payload: { mode: string };\n}\n\nexport interface PauseInteractionAction extends Action {\n type: typeof PAUSE_INTERACTION;\n}\n\nexport interface ResumeInteractionAction extends Action {\n type: typeof RESUME_INTERACTION;\n}\n\nexport interface SetCursorAction extends Action {\n type: typeof SET_CURSOR;\n payload: { cursor: string };\n}\n\nexport const activateMode = (mode: string): ActivateModeAction => ({\n type: ACTIVATE_MODE,\n payload: { mode },\n});\n\nexport const setCursor = (cursor: string): SetCursorAction => ({\n type: SET_CURSOR,\n payload: { cursor },\n});\n\nexport const pauseInteraction = (): PauseInteractionAction => ({\n type: PAUSE_INTERACTION,\n});\n\nexport const resumeInteraction = (): ResumeInteractionAction => ({\n type: RESUME_INTERACTION,\n});\n\nexport type InteractionManagerAction =\n | ActivateModeAction\n | PauseInteractionAction\n | ResumeInteractionAction\n | SetCursorAction;\n","import { PointerEventHandlers } from './types';\n\nexport function mergeHandlers(list: PointerEventHandlers[]): PointerEventHandlers {\n const keys: (keyof PointerEventHandlers)[] = [\n 'onPointerDown',\n 'onPointerUp',\n 'onPointerMove',\n 'onPointerEnter',\n 'onPointerLeave',\n 'onPointerCancel',\n ];\n const out: Partial<PointerEventHandlers> = {};\n for (const k of keys) {\n out[k] = (evt: any, nativeEvt: any, modeId: string) => {\n for (const h of list) h[k]?.(evt, nativeEvt, modeId);\n };\n }\n return out as PointerEventHandlers;\n}\n","import { PluginManifest } from '@embedpdf/core';\nimport { InteractionManagerPluginConfig } from './types';\n\nexport const INTERACTION_MANAGER_PLUGIN_ID = 'interaction-manager';\n\nexport const manifest: PluginManifest<InteractionManagerPluginConfig> = {\n id: INTERACTION_MANAGER_PLUGIN_ID,\n name: 'Interaction Manager Plugin',\n version: '1.0.0',\n provides: ['interaction-manager'],\n requires: [],\n optional: [],\n defaultConfig: {\n enabled: true,\n },\n};\n","import { Reducer } from '@embedpdf/core';\nimport {\n ACTIVATE_MODE,\n InteractionManagerAction,\n PAUSE_INTERACTION,\n RESUME_INTERACTION,\n SET_CURSOR,\n} from './actions';\nimport { InteractionManagerState } from './types';\n\nexport const initialState: InteractionManagerState = {\n activeMode: 'default',\n cursor: 'auto',\n paused: false,\n};\n\nexport const reducer: Reducer<InteractionManagerState, InteractionManagerAction> = (\n state,\n action,\n) => {\n switch (action.type) {\n case ACTIVATE_MODE:\n return {\n ...state,\n activeMode: action.payload.mode,\n };\n case SET_CURSOR:\n return {\n ...state,\n cursor: action.payload.cursor,\n };\n case PAUSE_INTERACTION:\n return {\n ...state,\n paused: true,\n };\n case RESUME_INTERACTION:\n return {\n ...state,\n paused: false,\n };\n default:\n return state;\n }\n};\n","import { PluginPackage } from '@embedpdf/core';\n\nimport { InteractionManagerPlugin } from './interaction-manager-plugin';\nimport { manifest, INTERACTION_MANAGER_PLUGIN_ID } from './manifest';\nimport { InteractionManagerPluginConfig, InteractionManagerState } from './types';\nimport { reducer, initialState } from './reducer';\nimport { InteractionManagerAction } from './actions';\n\nexport const InteractionManagerPluginPackage: PluginPackage<\n InteractionManagerPlugin,\n InteractionManagerPluginConfig,\n InteractionManagerState,\n InteractionManagerAction\n> = {\n manifest,\n create: (registry) => new InteractionManagerPlugin(INTERACTION_MANAGER_PLUGIN_ID, registry),\n reducer,\n initialState,\n};\n\nexport * from './interaction-manager-plugin';\nexport * from './types';\nexport * from './manifest';\nexport * from './reducer';\n"],"mappings":"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","names":[]}
1
+ {"version":3,"file":"index.cjs","sources":["../src/lib/actions.ts","../src/lib/interaction-manager-plugin.ts","../src/lib/helper.ts","../src/lib/manifest.ts","../src/lib/reducer.ts","../src/lib/index.ts"],"sourcesContent":["import { Action } from '@embedpdf/core';\n\nexport const ACTIVATE_MODE = 'INTERACTION/ACTIVATE_MODE';\nexport const PAUSE_INTERACTION = 'INTERACTION/PAUSE';\nexport const RESUME_INTERACTION = 'INTERACTION/RESUME';\nexport const SET_CURSOR = 'INTERACTION/SET_CURSOR';\n\nexport interface ActivateModeAction extends Action {\n type: typeof ACTIVATE_MODE;\n payload: { mode: string };\n}\n\nexport interface PauseInteractionAction extends Action {\n type: typeof PAUSE_INTERACTION;\n}\n\nexport interface ResumeInteractionAction extends Action {\n type: typeof RESUME_INTERACTION;\n}\n\nexport interface SetCursorAction extends Action {\n type: typeof SET_CURSOR;\n payload: { cursor: string };\n}\n\nexport const activateMode = (mode: string): ActivateModeAction => ({\n type: ACTIVATE_MODE,\n payload: { mode },\n});\n\nexport const setCursor = (cursor: string): SetCursorAction => ({\n type: SET_CURSOR,\n payload: { cursor },\n});\n\nexport const pauseInteraction = (): PauseInteractionAction => ({\n type: PAUSE_INTERACTION,\n});\n\nexport const resumeInteraction = (): ResumeInteractionAction => ({\n type: RESUME_INTERACTION,\n});\n\nexport type InteractionManagerAction =\n | ActivateModeAction\n | PauseInteractionAction\n | ResumeInteractionAction\n | SetCursorAction;\n","import { BasePlugin, createBehaviorEmitter, createEmitter, PluginRegistry } from '@embedpdf/core';\n\nimport {\n InteractionManagerCapability,\n InteractionManagerPluginConfig,\n InteractionManagerState,\n InteractionMode,\n InteractionScope,\n PointerEventHandlers,\n PointerEventHandlersWithLifecycle,\n RegisterAlwaysOptions,\n RegisterHandlersOptions,\n} from './types';\nimport { activateMode, pauseInteraction, resumeInteraction, setCursor } from './actions';\nimport { mergeHandlers } from './helper';\n\ninterface CursorClaim {\n cursor: string;\n priority: number;\n}\n\ntype HandlerSet = Set<PointerEventHandlersWithLifecycle>;\ntype PageHandlerMap = Map<number /*pageIdx*/, HandlerSet>;\n\ninterface ModeBuckets {\n /** handlers that listen on the global wrapper (only once per viewer) */\n global: HandlerSet;\n /** handlers that listen on a *specific* page wrapper */\n page: PageHandlerMap;\n}\n\nexport class InteractionManagerPlugin extends BasePlugin<\n InteractionManagerPluginConfig,\n InteractionManagerCapability,\n InteractionManagerState\n> {\n static readonly id = 'interaction-manager' as const;\n\n private modes = new Map<string, InteractionMode>();\n private cursorClaims = new Map<string, CursorClaim>();\n private buckets = new Map<string, ModeBuckets>();\n\n private alwaysGlobal = new Set<PointerEventHandlersWithLifecycle>();\n private alwaysPage = new Map<number, Set<PointerEventHandlersWithLifecycle>>();\n\n private readonly onModeChange$ = createEmitter<InteractionManagerState>();\n private readonly onHandlerChange$ = createEmitter<InteractionManagerState>();\n private readonly onCursorChange$ = createEmitter<string>();\n private readonly onStateChange$ = createBehaviorEmitter<InteractionManagerState>();\n\n constructor(id: string, registry: PluginRegistry) {\n super(id, registry);\n\n this.registerMode({\n id: 'default',\n scope: 'page',\n exclusive: false,\n cursor: 'auto',\n });\n }\n\n async initialize(_: InteractionManagerPluginConfig): Promise<void> {}\n\n protected buildCapability(): InteractionManagerCapability {\n return {\n activate: (modeId: string) => this.activate(modeId),\n onModeChange: this.onModeChange$.on,\n onCursorChange: this.onCursorChange$.on,\n onHandlerChange: this.onHandlerChange$.on,\n onStateChange: this.onStateChange$.on,\n getActiveMode: () => this.state.activeMode,\n getActiveInteractionMode: () => this.getActiveInteractionMode(),\n finish: () => this.activate('default'),\n registerMode: (mode: InteractionMode) => this.registerMode(mode),\n registerHandlers: (options: RegisterHandlersOptions) => this.registerHandlers(options),\n registerAlways: (options: RegisterAlwaysOptions) => this.registerAlways(options),\n setCursor: (token: string, cursor: string, priority = 0) =>\n this.setCursor(token, cursor, priority),\n removeCursor: (token: string) => this.removeCursor(token),\n getCurrentCursor: () => this.state.cursor,\n getHandlersForScope: (scope: InteractionScope) => this.getHandlersForScope(scope),\n activeModeIsExclusive: () => this.activeModeIsExclusive(),\n pause: () => this.dispatch(pauseInteraction()),\n resume: () => this.dispatch(resumeInteraction()),\n isPaused: () => this.state.paused,\n };\n }\n\n private activate(mode: string) {\n if (!this.modes.has(mode)) {\n throw new Error(`[interaction] unknown mode '${mode}'`);\n }\n if (mode === this.state.activeMode) return;\n\n const previousMode = this.state.activeMode;\n this.cursorClaims.clear(); // prevent cursor leaks\n\n this.notifyHandlersInactive(previousMode);\n\n this.dispatch(activateMode(mode));\n this.emitCursor();\n\n // Call lifecycle hooks for handlers going active\n this.notifyHandlersActive(mode);\n\n this.onModeChange$.emit({ ...this.state, activeMode: mode });\n }\n\n private notifyHandlersActive(modeId: string) {\n this.alwaysGlobal.forEach((handler) => {\n handler.onHandlerActiveStart?.(modeId);\n });\n\n this.alwaysPage.forEach((handlerSet) => {\n handlerSet.forEach((handler) => {\n handler.onHandlerActiveStart?.(modeId);\n });\n });\n\n const mode = this.modes.get(modeId);\n if (!mode) return;\n\n const bucket = this.buckets.get(modeId);\n if (!bucket) return;\n\n // Notify global handlers if mode is global\n if (mode.scope === 'global') {\n bucket.global.forEach((handler) => {\n handler.onHandlerActiveStart?.(modeId);\n });\n }\n\n // Notify page handlers if mode is page\n if (mode.scope === 'page') {\n bucket.page.forEach((handlerSet, pageIndex) => {\n handlerSet.forEach((handler) => {\n handler.onHandlerActiveStart?.(modeId);\n });\n });\n }\n }\n\n private notifyHandlersInactive(modeId: string) {\n this.alwaysGlobal.forEach((handler) => {\n handler.onHandlerActiveEnd?.(modeId);\n });\n\n this.alwaysPage.forEach((handlerSet) => {\n handlerSet.forEach((handler) => {\n handler.onHandlerActiveEnd?.(modeId);\n });\n });\n\n const mode = this.modes.get(modeId);\n if (!mode) return;\n\n const bucket = this.buckets.get(modeId);\n if (!bucket) return;\n\n // Notify global handlers if mode is global\n if (mode.scope === 'global') {\n bucket.global.forEach((handler) => {\n handler.onHandlerActiveEnd?.(modeId);\n });\n }\n\n // Notify page handlers if mode is page\n if (mode.scope === 'page') {\n bucket.page.forEach((handlerSet, pageIndex) => {\n handlerSet.forEach((handler) => {\n handler.onHandlerActiveEnd?.(modeId);\n });\n });\n }\n }\n\n private registerMode(mode: InteractionMode) {\n this.modes.set(mode.id, mode);\n if (!this.buckets.has(mode.id)) {\n this.buckets.set(mode.id, { global: new Set(), page: new Map() });\n }\n }\n\n /** ---------- pointer-handler handling ------------ */\n private registerHandlers({ modeId, handlers, pageIndex }: RegisterHandlersOptions): () => void {\n const modeIds = Array.isArray(modeId) ? modeId : [modeId];\n const cleanupFunctions: (() => void)[] = [];\n\n for (const id of modeIds) {\n const bucket = this.buckets.get(id);\n if (!bucket) throw new Error(`unknown mode '${id}'`);\n\n if (pageIndex == null) {\n bucket.global.add(handlers);\n } else {\n const set = bucket.page.get(pageIndex) ?? new Set();\n set.add(handlers);\n bucket.page.set(pageIndex, set);\n }\n\n // Create cleanup function for this specific mode\n cleanupFunctions.push(() => {\n if (pageIndex == null) {\n bucket.global.delete(handlers);\n } else {\n const set = bucket.page.get(pageIndex);\n if (set) {\n set.delete(handlers);\n if (set.size === 0) {\n bucket.page.delete(pageIndex);\n }\n }\n }\n });\n }\n\n this.onHandlerChange$.emit({ ...this.state });\n\n // Return a cleanup function that removes handlers from all registered modes\n return () => {\n cleanupFunctions.forEach((cleanup) => cleanup());\n this.onHandlerChange$.emit({ ...this.state });\n };\n }\n\n public registerAlways({ scope, handlers }: RegisterAlwaysOptions): () => void {\n if (scope.type === 'global') {\n this.alwaysGlobal.add(handlers);\n this.onHandlerChange$.emit({ ...this.state });\n return () => this.alwaysGlobal.delete(handlers);\n }\n const set = this.alwaysPage.get(scope.pageIndex) ?? new Set();\n set.add(handlers);\n this.alwaysPage.set(scope.pageIndex, set);\n this.onHandlerChange$.emit({ ...this.state });\n return () => {\n set.delete(handlers);\n this.onHandlerChange$.emit({ ...this.state });\n };\n }\n\n /** Returns the *merged* handler set that should be active for the given\n * provider (`global` wrapper or a single page wrapper).\n * – `alwaysGlobal` / `alwaysPage` are **always** active.\n * – Handlers that belong to the current mode are added on top **iff**\n * the mode’s own scope matches the provider’s scope. */\n private getHandlersForScope(scope: InteractionScope): PointerEventHandlers | null {\n if (!this.state) return null;\n\n const mode = this.modes.get(this.state.activeMode);\n if (!mode) return null;\n\n const bucket = this.buckets.get(mode.id);\n if (!bucket) return null;\n\n /** helper – merge two handler sets into one object (or `null` if both are empty) */\n const mergeSets = (a: HandlerSet, b: HandlerSet) =>\n a.size || b.size ? mergeHandlers([...a, ...b]) : null;\n\n /* ───────────────────── GLOBAL PROVIDER ─────────────────────── */\n if (scope.type === 'global') {\n const modeSpecific =\n mode.scope === 'global' // only include mode handlers if the\n ? bucket.global // mode itself is global-scoped\n : new Set<PointerEventHandlers>();\n return mergeSets(this.alwaysGlobal, modeSpecific);\n }\n\n /* ─────────────────────── PAGE PROVIDER ──────────────────────── */\n const alwaysPageSet = this.alwaysPage.get(scope.pageIndex) ?? new Set<PointerEventHandlers>();\n const modePageSet =\n mode.scope === 'page'\n ? (bucket.page.get(scope.pageIndex) ?? new Set<PointerEventHandlers>())\n : new Set<PointerEventHandlers>(); // global-scoped mode → ignore page buckets\n\n return mergeSets(alwaysPageSet, modePageSet);\n }\n\n /** ---------- cursor handling --------------------- */\n private setCursor(token: string, cursor: string, priority = 0) {\n this.cursorClaims.set(token, { cursor, priority });\n this.emitCursor();\n }\n private removeCursor(token: string) {\n this.cursorClaims.delete(token);\n this.emitCursor();\n }\n\n private emitCursor() {\n /* pick highest priority claim, else mode baseline */\n const top = [...this.cursorClaims.values()].sort((a, b) => b.priority - a.priority)[0] ?? {\n cursor: this.modes.get(this.state.activeMode)?.cursor ?? 'auto',\n };\n\n if (top.cursor !== this.state.cursor) {\n this.dispatch(setCursor(top.cursor));\n this.onCursorChange$.emit(top.cursor);\n }\n }\n\n override onStoreUpdated(_: InteractionManagerState, newState: InteractionManagerState): void {\n this.onStateChange$.emit(newState);\n }\n\n private activeModeIsExclusive(): boolean {\n const mode = this.modes.get(this.state.activeMode);\n return !!mode?.exclusive;\n }\n\n private getActiveInteractionMode(): InteractionMode | null {\n return this.modes.get(this.state.activeMode) ?? null;\n }\n\n // keep emitter clean\n async destroy(): Promise<void> {\n this.onModeChange$.clear();\n this.onCursorChange$.clear();\n await super.destroy();\n }\n}\n","import { PointerEventHandlers } from './types';\n\nexport function mergeHandlers(list: PointerEventHandlers[]): PointerEventHandlers {\n const keys: (keyof PointerEventHandlers)[] = [\n 'onPointerDown',\n 'onPointerUp',\n 'onPointerMove',\n 'onPointerEnter',\n 'onPointerLeave',\n 'onPointerCancel',\n 'onClick',\n 'onDoubleClick',\n ];\n const out: Partial<PointerEventHandlers> = {};\n for (const k of keys) {\n out[k] = (evt: any, nativeEvt: any, modeId: string) => {\n for (const h of list) h[k]?.(evt, nativeEvt, modeId);\n };\n }\n return out as PointerEventHandlers;\n}\n","import { PluginManifest } from '@embedpdf/core';\nimport { InteractionManagerPluginConfig } from './types';\n\nexport const INTERACTION_MANAGER_PLUGIN_ID = 'interaction-manager';\n\nexport const manifest: PluginManifest<InteractionManagerPluginConfig> = {\n id: INTERACTION_MANAGER_PLUGIN_ID,\n name: 'Interaction Manager Plugin',\n version: '1.0.0',\n provides: ['interaction-manager'],\n requires: [],\n optional: [],\n defaultConfig: {\n enabled: true,\n },\n};\n","import { Reducer } from '@embedpdf/core';\nimport {\n ACTIVATE_MODE,\n InteractionManagerAction,\n PAUSE_INTERACTION,\n RESUME_INTERACTION,\n SET_CURSOR,\n} from './actions';\nimport { InteractionManagerState } from './types';\n\nexport const initialState: InteractionManagerState = {\n activeMode: 'default',\n cursor: 'auto',\n paused: false,\n};\n\nexport const reducer: Reducer<InteractionManagerState, InteractionManagerAction> = (\n state,\n action,\n) => {\n switch (action.type) {\n case ACTIVATE_MODE:\n return {\n ...state,\n activeMode: action.payload.mode,\n };\n case SET_CURSOR:\n return {\n ...state,\n cursor: action.payload.cursor,\n };\n case PAUSE_INTERACTION:\n return {\n ...state,\n paused: true,\n };\n case RESUME_INTERACTION:\n return {\n ...state,\n paused: false,\n };\n default:\n return state;\n }\n};\n","import { PluginPackage } from '@embedpdf/core';\n\nimport { InteractionManagerPlugin } from './interaction-manager-plugin';\nimport { manifest, INTERACTION_MANAGER_PLUGIN_ID } from './manifest';\nimport { InteractionManagerPluginConfig, InteractionManagerState } from './types';\nimport { reducer, initialState } from './reducer';\nimport { InteractionManagerAction } from './actions';\n\nexport const InteractionManagerPluginPackage: PluginPackage<\n InteractionManagerPlugin,\n InteractionManagerPluginConfig,\n InteractionManagerState,\n InteractionManagerAction\n> = {\n manifest,\n create: (registry) => new InteractionManagerPlugin(INTERACTION_MANAGER_PLUGIN_ID, registry),\n reducer,\n initialState,\n};\n\nexport * from './interaction-manager-plugin';\nexport * from './types';\nexport * from './manifest';\nexport * from './reducer';\n"],"names":["ACTIVATE_MODE","PAUSE_INTERACTION","RESUME_INTERACTION","SET_CURSOR","_InteractionManagerPlugin","BasePlugin","constructor","id","registry","super","this","modes","Map","cursorClaims","buckets","alwaysGlobal","Set","alwaysPage","onModeChange$","createEmitter","onHandlerChange$","onCursorChange$","onStateChange$","createBehaviorEmitter","registerMode","scope","exclusive","cursor","initialize","_","buildCapability","activate","modeId","onModeChange","on","onCursorChange","onHandlerChange","onStateChange","getActiveMode","state","activeMode","getActiveInteractionMode","finish","mode","registerHandlers","options","registerAlways","setCursor","token","priority","removeCursor","getCurrentCursor","getHandlersForScope","activeModeIsExclusive","pause","dispatch","type","resume","isPaused","paused","has","Error","previousMode","clear","notifyHandlersInactive","payload","activateMode","emitCursor","notifyHandlersActive","emit","forEach","handler","_a","onHandlerActiveStart","call","handlerSet","get","bucket","global","page","pageIndex","onHandlerActiveEnd","set","handlers","modeIds","Array","isArray","cleanupFunctions","add","push","delete","size","cleanup","mergeSets","a","b","list","keys","out","k","evt","nativeEvt","h","mergeHandlers","modeSpecific","top","values","sort","onStoreUpdated","newState","destroy","InteractionManagerPlugin","INTERACTION_MANAGER_PLUGIN_ID","manifest","name","version","provides","requires","optional","defaultConfig","enabled","initialState","reducer","action","InteractionManagerPluginPackage","create"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,177 +1 @@
1
- import { BasePluginConfig, EventHook, BasePlugin, PluginRegistry, Action, PluginManifest, Reducer, PluginPackage } from '@embedpdf/core';
2
- import { Position } from '@embedpdf/models';
3
-
4
- interface InteractionManagerPluginConfig extends BasePluginConfig {
5
- }
6
- interface InteractionManagerState {
7
- /** Mode-id that is currently active (e.g. `"default"` or `"annotationCreation"`). */
8
- activeMode: string;
9
- /** Cursor that is currently active (e.g. `"auto"` or `"pointer"`). */
10
- cursor: string;
11
- /** Whether the interaction is paused */
12
- paused: boolean;
13
- }
14
- interface InteractionMode {
15
- /** unique id */
16
- id: string;
17
- /** where the handlers should listen for events */
18
- scope: 'global' | 'page';
19
- /** if true the page will receive events through a transparent overlay and no other page‑level
20
- * listener gets invoked until the mode finishes. */
21
- exclusive: boolean;
22
- /** baseline cursor while the mode is active (before any handler overrides it). */
23
- cursor?: string;
24
- }
25
- interface EmbedPdfPointerEvent {
26
- clientX: number;
27
- clientY: number;
28
- ctrlKey: boolean;
29
- shiftKey: boolean;
30
- altKey: boolean;
31
- metaKey: boolean;
32
- }
33
- interface PointerEventHandlers<T = EmbedPdfPointerEvent> {
34
- onPointerDown?(pos: Position, evt: T, modeId: string): void;
35
- onPointerUp?(pos: Position, evt: T, modeId: string): void;
36
- onPointerMove?(pos: Position, evt: T, modeId: string): void;
37
- onPointerEnter?(pos: Position, evt: T, modeId: string): void;
38
- onPointerLeave?(pos: Position, evt: T, modeId: string): void;
39
- onPointerCancel?(pos: Position, evt: T, modeId: string): void;
40
- }
41
- interface PointerEventHandlersWithLifecycle<T = EmbedPdfPointerEvent> extends PointerEventHandlers<T> {
42
- onHandlerActiveStart?(modeId: string): void;
43
- onHandlerActiveEnd?(modeId: string): void;
44
- }
45
- interface GlobalInteractionScope {
46
- type: 'global';
47
- }
48
- interface PageInteractionScope {
49
- type: 'page';
50
- pageIndex: number;
51
- }
52
- type InteractionScope = GlobalInteractionScope | PageInteractionScope;
53
- interface RegisterHandlersOptions {
54
- /** the mode the handlers belong to */
55
- modeId: string | string[];
56
- /** callbacks */
57
- handlers: PointerEventHandlersWithLifecycle;
58
- /** if omitted ⇒ handlers listen on the *global* layer */
59
- pageIndex?: number;
60
- }
61
- interface RegisterAlwaysOptions {
62
- scope: InteractionScope;
63
- handlers: PointerEventHandlersWithLifecycle;
64
- }
65
- interface InteractionManagerCapability {
66
- /** returns the active mode id */
67
- getActiveMode(): string;
68
- /** returns the active interaction mode */
69
- getActiveInteractionMode(): InteractionMode | null;
70
- /** programmatically switch to a mode */
71
- activate(modeId: string): void;
72
- /** finish current mode -> jumps back to `default` */
73
- finish(): void;
74
- /** register a mode (should be called at start‑up by each plugin/tool). */
75
- registerMode(mode: InteractionMode): void;
76
- /** register pointer handlers that run *only* while the given mode is active. */
77
- registerHandlers(options: RegisterHandlersOptions): () => void;
78
- /** register pointer handlers that run *always* (even if no mode is active). */
79
- registerAlways(options: RegisterAlwaysOptions): () => void;
80
- /** low‑level cursor API. Handlers can claim the cursor with a priority (larger wins). */
81
- setCursor(token: string, cursor: string, priority?: number): void;
82
- /** Returns the current cursor */
83
- getCurrentCursor(): string;
84
- /** remove a cursor */
85
- removeCursor(token: string): void;
86
- /** subscribe to mode changes (so framework layers can raise overlays, etc.) */
87
- onModeChange: EventHook<InteractionManagerState>;
88
- /** subscribe to cursor changes */
89
- onCursorChange: EventHook<string>;
90
- /** subscribe to handler changes */
91
- onHandlerChange: EventHook<InteractionManagerState>;
92
- /** subscribe to state changes */
93
- onStateChange: EventHook<InteractionManagerState>;
94
- /** framework helpers -------------------------------------------------------------- */
95
- /** Returns the *merged* handler set for the current mode + given scope.
96
- * Used by the PointerInteractionProvider inside each page / at the root. */
97
- getHandlersForScope(scope: InteractionScope): PointerEventHandlers | null;
98
- /** Returns whether the current active mode demands an overlay */
99
- activeModeIsExclusive(): boolean;
100
- /** Pause the interaction */
101
- pause(): void;
102
- /** Resume the interaction */
103
- resume(): void;
104
- /** Returns whether the interaction is paused */
105
- isPaused(): boolean;
106
- }
107
-
108
- declare class InteractionManagerPlugin extends BasePlugin<InteractionManagerPluginConfig, InteractionManagerCapability, InteractionManagerState> {
109
- static readonly id: "interaction-manager";
110
- private modes;
111
- private cursorClaims;
112
- private buckets;
113
- private alwaysGlobal;
114
- private alwaysPage;
115
- private readonly onModeChange$;
116
- private readonly onHandlerChange$;
117
- private readonly onCursorChange$;
118
- private readonly onStateChange$;
119
- constructor(id: string, registry: PluginRegistry);
120
- initialize(_: InteractionManagerPluginConfig): Promise<void>;
121
- protected buildCapability(): InteractionManagerCapability;
122
- private activate;
123
- private notifyHandlersActive;
124
- private notifyHandlersInactive;
125
- private registerMode;
126
- /** ---------- pointer-handler handling ------------ */
127
- private registerHandlers;
128
- registerAlways({ scope, handlers }: RegisterAlwaysOptions): () => void;
129
- /** Returns the *merged* handler set that should be active for the given
130
- * provider (`global` wrapper or a single page wrapper).
131
- * – `alwaysGlobal` / `alwaysPage` are **always** active.
132
- * – Handlers that belong to the current mode are added on top **iff**
133
- * the mode’s own scope matches the provider’s scope. */
134
- private getHandlersForScope;
135
- /** ---------- cursor handling --------------------- */
136
- private setCursor;
137
- private removeCursor;
138
- private emitCursor;
139
- onStoreUpdated(_: InteractionManagerState, newState: InteractionManagerState): void;
140
- private activeModeIsExclusive;
141
- private getActiveInteractionMode;
142
- destroy(): Promise<void>;
143
- }
144
-
145
- declare const ACTIVATE_MODE = "INTERACTION/ACTIVATE_MODE";
146
- declare const PAUSE_INTERACTION = "INTERACTION/PAUSE";
147
- declare const RESUME_INTERACTION = "INTERACTION/RESUME";
148
- declare const SET_CURSOR = "INTERACTION/SET_CURSOR";
149
- interface ActivateModeAction extends Action {
150
- type: typeof ACTIVATE_MODE;
151
- payload: {
152
- mode: string;
153
- };
154
- }
155
- interface PauseInteractionAction extends Action {
156
- type: typeof PAUSE_INTERACTION;
157
- }
158
- interface ResumeInteractionAction extends Action {
159
- type: typeof RESUME_INTERACTION;
160
- }
161
- interface SetCursorAction extends Action {
162
- type: typeof SET_CURSOR;
163
- payload: {
164
- cursor: string;
165
- };
166
- }
167
- type InteractionManagerAction = ActivateModeAction | PauseInteractionAction | ResumeInteractionAction | SetCursorAction;
168
-
169
- declare const INTERACTION_MANAGER_PLUGIN_ID = "interaction-manager";
170
- declare const manifest: PluginManifest<InteractionManagerPluginConfig>;
171
-
172
- declare const initialState: InteractionManagerState;
173
- declare const reducer: Reducer<InteractionManagerState, InteractionManagerAction>;
174
-
175
- declare const InteractionManagerPluginPackage: PluginPackage<InteractionManagerPlugin, InteractionManagerPluginConfig, InteractionManagerState, InteractionManagerAction>;
176
-
177
- export { type EmbedPdfPointerEvent, INTERACTION_MANAGER_PLUGIN_ID, type InteractionManagerCapability, InteractionManagerPlugin, type InteractionManagerPluginConfig, InteractionManagerPluginPackage, type InteractionManagerState, type InteractionMode, type InteractionScope, type PointerEventHandlers, type PointerEventHandlersWithLifecycle, type RegisterAlwaysOptions, type RegisterHandlersOptions, initialState, manifest, reducer };
1
+ export * from './lib';