flipbookengine 0.3.0 → 0.5.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.
@@ -1,43 +1,58 @@
1
- import { jsx as a } from "react/jsx-runtime";
2
- import { forwardRef as g, useRef as o, useImperativeHandle as b, useEffect as c } from "react";
3
- import { FlipbookEngine as x } from "./flipbook-engine.js";
4
- const v = g(({
5
- className: f,
6
- style: l,
7
- pdfUrl: s,
8
- pages: t,
1
+ import { jsx as m } from "react/jsx-runtime";
2
+ import { forwardRef as P, useRef as g, useImperativeHandle as x, useEffect as c } from "react";
3
+ import { F as d } from "./engine-BuVkDIh-.js";
4
+ const v = P(({
5
+ className: a,
6
+ style: f,
7
+ pdfUrl: i,
8
+ pages: s,
9
9
  onPageChange: n,
10
10
  ...u
11
- }, p) => {
12
- const i = o(null), e = o(null);
13
- return b(p, () => ({
11
+ }, l) => {
12
+ const o = g(null), r = g(null);
13
+ return x(l, () => ({
14
14
  get engine() {
15
- return e.current;
15
+ return r.current;
16
+ },
17
+ nextPage: () => {
18
+ var e;
19
+ return (e = r.current) == null ? void 0 : e.nextPage();
20
+ },
21
+ prevPage: () => {
22
+ var e;
23
+ return (e = r.current) == null ? void 0 : e.prevPage();
24
+ },
25
+ goToPage: (e) => {
26
+ var t;
27
+ return (t = r.current) == null ? void 0 : t.goToPage(e);
16
28
  },
17
29
  flipNext: () => {
18
- var r;
19
- return (r = e.current) == null ? void 0 : r.nextPage();
30
+ var e;
31
+ return (e = r.current) == null ? void 0 : e.nextPage();
20
32
  },
21
33
  flipPrev: () => {
22
- var r;
23
- return (r = e.current) == null ? void 0 : r.prevPage();
34
+ var e;
35
+ return (e = r.current) == null ? void 0 : e.prevPage();
24
36
  },
25
- turnToPage: (r) => {
26
- e.current && e.current.goToPage(r);
37
+ turnToPage: (e) => {
38
+ var t;
39
+ return (t = r.current) == null ? void 0 : t.goToPage(e);
27
40
  }
28
- })), c(() => {
29
- if (!i.current) return;
30
- const r = new x(i.current, u);
31
- e.current = r;
32
- const m = r.on("pageChange", (d) => n == null ? void 0 : n(d));
33
- return r.init(s, t || []).catch(console.error), () => {
34
- m(), r.destroy(), e.current = null;
41
+ }), []), c(() => {
42
+ if (!o.current) return;
43
+ const e = new d(o.current, u);
44
+ r.current = e;
45
+ const t = e.on("pageChange", (p) => n == null ? void 0 : n(p));
46
+ return () => {
47
+ t(), e.destroy(), r.current = null;
35
48
  };
36
49
  }, []), c(() => {
37
- e.current && e.current.updateOptions(u);
38
- }, [u]), c(() => {
39
- e.current && e.current.setPages(t || []);
40
- }, [t]), /* @__PURE__ */ a("div", { ref: i, className: f, style: { width: "100%", height: "100%", minHeight: "400px", ...l } });
50
+ const e = r.current;
51
+ e && e.setPages(s, i).catch(console.error);
52
+ }, [i, s]), c(() => {
53
+ var e;
54
+ (e = r.current) == null || e.updateOptions(u);
55
+ }, [u]), /* @__PURE__ */ m("div", { ref: o, className: a, style: { width: "100%", height: "100%", minHeight: "400px", ...f } });
41
56
  });
42
57
  v.displayName = "Flipbook";
43
58
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"flipbook-engine.react.js","sources":["../src/react/index.tsx"],"sourcesContent":["/**\n * FlipbookEngine\n * Copyright (c) 2026 Murat Dogan\n * SPDX-License-Identifier: AGPL-3.0-or-later\n * https://flipbookengine.com\n */\n\n/** @jsxImportSource react */\nimport React, { forwardRef, useEffect, useImperativeHandle, useRef } from 'react';\nimport { FlipbookEngine, FlipbookEngineOptions, FlipbookPageAsset } from '../index';\n\nexport interface FlipbookProps extends Omit<FlipbookEngineOptions, 'theme'> {\n className?: string;\n style?: React.CSSProperties;\n pdfUrl: string;\n pages?: FlipbookPageAsset[];\n theme?: 'auto' | 'light' | 'dark';\n onPageChange?: (e: { currentPage: number; totalPages: number }) => void;\n}\n\nexport interface FlipbookRef {\n engine: FlipbookEngine | null;\n flipNext: () => void;\n flipPrev: () => void;\n turnToPage: (pageIndex: number) => void;\n}\n\nexport const Flipbook = forwardRef<FlipbookRef, FlipbookProps>(({\n className,\n style,\n pdfUrl,\n pages,\n onPageChange,\n ...options\n}, ref) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const engineRef = useRef<FlipbookEngine | null>(null);\n\n useImperativeHandle(ref, () => ({\n get engine() { return engineRef.current; },\n flipNext: () => engineRef.current?.nextPage(),\n flipPrev: () => engineRef.current?.prevPage(),\n turnToPage: (idx: number) => {\n if (engineRef.current) {\n engineRef.current.goToPage(idx);\n }\n }\n }));\n\n useEffect(() => {\n if (!containerRef.current) return;\n\n const engine = new FlipbookEngine(containerRef.current, options);\n engineRef.current = engine;\n\n const unsubscribeChange = engine.on('pageChange', (e: any) => onPageChange?.(e));\n\n engine.init(pdfUrl, pages || []).catch(console.error);\n\n return () => {\n unsubscribeChange();\n engine.destroy();\n engineRef.current = null;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []); // Run once on mount\n\n useEffect(() => {\n if (engineRef.current) {\n engineRef.current.updateOptions(options);\n }\n }, [options]);\n\n useEffect(() => {\n if (engineRef.current) {\n engineRef.current.setPages(pages || []);\n }\n }, [pages]);\n\n return <div ref={containerRef} className={className} style={{ width: '100%', height: '100%', minHeight: '400px', ...style }} />;\n});\n\nFlipbook.displayName = 'Flipbook';\n"],"names":["Flipbook","forwardRef","className","style","pdfUrl","pages","onPageChange","options","ref","containerRef","useRef","engineRef","useImperativeHandle","_a","idx","useEffect","engine","FlipbookEngine","unsubscribeChange","e","jsx"],"mappings":";;;AA2BO,MAAMA,IAAWC,EAAuC,CAAC;AAAA,EAC5D,WAAAC;AAAA,EACA,OAAAC;AAAA,EACA,QAAAC;AAAA,EACA,OAAAC;AAAA,EACA,cAAAC;AAAA,EACA,GAAGC;AACP,GAAGC,MAAQ;AACP,QAAMC,IAAeC,EAAuB,IAAI,GAC1CC,IAAYD,EAA8B,IAAI;AAEpD,SAAAE,EAAoBJ,GAAK,OAAO;AAAA,IAC5B,IAAI,SAAS;AAAE,aAAOG,EAAU;AAAA,IAAS;AAAA,IACzC,UAAU,MAAA;;AAAM,cAAAE,IAAAF,EAAU,YAAV,gBAAAE,EAAmB;AAAA;AAAA,IACnC,UAAU,MAAA;;AAAM,cAAAA,IAAAF,EAAU,YAAV,gBAAAE,EAAmB;AAAA;AAAA,IACnC,YAAY,CAACC,MAAgB;AACzB,MAAIH,EAAU,WACVA,EAAU,QAAQ,SAASG,CAAG;AAAA,IAEtC;AAAA,EAAA,EACF,GAEFC,EAAU,MAAM;AACZ,QAAI,CAACN,EAAa,QAAS;AAE3B,UAAMO,IAAS,IAAIC,EAAeR,EAAa,SAASF,CAAO;AAC/D,IAAAI,EAAU,UAAUK;AAEpB,UAAME,IAAoBF,EAAO,GAAG,cAAc,CAACG,MAAWb,KAAA,gBAAAA,EAAea,EAAE;AAE/E,WAAAH,EAAO,KAAKZ,GAAQC,KAAS,CAAA,CAAE,EAAE,MAAM,QAAQ,KAAK,GAE7C,MAAM;AACT,MAAAa,EAAA,GACAF,EAAO,QAAA,GACPL,EAAU,UAAU;AAAA,IACxB;AAAA,EAEJ,GAAG,CAAA,CAAE,GAELI,EAAU,MAAM;AACZ,IAAIJ,EAAU,WACVA,EAAU,QAAQ,cAAcJ,CAAO;AAAA,EAE/C,GAAG,CAACA,CAAO,CAAC,GAEZQ,EAAU,MAAM;AACZ,IAAIJ,EAAU,WACVA,EAAU,QAAQ,SAASN,KAAS,CAAA,CAAE;AAAA,EAE9C,GAAG,CAACA,CAAK,CAAC,GAEH,gBAAAe,EAAC,OAAA,EAAI,KAAKX,GAAc,WAAAP,GAAsB,OAAO,EAAE,OAAO,QAAQ,QAAQ,QAAQ,WAAW,SAAS,GAAGC,KAAS;AACjI,CAAC;AAEDH,EAAS,cAAc;"}
1
+ {"version":3,"file":"flipbook-engine.react.js","sources":["../src/react/index.tsx"],"sourcesContent":["/**\n * FlipbookEngine\n * Copyright (c) 2026 Murat Dogan\n * SPDX-License-Identifier: AGPL-3.0-or-later\n * https://flipbookengine.com\n */\n\n/** @jsxImportSource react */\nimport React, { forwardRef, useEffect, useImperativeHandle, useRef } from 'react';\nimport { FlipbookEngine, FlipbookEngineOptions, FlipbookPageAsset } from '../index';\n\nexport interface FlipbookProps extends Omit<FlipbookEngineOptions, 'theme'> {\n className?: string;\n style?: React.CSSProperties;\n pdfUrl?: string;\n pages?: FlipbookPageAsset[];\n theme?: 'auto' | 'light' | 'dark';\n onPageChange?: (e: { currentPage: number; totalPages: number }) => void;\n}\n\nexport interface FlipbookRef {\n engine: FlipbookEngine | null;\n nextPage: () => void;\n prevPage: () => void;\n goToPage: (pageIndex: number) => void;\n flipNext: () => void;\n flipPrev: () => void;\n turnToPage: (pageIndex: number) => void;\n}\n\nexport const Flipbook = forwardRef<FlipbookRef, FlipbookProps>(({\n className,\n style,\n pdfUrl,\n pages,\n onPageChange,\n ...options\n}, ref) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const engineRef = useRef<FlipbookEngine | null>(null);\n\n useImperativeHandle(ref, () => ({\n get engine() { return engineRef.current; },\n nextPage: () => engineRef.current?.nextPage(),\n prevPage: () => engineRef.current?.prevPage(),\n goToPage: (index: number) => engineRef.current?.goToPage(index),\n flipNext: () => engineRef.current?.nextPage(),\n flipPrev: () => engineRef.current?.prevPage(),\n turnToPage: (index: number) => engineRef.current?.goToPage(index)\n }), []);\n\n // Create one engine for the mounted component. Source data is managed by the\n // separate effect below so PDF-only renders do not trigger a second empty init.\n useEffect(() => {\n if (!containerRef.current) return;\n\n const engine = new FlipbookEngine(containerRef.current, options);\n engineRef.current = engine;\n const unsubscribeChange = engine.on('pageChange', (e: any) => onPageChange?.(e));\n\n return () => {\n unsubscribeChange();\n engine.destroy();\n engineRef.current = null;\n };\n // The engine is intentionally created once per mount, including Strict Mode remounts.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // A source update is the only place that initializes or reinitializes the engine.\n useEffect(() => {\n const engine = engineRef.current;\n if (!engine) return;\n engine.setPages(pages, pdfUrl).catch(console.error);\n }, [pdfUrl, pages]);\n\n useEffect(() => {\n engineRef.current?.updateOptions(options);\n }, [options]);\n\n return <div ref={containerRef} className={className} style={{ width: '100%', height: '100%', minHeight: '400px', ...style }} />;\n});\n\nFlipbook.displayName = 'Flipbook';\r\n"],"names":["Flipbook","forwardRef","className","style","pdfUrl","pages","onPageChange","options","ref","containerRef","useRef","engineRef","useImperativeHandle","_a","index","useEffect","engine","FlipbookEngine","unsubscribeChange","e","jsx"],"mappings":";;;AA8BO,MAAMA,IAAWC,EAAuC,CAAC;AAAA,EAC5D,WAAAC;AAAA,EACA,OAAAC;AAAA,EACA,QAAAC;AAAA,EACA,OAAAC;AAAA,EACA,cAAAC;AAAA,EACA,GAAGC;AACP,GAAGC,MAAQ;AACP,QAAMC,IAAeC,EAAuB,IAAI,GAC1CC,IAAYD,EAA8B,IAAI;AAEpD,SAAAE,EAAoBJ,GAAK,OAAO;AAAA,IAC5B,IAAI,SAAS;AAAE,aAAOG,EAAU;AAAA,IAAS;AAAA,IACzC,UAAU,MAAA;;AAAM,cAAAE,IAAAF,EAAU,YAAV,gBAAAE,EAAmB;AAAA;AAAA,IACnC,UAAU,MAAA;;AAAM,cAAAA,IAAAF,EAAU,YAAV,gBAAAE,EAAmB;AAAA;AAAA,IACnC,UAAU,CAACC,MAAA;;AAAkB,cAAAD,IAAAF,EAAU,YAAV,gBAAAE,EAAmB,SAASC;AAAA;AAAA,IACzD,UAAU,MAAA;;AAAM,cAAAD,IAAAF,EAAU,YAAV,gBAAAE,EAAmB;AAAA;AAAA,IACnC,UAAU,MAAA;;AAAM,cAAAA,IAAAF,EAAU,YAAV,gBAAAE,EAAmB;AAAA;AAAA,IACnC,YAAY,CAACC,MAAA;;AAAkB,cAAAD,IAAAF,EAAU,YAAV,gBAAAE,EAAmB,SAASC;AAAA;AAAA,EAAK,IAChE,CAAA,CAAE,GAINC,EAAU,MAAM;AACZ,QAAI,CAACN,EAAa,QAAS;AAE3B,UAAMO,IAAS,IAAIC,EAAeR,EAAa,SAASF,CAAO;AAC/D,IAAAI,EAAU,UAAUK;AACpB,UAAME,IAAoBF,EAAO,GAAG,cAAc,CAACG,MAAWb,KAAA,gBAAAA,EAAea,EAAE;AAE/E,WAAO,MAAM;AACT,MAAAD,EAAA,GACAF,EAAO,QAAA,GACPL,EAAU,UAAU;AAAA,IACxB;AAAA,EAGJ,GAAG,CAAA,CAAE,GAGLI,EAAU,MAAM;AACZ,UAAMC,IAASL,EAAU;AACzB,IAAKK,KACLA,EAAO,SAASX,GAAOD,CAAM,EAAE,MAAM,QAAQ,KAAK;AAAA,EACtD,GAAG,CAACA,GAAQC,CAAK,CAAC,GAElBU,EAAU,MAAM;;AACZ,KAAAF,IAAAF,EAAU,YAAV,QAAAE,EAAmB,cAAcN;AAAA,EACrC,GAAG,CAACA,CAAO,CAAC,GAEL,gBAAAa,EAAC,OAAA,EAAI,KAAKX,GAAc,WAAAP,GAAsB,OAAO,EAAE,OAAO,QAAQ,QAAQ,QAAQ,WAAW,SAAS,GAAGC,KAAS;AACjI,CAAC;AAEDH,EAAS,cAAc;"}
@@ -1,11 +1,12 @@
1
- import { defineComponent as l, ref as u, onMounted as f, onBeforeUnmount as g, watch as r, h as s } from "vue";
2
- import { FlipbookEngine as d } from "./flipbook-engine.js";
3
- const m = l({
1
+ import { defineComponent as d, ref as s, onMounted as g, onBeforeUnmount as P, watch as l, h as c } from "vue";
2
+ import { F as h } from "./engine-BuVkDIh-.js";
3
+ const v = d({
4
4
  name: "Flipbook",
5
5
  props: {
6
6
  pdfUrl: {
7
7
  type: String,
8
- required: !0
8
+ required: !1,
9
+ default: ""
9
10
  },
10
11
  pages: {
11
12
  type: Array,
@@ -18,31 +19,33 @@ const m = l({
18
19
  }
19
20
  },
20
21
  emits: ["pageChange"],
21
- setup(n, { emit: a, expose: p }) {
22
- const o = u(null);
23
- let e = null, i;
24
- return f(() => {
25
- o.value && (e = new d(o.value, n.options), i = e.on("pageChange", (t) => a("pageChange", t)), e.init(n.pdfUrl, n.pages || []).catch(console.error));
26
- }), g(() => {
27
- i && i(), e && (e.destroy(), e = null);
28
- }), r(() => n.options, (t) => {
29
- e && e.updateOptions(t);
30
- }, { deep: !0 }), r(() => n.pages, (t) => {
31
- e && e.setPages(t || []);
32
- }, { deep: !0 }), p({
22
+ setup(o, { emit: p, expose: f }) {
23
+ const r = s(null);
24
+ let e = null, a;
25
+ return g(() => {
26
+ r.value && (e = new h(r.value, o.options), a = e.on("pageChange", (t) => p("pageChange", t)), e.setPages(o.pages, o.pdfUrl).catch(console.error));
27
+ }), P(() => {
28
+ a == null || a(), e == null || e.destroy(), e = null;
29
+ }), l(() => o.options, (t) => {
30
+ e == null || e.updateOptions(t);
31
+ }, { deep: !0 }), l([() => o.pdfUrl, () => o.pages], ([t, u]) => {
32
+ e == null || e.setPages(u || [], t || "").catch(console.error);
33
+ }, { deep: !0 }), f({
33
34
  getEngine: () => e,
35
+ engine: () => e,
36
+ nextPage: () => e == null ? void 0 : e.nextPage(),
37
+ prevPage: () => e == null ? void 0 : e.prevPage(),
38
+ goToPage: (t) => e == null ? void 0 : e.goToPage(t),
34
39
  flipNext: () => e == null ? void 0 : e.nextPage(),
35
40
  flipPrev: () => e == null ? void 0 : e.prevPage(),
36
- turnToPage: (t) => {
37
- e && e.goToPage(t);
38
- }
39
- }), () => s("div", {
40
- ref: o,
41
+ turnToPage: (t) => e == null ? void 0 : e.goToPage(t)
42
+ }), () => c("div", {
43
+ ref: r,
41
44
  style: { width: "100%", height: "100%", minHeight: "400px" }
42
45
  });
43
46
  }
44
47
  });
45
48
  export {
46
- m as Flipbook
49
+ v as Flipbook
47
50
  };
48
51
  //# sourceMappingURL=flipbook-engine.vue.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"flipbook-engine.vue.js","sources":["../src/vue/index.ts"],"sourcesContent":["/**\n * FlipbookEngine\n * Copyright (c) 2026 Murat Dogan\n * SPDX-License-Identifier: AGPL-3.0-or-later\n * https://flipbookengine.com\n */\n\nimport { defineComponent, h, ref, onMounted, onBeforeUnmount, watch, PropType } from 'vue';\nimport { FlipbookEngine, FlipbookEngineOptions, FlipbookPageAsset } from '../index';\n\nexport const Flipbook = defineComponent({\n name: 'Flipbook',\n props: {\n pdfUrl: {\n type: String,\n required: true\n },\n pages: {\n type: Array as PropType<FlipbookPageAsset[]>,\n required: false,\n default: () => []\n },\n options: {\n type: Object as PropType<Omit<FlipbookEngineOptions, 'theme'> & { theme?: 'auto' | 'light' | 'dark' }>,\n default: () => ({})\n }\n },\n emits: ['pageChange'],\n setup(props, { emit, expose }) {\n const containerRef = ref<HTMLElement | null>(null);\n let engine: FlipbookEngine | null = null;\n let unsubscribeChange: () => void;\n \n onMounted(() => {\n if (!containerRef.value) return;\n \n engine = new FlipbookEngine(containerRef.value, props.options as any);\n \n unsubscribeChange = engine.on('pageChange', (e: any) => emit('pageChange', e));\n \n engine.init(props.pdfUrl, props.pages || []).catch(console.error);\n });\n \n onBeforeUnmount(() => {\n if (unsubscribeChange) unsubscribeChange();\n if (engine) {\n engine.destroy();\n engine = null;\n }\n });\n \n watch(() => props.options, (newOptions) => {\n if (engine) {\n engine.updateOptions(newOptions as any);\n }\n }, { deep: true });\n \n watch(() => props.pages, (newPages) => {\n if (engine) {\n engine.setPages(newPages || []);\n }\n }, { deep: true });\n\n expose({\n getEngine: () => engine,\n flipNext: () => engine?.nextPage(),\n flipPrev: () => engine?.prevPage(),\n turnToPage: (idx: number) => {\n if (engine) {\n engine.goToPage(idx);\n }\n }\n });\n\n return () => h('div', {\n ref: containerRef,\n style: { width: '100%', height: '100%', minHeight: '400px' }\n });\n }\n});\n"],"names":["Flipbook","defineComponent","props","emit","expose","containerRef","ref","engine","unsubscribeChange","onMounted","FlipbookEngine","e","onBeforeUnmount","watch","newOptions","newPages","idx","h"],"mappings":";;AAUO,MAAMA,IAAWC,EAAgB;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,IACH,QAAQ;AAAA,MACJ,MAAM;AAAA,MACN,UAAU;AAAA,IAAA;AAAA,IAEd,OAAO;AAAA,MACH,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS,MAAM,CAAA;AAAA,IAAC;AAAA,IAEpB,SAAS;AAAA,MACL,MAAM;AAAA,MACN,SAAS,OAAO,CAAA;AAAA,IAAC;AAAA,EACrB;AAAA,EAEJ,OAAO,CAAC,YAAY;AAAA,EACpB,MAAMC,GAAO,EAAE,MAAAC,GAAM,QAAAC,KAAU;AAC3B,UAAMC,IAAeC,EAAwB,IAAI;AACjD,QAAIC,IAAgC,MAChCC;AAEJ,WAAAC,EAAU,MAAM;AACZ,MAAKJ,EAAa,UAElBE,IAAS,IAAIG,EAAeL,EAAa,OAAOH,EAAM,OAAc,GAEpEM,IAAoBD,EAAO,GAAG,cAAc,CAACI,MAAWR,EAAK,cAAcQ,CAAC,CAAC,GAE7EJ,EAAO,KAAKL,EAAM,QAAQA,EAAM,SAAS,CAAA,CAAE,EAAE,MAAM,QAAQ,KAAK;AAAA,IACpE,CAAC,GAEDU,EAAgB,MAAM;AAClB,MAAIJ,KAAmBA,EAAA,GACnBD,MACAA,EAAO,QAAA,GACPA,IAAS;AAAA,IAEjB,CAAC,GAEDM,EAAM,MAAMX,EAAM,SAAS,CAACY,MAAe;AACvC,MAAIP,KACAA,EAAO,cAAcO,CAAiB;AAAA,IAE9C,GAAG,EAAE,MAAM,IAAM,GAEjBD,EAAM,MAAMX,EAAM,OAAO,CAACa,MAAa;AACnC,MAAIR,KACAA,EAAO,SAASQ,KAAY,EAAE;AAAA,IAEtC,GAAG,EAAE,MAAM,IAAM,GAEjBX,EAAO;AAAA,MACH,WAAW,MAAMG;AAAA,MACjB,UAAU,MAAMA,KAAA,gBAAAA,EAAQ;AAAA,MACxB,UAAU,MAAMA,KAAA,gBAAAA,EAAQ;AAAA,MACxB,YAAY,CAACS,MAAgB;AACzB,QAAIT,KACAA,EAAO,SAASS,CAAG;AAAA,MAE3B;AAAA,IAAA,CACH,GAEM,MAAMC,EAAE,OAAO;AAAA,MAClB,KAAKZ;AAAA,MACL,OAAO,EAAE,OAAO,QAAQ,QAAQ,QAAQ,WAAW,QAAA;AAAA,IAAQ,CAC9D;AAAA,EACL;AACJ,CAAC;"}
1
+ {"version":3,"file":"flipbook-engine.vue.js","sources":["../src/vue/index.ts"],"sourcesContent":["/**\n * FlipbookEngine\n * Copyright (c) 2026 Murat Dogan\n * SPDX-License-Identifier: AGPL-3.0-or-later\n * https://flipbookengine.com\n */\n\nimport { defineComponent, h, ref, onMounted, onBeforeUnmount, watch, PropType } from 'vue';\nimport { FlipbookEngine, FlipbookEngineOptions, FlipbookPageAsset } from '../index';\n\nexport const Flipbook = defineComponent({\n name: 'Flipbook',\n props: {\n pdfUrl: {\n type: String,\n required: false,\n default: ''\n },\n pages: {\n type: Array as PropType<FlipbookPageAsset[]>,\n required: false,\n default: () => []\n },\n options: {\n type: Object as PropType<Omit<FlipbookEngineOptions, 'theme'> & { theme?: 'auto' | 'light' | 'dark' }>,\n default: () => ({})\n }\n },\n emits: ['pageChange'],\n setup(props, { emit, expose }) {\n const containerRef = ref<HTMLElement | null>(null);\n let engine: FlipbookEngine | null = null;\n let unsubscribeChange: (() => void) | undefined;\n\n onMounted(() => {\n if (!containerRef.value) return;\n\n engine = new FlipbookEngine(containerRef.value, props.options as any);\n unsubscribeChange = engine.on('pageChange', (e: any) => emit('pageChange', e));\n engine.setPages(props.pages, props.pdfUrl).catch(console.error);\n });\n\n onBeforeUnmount(() => {\n unsubscribeChange?.();\n engine?.destroy();\n engine = null;\n });\n\n watch(() => props.options, (newOptions) => {\n engine?.updateOptions(newOptions as any);\n }, { deep: true });\n\n // Source changes are handled together to guarantee one reinitialization per update.\n watch([() => props.pdfUrl, () => props.pages], ([newPdfUrl, newPages]) => {\n engine?.setPages(newPages || [], newPdfUrl || '').catch(console.error);\n }, { deep: true });\n\n expose({\n getEngine: () => engine,\n engine: () => engine,\n nextPage: () => engine?.nextPage(),\n prevPage: () => engine?.prevPage(),\n goToPage: (index: number) => engine?.goToPage(index),\n flipNext: () => engine?.nextPage(),\n flipPrev: () => engine?.prevPage(),\n turnToPage: (index: number) => engine?.goToPage(index)\n });\n\n return () => h('div', {\n ref: containerRef,\n style: { width: '100%', height: '100%', minHeight: '400px' }\n });\n }\n});\r\n"],"names":["Flipbook","defineComponent","props","emit","expose","containerRef","ref","engine","unsubscribeChange","onMounted","FlipbookEngine","e","onBeforeUnmount","watch","newOptions","newPdfUrl","newPages","index","h"],"mappings":";;AAUO,MAAMA,IAAWC,EAAgB;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,IACH,QAAQ;AAAA,MACJ,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,IAAA;AAAA,IAEb,OAAO;AAAA,MACH,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS,MAAM,CAAA;AAAA,IAAC;AAAA,IAEpB,SAAS;AAAA,MACL,MAAM;AAAA,MACN,SAAS,OAAO,CAAA;AAAA,IAAC;AAAA,EACrB;AAAA,EAEJ,OAAO,CAAC,YAAY;AAAA,EACpB,MAAMC,GAAO,EAAE,MAAAC,GAAM,QAAAC,KAAU;AAC3B,UAAMC,IAAeC,EAAwB,IAAI;AACjD,QAAIC,IAAgC,MAChCC;AAEJ,WAAAC,EAAU,MAAM;AACZ,MAAKJ,EAAa,UAElBE,IAAS,IAAIG,EAAeL,EAAa,OAAOH,EAAM,OAAc,GACpEM,IAAoBD,EAAO,GAAG,cAAc,CAACI,MAAWR,EAAK,cAAcQ,CAAC,CAAC,GAC7EJ,EAAO,SAASL,EAAM,OAAOA,EAAM,MAAM,EAAE,MAAM,QAAQ,KAAK;AAAA,IAClE,CAAC,GAEDU,EAAgB,MAAM;AAClB,MAAAJ,KAAA,QAAAA,KACAD,KAAA,QAAAA,EAAQ,WACRA,IAAS;AAAA,IACb,CAAC,GAEDM,EAAM,MAAMX,EAAM,SAAS,CAACY,MAAe;AACvC,MAAAP,KAAA,QAAAA,EAAQ,cAAcO;AAAA,IAC1B,GAAG,EAAE,MAAM,IAAM,GAGjBD,EAAM,CAAC,MAAMX,EAAM,QAAQ,MAAMA,EAAM,KAAK,GAAG,CAAC,CAACa,GAAWC,CAAQ,MAAM;AACtE,MAAAT,KAAA,QAAAA,EAAQ,SAASS,KAAY,IAAID,KAAa,IAAI,MAAM,QAAQ;AAAA,IACpE,GAAG,EAAE,MAAM,IAAM,GAEjBX,EAAO;AAAA,MACH,WAAW,MAAMG;AAAA,MACjB,QAAQ,MAAMA;AAAA,MACd,UAAU,MAAMA,KAAA,gBAAAA,EAAQ;AAAA,MACxB,UAAU,MAAMA,KAAA,gBAAAA,EAAQ;AAAA,MACxB,UAAU,CAACU,MAAkBV,KAAA,gBAAAA,EAAQ,SAASU;AAAA,MAC9C,UAAU,MAAMV,KAAA,gBAAAA,EAAQ;AAAA,MACxB,UAAU,MAAMA,KAAA,gBAAAA,EAAQ;AAAA,MACxB,YAAY,CAACU,MAAkBV,KAAA,gBAAAA,EAAQ,SAASU;AAAA,IAAK,CACxD,GAEM,MAAMC,EAAE,OAAO;AAAA,MAClB,KAAKb;AAAA,MACL,OAAO,EAAE,OAAO,QAAQ,QAAQ,QAAQ,WAAW,QAAA;AAAA,IAAQ,CAC9D;AAAA,EACL;AACJ,CAAC;"}
@@ -4,7 +4,7 @@ import { FlipbookEngine, FlipbookEngineOptions, FlipbookPageAsset } from '../ind
4
4
  export interface FlipbookProps extends Omit<FlipbookEngineOptions, 'theme'> {
5
5
  className?: string;
6
6
  style?: React.CSSProperties;
7
- pdfUrl: string;
7
+ pdfUrl?: string;
8
8
  pages?: FlipbookPageAsset[];
9
9
  theme?: 'auto' | 'light' | 'dark';
10
10
  onPageChange?: (e: {
@@ -14,6 +14,9 @@ export interface FlipbookProps extends Omit<FlipbookEngineOptions, 'theme'> {
14
14
  }
15
15
  export interface FlipbookRef {
16
16
  engine: FlipbookEngine | null;
17
+ nextPage: () => void;
18
+ prevPage: () => void;
19
+ goToPage: (pageIndex: number) => void;
17
20
  flipNext: () => void;
18
21
  flipPrev: () => void;
19
22
  turnToPage: (pageIndex: number) => void;
@@ -1,32 +1,51 @@
1
+ import { Signal, ReadonlySignal } from '@preact/signals-core';
1
2
  import { FlipbookThemeMode } from '../theme/theme';
2
3
  import { NormalizedFlipbookPage } from '../model/pages';
3
4
  import { FlipbookEngineOptions } from '../engine';
5
+ import { PartialFlipbookMessages } from '../i18n/service';
4
6
 
5
- export declare const currentPage: import('@preact/signals-core').Signal<number>;
6
- export declare const totalPages: import('@preact/signals-core').Signal<number>;
7
- export declare const isSingleMode: import('@preact/signals-core').Signal<boolean>;
8
- export declare const showThumbs: import('@preact/signals-core').Signal<boolean>;
9
- export declare const showArrows: import('@preact/signals-core').Signal<boolean>;
10
- export declare const orientation: import('@preact/signals-core').Signal<"landscape" | "portrait">;
11
- export declare const flipState: import('@preact/signals-core').Signal<"read" | "fold_corner" | "flipping">;
12
- export declare const themeMode: import('@preact/signals-core').Signal<FlipbookThemeMode>;
13
- export declare const allowDownload: import('@preact/signals-core').Signal<boolean>;
14
- export declare const hasDownloadUrl: import('@preact/signals-core').Signal<boolean>;
15
- export declare const primaryColor: import('@preact/signals-core').Signal<string>;
16
- export declare const whiteLabel: import('@preact/signals-core').Signal<boolean>;
17
- export declare const isZoomed: import('@preact/signals-core').Signal<boolean>;
18
- export declare const isAutoPlaying: import('@preact/signals-core').Signal<boolean>;
19
- export declare const autoPlayInterval: import('@preact/signals-core').Signal<number>;
20
- export declare const soundEnabled: import('@preact/signals-core').Signal<boolean>;
21
- export declare const zoomState: import('@preact/signals-core').Signal<{
7
+ export type FlipState = 'read' | 'fold_corner' | 'flipping';
8
+ export type Orientation = 'landscape' | 'portrait';
9
+ export interface ZoomState {
22
10
  isActive: boolean;
23
11
  translateX: number;
24
12
  translateY: number;
25
13
  isDragging: boolean;
26
14
  scale: number;
27
- }>;
28
- export declare const pages: import('@preact/signals-core').Signal<NormalizedFlipbookPage[]>;
29
- export declare const isDoublePageLayout: import('@preact/signals-core').ReadonlySignal<boolean>;
30
- export declare const isFrontCover: import('@preact/signals-core').ReadonlySignal<boolean>;
31
- export declare const isBackCover: import('@preact/signals-core').ReadonlySignal<boolean>;
15
+ }
16
+ export interface FlipbookStore {
17
+ currentPage: Signal<number>;
18
+ totalPages: Signal<number>;
19
+ isSingleMode: Signal<boolean>;
20
+ showThumbs: Signal<boolean>;
21
+ showArrows: Signal<boolean>;
22
+ orientation: Signal<Orientation>;
23
+ flipState: Signal<FlipState>;
24
+ themeMode: Signal<FlipbookThemeMode>;
25
+ allowDownload: Signal<boolean>;
26
+ hasDownloadUrl: Signal<boolean>;
27
+ primaryColor: Signal<string>;
28
+ whiteLabel: Signal<boolean>;
29
+ isZoomed: Signal<boolean>;
30
+ isAutoPlaying: Signal<boolean>;
31
+ autoPlayInterval: Signal<number>;
32
+ soundEnabled: Signal<boolean>;
33
+ locale: Signal<string>;
34
+ messages: Signal<Partial<Record<string, PartialFlipbookMessages>>>;
35
+ zoomState: Signal<ZoomState>;
36
+ pages: Signal<NormalizedFlipbookPage[]>;
37
+ isDoublePageLayout: ReadonlySignal<boolean>;
38
+ isFrontCover: ReadonlySignal<boolean>;
39
+ isBackCover: ReadonlySignal<boolean>;
40
+ init(options: FlipbookEngineOptions, total: number, mappedPages: NormalizedFlipbookPage[], hasPdfUrl: boolean): void;
41
+ }
42
+ /** Creates an isolated reactive state container for one FlipbookEngine instance. */
43
+ export declare function createFlipbookStore(): FlipbookStore;
44
+ export declare const currentPage: Signal<number>, totalPages: Signal<number>, isSingleMode: Signal<boolean>;
45
+ export declare const showThumbs: Signal<boolean>, showArrows: Signal<boolean>, orientation: Signal<Orientation>;
46
+ export declare const flipState: Signal<FlipState>, themeMode: Signal<FlipbookThemeMode>, allowDownload: Signal<boolean>;
47
+ export declare const hasDownloadUrl: Signal<boolean>, primaryColor: Signal<string>, whiteLabel: Signal<boolean>;
48
+ export declare const isZoomed: Signal<boolean>, isAutoPlaying: Signal<boolean>, autoPlayInterval: Signal<number>;
49
+ export declare const soundEnabled: Signal<boolean>, locale: Signal<string>, messages: Signal<Partial<Record<string, Partial<import('..').FlipbookMessages>>>>, zoomState: Signal<ZoomState>, pages: Signal<NormalizedFlipbookPage[]>;
50
+ export declare const isDoublePageLayout: ReadonlySignal<boolean>, isFrontCover: ReadonlySignal<boolean>, isBackCover: ReadonlySignal<boolean>;
32
51
  export declare function initStore(options: FlipbookEngineOptions, total: number, mappedPages: NormalizedFlipbookPage[], hasPdfUrl: boolean): void;
@@ -4,7 +4,8 @@ import { FlipbookEngineOptions, FlipbookPageAsset } from '../index';
4
4
  export declare const Flipbook: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
5
5
  pdfUrl: {
6
6
  type: StringConstructor;
7
- required: true;
7
+ required: false;
8
+ default: string;
8
9
  };
9
10
  pages: {
10
11
  type: PropType<FlipbookPageAsset[]>;
@@ -22,7 +23,8 @@ export declare const Flipbook: import('vue').DefineComponent<import('vue').Extra
22
23
  }>, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, "pageChange"[], "pageChange", import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
23
24
  pdfUrl: {
24
25
  type: StringConstructor;
25
- required: true;
26
+ required: false;
27
+ default: string;
26
28
  };
27
29
  pages: {
28
30
  type: PropType<FlipbookPageAsset[]>;
@@ -39,6 +41,7 @@ export declare const Flipbook: import('vue').DefineComponent<import('vue').Extra
39
41
  onPageChange?: ((...args: any[]) => any) | undefined;
40
42
  }>, {
41
43
  pages: FlipbookPageAsset[];
44
+ pdfUrl: string;
42
45
  options: Omit<FlipbookEngineOptions, "theme"> & {
43
46
  theme?: "auto" | "light" | "dark";
44
47
  };
package/package.json CHANGED
@@ -1,14 +1,18 @@
1
1
  {
2
2
  "name": "flipbookengine",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "A modern, embeddable HTML flipbook engine for PDF-backed catalogs and digital publications.",
5
5
  "private": false,
6
6
  "scripts": {
7
7
  "dev": "vite",
8
8
  "build": "vite build && vite build --config vite.config.iife.js",
9
9
  "test": "tsx --loader ./tests/css-loader.js --test tests/*.test.ts",
10
+ "test:e2e": "playwright test",
10
11
  "typecheck": "tsc --noEmit",
11
- "clean": "rimraf dist"
12
+ "clean": "rimraf dist",
13
+ "pack:check": "npm pack --dry-run",
14
+ "audit:deps": "npm audit --omit=dev --audit-level=high",
15
+ "release:verify": "npm run typecheck && npm test && npm run build && npm run audit:deps && npm run pack:check"
12
16
  },
13
17
  "keywords": [
14
18
  "flipbook",
@@ -84,12 +88,15 @@
84
88
  }
85
89
  },
86
90
  "devDependencies": {
91
+ "@playwright/test": "^1.63.0",
87
92
  "@types/jsdom": "^28.0.3",
88
93
  "@types/node": "^25.0.10",
89
94
  "@types/page-flip": "^2.0.4",
90
95
  "@types/react": "^19.2.14",
96
+ "@types/react-dom": "^19.2.3",
91
97
  "jsdom": "^29.1.1",
92
98
  "react": "^19.2.6",
99
+ "react-dom": "^19.2.6",
93
100
  "rimraf": "^6.0.0",
94
101
  "tsx": "^4.22.4",
95
102
  "typescript": "^5.0.0",